1. 程式人生 > >微信小程式:web-view巢狀H5實現微信支付功能解決方案及填坑

微信小程式:web-view巢狀H5實現微信支付功能解決方案及填坑

微信小程式: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') {
        // 使用者取消返回訂單頁
    }
  }
 })
}

#####注意:

  1. 在生成訂單表,下單成功後,即進入支付中狀態
  2. 建議區分訂單表和支付表
  3. 實際支付頁面的喚起只能在小程式中進行,不能使用h5喚起微信支付頁面
  4. 支付結果必須以微信回撥為準,不能直接使用wx.program.navigateTo返回的結果
  5. 因為公眾號和小程式使用的是同一套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 部落格: IT老五

ps 時間有點緊張,還有一些具體方案實現和坑沒總結,後續再補充。有什麼錯誤或者不足歡迎指出…
另外,使用web-view在體驗上感覺有點坑,坑1. h5載入比純使用小程式要慢很多 坑2. 無法準確捕獲到h5頁面載入的進度…