JS交互微信之JSAPI支付
- 2020 年 3 月 6 日
- 筆記
前言
本篇為JS交互微信系列篇的第四篇微信JSAPI支付,記錄在微信內置瀏覽器內用調用微信支付過程。
一、 介紹
JSAPI支付是用戶在微信中打開商戶的H5頁面,商戶在H5頁面通過調用微信支付提供的JSAPI介面調起微信支付模組完成支付。
應用場景:
- 用戶在微信公眾帳號內進入商家公眾號,打開某個主頁面,完成支付
- 用戶的好友在朋友圈、聊天窗口等分享商家頁面連接,用戶點擊鏈接打開商家頁面,完成支付
- 將商戶頁面轉換成二維碼,用戶掃描二維碼後在微信瀏覽器中打開頁面後完成支付
二、 準備
1. 準備內容
要擁有兩個帳號:
- 微信服務號,要通過認證(企業才擁有資格)
- 微信商戶平台號(微信支付平台)
2. 平台配置
2.1 微信支付(商戶平台)中
要開通產品中心的JSAPI支付。然後 產品中心=>開發配置=>支付配置=>公眾號支付配置
綁定支付授權目錄,寫已通過ICP備案的域名。另外,要在ip白名單中,配置測試地址ip和線上生產地址ip,不然各種回調都會失敗!
2.2 微信公眾平台中
由於在微信內支付需要獲取用戶的 openid
,要獲取它則必須通過網頁授權配置。在公微信公眾平台中, 公眾號設置=>功能設置=>網頁授權域名
中按要求填寫。
三、 開發
在支付流程方面,重點依然都在後端處理,前端方面步驟比較簡單。本文只敘述前端內容。
1. 用戶授權,獲取code
在將要進入支付的前一頁面,直接接入微信授權,然後跳轉進要支付的那個頁面。舉個例子:有a、b兩個頁面,在b頁面用到支付,b頁面由a頁面跳轉而來。那麼在a頁面跳b頁面的時候,別直接跳轉b的url,而是跳轉到:https://open.weixin.qq.com/connect/oauth2/authorize?appid={appId}&redirect_uri={b.html}&response_type=code&scope=snsapi_base#wechat_redirect
我們注意到,這裡有這兩個需要自己寫的參數:appid
和 redirect_uri
,意義是:
- appid——服務號id
- redirect_uri——獲取授權後回調的頁面地址,比如b頁面
另外,還有一個注意的點是,b.html這個url我們要進行encode轉碼,不然地址解析可能會出現問題!
// url轉碼 let url = 'a.html'; url = escape(url);
2. 得到code,換取憑證獲取openid
上一步執行完後,在微信瀏覽器中,我們會得到一個鏈接,類似:b.html?&code={code}&state=#/
在此處,我們得到了一個code值,這就是我們獲取 openid
的憑證了。獲取方法當然是把值傳給後台,後台去處理啦~
3. 接收後端返回的我們需要的參數值
在上一步中,我們拿到code值後,就可以提交一些資訊給後端了,比如商品相關屬性、總價等,另外加上code值,傳給後端。後端一頓操作後,返回給前端。我們需要的參數如下(後端返回下面這些參數):
// 微信支付需要參數 orderInfo: { package: '', // 前端需要從後台獲取該數據 paySign: '', // 微信簽名,前端需要從後台獲取該數據 appId: '', // 需要在微信綁定商戶號,成功之後會生成有appid signType: '', // 微信簽名方式,默認為"MD5",也可以從後台獲取 nonceStr: '', // 隨機串,前端需要從後台獲取該數據 timeStamp: '', // 時間戳,自1970年以來的秒數,前端需要從後台獲取該數據 }
4. 交互微信
上個步驟拿到需要交互微信的參數後,就開始調用微信的支付介面了,如下:
// 微信支付 WeixinJSBridge.invoke('getBrandWCPayRequest', { appId: _this.orderInfo.appId, // 上一步得到的參數 nonceStr: _this.orderInfo.nonceStr, // 上一步得到的參數 package: _this.orderInfo.package, // 上一步得到的參數 signType: _this.orderInfo.signType, // 上一步得到的參數 timeStamp: _this.orderInfo.timeStamp, // 上一步得到的參數 paySign: _this.orderInfo.paySign // 上一步得到的參數 }, res => { // 調用後要做的事兒 // codes... // 根據get_brand_wcpay_request的值判斷支付狀態 if (res.err_msg === "get_brand_wcpay_request:ok") { // ok:支付成功 // 支付成功要做的事兒,比如跳轉支付完成後的頁面等 } else if (res.err_msg === "get_brand_wcpay_request:cancel") { // cancel:用戶取消支付 // 取消支付要做的事兒,比如進入重新支付步驟等 } else if (res.err_msg === "get_brand_wcpay_request:fail") { // fail:支付失敗 // 支付失敗要做的事兒,比如進入支付失敗步驟等 } // 註:使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回ok,但並不保證它絕對可靠。 })
5. 常見錯誤碼
名稱 |
描述 |
原因 |
解決方案 |
---|---|---|---|
INVALID_REQUEST |
參數錯誤 |
參數格式有誤或者未按規則上傳 |
訂單重入時,要求參數值與原請求一致,請確認參數問題 |
NOAUTH |
商戶無此介面許可權 |
商戶未開通此介面許可權 |
請商戶前往申請此介面許可權 |
NOTENOUGH |
餘額不足 |
用戶帳號餘額不足 |
用戶帳號餘額不足,請用戶充值或更換支付卡後再支付 |
ORDERPAID |
商戶訂單已支付 |
商戶訂單已支付,無需重複操作 |
商戶訂單已支付,無需更多操作 |
ORDERCLOSED |
訂單已關閉 |
當前訂單已關閉,無法支付 |
當前訂單已關閉,請重新下單 |
SYSTEMERROR |
系統錯誤 |
系統超時 |
系統異常,請用相同參數重新調用 |
APPIDNOTEXIST |
APPID不存在 |
參數中缺少APPID |
請檢查APPID是否正確 |
MCHIDNOTEXIST |
MCHID不存在 |
參數中缺少MCHID |
請檢查MCHID是否正確 |
APPIDMCHIDNOT_MATCH |
appid和mch_id不匹配 |
appid和mch_id不匹配 |
請確認appid和mch_id是否匹配 |
LACK_PARAMS |
缺少參數 |
缺少必要的請求參數 |
請檢查參數是否齊全 |
OUTTRADENO_USED |
商戶訂單號重複 |
同一筆交易不能多次提交 |
請核實商戶訂單號是否重複提交 |
SIGNERROR |
簽名錯誤 |
參數簽名結果不正確 |
請檢查簽名參數和方法是否都符合簽名演算法要求 |
XMLFORMATERROR |
XML格式錯誤 |
XML格式錯誤 |
請檢查XML參數格式是否正確 |
REQUIREPOSTMETHOD |
請使用post方法 |
未使用post傳遞參數 |
請檢查請求參數是否通過post方法提交 |
POSTDATAEMPTY |
post數據為空 |
post數據不能為空 |
請檢查post數據是否為空 |
NOT_UTF8 |
編碼格式錯誤 |
未使用指定編碼格式 |
請使用UTF-8編碼格式 |
三、 完成
至此,調用微信JSAPI來完成在微信內的支付就完成了。