在项目中用到小程序支付,费话不多说上代码

因为我这涉及么微信的很多开发功能  所以我把公共的方法放到的公共类中

WechatPublic
<?php
namespace app\zhonglian\controller\wechat;
use app\BaseController;
use think\facade\Config;
use EasyWeChat\Factory;
use app\zhonglian\controller\ZhonglianPublic;
class WechatPublic extends ZhonglianPublic{
    public $config;         //公众号配置文件
    public $app;            //公众号配置
    public $minConfig;      //小程序配置
    public $wechatPay;      //微信支付配置
    public function __construct(){
        $this->config = [
            /**
             * 账号基本信息,请从微信公众平台/开放平台获取
             */
            'app_id'  => Config::get('zhonglian.wechat.AppID'),      // AppID
            'secret'  => Config::get('zhonglian.wechat.AppSecret'),     // AppSecret
            'token'   => Config::get('zhonglian.wechat.token'),      // Token
            'aes_key' => Config::get('zhonglian.wechat.aes_key'),    // EncodingAESKey,安全模式与兼容模式下请一定要填写!!!
            'response_type' => 'array',
        ];
        // 小程序
        $this->minConfig = [
            'app_id' => Config::get('zhonglian.minWechat.AppID'),
            'secret' => Config::get('zhonglian.minWechat.AppSecret'),
        
            // 下面为可选项
            // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => __DIR__.'/wechat.log',
            ],
        ];
        $this->webHost = 'https:://'.$_SERVER['HTTP_HOST'];   //站点域名
        //微信支付
        $this->wechatPay    =   [
            // 必要配置
            'app_id'             => Config::get('zhonglian.wechatPay.app_id'),
            'mch_id'             => Config::get('zhonglian.wechatPay.mch_id'),
            'key'                => Config::get('zhonglian.wechatPay.key'),   // API 密钥

            // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path'          => 'V6/wechatpay/apiclient_cert.pem', // XXX: 绝对路径!!!!
            'key_path'           => 'V6/wechatpay/apiclient_key.pem',  // XXX: 绝对路径!!!!
            'notify_url'         => $this->webHost.'/zhonglian/zl/pay_notify',     // 你也可以在下单时单独设置来想覆盖它
        ];
        
        $this->app = Factory::officialAccount($this->config);
        $this->minApp = Factory::miniProgram($this->minConfig);
        $this->pay = Factory::payment($this->wechatPay);
    }
}

Pay

<?php
namespace app\zhonglian\controller\wechat;
use app\zhonglian\controller\wechat\WechatPublic;
use app\zhonglian\model\UserAccessToken;
use app\zhonglian\model\UserZhonglianOrder;
use think\Controller;
use EasyWeChat\Foundation\Application;
use think\exception\ValidateException;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Messages\Text;
use think\facade\Log;

use app\zhonglian\validate\Pay as PayV;
class Pay extends WechatPublic{
    public function pay(){
        if(request()->isPost()){
            $data = input('post.');
            try {
                validate(PayV::class)
                    ->scene('pay')
                    ->check($data);
            } catch (ValidateException $e) {
                // 验证失败 输出错误信息
                return json(['code'=>10001,'msg'=>$e->getError()]);
            }
            $data['orderId'] = date('YmdHis', time()).rand(10000,99999);
            $data['userId'] = UserAccessToken::where('accessToken',$data['access_token'])->value('userId');
            //存入数据至本地表
            $res = UserZhonglianOrder::addData($data);
            $result = $this->pay->order->unify([
                'body'          => $data['body'],
                'out_trade_no'  => $date['orderId'],
                'total_fee'     => floatval($data['total_fee'] * 100),
                'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
                'notify_url'    => $this->webHost.'/zhonglian/zl/pay_notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                'trade_type'    => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid'        => $data['openid'],
            ]);
            /*$result返回数据如下
            $result = [
                "return_code" => "SUCCESS",         
                "return_msg" => "OK",
                "appid" => "****************",
                "mch_id" => ""****************",",
                "nonce_str" => "oYRmqEGsfV95H221",
                "sign" => "37DC4CB564102893FC8C09C488D2FA00",
                "result_code" => "SUCCESS",
                "prepay_id" => "wx0411540670981758f0ccc5845afd110000",
                "trade_type" => "JSAPI"
            ];
            */
            if($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS'){
                return json(['code'=>1,'msg'=>'获取支付订单失败']);
            }else{
                if ($res) {
                    $jssdk = $this->pay->jssdk;
                    $config = $jssdk->bridgeConfig($result['prepay_id'], false);
                    return json(['code'=>0,'data'=>$config]);
                } else {
                    return json(['code'=>1,'msg'=>'创建订单失败!']);
                }    
            }
            /*$config返回如下
            [
                'appId' => 'wx9ae6b16168110e36',
                'timeStamp' => '1604475465',
                'nonceStr' => '5fa25a49a887b',
                'package' => 'prepay_id=wx0411540670981758f0ccc5845afd110000',
                'signType' => 'MD5',
                'paySign' => 'A332227D36EC94B3610A86C8049F069C',
              ]
            */
        }  
    }
    //支付回调
    public function pay_notify(){
        $response = $this->pay->handlePaidNotify(function($message, $fail){
            $order = Db::name('order')->where(['order'=> $message['out_trade_no']])->find();
            if (!$order || $order['status']==2) { // 如果订单不存在 或者 订单已经支付过了
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
                // 用户是否支付成功
                if ($message['result_code'] === 'SUCCESS') {
                 //成功处理操作 略
          //$message['out_trade_no']  商户订单号
// 用户支付失败
                } elseif ($message['result_code'] === 'FAIL') {
                    return true;
                }
            } else {
                return false;
            }
        });
        return $response;
    }

    public function get_openid()
    {
        $code = $this->request->param('code');
        $res = $this->app->auth->session($code);
        return json($res);
    }
}

小程序

getUserInfo: function (e){
    var that = this;
    if (e.detail.userInfo) {
      wx.login({
        success: res_user => {
          http.Get("/zhonglian/zl/get_openid", {code:res_user.code}, function (res) {
            console.log(res.data)
            wx.setStorageSync('openid', res.data.openid);
            wx.setStorageSync('nickname', e.detail.userInfo.nickName);
            wx.setStorageSync('image',  e.detail.userInfo.avatarUrl);
            wx.setStorageSync('sex',   e.detail.userInfo.gender);
            that.setData({login:false})
          });
        }
      })  
    } else {
      console.log('用户拒绝了授权')
      wx.showToast({
        title: "为了您更好的体验,请同意授权登陆",
        icon: 'none',
        duration: 2000
      });
    }
  },
pay:function (){
    var that = this
    var formData = {
      access_token: '***********',
      total_fee: 0.01,
      openid: wx.getStorageSync('openid'),
      body: '支付产品',
    }
    http.Post("/zhonglian/zl/pay", formData, function (res) { 
        console.log(res.data);  
        console.log('调起支付');  
        wx.requestPayment({  
          'timeStamp': res.data.timeStamp,  
          'nonceStr': res.data.nonceStr,  
          'package': res.data.package,  
          'signType':'MD5',  
          'paySign': res.data.paySign,  
          'success':function(resa){              
            console.log('支付成功')
          },  
          'fail':function(err){ 
            console.log('支付失败');  
          } 
        });  
     
    });
  },