thinkPHP + easywechat 小程式支付(含回撥)
阿新 • • 發佈:2021-07-15
thinkPHP框架+easywechat擴充套件包,composer下載
$ composer require overtrue/wechat:~5.0 -vvv
composer安裝擴充套件包,這裡就不說了,可以看官方文件。
注意:微信小程式支付驗證簽名失敗 EasyWeChat 需要二次簽名!
必須使用二次簽名 必須使用二次簽名 必須使用二次簽名 重要的事情說三遍!!!
先建一個php檔案
<?php namespace wechat; use EasyWeChat\Factory; /* * 支付 * */ class WeChat extends Base {//小程式支付使用JSAPI public function pay(){ //必要配置 $config = [ 'app_id' => 'wx1234556677888', 'mch_id' => '1232545667', 'key' => '95e26976346a8431d89569c0f742', 'notify_url' => "http://www.xxx.com/pay/notify" ]; $app= Factory::payment($config); $pay_info = [ 'trade_type' => 'JSAPI', // 支付方式,小程式支付使用JSAPI 'body' => '測試訂單', // 訂單說明 'out_trade_no' => 'wx35465768535', // 自定義訂單號 'total_fee' => 1 * 100, //單位:分 'openid' => $openid // 當前使用者的openId ] $result = $app->order->unify($pay_info); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { // $prepayId = $result['prepay_id']; //$jssdk = $app->jssdk; // $config = $jssdk->sdkConfig($prepayId); //不能使用返回的配置引數,否則會報簽名錯誤 //必須使用二次簽名 $appId = $result['appid']; $nonceStr = $result['nonce_str']; $prepay_id = $result['prepay_id']; $timeStamp = time(); $key = $payment['app_key']; $paySign = md5("appId=$appId&nonceStr=$nonceStr&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$timeStamp&key=$key"); // 這個地方就是我所說的二次簽名! // 返回給小程式使用 $config=[]; $config['nonceStr']=$nonceStr; $config['timeStamp']=strval($timeStamp); // 小程式支付的timeStamp引數,必須使用這個 timeStamp,因為已經計算到了paySign中 $config['package']="prepay_id=".$prepay_id; $config['paySign']=$paySign; $config['signType']='MD5'; return $success('成功', ['config'=>$config, 'url' => "http://www.xxx.com/pay/notify"]); } if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) { return $fail('錯誤:' . $result['return_msg']); } return $fail('錯誤' . $result['err_code_des']); } //支付回撥 public function notify() { //必要配置 $config = [ 'app_id' => 'wx1234556677888', 'mch_id' => '1232545667', 'key' => '95e26976346a8431d89569c0f742', 'notify_url' => "http://www.xxx.com/pay/notify" ]; $app = Factory::payment($config); $response = $app->handlePaidNotify(function($message, $fail){ // 使用通知裡的 "微信支付訂單號" 或者 "商戶訂單號" 去自己的資料庫找到訂單 $order = 查詢訂單($message['out_trade_no']); if (!$order || $order->paid_at) { // 如果訂單不存在 或者 訂單已經支付過了 return true; // 告訴微信,我已經處理完了,訂單沒找到,別再通知我了 } ///////////// <- 建議在這裡呼叫微信的【訂單查詢】介面查一下該筆訂單的情況,確認是已經支付 ///////////// if ($message['return_code'] === 'SUCCESS') { // return_code 表示通訊狀態,不代表支付狀態 // 使用者是否支付成功 if (array_get($message, 'result_code') === 'SUCCESS') { $order->paid_at = time(); // 更新支付時間為當前時間 $order->status = 'paid'; // 使用者支付失敗 } elseif (array_get($message, 'result_code') === 'FAIL') { $order->status = 'paid_fail'; } } else { return $fail('通訊失敗,請稍後再通知我'); } $order->save(); // 儲存訂單 return true; // 返回處理完成 }); $response->send(); // return $response; } }