使用easywechat和THINKPHP6做小程序支付


在項目中用到小程序支付,費話不多說上代碼

因為我這涉及么微信的很多開發功能  所以我把公共的方法放到的公共類中

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('支付失敗');  
          } 
        });  
     
    });
  },

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM