微信小程序開發之(zhī)webview組件内網頁實現微信原生支付
發表時(shí)間:2021-3-31
發布人(rén):融晨科技
浏覽次數:73
前言、背景
本人(rén)目前的(de)工作崗位是(shì)安卓工程師,在(zài)這(zhè)之(zhī)前對于(yú)前端和(hé / huò)後台的(de)知識基本是(shì)白紙,隻是(shì)在(zài)日常的(de)工作項目中有需要(yào / yāo)和(hé / huò)小夥伴進行對接的(de)時(shí)候接觸了(le/liǎo)那麽一丢丢,對于(yú)前端和(hé / huò)後台的(de)一些專業描述和(hé / huò)理解有不(bù)當之(zhī)處還請各位指正。
目前部門的(de)主營項目是(shì)一個(gè)電商項目,在(zài)本人(rén)入職之(zhī)前整個(gè)項目系統的(de)主營業務流程已經完備,也(yě)已經在(zài)正式運營,不(bù)過因爲(wéi / wèi)各種原因平台主要(yào / yāo)是(shì)在(zài)PC端和(hé / huò)微信公衆号進行運營。小程序其實出(chū)來(lái)的(de)挺早的(de),但是(shì)優先級對于(yú)我們目前的(de)規劃來(lái)說(shuō)其實還是(shì)很低的(de)。直到(dào)17年11月的(de)時(shí)候小程序推出(chū)了(le/liǎo)web-view組件,在(zài)當時(shí)被譽爲(wéi / wèi)移動電商的(de)福音&&&&$$$...此處省略五千字。
有了(le/liǎo)web-view那什麽公衆号内容、官網、網頁有域名的(de)那種直接就(jiù)可以(yǐ)扔到(dào)小程序的(de)webview組件了(le/liǎo),極大(dà)的(de)減少了(le/liǎo)開發成本,就(jiù)是(shì)一把梭。。。。
關于(yú)小程序
小程序的(de)解釋什麽的(de)不(bù)巴拉巴拉,直接上(shàng)幹貨開發文檔就(jiù)不(bù)做過多解釋 微信小程序
關于(yú)小程序web-view組件
先奉上(shàng)傳送門小程序 webview相關說(shuō)明和(hé / huò)API使用
官方解釋:web-view 組件是(shì)一個(gè)可以(yǐ)用來(lái)承載網頁的(de)容器,會自動鋪滿整個(gè)小程序頁面。個(gè)人(rén)類型與海外類型的(de)小程序暫不(bù)支持使用。
web-view組件開放時(shí)間并不(bù)久,所以(yǐ)目前的(de)還是(shì)有很多局限性的(de)。
關于(yú)webview配置指向的(de)鏈接的(de)去小程序後台進行配置就(jiù)好(不(bù)配置webview是(shì)訪問不(bù)了(le/liǎo)的(de))必須支持https 如圖:
示例代碼:
如圖:小程序調用微信支付參數


