博客 / 詳情

返回

微信小程序內嵌H5頁面,完成微信支付閉環

前言

本文介紹如何在小程序中內嵌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喚起支付,並處理成功和失敗的邏輯。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.