前言
本文介紹如何在小程序中內嵌H5,並完成微信支付的整個流程閉環。我們知道微信H5支付是通過生成特定的支付鏈接,並跳轉到這個鏈接去完成支付操作的。但在微信小程序中對於內嵌的頁面域名具有白名單限制,如果支付鏈接是第三方的無法做加白處理。
這個時候我們就得換個思路了,該怎麼解決呢?咱們往下看。
實現過程
小程序入口
在微信小程序中新建一個頁面,使用web-view組件作為內嵌H5的入口,由於後續支付需要用到appId以及openId信息,因此需要對url做帶參做處理
// page.wxml
<web-view src="{{url}}"></web-view>
url處理邏輯:
Page({
data: {
url: ''
},
onLoad: function (options) {
wx.showLoading()
wx.login({
success: res => {
const code = res.code
api.getUserOpenId({
code
}, data => {
const openId = data.bean
const params = {
wxAppletId: 'your appId',
wxAppletOpenId: openId,
...options // 小程序啓動路徑的參數
}
this.setData({
url: this.stringifyUrlArgs('your h5 url', params)
})
wx.hideLoading()
})
}
})
},
stringifyUrlArgs(url, params) => {
url += (/\?/).test(url) ? '&' : '?'
url += Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
return url
}
})
在頁面onload的時候,調用APIwx.login獲取code,傳遞給後端換取該用户的openId,然後將appId、openId、以及啓動路徑參數拼接到你的H5 url 後面。這個url可以是個短鏈,方便後續修改不需要重新提交小程序代碼審核,縮短髮版的時間。只需要去修改該短鏈對應的H5鏈接即可。
H5 頁面處理
當我們在小程序入口處理好url後,會通過web-view組件進行訪問H5鏈接,這個時候鏈接上攜帶了支付所必需的參數,我們上面提到如果這時候H5頁面仍然還是調用生成H5支付鏈接的方式的話,會有頁面白名單限制,導致第三方支付鏈接頁面無法訪問的情況。
這個時候我們可以繞開這個點,竟然是在小程序內部,我們可不可以使用小程序支付呢?答案當然是可以!
處理的過程:
H5頁面請求後端支付接口獲取微信小程序支付所必須的參數,這個時候appId和openId都是必要的,其他的信息則根據具體需求而定。
// 微信小程序支付參數
interface appletPayParams {
timeStamp: 'string', // 時間戳,從 1970 年 1 月 1 日 00:00:00 至今的秒數,即當前的時間
nonceStr: 'string', // 隨機字符串,長度為32個字符以下
package: 'string', // 統一下單接口返回的 prepay_id 參數值,提交格式如:prepay_id=***
signType?: 'string', // 簽名算法,應與後台下單時的值一致
paySign: 'string' // 簽名,具體見微信支付文檔
}
由於H5是內嵌在小程序的web-view裏面,當成功從後端獲取到支付所需的參數後,需要通過web-view 跳到內部小程序的方式,跳轉到對應的小程序支付頁面進行支付操作,這個時候得使用wx.miniProgram.redirectTo進行處理,將獲取到的支付參數encodeURIComponent一下再拼接到鏈接上。注意url是一個相對路徑,如下:
wx.miniProgram.redirectTo({ url: `../insure-pay/insure-pay?payData=${encodeURIComponent(JSON.stringify(bean.applet))}` })
小程序支付頁
新建一個支付頁面,當從web-view內嵌H5頁面跳轉到支付頁的時候,處理支付的邏輯處理,如下:
Page({
onLoad: function (options) {
const payData = decodeURIComponent(options.payData) // 支付參數
let pageSuccessUrl = '../pay-success/pay-success' // 成功頁
let pageFailUrl = './insure-repay/insure-repay' // 失敗頁,重新支付
wx.requestPayment({
...JSON.parse(payData),
success(res) {
wx.redirectTo({
url: pageSuccessUrl,
})
},
fail(err) {
console.log(err)
wx.redirectTo({
url: `${pageFailUrl}?payData=${options.payData}`,
})
}
})
}
})
進入到支付頁,會通過wx.requestPayment調起支付,將鏈接上的參數decodeURIComponent出來,傳入API中,可通過回調函數success和fail監聽成功和失敗,並跳轉到不同的處理頁面。
總結
大致的流程可以總結為一下幾點:
- 在微信小程序建立一個入口頁面,通過web-view內嵌H5,在這個頁面onload的時候獲取用户的openId以及appId並攜帶到H5鏈接上
- 在H5中獲取鏈接攜帶的appId和openId,請求後端獲取小程序支付所需的參數,並通過wx.miniProgram.redirectTo,從web-view重定向到小程序支付頁。
- 在小程序支付頁獲取鏈接上攜帶的支付參數,通過wx.requestPaymen喚起支付,並處理成功和失敗的邏輯。