一、微信支付分介紹及開通
- 產(chǎn)品介紹:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_0.shtml
- 接入前準(zhǔn)備:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_1.shtml
- 測(cè)試號(hào)配置:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_5.shtml
二、免確認(rèn)模式開發(fā)
參考網(wǎng)址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_3.shtml
- 步驟1 用戶在商戶側(cè)下單購(gòu)買產(chǎn)品或服務(wù),此時(shí),我們需要先對(duì)用戶的授權(quán)狀態(tài)進(jìn)行查詢
- 步驟2 引導(dǎo)用戶開啟授權(quán)服務(wù)
- 步驟3 創(chuàng)建支付分訂單
- 步驟4 商戶為用戶提供服務(wù),待服務(wù)結(jié)束后,商戶調(diào)用完結(jié)訂單接口完結(jié)當(dāng)前訂單。
- 步驟5 收到用戶扣款成功通知,業(yè)務(wù)流程結(jié)束
三、SDK相關(guān)
- 官方文檔:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml
- wechatpay-php(推薦):https://github.com/wechatpay-apiv3/wechatpay-php
四、代碼示例
/** * Notes: 步驟1 用戶在商戶側(cè)下單購(gòu)買產(chǎn)品或服務(wù),此時(shí),我們需要先對(duì)用戶的授權(quán)狀態(tài)進(jìn)行查詢 * User: XXX * DateTime: 2021/7/27 9:59 */ public function getAuthStatus(string $cid) { $openid = $this->getOpenid($cid); if (!$openid) { return false; } try { $resp = $this->instance->v3->payscore->permissions->openid->{'{openid}'} ->get( [ 'query' => [ 'appid' => $this->appid, 'service_id' => $this->serviceId, ], // uri_template 字面量參數(shù) 'openid' => $openid, ] ); $res = json_decode($resp->getBody()->getContents(), true); if ($res['authorization_state'] == 'AVAILABLE') { return true; } else { return false; } } catch (Exception $e) { return false; /*echo($e->getResponse()->getStatusCode()); // 進(jìn)行錯(cuò)誤處理 echo $e->getMessage()->getReasonPhrase(), PHP_EOL; if ($e instanceof PsrHttpMessageResponseInterface && $e->hasResponse()) { echo $e->getResponse()->getStatusCode() . ' ' . $e->getResponse()->getReasonPhrase(), PHP_EOL; echo $e->getResponse()->getBody(); }*/ } }
/** * Notes:步驟2 引導(dǎo)用戶開啟授權(quán)服務(wù)-獲取預(yù)授權(quán)碼 * User: XXX * DateTime: 2021/7/27 18:37 */ public function openAuthStatus() { try { $resp = $this->instance->v3->payscore->permissions->post( [ 'json' => [ 'service_id' => $this->serviceId, 'appid' => $this->appid, 'authorization_code' => $this->getRandStr(12), // 授權(quán)協(xié)議號(hào),類似訂單號(hào) //'notify_url' => 'https://weixin.qq.com/', ] ] ); $res = json_decode($resp->getBody(), true); return $res['apply_permissions_token']; } catch (Exception $e) { // 進(jìn)行錯(cuò)誤處理 /*if ($e->hasResponse()) { echo $e->getResponse()->getBody(); }*/ return false; } }
/** * Notes: 步驟3 創(chuàng)建支付分訂單 * User: xxx * DateTime: 2021/7/27 19:21 * @param string $cid 用戶ID * @param string $orderSn 訂單號(hào) */ public function makeOrder(string $cid, string $orderSn) { // 訂單信息 .... $openid = $this->getOpenid($cid); if (!$openid) { return [ 'code' => -1, 'msg' => 'openid不可以為空', ]; } // 異步通知地址,有時(shí)候發(fā)現(xiàn)莫名的變成了localhost,這里先固定 $notiryUrl = route('api.v1.wxpayPointsNotify'); $json = [ 'out_order_no' => $orderSn, // 商戶服務(wù)訂單號(hào) 'appid' => $this->appid, // 應(yīng)用ID 'service_id' => $this->serviceId, // 服務(wù)ID 'service_introduction' => '換電費(fèi)用', // 服務(wù)信息,用于介紹本訂單所提供的服務(wù) ,當(dāng)參數(shù)長(zhǎng)度超過20個(gè)字符時(shí),報(bào)錯(cuò)處理 'time_range' => [ 'start_time' => $startTime, //'20210729160710', ], 'risk_fund' => [ 'name' => 'ESTIMATE_ORDER_COST', // 風(fēng)險(xiǎn)金名稱 'amount' => 300, // 風(fēng)險(xiǎn)金額 數(shù)字,必須>0(單位分) ], 'attach' => $orderSn,// 商戶數(shù)據(jù)包 'notify_url' => $notiryUrl, 'openid' => $openid,// 用戶標(biāo)識(shí) 'need_user_confirm' => false,// 是否需要用戶確認(rèn) ]; try { $resp = $this->instance->v3->payscore->serviceorder->post( [ 'json' => $json ] ); $res = json_decode($resp->getBody(), true); // 入庫(kù)支付分訂單 ... return [ 'code' => 0, 'msg' => '支付分訂單創(chuàng)建完成', ]; } catch (Exception $e) { // 進(jìn)行錯(cuò)誤處理 if ($e->hasResponse()) { $body = $e->getResponse()->getBody(); if ($body) { return [ 'code' => -1, 'msg' => (string)$body, ]; } } return ''; } }
完結(jié)支付分訂單、取消支付分訂單、查詢支付分訂單 類似,這里不再寫出來(lái)。
/** * Notes: 異步通知 * User: XXX * DateTime: 2021/8/3 14:20 */ public function notify() { // 獲取返回的信息 $responseBody = file_get_contents("php://input"); $responseArr = json_decode($responseBody, true); if ($responseArr) { $res = AesGcm::decrypt($responseArr['resource']['ciphertext'], 'xxxapi密鑰', $responseArr['resource']['nonce'], $responseArr['resource']['associated_data']); $resArr = json_decode($res, true); if ($resArr) { // 記錄日志 ... // 業(yè)務(wù)邏輯處理 ... // 訂單日志記錄 ... } else { return [ 'code' => -1, 'msg' => '解析有誤', ]; } } else { return [ 'code' => -1, 'msg' => 'nothing post', ]; } }
五、注意事項(xiàng)
- 嚴(yán)格遵循文檔中的參數(shù)要求,出現(xiàn)問題第一時(shí)間比較傳入?yún)?shù)和官方示例的區(qū)別
-
支付分訂單必須取消,或完結(jié)
推薦學(xué)習(xí):《PHP視頻教程》