场景:小程序页面有一个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 的