場景:小程序頁面有一個web-view組件,組件嵌套的H5頁面,要喚起微信支付。javascript
先講一下個人項目,首先我是本身開發的一個H5觸屏版的商城系統,裏面含有購物車,訂單支付等功能。而後剛開始,咱們公衆號裏面點擊官網導航,其實就是訪問的 https://m.xxxx.comhtml
而後支付的時候,我斷定了若是是微信瀏覽器則只展現微信公衆號支付,若是是外部瀏覽器則展現支付寶、微信H5支付 2個選項。java
小提示:(微信支付分了 微信公衆號支付和微信H5支付,微信H5支付是後期纔出的,早期沒有。微信公衆號支付是在微信瀏覽器內訪問H5頁面發起支付,微信H5支付是外部手機瀏覽器喚起微信客戶端發起支付。)web
而後後來,公司以爲,公衆號的直達性不夠好,也就是用戶掃一掃出現公衆號後,還須要點一下官網才能訪問官網,而咱們但願用戶在海報上掃一下二維碼就打開官網,而不要和公衆號產生關係。因此就去申請了一個小程序,而且與咱們公衆號綁定。而後人手不足,咱們不打算從新開發一個小程序,因此直接拿小程序的web-view嵌套咱們的官網地址 https://m.xxxx.com 這個域名。json
嵌套好了之後,一切沒問題,可是在支付這塊有問題,調用微信公衆號支付無法用,一片空白,調用微信H5支付,提示我須要在外部瀏覽器打開。小程序
而後我在此不得不吐槽一下微信支付,自家的產品,自家的小程序,爲何不能讓咱們開發者用得省心點?明明是web-view組件,嵌套H5頁面,也知足了微信內部瀏覽器訪問纔對,愣是不給我調用微信公衆號支付,還得本身去實現新的支付。醉了。按道理來講,開發者調用你的jssdk,最省心的就是,我不須要管我當前的環境,只負責調用你的jssdk的某個方法,你本身管好當前是微信瀏覽器,仍是外部瀏覽器,選擇合適的方式彈出微信支付確認框便可。可是,特麼的爲了集成你一個微信支付,我愣是對接了一個微信公衆號支付,微信H5支付,如今又要多一個小程序支付,明明明明他們都是一個H5支付而已。吐槽完畢,步入正題。他們這樣作畢竟有他們的道理,我等開發者只有老老實實按別人說的作就能夠了。微信小程序
如今明確知道的小程序嵌套H5頁面,引用微信的jssdk後,支持的接口以下連接展現 https://developers.weixin.qq.com/miniprogram/dev/component/web-view.htmlapi
能夠知道是支持不了微信公衆號支付的。其實,微信公衆號支付,也就是統一下單後,再調用 WeixinJSBridge.invoke('getBrandWCPayRequest 這個方法喚起支付確認框,能夠明確知道這個方法並無被小程序web-view支持。瀏覽器
同時,若是調用微信H5支付,會被提示在微信外瀏覽器打開,我估計是由於微信H5支付的那個支付地址(H5支付會讓用戶去訪問一個mweb_url 這個 mweb_url地址我估計是斷定了useragent,小程序web-view的useragent帶了 MicroMessenger)緩存
綜上,各位開發者們,就不要再想歪門邪道的方法在小程序web-view頁面嵌套的H5頁面上喚起 微信公衆號支付或者微信H5支付了,不可能的!就目前(20180930)而言確定不可能。若是你還想一想辦法讓它兼容你的網頁,你就慢慢想吧,有辦法了告訴我。因此,個人結論是:惟一的辦法就是,想辦法讓H5頁面,喚起小程序支付。
根據上面說的,惟一的路子就是你的H5頁面喚起小程序支付,其實也簡單,我是按下面這麼幹的。
首先,小程序放一個頁面,叫作 orderPay.js ,這個是發起小程序支付用的頁面,而後咱們在H5頁面發起支付的時候,把頁面導到這個小程序頁面便可,這點是能夠作到的,接口是 wx.miniProgram.navigateTo ,你們能夠看下這個接口的描述,是容許你帶參數的。因此,一切就很明瞭了。
個人流程是:斷定當前環境是否小程序-->跳轉到 miniProgramPaySend.aspx ,這個頁面將程序導向小程序原生頁面 orderPay ,而且帶着一個參數 orderId(我商城系統的訂單id)
miniProgramPaySend.aspx 頁面代碼
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> <script type="text/javascript"> wx.miniProgram.getEnv(function (res) { if (res.miniprogram) { //只有在小程序環境下,才跳轉到小程序支付頁面去支付,不然的話都是跳轉到訂單詳情去讓它從新選支付方式。 wx.miniProgram.navigateTo({ //這將喚起小程序的原生頁面 url: '/pages/pay/orderpay?orderId=<%=Request.QueryString["orderId"]%>&username=<%=new Cookies().Username%>&token=<%=new Cookies().Token%>' }) } else { var ok = confirm("非微信小程序環境,請選擇在公衆號處支付。"); if(true){ //無論用戶點哪一個按鈕都是去訂單詳情 location.href = "/muserCenter/myWebsiteOrder/detail/?orderId="+<%=Request.QueryString["orderId"]%>; } } })
而後,小程序 orderPay 頁面 onload 的時候,獲取這個單號,而後用 wx.request 方法請求我本身的接口,這個接口去請求微信 統一下單接口,返回小程序支付須要的相關參數 ,好比 package timeStamp 等 而後再用 wx.requestPayment
來發起請求支付便可正常彈出支付請求頁面了。
代碼片斷我貼一點吧。 如下是我小程序 orderPay 頁面的 onLoad 方法
onLoad: function (option) { //console.log("orderId:" + option.orderId); var openid = wx.getStorageSync("openid"); //我在app.js裏面登陸而後換好了openId保存在了本地緩存中了 var orderId=option.orderId; //這是我商城系統的orderId var username=option.username; //這是我商城系統鑑權的username var token=option.token; //這是我商城系統鑑權用的 token console.log("orderId:" + orderId + "|username:" + username + "|token:" + token);
//這個請求是去拿小程序支付須要的相關參數用的,具體怎麼獲取這些參數,看文檔吧兄臺。 wx.request({ url: config.api_baseDomain +'/musercenter/wxMiniProgram/ApiRequest.aspx?action=getPayInfo&orderId='+orderId+'&openid='+openid+'&username='+username+'&token='+token, dataType: 'json', success(res) { console.log("支付信息:" + JSON.stringify(res.data)); if (typeof (res.data.package) == "undefined") { //說明統一下單失敗了,由小程序頁面喚起 web-view 頁面,並指定web-view 訪問的地址,其實吧,也就是打開一個H5頁面 console.log("發起支付異常,緣由:"+res.data); var urlTemp = config.api_baseDomain + '/muserCenter/myWebsiteOrder/detail/?orderId=' + orderId + '&msg=' + res.data.errorMsg; webviewUtils.GoToWebViewWithUrl(urlTemp); } else{ //若是相關參數請求正確的話,就開始發起小程序支付 wx.requestPayment( { 'timeStamp': '' + res.data.timeStamp + '', 'nonceStr': '' + res.data.nonceStr + '', 'package': '' + res.data.package + '', 'signType': '' + res.data.signType + '', 'paySign': '' + res.data.paySign + '', 'success': function (res) //支付成功的話,打開一個H5地址 { var urlTemp = config.api_baseDomain + '/muserCenter/myWebsiteOrder/detail/?orderId=' + orderId + '&msg=支付成功!' console.log(JSON.stringify(res)) webviewUtils.GoToWebViewWithUrl(urlTemp); }, 'fail': function (res) //同上 { var msg="支付失敗"; if (res.errMsg.indexOf("fail cancel")) { msg="支付取消"; } var urlTemp = config.api_baseDomain + '/muserCenter/myWebsiteOrder/detail/?orderId=' + orderId + '&msg='+msg console.log(JSON.stringify(res)) webviewUtils.GoToWebViewWithUrl(urlTemp); }, 'complete': function (res) { } }) } } }) },
整個支付擼明白了就不算難了。當時花了好長的時間再那裏求證web-view到底能不能喚起微信公衆號支付,當時一臉矇蔽的認爲都是微信的東西,應該 不用作任何修改就能直接喚起微信公衆號支付。。。。其實原本應該要能夠纔對的。。。。
哦,對了,還有關於統一下單的,用戶openId的問題,這個openId,你不能拿公衆號的那套方法去獲取,獲取出來的雖然能用來統一下單,可是不能用小程序來支付,會提示你appid不正確,由於你統一下單拿公衆號的appid,而後支付的時候用的是小程序的appid,鐵定不行,應該要按小程序的辦法獲取openId來作統一下單才行,我是在小程序啓動,即 app.js 的