微信小程序嵌套webview實(shí)現(xiàn)小程序微信支付

功能介紹

第一次開發(fā)小程序,不知道如何下手,當(dāng)前公司需要開發(fā)小程序,但是我們現(xiàn)在項(xiàng)目已經(jīng)有h5頁面web端,跟微信公眾號(hào),從網(wǎng)上查詢自17年11月可以用webview插件直接嵌套,省去開發(fā)的環(huán)節(jié),簡(jiǎn)直是福利。像我們公司開發(fā)需求設(shè)計(jì)發(fā)布基本都在一個(gè)人身上,沒有時(shí)間從零開發(fā)小程序了。

開始

  1. 申請(qǐng)小程序步驟,詳細(xì)看此處
  2. 下載開發(fā)者工具,微信登錄小程序。不過多描述
  3. 簡(jiǎn)單快速開始


    image.png

之后發(fā)現(xiàn)微信支付無法使用,這可能是無法一個(gè)卡點(diǎn)了。
開始百度搜索好多說webview實(shí)現(xiàn)微信原生支付,以為是真的,但是試了好多方式都不行,開始時(shí)間跟成本都在這里擺著呢,不可能重新開發(fā)小程序不用webview,只好繼續(xù)想辦法。

實(shí)現(xiàn)

做過微信公眾號(hào)的童鞋應(yīng)該都知道,在公眾號(hào)里商家H5頁面內(nèi)調(diào)用JSSDK就可以實(shí)現(xiàn)微信支付功能。但是看過webview組件的API的文檔的童鞋應(yīng)該知道:webview 里面的網(wǎng)頁(公眾號(hào)遷移的網(wǎng)頁)是調(diào)用不了外部的微信支付what… 雖然微信支付也確實(shí)是提供了小程序的微信支付API,但是因?yàn)槲覀冋麄€(gè)小程序的內(nèi)容就是一個(gè)webview嵌入公眾號(hào)內(nèi)容的網(wǎng)頁,在網(wǎng)頁內(nèi)下訂單的過程中是無法通過webview的api接口通知小程序調(diào)起微信支付的。 查看微信支付小程序的支付文檔,我們小程序如果要調(diào)用微信支付只需要得到以下參數(shù)就可以。

image.png
wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success (res) { },
  fail (res) { }
})

上邊我們最無法獲取的是paySIgn
具體業(yè)務(wù)流程查看微信支付接口

獲取方式

image.png

第一步獲取用戶openid

但是我們主程序在webview里邊無法獲取code并獲得openid
我的思路如下


image.png

具體代碼實(shí)現(xiàn)

所有webview與小程序交互的頁面必須引入以下js

1.assemblyRequestString我寫的組裝參數(shù)的方法,

var path = "/pages/getcode/tempcode?"+$.assemblyRequestString(temp.payFormParams);
 wx.miniProgram.navigateTo({url: path});

2

