JS交互微信之JSAPI支付

前言

本篇為JS交互微信系列篇的第四篇微信JSAPI支付,記錄在微信內置瀏覽器內用調用微信支付過程。

一、 介紹

JSAPI支付是用戶在微信中打開商戶的H5頁面,商戶在H5頁面通過調用微信支付提供的JSAPI介面調起微信支付模組完成支付。

應用場景:

  • 用戶在微信公眾帳號內進入商家公眾號,打開某個主頁面,完成支付
  • 用戶的好友在朋友圈、聊天窗口等分享商家頁面連接,用戶點擊鏈接打開商家頁面,完成支付
  • 將商戶頁面轉換成二維碼,用戶掃描二維碼後在微信瀏覽器中打開頁面後完成支付

二、 準備

1. 準備內容

要擁有兩個帳號:

  1. 微信服務號,要通過認證(企業才擁有資格)
  2. 微信商戶平台號(微信支付平台)

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我們注意到,這裡有這兩個需要自己寫的參數:appidredirect_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來完成在微信內的支付就完成了。