1. 程式人生 > >微信小程式支付流程,非同步回撥及訊息模板呼叫(php原始碼)

微信小程式支付流程,非同步回撥及訊息模板呼叫(php原始碼)

首先還是老樣子把流程圖給大家發一下

商戶系統和微信支付系統主要互動:

1、小程式內呼叫登入介面,獲取到使用者的openid,api參見公共api【小程式登入API

2、商戶server呼叫支付統一下單,api參見公共api【統一下單API

3、商戶server呼叫再次簽名,api參見公共api【再次簽名

4、商戶server接收支付通知,api參見公共api【支付結果通知API

5、商戶server查詢支付結果,api參見公共api【查詢訂單API

獲取openid首先客戶端要呼叫wx.login()方法,得到code傳給伺服器端,伺服器接收code通過

wx.code2Session()獲取openid及其他引數,php程式碼如下:

public function login(Request $request){
        $code = $request -> get('code');
        $url = 'https://api.weixin.qq.com/sns/jscode2session';
        $str = 'appid='.self::appid.'&secret='.self::secret.'&js_code='.$code.'&grant_type=authorization_code';
        $new_url = $url.'?'.$str;
        $res = $this -> curlRequest($new_url);
        $res = json_decode($res,true);
        if(empty($res['openid'])){
            return json_encode(['status'=>1,'content'=>$res['errmsg']]);
        }
        $openid = $res['openid'];
        $session_key = $res['session_key'];
        $token = uniqid();
        $arr = [
            'openid' => $openid,
            'session_key' => $session_key,
            'token' => $token,
            'money' => 0,
            'status' => 1
        ];
        $data = DB::table('mobai_token')->where('openid',$openid)->first();
        if(empty($data)){
            DB::table('mobai_token')->insert($arr);
            return json_encode(['status'=>0,'content'=>$token]);
        }
        $token = $data->token;
        return json_encode(['status'=>0,'content'=>$token]);
    }

呼叫統一下單介面並返回wx.requestPayment()所需的引數(注意生成paySign的時候一定要按規則生成

//調取統一下單介面
    public function unpay(Request $request){
        $order = $request->get('rtime');
        $money = $request->get('money');
        $data = DB::table('mobai_order')->where('rtime',$order)->first();
        $openid = $data->openid;
        $unurl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $params = [
            'appid'             => self::appid,
            'mch_id'            => self::mch_id,
            'nonce_str'         => uniqid(),
            'body'              => '摩拜單車',
            'out_trade_no'      => $order,
            'total_fee'         => $money,
            'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
            'notify_url'        => 'https://mobai.xxxx.cn/notify',//此處寫你的回撥地址
            'trade_type'        => 'JSAPI',
            'openid'            => $openid,
        ];
        $params['sign'] = $this -> getSign($params);
        $xml = $this -> ArrToXml($params);
        $res = $this -> curlRequest($unurl,$xml);
        $arr = $this -> XmlToArr($res);
        $params2 = [
            'appId'     => self::appid,
            'timeStamp'     => strval(time()),   //建議把時間戳轉變成字串
            'nonceStr'     => uniqid(),
            'package'     => 'prepay_id='.$arr['prepay_id'],
            'signType'     => 'MD5'
        ];
        $params2['paySign'] = $this -> getSign($params2);
        $params2['prepay_id'] = $arr['prepay_id'];
        $redis = new \Redis();
        $redis -> connect('127.0.0.1',6379);
        $redis -> set($order,$arr['prepay_id']);   //儲存prepay_id,呼叫模板訊息的時候需要
        return $params2;
    }

 非同步回撥

 public function notify(){
        $data = file_get_contents('php://input');
        $arr = $this -> XmlToArr($data);
        $sign = $this -> getSign($arr);
        if($sign == $arr['sign']){
            //判斷返回狀態
            if($arr['return_code'] == 'SUCCESS' || $arr['result_code'] == 'SUCCESS'){
                $data = DB::table('mobai_order')->where('rtime',$arr['out_trade_no'])->where('status',1)->first();
                //判斷訂單金額
                if($data->money == $arr['total_fee']){
                    //修改訂單狀態
                    $res = DB::table('mobai_order')->where('rtime',$arr['out_trade_no'])->where('status',1)->update(['status'=>2]);
                    if($res){
                        $redis = new \Redis();
                        $redis -> connect('127.0.0.1',6379);
                        $prepay_id = $redis -> get($arr['out_trade_no']);  //prepay_id要在統一下單的時候做儲存
                        $money = $arr['total_fee']/100;
                        $this -> sendTemplateMessage($prepay_id,$arr['out_trade_no'],$money,$arr['openid']); //傳送模板訊息
                        echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';//給微信正常相應(如果沒有正常相應微信會根據自己的機制多次請求)
                    }
                }
            }
        }
    }

getSign()、XmlToArr()、ArrToXml()方法可以在這個部落格看:https://blog.csdn.net/weixin_42579642/article/details/84861502