// pages/getcode/tempcode.js
//獲取應(yīng)用實(shí)例
const app = getApp()
Page({

  /**
   * 頁面的初始數(shù)據(jù)
   */
  data: {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面加載
   */
  onLoad: function (options) {
    var temp = this;
    wx.login({
      success: res => {
        // 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
        console.log("tempcode,wx.login")
        console.log(res.code)
        console.log(options)
        temp.topayview(options,res.code);
      }
    })
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函數(shù)
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點(diǎn)擊右上角分享
   */
  onShareAppMessage: function () {

  },
  topayview: function (options, code){
    //定義小程序頁面集合
    var pages = getCurrentPages();
    //當(dāng)前頁面 (wxpay page)
    var currPage = pages[pages.length - 1];
    //上一個(gè)頁面 (index page) 
    var prevPage = pages[pages.length - 2];
    //通過page.setData方法使index的webview 重新加載url  有點(diǎn)類似于后臺(tái)刷新頁面
    //此處有點(diǎn)類似小程序通過加載URL的方式回調(diào)通知后端 該訂單支付成功。后端邏輯不做贅述。
    prevPage.setData({
      url: 你的跳轉(zhuǎn)后臺(tái)地址?orderNo=" + options.orderNo + '&payMethod=' +'wxmn'+ '&code=' + code,
    }),
      //小程序主動(dòng)返回到上一個(gè)頁面。即從wxpay page到index page。此時(shí)index page的webview已經(jīng)重新加載了url 了
      //微信小程序的page 也有棧的概念navigateBack 相當(dāng)于頁面出棧的操作
      wx.navigateBack();
  }
})

3 帶著code請(qǐng)求后臺(tái)
獲取用戶openid地址
https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code
生成微信支付訂單接口
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1
4

var resultMap = JSON.parse(data.result.er.resultMessage);
                            //點(diǎn)擊微信支付后,調(diào)取統(tǒng)一下單接口生成微信小程序支付需要的支付參數(shù)
                            var params = '?timestamp='+resultMap.timeStamp+'&nonceStr='+resultMap.nonceStr
                                +'&package='+resultMap.package.replace('=','%3D')+'&signType='+resultMap.signType
                                +'&paySign='+resultMap.paySign + "&orderNo="+temp.params.orderNo;
                            //定義path 與小程序的支付頁面的路徑相對(duì)應(yīng)
                            var path = '/pages/wxpay/wxpay'+params;

                            //通過JSSDK的api使小程序跳轉(zhuǎn)到指定的小程序頁面
                            wx.miniProgram.navigateTo({url: path});
// pages/wxpay/wxpay.js
const app = getApp()
Page({

  /**
   * 頁面的初始數(shù)據(jù)
   */
  data: {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面加載
   */
  onLoad: function (options) {
    var that = this;
    console.log(options)
    //頁面加載調(diào)取微信支付(原則上應(yīng)該對(duì)options的攜帶的參數(shù)進(jìn)行校驗(yàn))
    that.requestPayment(options);
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函數(shù)
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點(diǎn)擊右上角分享
   */
  onShareAppMessage: function () {

  },
  //根據(jù) obj 的參數(shù)請(qǐng)求wx 支付
  requestPayment: function (obj) {
    //獲取options的訂單Id
    var orderNo = obj.orderNo;
    //調(diào)起微信支付
    wx.requestPayment({
      //相關(guān)支付參數(shù)
      'timeStamp': obj.timestamp,
      'nonceStr': obj.nonceStr,
      'package': obj.package.replace('%3D','='),
      'signType': obj.signType,
      'paySign': obj.paySign,
      //小程序微信支付成功的回調(diào)通知
      'success': function (res) {
        console.log('支付成功')
        //定義小程序頁面集合
        var pages = getCurrentPages();
        //當(dāng)前頁面 (wxpay page)
        var currPage = pages[pages.length - 1];
        //上一個(gè)頁面 (index page) 
        var prevPage = pages[pages.length - 2];
        //通過page.setData方法使index的webview 重新加載url  有點(diǎn)類似于后臺(tái)刷新頁面
        //此處有點(diǎn)類似小程序通過加載URL的方式回調(diào)通知后端 該訂單支付成功。后端邏輯不做贅述。
        //支付成功跳轉(zhuǎn)支付結(jié)果頁面
        prevPage.setData({
          url: "你的成功地址" ,

        }),
          //小程序主動(dòng)返回到上一個(gè)頁面。即從wxpay page到index page。此時(shí)index page的webview已經(jīng)重新加載了url 了
          //微信小程序的page 也有棧的概念navigateBack 相當(dāng)于頁面出棧的操作
          wx.navigateBack();
      },
      //小程序支付失敗的回調(diào)通知
      'fail': function (res) {
        console.log("支付失敗"),
          console.log(res)
        var pages = getCurrentPages();
        var currPage = pages[pages.length - 1];
        var prevPage = pages[pages.length - 2];
        console.log("準(zhǔn)備修改數(shù)據(jù)")
        //支付失敗繼續(xù)跳轉(zhuǎn)支付頁
        prevPage.setData({
          url: "你的失敗地址",
        }),
          console.log("準(zhǔn)備結(jié)束頁面")
        wx.navigateBack();
      }
    })
  },

})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容