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; } }