微信小程序開發(fā)之webview組件內(nèi)網(wǎng)頁實(shí)現(xiàn)微信原生支付

前言、背景

本人目前的工作崗位是安卓工程師,在這之前對(duì)于前端和后臺(tái)的知識(shí)基本是白紙,只是在日常的工作項(xiàng)目中有需要和小伙伴進(jìn)行對(duì)接的時(shí)候接觸了那么一丟丟,對(duì)于前端和后臺(tái)的一些專業(yè)描述和理解有不當(dāng)之處還請(qǐng)各位指正。

目前部門的主營(yíng)項(xiàng)目是一個(gè)電商項(xiàng)目,在本人入職之前整個(gè)項(xiàng)目系統(tǒng)的主營(yíng)業(yè)務(wù)流程已經(jīng)完備,也已經(jīng)在正式運(yùn)營(yíng),不過因?yàn)楦鞣N原因平臺(tái)主要是在PC端和微信公眾號(hào)進(jìn)行運(yùn)營(yíng)。小程序其實(shí)出來的挺早的,但是優(yōu)先級(jí)對(duì)于我們目前的規(guī)劃來說其實(shí)還是很低的。直到17年11月的時(shí)候小程序推出了web-view組件,在當(dāng)時(shí)被譽(yù)為移動(dòng)電商的福音&&&&$$$...此處省略五千字。

有了web-view那什么公眾號(hào)內(nèi)容、官網(wǎng)、網(wǎng)頁有域名的那種直接就可以扔到小程序的webview組件了,極大的減少了開發(fā)成本,就是一把梭。。。。

關(guān)于小程序

小程序的解釋什么的不巴拉巴拉,直接上干貨開發(fā)文檔就不做過多解釋
微信小程序

關(guān)于小程序web-view組件

先奉上傳送門小程序 webview相關(guān)說明和API使用
官方解釋:web-view 組件是一個(gè)可以用來承載網(wǎng)頁的容器,會(huì)自動(dòng)鋪滿整個(gè)小程序頁面。個(gè)人類型與海外類型的小程序暫不支持使用
web-view組件開放時(shí)間并不久,所以目前的還是有很多局限性的。
關(guān)于webview配置指向的鏈接的去小程序后臺(tái)進(jìn)行配置就好(不配置webview是訪問不了的)必須支持https 如圖:

小程序wevbiew服務(wù)器域名配置

示例代碼:


示例代碼

做過微信公眾號(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ù)就可以。
如圖:小程序調(diào)用微信支付參數(shù)

小程序調(diào)用微信支付參數(shù)

以及示例代碼


示例代碼

看到這些一切就明朗了,在小程序端只要能通過某種方式得到webview內(nèi)網(wǎng)頁下單后的生成的相關(guān)參數(shù)就能調(diào)起微信支付從而實(shí)現(xiàn)webview組件內(nèi)網(wǎng)頁微信支付。

實(shí)現(xiàn)方式和主要流程

  1. 先說明一下整個(gè)小程序?qū)崿F(xiàn)webview調(diào)用支付的代碼結(jié)構(gòu)如圖
    項(xiàng)目代碼結(jié)構(gòu)

整個(gè)結(jié)構(gòu)很清晰、簡(jiǎn)單,不做過多解釋。微信小程序采用的MVVM的模式。
xxxx.wxml類似于安卓activity的xml文件。
xxxx.js類似于安卓中MVC模式的控制層。
xxxx.wxss類似于前端的CSS樣式。我們目前幾乎沒用到,因?yàn)橹挥玫搅诵〕绦虻膚ebview組件。

  1. 原理分析

我們來看一下微信小程序支付的的業(yè)務(wù)流程:

支付流程時(shí)序圖

上面已經(jīng)提到如果需要小程序的webview組件調(diào)起微信支付,需要網(wǎng)頁內(nèi)部統(tǒng)一下單得到支付參數(shù),然后通過小程序API調(diào)起微信支付,如下:

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

那么小程序如何得到支付參數(shù)呢,查看webview的API文檔發(fā)現(xiàn) webview的內(nèi)部網(wǎng)頁可以通過JSSDK的該API 實(shí)現(xiàn)webview網(wǎng)頁內(nèi)部控制小程序。
wx.miniProgram.navigateBack 進(jìn)行小程序頁面的跳轉(zhuǎn)比如我們的項(xiàng)目在 index.wxml 的 webview 網(wǎng)頁內(nèi)部使用該API就可以控制小程序從index page 跳轉(zhuǎn)到wxpay page。

具體實(shí)現(xiàn)步驟

  1. 在index.wxml文件添加webview組件,用來裝載原公眾號(hào)里面的網(wǎng)頁內(nèi)容
<web-view src="{{url}}"></web-view>

