最新公司要开发一个带微信支付功能的小程序,本文将详细记录开发一个带微信支付功能的小程序的后台实现代码流程,以供开发者参考和复用。

在开始编码之前,确保已经具备以下条件:ThinkPHP依赖以下环境Nginx/Apache+PHP,建议提前装好Composer。PHP、Composer需要设置好系统环境变量。注册并登录微信公众平台,获取小程序的AppID和秘钥。注册并登录微信支付平台,获取微信支付商户号(MchID)和支付秘钥。

ThinkPHP6.0的环境要求如下:PHP >= 7.2.5。ThinkPHP6.0版本开始,必须通过Composer方式安装和更新,所以无法通过Git下载安装。


1.通过 Composer 安装 ThinkPHP6框架 

thinkphp6官方手册

composer create-project topthink/think thinkphp6

ThinkPHP6+EasyWeChat5实现(小程序获取用户openid,手机号,支付)小白图文教程1_ThinkPHP

启动服务测试

cd thinkphp6
php think run

然后就可以在浏览器中访问

http://localhost:8000/

ThinkPHP6+EasyWeChat5实现(小程序获取用户openid,手机号,支付)小白图文教程1_微信支付_02

如果不能显示这个界面,请检查是否漏掉了上面某个步骤

如果需要更新框架使用

composer update topthink/framework

2.通过 Composer 安装 EasyWeChat

easywechat5.x官方手册

composer require w7corp/easywechat

ThinkPHP6+EasyWeChat5实现(小程序获取用户openid,手机号,支付)小白图文教程1_ThinkPHP_03

3.创建配置文件,设置小程序的appid和appsercret等信息

在 config 目录中创建配置文件 wechat.php, 这里只用到了小程序登录和支付,如需要其他的功能, 按需增加配置信息即可,格式可以自己定。不建议把小程序信息写入代码中,最好是写在.env文件中。

wechat.php代码

<?php
return [
    'app_id' => env('wechat.app_id', ''),
    'secret' => env('wechat.secret', ''),
    // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
    'response_type' => 'array',
    // 缓存 目录为 `runtime/wechat.log`
    'log' => [
        'level' => 'debug',
        'file' => app()->getRuntimePath() . '/wechat.log',
    ],
    // V2 支付配置
    'pay' => [
        'mch_id' => env('wechat.mch_id', ''),
        // V2 密钥
        'v2_key' => env('wechat.v2_key', ''),
        // 绝对路径
        'cert_path' => app()->getRuntimePath() . '/cert/cert.pem',
        // 绝对路径
        'key_path' => app()->getRuntimePath() . '/cert/key.pem',
        // 异步通知地址
        'notify_url' => app()->request->scheme(). '://'. app()->request->host(). '/index.php/wechat/notify',
    ]
];

.env代码,具体数据替换成你自己的

APP_DEBUG = true

[APP]
DEFAULT_TIMEZONE = Asia/Shanghai

[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = test
USERNAME = username
PASSWORD = password
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true

[LANG]
default_lang = zh-cn

[WECHAT]
app_id = app_id
secret = secret
mch_id = mch_id
v2_key = v2_key

4.创建请求文件

在 app 目录创建 controller/Wechat.php

<?php

namespace app\controller;

use app\BaseController;
use EasyWeChat\Factory;
use think\facade\Config;

class Wechat extends BaseController
{

    public function getConfig(): array
    {
        $wechat = Config::get('wechat');
        return [
            'app_id' => $wechat['app_id'],
            'secret' => $wechat['secret'],
            'mch_id' => $wechat['pay']['mch_id'],
            'key' => $wechat['pay']['v2_key'],
            'cert_path' => $wechat['pay']['cert_path'],
            'key_path' => $wechat['pay']['key_path'],
            'notify_url' => $wechat['pay']['notify_url'],
        ];
    }

    /**
     * 生产不重复的随机字符串
     */
    public function createNonceStr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return date('Ymd') . $str;
    }

    /**
     * 获取用户openid
     *
     */
    public function getOpenid()
    {
        $code = $this->request->param('code');
        if ($code) {
            // 创建微信小程序对象
            $wechat = Factory::miniProgram($this->getConfig());
            // 获取 session_key 和 openid
            $result = $wechat->auth->session($code);
            // 处理结果
            if (isset($result['openid'])) {
                // 业务处理
                return json(['code' => 1, 'data' => $result['openid'], 'msg' => '获取openid成功']);
            } else {
                // 报错 $res['errmsg']
                return json(['code' => 0, 'data' => '', 'msg' => $result['errmsg']]);
            }
        } else {
            return json(['code' => 0, 'data' => '', 'msg' => 'code不能为空']);
        }
    }

    /**
     * 获取用户手机号
     *
     */
    public function getPhoneNumber()
    {
        $phone_code = $this->request->param('phone_code');
        if ($phone_code) {
            $wechat = Factory::miniProgram($this->getConfig());
            $result = $wechat->phone_number->getUserPhoneNumber($phone_code);
            if (isset($result['phone_info'])) {
                // 业务处理
                return json(['code' => 1, 'data' => $result['phone_info']['phoneNumber'], 'msg' => '获取手机号成功']);
            } else {
                // 报错 $res['errmsg']
                return json(['code' => 0, 'data' => '', 'msg' => $result['errmsg']]);
            }
        } else {
            return json(['code' => 0, 'data' => '', 'msg' => 'phone_code不能为空']);
        }
    }

    /**
     * 微信支付
     */
    public function pay()
    {
        $open_id = $this->request->param('open_id');
        if ($open_id) {
            // 创建微信支付对象
            $wechat = Factory::payment($this->getConfig());
            // 组装请求参数
            $params = [
                'body' => '1分钱支付测试',                                // 商品描述
                'out_trade_no' => $this->createNonceStr(10),     // 商户订单号
                'total_fee' => 1,                                       // 订单总金额,单位为分,只能为整数
                'spbill_create_ip' => '',                               // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
                'notify_url' => 'https://你的线上地址/index.php/wechat/notify',     // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI',                                // 请对应换成你的支付方式对应的值类型
                'openid' => $open_id,
            ];
            // 发起支付请求
            $result = $wechat->order->unify($params);
            // 处理支付结果
            if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
                // 根据$result中的prepay_id生成签名等信息
                // 将生成的信息返回给前端进行支付
                $response = $wechat->jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
                return json(['code' => 1, 'data' => $response, 'msg' => '微信支付成功']);
            } else {
                // 支付失败,处理错误信息
                return json(['code' => 0, 'data' => $result, 'msg' => '微信支付失败']);
            }
        } else {
            return json(['code' => 0, 'data' => '', 'msg' => 'open_id不能为空']);
        }
    }

}

大家也可以根据自己的需求编写代码。

我的demo代码地址:微信小程序前后台完整demo示例。喜欢的给一个Star,有帮助的给一个Fork。

创作不易,如果您觉得这篇文章对您有帮助,欢迎点赞、收藏、转发,有不同的见解可以评论区留言。感谢支持!