實現方式和(hé / huò)主要(yào / yāo)流程
- 先說(shuō)明一下整個(gè)小程序實現webview調用支付的(de)代碼結構如圖:
xxxx.wxml
類似于(yú)安卓activity的(de)xml文件。xxxx.js
類似于(yú)安卓中MVC模式的(de)控制層。xxxx.wxss
類似于(yú)前端的(de)CSS樣式。我們目前幾乎沒用到(dào),因爲(wéi / wèi)隻用到(dào)了(le/liǎo)小程序的(de)webview組件。
- 原理分析
我們來(lái)看一下微信小程序支付的(de)的(de)業務流程:
wx.requestPayment(
{
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success':function(res){},
'fail':function(res){},
'complete':function(res){}
})
那麽小程序如何得到(dào)支付參數呢,查看webview的(de)API文檔發現 webview的(de)内部網頁可以(yǐ)通過JSSDK的(de)該API 實現webview網頁内部控制小程序。
wx.miniProgram.navigateBack
進行小程序頁面的(de)跳轉比如我們的(de)項目在(zài) index.wxml 的(de) webview 網頁内部使用該API就(jiù)可以(yǐ)控制小程序從index page 跳轉到(dào)wxpay page。
- 具體實現步驟
1 在(zài)index.wxml文件添加webview組件,用來(lái)裝載原公衆号裏面的(de)網頁内容
<web-view src="https://www.wxapp-union.com/{{url}}"></web-view>
該url是(shì)index.js裏面data定義的(de)一個(gè)變量``,方便通過index.js的(de)setData方法對webview的(de)網頁進行動态加載
2 新建wxpay目錄,并新建wxpay的(de)page頁面用來(lái)處理支付邏輯。(該頁面目前是(shì)空白的(de),功能上(shàng)分析該頁面隻是(shì)爲(wéi / wèi)了(le/liǎo)收到(dào)webview網頁的(de)支付參數,從用戶使用角度上(shàng)來(lái)說(shuō)該頁面是(shì)一個(gè)支付頁面應該需要(yào / yāo)添加一些用戶交互的(de),比如轉圈QAQ)
3 webview網頁用戶在(zài)生成訂單後,選擇微信支付即走微信的(de)統一下單流程,生成微信支付的(de)參數和(hé / huò)sgin。在(zài)webview網頁内部通過path攜帶參數跳轉到(dào)wxpay頁面,具體僞代碼實現如下(注釋很清楚):
//判斷是(shì)否是(shì)在(zài)wx小程序環境
if(small_wx && data.resultCode=='success'){
//點擊微信支付後,調取統一下單接口生成微信小程序支付需要(yào / yāo)的(de)支付參數
var params = '?timestamp='+data.jsparams.timeStamp+'&nonceStr='+data.jsparams.nonceStr
+'&'+data.jsparams.pkg+'&signType='+data.jsparams.signType
+'&paySign='+data.jsparams.paySign+'&orderId='+data.orderid+'&pType=0';
//定義path 與小程序的(de)支付頁面的(de)路徑相對應
var path = '/pages/wxpay/wxpay'+params;
//通過JSSDK的(de)api使小程序跳轉到(dào)指定的(de)小程序頁面
wx.miniProgram.navigateTo({url: path});
}
4 小程序端wxpay頁面邏輯實現(wxpay.js),webview内的(de)網頁通過wx.miniProgram.navigateTo({url: path})
攜帶參數使小程序跳轉到(dào)wxpay頁面。wxpay.js 對url中攜帶的(de)參數進行處理,然後通過wx.requestPayment
調起微信支付并對支付的(de)回調通知進行處理,具體代碼實現如下(注釋很詳細不(bù)做過多贅述):
onLoad: function (options) {
var that = this;
//頁面加載調取微信支付(原則上(shàng)應該對options的(de)攜帶的(de)參數進行校驗)
that.requestPayment(options);
},
//根據 obj 的(de)參數請求wx 支付
requestPayment: function (obj) {
//獲取options的(de)訂單Id
var orderId = obj.orderId;
//調起微信支付
wx.requestPayment({
//相關支付參數
'timeStamp': obj.timestamp,
'nonceStr': obj.nonceStr,
'package': 'prepay_id=' + obj.prepay_id,
'signType': obj.signType,
'paySign': obj.paySign,
//小程序微信支付成功的(de)回調通知
'success': function (res) {
//定義小程序頁面集合
var pages = getCurrentPages();
//當前頁面 (wxpay page)
var currPage = pages[pages.length - 1];
//上(shàng)一個(gè)頁面 (index page)
var prevPage = pages[pages.length - 2];
//通過page.setData方法使index的(de)webview 重新加載url 有點類似于(yú)後台刷新頁面
//此處有點類似小程序通過加載URL的(de)方式回調通知後端 該訂單支付成功。後端邏輯不(bù)做贅述。
prevPage.setData({
url: "https://xxxxxxxxxx.com/wx_isPayment.jhtml?orderId=" + orderId + '&ispay=0',
}),
//小程序主動返回到(dào)上(shàng)一個(gè)頁面。即從wxpay page到(dào)index page。此時(shí)index page的(de)webview已經重新加載了(le/liǎo)url 了(le/liǎo)
//微信小程序的(de)page 也(yě)有棧的(de)概念navigateBack 相當于(yú)頁面出(chū)棧的(de)操作
wx.navigateBack();
},
//小程序支付失敗的(de)回調通知
'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("準備修改數據")
prevPage.setData({
url: "https://xxxxxxxxxx/wx_isPayment.jhtml?orderId=" + orderId + '&ispay=0' ,
}),
console.log("準備結束頁面")
wx.navigateBack();
}
})
},
- 微信支付後的(de)回調通知,當wxpay頁面調用
navigateBack
的(de)時(shí)候回到(dào)index頁面的(de)時(shí)候webview 已經加載https://xxxxxxxxxx/wx_isPayment.jhtml?orderId=" + orderId + '&ispay=0'
這(zhè)個(gè)網頁,後台實現相關邏輯。通過orderId查詢該訂單是(shì)否支付成功。如果支付成功就(jiù)網頁重定向到(dào)支付成功的(de)頁面,如果支付失敗還是(shì)待支付頁面。用戶依舊可以(yǐ)點擊微信支付按鈕進行微信支付。 - 至此小程序的(de)webview組件内網頁就(jiù)可以(yǐ)實現微信支付了(le/liǎo)。
see you agin
如果用原生小程序組件實現商城支付就(jiù)沒這(zhè)麽麻煩,但是(shì)工作量會非常巨大(dà)。直接把公衆号的(de)網頁移植到(dào)小程序的(de)webview裏面,極大(dà)的(de)節省了(le/liǎo)開發時(shí)間,對于(yú)小商戶來(lái)說(shuō)還是(shì)非常方便的(de)。我們現在(zài)也(yě)算是(shì)偷懶把,畢竟投入不(bù)大(dà)、優先級不(bù)夠、先弄個(gè)東西出(chū)來(lái)可以(yǐ)用,小程序沒有一個(gè)向服務端的(de)wx.request
請求。但是(shì)我内心其實拒絕的(de)。。。。。因爲(wéi / wèi)用戶體驗和(hé / huò)産品角度都很low.........