該url是index.js里面data定義的一個(gè)變量``,方便通過index.js的setData方法對(duì)webview的網(wǎng)頁進(jìn)行動(dòng)態(tài)加載

  1. 新建wxpay目錄,并新建wxpay的page頁面用來處理支付邏輯。(該頁面目前是空白的,功能上分析該頁面只是為了收到webview網(wǎng)頁的支付參數(shù),從用戶使用角度上來說該頁面是一個(gè)支付頁面應(yīng)該需要添加一些用戶交互的,比如轉(zhuǎn)圈QAQ)
  2. webview網(wǎng)頁用戶在生成訂單后,選擇微信支付即走微信的統(tǒng)一下單流程,生成微信支付的參數(shù)和sgin。在webview網(wǎng)頁內(nèi)部通過path攜帶參數(shù)跳轉(zhuǎn)到wxpay頁面,具體偽代碼實(shí)現(xiàn)如下(注釋很清楚): 重點(diǎn): 這部分是后端代碼 即小程序內(nèi)部網(wǎng)頁的代碼(在java工程中為 .ftl文件)。我的這個(gè)方案是需要后端進(jìn)行邏輯更改的。看懂的朋友應(yīng)該知道只有當(dāng)后端微信支付下單流程完成后才能得到調(diào)起微信支付需要的參數(shù)。這部分都是后端實(shí)現(xiàn)的。 只有后端下單流程完成,然后判斷是不是小程序是小程序就是下面的代碼。不是就繼續(xù)走公眾號(hào)的微信支付
//判斷是否是在wx小程序環(huán)境
if(small_wx  && data.resultCode=='success'){
  //點(diǎn)擊微信支付后,調(diào)取統(tǒng)一下單接口生成微信小程序支付需要的支付參數(shù)
  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 與小程序的支付頁面的路徑相對(duì)應(yīng)
  var path = '/pages/wxpay/wxpay'+params;
  //通過JSSDK的api使小程序跳轉(zhuǎn)到指定的小程序頁面
  wx.miniProgram.navigateTo({url: path});                         
  }
  1. 小程序端wxpay頁面邏輯實(shí)現(xiàn)(wxpay.js),webview內(nèi)的網(wǎng)頁通過wx.miniProgram.navigateTo({url: path})攜帶參數(shù)使小程序跳轉(zhuǎn)到wxpay頁面。wxpay.js 對(duì)url中攜帶的參數(shù)進(jìn)行處理,然后通過wx.requestPayment調(diào)起微信支付并對(duì)支付的回調(diào)通知進(jìn)行處理,具體代碼實(shí)現(xiàn)如下(注釋很詳細(xì)不做過多贅述):
onLoad: function (options) {
   var that = this;
   //頁面加載調(diào)取微信支付(原則上應(yīng)該對(duì)options的攜帶的參數(shù)進(jìn)行校驗(yàn))
   that.requestPayment(options);
 },
//根據(jù) obj 的參數(shù)請(qǐng)求wx 支付
 requestPayment: function (obj) {
   //獲取options的訂單Id
   var orderId = obj.orderId;
   //調(diào)起微信支付
   wx.requestPayment({
     //相關(guān)支付參數(shù)
     'timeStamp': obj.timestamp,
     'nonceStr': obj.nonceStr,
     'package': 'prepay_id=' + obj.prepay_id,
     'signType': obj.signType,
     'paySign': obj.paySign,
     //小程序微信支付成功的回調(diào)通知
     'success': function (res) {
       //定義小程序頁面集合
       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: "https://xxxxxxxxxx.com/wx_isPayment.jhtml?orderId=" + orderId  + '&ispay=0',
           
         }),
         //小程序主動(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ù)")
         prevPage.setData({
           url: "https://xxxxxxxxxx/wx_isPayment.jhtml?orderId=" + orderId + '&ispay=0' ,
         }),
           console.log("準(zhǔn)備結(jié)束頁面")
       wx.navigateBack(); 
     }
   })
 },
  1. 微信支付后的回調(diào)通知,當(dāng)wxpay頁面調(diào)用navigateBack的時(shí)候回到index頁面的時(shí)候webview 已經(jīng)加載https://xxxxxxxxxx/wx_isPayment.jhtml?orderId=" + orderId + '&ispay=0' 這個(gè)網(wǎng)頁,后臺(tái)實(shí)現(xiàn)相關(guān)邏輯。通過orderId查詢?cè)撚唵问欠裰Ц冻晒ΑH绻Ц冻晒途W(wǎng)頁重定向到支付成功的頁面,如果支付失敗還是待支付頁面。用戶依舊可以點(diǎn)擊微信支付按鈕進(jìn)行微信支付。
  2. 至此小程序的webview組件內(nèi)網(wǎng)頁就可以實(shí)現(xiàn)微信支付了。

see you agin

如果用原生小程序組件實(shí)現(xiàn)商城支付就沒這么麻煩,但是工作量會(huì)非常巨大。直接把公眾號(hào)的網(wǎng)頁移植到小程序的webview里面,極大的節(jié)省了開發(fā)時(shí)間,對(duì)于小商戶來說還是非常方便的。我們現(xiàn)在也算是偷懶把,畢竟投入不大、優(yōu)先級(jí)不夠、先弄個(gè)東西出來可以用,小程序沒有一個(gè)向服務(wù)端的wx.request請(qǐng)求。但是我內(nèi)心其實(shí)拒絕的。。。。。因?yàn)橛脩趔w驗(yàn)和產(chǎn)品角度都很low.........

