微信小程序與内嵌網頁交互實現支付功能
發表時(shí)間:2021-3-31
發布人(rén):融晨科技
浏覽次數:75
上(shàng)個(gè)月,小程序開放了(le/liǎo)新功能,支持内嵌網頁,所以(yǐ)我就(jiù)開始了(le/liǎo)小程序内嵌網頁之(zhī)路,之(zhī)前我隻是(shì)個(gè)小安卓。
内嵌網頁中可使用JSSDK 1.3.0提供的(de)接口,可坑就(jiù)來(lái)了(le/liǎo),居然不(bù)支持支付接口的(de)調用,經過一番研究,總算打通了(le/liǎo)兩邊的(de)交互
大(dà)概流程
1、先說(shuō)明涉及到(dào)的(de)文件,下面會用到(dào)
1.1 app.js:小程序的(de)app.js文件,在(zài)globalData裏定義一個(gè)全局變量paySuccessUrl: '',用來(lái)保存支付成功跳轉url
1.2 wxminiwebview.js:小程序中放web-view的(de)界面
1.3 wxminipay.js:小程序原生支付界面
1.4 web_pay.vue:内嵌網頁會調起支付的(de)路由組件界面,由于(yú)我是(shì)用vue+vue-router寫的(de),所以(yǐ)你最好了(le/liǎo)解下vue和(hé / huò)vue-router,記得引入微信jssdk1.3.0,最新版本才包含小程序相對應方法。很遺憾,微信并沒提供npm包,github有人(rén)提供的(de)commonjs引入方式的(de)微信jssdk版本也(yě)隻有1.2.0,所以(yǐ)就(jiù)隻能這(zhè)樣引入了(le/liǎo)
<script src="./static/jweixin-1.3.0.js">script>
2、首先我們像官網那樣正常嵌入一個(gè)内嵌網頁,url是(shì)wxmini_webview.js中data中定義的(de)變量,webview加載的(de)就(jiù)是(shì)網頁就(jiù)是(shì)這(zhè)個(gè)url
<web-view src="{{url}}">web-view>
3、在(zài)内嵌網頁web_pay.vue裏判斷當前是(shì)否是(shì)微信環境
window.wx.ready(function () {
isWxMini = window.__wxjs_environment === 'miniprogram'
})
4、在(zài)内嵌網頁web_pay.vue調用支付時(shí)把支付金額,支付說(shuō)明,支付成功跳轉url...(任何你想要(yào / yāo)的(de)參數,記得encodeURIComponent),傳給小程序原生頁面
if (isWxMini) {
let jumpUrl = encodeURIComponent(window.location)
let path = `/page/pay/pay?amount=${amount}&title=${desc}&jumpUrl=${jumpUrl}`
window.wx.miniProgram.navigateTo({
url: path
})
}
5、在(zài)小程序支付界面wxmini_pay.js裏獲取到(dào)内嵌網頁傳過來(lái)的(de)值,這(zhè)裏演示方便,實際上(shàng)是(shì)在(zài)page的(de)data裏存儲這(zhè)些會顯示在(zài)界面的(de)值好些
onLoad: function (options) {
console.log(options)
// 獲取網頁傳過來(lái)的(de)值
// TODO 用es6解構來(lái)獲取值TODO
jumpUrl = options.jumpUrl
amount = options.amount
title = options.title
...
},
6、支付成功後,把跳轉url附帶支付結果及當前時(shí)間保存到(dào)全局變量
paySuccess () {
let currentTime = new Date().getTime()
//這(zhè)是(shì)爲(wéi / wèi)了(le/liǎo)防止wxmini_webview.js文件裏調用setData由于(yú)前後兩個(gè)url一緻導緻路由不(bù)觸發刷新的(de)bug
jumpUrl = options.jumpUrl+encodeURIComponent(`?payResult=1&time=${currentTime}`)
//payResult=1表示支付成功,這(zhè)裏我偷懶了(le/liǎo)直接在(zài)url後面補?,實際情況比較複雜
//爲(wéi / wèi)了(le/liǎo)實現支付成功返回後的(de)無刷新加載,這(zhè)裏的(de)參數應該是(shì)屬于(yú)路由web_pay.vue的(de),而(ér)不(bù)是(shì)屬于(yú)window.location.search的(de)
//所以(yǐ)要(yào / yāo)判斷路由錨點#的(de)位置和(hé / huò)是(shì)否已經有路由參數(如果是(shì)vue-router的(de)history模式我沒用過,應該和(hé / huò)window.location一樣吧)
getApp().globalData.paySuccessUrl=jumpUrl //保存跳轉url到(dào)小程序全局變量裏
wx.navigateBack() //返回會上(shàng)個(gè)頁面,也(yě)就(jiù)是(shì)承載網頁的(de)容器頁面wxmini_pay.js
}
7、回到(dào)小程序wxmini_webview.js,會觸發onshow,在(zài)裏面進行界面無刷新加載
onShow: function () {
console.log('on show')
let paySuccessUrl = getApp().globalData.paySuccessUrl
getApp().globalData.paySuccessUrl="" //清空支付成功url,防止一些操作觸發onShow事件
if (paySuccessUrl) {
let url = decodeURIComponent(paySuccessUrl)
this.setData({
//這(zhè)裏在(zài)次說(shuō)明下步驟6中的(de)&time=${currentTime},就(jiù)是(shì)因爲(wéi / wèi)不(bù)加這(zhè)個(gè)當你第一次支付成功回來(lái)這(zhè)裏
//這(zhè)個(gè)url跟你第二次支付成功回來(lái)這(zhè)裏是(shì)一樣的(de),會導緻第二次支付開始,這(zhè)裏的(de)setData方法失效
url
})
}
},
8、步驟7中的(de)setData會觸發webview中的(de)網頁加載,由于(yú)我采用的(de)是(shì)vue-router,而(ér)且前後兩個(gè)url隻有路由的(de)參數query不(bù)一樣,所以(yǐ)并不(bù)會觸發界面刷新,也(yě)不(bù)會觸發路由的(de)重新加載,而(ér)是(shì)隻會觸發beforeRouteUpdate 這(zhè)個(gè)方法,舉個(gè)例子(zǐ),現在(zài)支付前界面是(shì)https://host/#/pay,然後支付成功後跳轉https://host/?
payResult=1&time=123456#/pay,此時(shí)界面不(bù)會刷新,pay路由也(yě)不(bù)會重新加載,而(ér)是(shì)觸發beforeRouteUpdate (to, from, next),你要(yào / yāo)做的(de)隻是(shì)在(zài)這(zhè)裏界面解析to.query裏的(de)數據,然後該幹嘛幹嘛
beforeRouteUpdate (to, from, next) {
console.log('路由發生改變,很有可能是(shì)小程序的(de)支付成功回調')
let payResult = to.query.payResult
if (payResult) { // 小程序支付成功
if (payResult === '1') {
console.log('支付成功,下班打卡走人(rén)')
}
}
next()
},
這(zhè)麽晚了(le/liǎo),先睡了(le/liǎo),如果有空我再整理個(gè)demo,如果文章對你有幫助麻煩點個(gè)贊