微信小程式:web-view巢狀H5實現微信支付功能解決方案及填坑
最近一個多月加班比較嚴重,偶爾休息一天也是在補睡眠+陪家人,比較長時間沒有來進行總結記錄了。今天不加班,開始為這段時間做的東西進行下經驗總結。
這段時間因為公司需要,接觸了一些.Net前後臺開發,慢慢了解了一些WCF、H5站點、WebService、Soap、Linq等,也瞭解了一些BLL、DAL相關內容。同時也參與了微信支付、微信醫保支付相關功能的改版,以及為微信小程式增加微信支付、微信醫保支付功能。
下面主要記錄下小程式支付相關方案、實現及填坑。
一. 產品現狀
首先,在接入微信支付功能以前,我們的產品情況是這樣的:
1
有公眾號和app的h5站點及相關配套功能
2
小程式已經有一些基礎功能,這些功能沒有使用web-view
3
小程式之前的伺服器是與現有公眾號h5站點不同的一個webapi站點
二. 備選方案
基於以上幾點,當時提出了兩套解決方案:
方案1. 支付相關功能使用小程式程式碼進行開發,並在webapi站點增加相應介面
方案2. 使用web-view嵌入公眾號h5站點的支付功能,包括訂單列表、訂單詳情、支付確認、支付下單、支付結果展示、支付歷史等,僅實際支付時使用小程式程式碼進行開發
最終我們使用的是第二套方案,本來以為有了現成的h5頁面,需要解決的僅僅是h5站點與webapi站點的登入同步以及小程式的支付介面喚起這兩個問題,結果發現,坑還是不少的。
三. 方案實現

微信小程式web-view巢狀h5接入支付功能
基本流程如上述示意圖,訂單相關頁面及微信支付下單過程都在h5,下單成功後通過wx.program.navigateTo跳轉回小程式,小程式執行wx.requestPayment喚起支付頁面,獲取的結果以h5展示。同時,在下單時會設定支付結果回撥頁(PayNotify),實際支付成功後,微信會主動呼叫PayNotify頁面,在該頁面操作訂單支付表的支付狀態。
小程式程式碼如下:
// 直接在onLoad中喚起支付頁面(中間的部分引數需要用decodeURIComponent解碼) onLoad: function(options) { var payType = options.type; var timeStamp = options.timeStamp; var nonceStr = decodeURIComponent(options.nonceStr); var package = decodeURIComponent(options.package); var signType = options.signType; var paySign = decodeURIComponent(options.paySign); if(type == 1) { // 微信支付 this.wxPay(timeStamp, nonceStr, package, signType, paySign); }else { var payAppId = options.appid; var payUrl = decodeURIComponent(options.payUrl); // 醫保支付,需要跳轉到醫保小程式進行支付,需要獲取醫保小程式appid和payurl } } // 喚起微信支付視窗 wxPay: function(timeStamp, nonceStr, package, signType, paySign) { wx.requestPayment({ 'timeStamp': timeStamp, 'nonceStr': nonceStr, 'package': package, 'signType': signType,//'MD5', 'paySign': paySign, 'success':function(res){ // 成功跳轉到h5結果頁面 }, 'fail':function(res){ // 失敗提示並返回訂單頁 }, 'complete': function(res){ // 較早版本,使用者取消支付,不進入fail回撥,僅回撥complete // res.errMsg為requestPayment:fail cancel if(res.errMsg=='requestPayment:fail cancel') { // 使用者取消返回訂單頁 } } }) }
注意:
- 在生成訂單表,下單成功後,即進入支付中狀態
- 建議區分訂單表和支付表
- 實際支付頁面的喚起只能在小程式中進行,不能使用h5喚起微信支付頁面
- 支付結果必須以微信回撥為準,不能直接使用wx.program.navigateTo返回的結果
- 因為公眾號和小程式使用的是同一套h5程式碼,所以必須將appid等設定為配置項,不同的入口,使用不同的appid;而且在支付表中,必須能明確是小程式還是公眾號支付的,不然會出現無法退款等情況。(退款的appid必須是支付的appid)
四. 填坑
坑1
支付商戶和小程式主體不一致,而且我們的商戶是特約商戶,導致小程式無法進行M-A授權並開通微信支付功能
解決方案:
這裡有多種解決方案,最快捷的是找騰訊內部人員提交申請,提交資訊後他們會幫忙進行M-A授權(我們下午提交第二天就ok了)
坑2
appid等資訊不同導致需要h5站點相容
解決方案:
增加支付相關的配置,不同的入口讀取不同的配置項,包含appid, appsecret,mchid,回撥地址等配置。
坑3
由於之前是在webapi進行登入,h5站點存在未登入的問題
解決方案:
我們webapi和h5使用的是同一個資料庫,所以我們只是在h5站點再進行一次openid的繫結,當然,這裡需要考慮的是小程式和公眾號都存在openid,我們得分開建立繫結關係。
這是我們產品之前設計存在的問題,其實是可以通過unionid來建立繫結關係(因為這個才是對微信使用者而言唯一不變的標識),同時也可以考慮快取不同來源的openid
坑4
歷史記錄及退款問題
解決方案:
需要在支付記錄中儲存是哪個端下的訂單,因為如果小程式支付的,一定要用小程式的appid等資訊去退款,公眾號也一樣。所以支付記錄表中應該有payType欄位,最好支付的訂單號生成時前兩位用於記錄支付方式,比如01開頭的是公眾號支付,02開頭是小程式支付。
我們的訂單號生成規則是 2位支付方式+1位交易訂單型別(支付、退款等)+2位商品型別 + 時間戳 + 其他
原文:簡書ThinkinLiu 部落格: ofollow,noindex">IT老五
ps
時間有點緊張,還有一些具體方案實現和坑沒總結,後續再補充。有什麼錯誤或者不足歡迎指出...