補(bǔ)上兩張支付效果圖嗯哼。。。(有小伙伴問到我就統(tǒng)一說明一下)

1 webview內(nèi)的網(wǎng)頁下單成功

webview內(nèi)的網(wǎng)頁下單成功

熟悉開發(fā)的小伙伴應(yīng)該知道出現(xiàn)這個(gè)頁面的時(shí)候。其實(shí)只是后端生成了一個(gè)訂單而已,這個(gè)時(shí)候和支付還沒有一毛錢關(guān)系(微信支付時(shí)序圖中的生成商戶訂單)。 此時(shí)用戶點(diǎn)擊微信支付按鈕即為時(shí)序圖中的 5 調(diào)用統(tǒng)一下單API()---》生成預(yù)付單----》返回預(yù)付單信息(prepay_id). 6 生成JSAPI頁面調(diào)用的支付參數(shù)并簽名() 返回支付參數(shù)(prepay_id, paySgin等) 以上其實(shí)都還是微信公眾號(hào)的下單,生成支付邏輯
只有當(dāng)?shù)玫街Ц秴?shù)后,判斷是小程序環(huán)境才通過

var path = '/pages/wxpay/wxpay'+params;

//通過JSSDK的api使小程序跳轉(zhuǎn)到指定的小程序頁面

wx.miniProgram.navigateTo({url: path});

這個(gè)API 將支付參數(shù)傳到wxpay page頁面。 至此通信流程完成

附上微信公眾號(hào)支付的 時(shí)序圖 微信公眾號(hào)支付時(shí)序圖參考

2 當(dāng)index的微信支付下單流程完成后,通過jssdk的 wx.miniProgram.navigateTo API 將數(shù)據(jù)傳遞到wxpay page頁面。 當(dāng)wxpay得到參數(shù)后,驗(yàn)證參數(shù)無誤就調(diào)用 wx.requestPayment 調(diào)起微信支付

微信支付

如何聯(lián)系我:https://wyysz.github.io/

劃重點(diǎn)、很重要 很重要 2018/2/24更新。針對(duì)不少朋友咨詢我不成功,調(diào)用不了微信支付、小程序提示我appid與商戶號(hào)不一致的問題解釋說明。。。。

首先上面的博客主要是說的實(shí)現(xiàn)流程、對(duì)于微信支付的邏輯我?guī)缀鯖]提。因?yàn)闈撘庾R(shí)我理解為要做著功能的小伙伴是知道微信支付如何實(shí)現(xiàn)的。因?yàn)楹芏嗳藛柫?所以就補(bǔ)充一下吧。
一個(gè)訂單要能支付那么 openid 微信用戶的標(biāo)識(shí),appid 小程序標(biāo)識(shí)或者公眾號(hào)標(biāo)識(shí) ,商戶號(hào),mchid,證書啥的。。
按照我博客的內(nèi)容來走到現(xiàn)在 應(yīng)該是小程序能正常使用,但是就是調(diào)起不了微信支付。 。。。 很正常呀,因?yàn)槟銢]參考小程序支付的微信支付流程來呀,你用公眾號(hào)的支付邏輯在小程序的里面怎么能走的通。 一定要修改后端支付邏輯并且按照微信支付 小程序支付的文檔說明來

第一步:openid的獲取,通過wx.login的到的code換取session_key
參考鏈接: https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject
截圖如下:

WX20180224-182956@2x.png

返回參數(shù):
WX20180224-183134@2x.png

這是第一步通過這種方式得到用戶的唯一標(biāo)識(shí) openid。。。。

第二步就是參考微信支付 小程序支付了(即修改的邏輯)
首先讓小程序有微信支付的能力,即開通微信支付可以選擇截圖的方式,前提是有微信商戶號(hào)。
參考鏈接:
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_11&index=2

參考截圖:
WX20180224-183546@2x.png

然后就是參考小程序支付api 實(shí)現(xiàn)支付生成支付參數(shù)。。。。即開始說的timeStamp、noncestr、package、signtype、paysgin等。
微信支付 小程序支付文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=4
截圖:

WX20180224-183822@2x.png

最后附上我們自己的后端生成支付參數(shù)的代碼,這里用到了openid 對(duì)應(yīng)了微信支付 小程序支付 提到的統(tǒng)一下單------》都需要先獲取到Openid,調(diào)用相同的API。
代碼參考:


后端生成支付訂單.png

代碼中的result就包含了 喚醒微信支付sdk 所需要的參數(shù)。至此后端邏輯應(yīng)該就講完了。 按照我的博客來做 不能實(shí)現(xiàn)支付的九成九是沒改后端邏輯的小伙伴,沒有仔細(xì)理解微信支付 小程序支付該怎么做。 和我開始沒說要該支付邏輯也有一定關(guān)系。。。補(bǔ)上。有問題可以留言或者聯(lián)系我。 碼字不易,如果對(duì)你有幫助請(qǐng)多支持。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評(píng)論 3 417
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容