僅此文章記錄一下蛋疼的微信小程式支付?
小程式微信支付基本介紹
小程式支付的文件地址見 (小程式微信支付API)以及 小程式支付業務流程
在業務流程裡我們可以看到幾個基礎的步驟。
- 首先要獲取到使用者的openid
- 呼叫微信的統一下單API來生成訂單
- 伺服器再次進行簽名
- 接收支付通知
- 查詢支付結果
我在開發過程中碰到的主要問題就是伺服器進行再次簽名,這裡主要是微信的文件寫著比較模糊。導致在這裡浪費了比較多的精力。
伺服器端程式碼
首先引入 @安正超 大大的 overtrue/laravel-wechat
composer包。當然引入 overtrue/wechat
也是可以的。基礎的配置檔案就不說了。按照說明配置好就可以了。
獲取小程式使用者的 openid
在小程式中呼叫wx.login()
會返回一個code,將code引數傳給我們的API中進行處理就可以得到openid了。 示例程式碼如下
$mini = \EasyWeChat::miniProgram();
$result = $mini->auth->session($code); // $code 為wx.login裡的code
// 如果code正確的話,那麼此時$result 裡就會包含openid, session_key等資訊。
// 此時可以將openid儲存到自己需要的資料庫中
// $result['openid'] = 'your-openid';
統一下單 && 二次簽名
通過使用安正超大大封裝的包,我們可以很方便的進行統一下單,不過與 easywechat 裡的文件示例不太一樣的是我們要傳的引數要多一些。以及配置檔案裡的'notify_url'一定要配置正確。 具體程式碼如下
use function EasyWeChat\Kernel\Support\generate_sign;
$payment = \EasyWeChat::payment(); // 微信支付
$result = $payment->order->unify([
'body' => '你自己想寫的名稱',
'out_trade_no' => '你自己定義的訂單號',
'trade_type' => 'JSAPI', // 必須為JSAPI
'openid' => '在上一步中獲取到的openid', // 這裡的openid為付款人的openid
'total_fee' => 1, // 總價
]);
// 如果成功生成統一下單的訂單,那麼進行二次簽名
if ($result['return_code'] === 'SUCCESS') {
// 二次簽名的引數必須與下面相同
$params = [
'appId' => '你的小程式的appid',
'timeStamp' => time(),
'nonceStr' => $result['nonce_str'],
'package' => 'prepay_id=' . $result['prepay_id'],
'signType' => 'MD5',
];
// config('wechat.payment.default.key')為商戶的key
$params['paySign'] = generate_sign($params, config('wechat.payment.default.key'));
return $params;
} else {
return $result;
}
// 如果成功二次簽名,返回的結果與下面的類似
// $params = {
// "appId": "wxedsadwvsager343df5",
// "timeStamp": 1520515252,
// "nonceStr": "wGs9JOpqKQcJYf7m",
// "package": "prepay_id=wx201803cdsqa2ae1e202110689669353",
// "signType": "MD5",
// "paySign": "398729A0461F5A825DA169CA29721038"
// }
在小程式支付文件中可能對二次簽名加密說了很多的步驟,不過我在翻閱了overtrue/wechat
包之後,發現已經將二次簽名方法封裝了,所以直接引入use function EasyWeChat\Kernel\Support\generate_sign;
後進行呼叫即可。
最後付款API返回上面的$params供小程式端呼叫即可,當然,還有回撥裡的notify_url需要進行處理,可以參照 這裡 進行處理。
小程式端程式碼實現
// 首先使用wx.request來呼叫上面的Laravel API 返回 data。
// 然後將獲取到的引數傳入到付款API裡面就可以了。
// 如果一切順利的話,微信小程式支付就成功的跑通了?
wepy.requestPayment({
timeStamp: data.timeStamp.toString(),
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.paySign,
success: function(res) {
console.log('付款成功')
console.log(res)
},
fail: function(res) {
console.log('付款失敗')
console.log(res)
}
})