程序web-view(webview)嵌套H5页⾯唤起⽀付的实现⽅
场景:⼩程序页⾯有⼀个web-view组件,组件嵌套的H5页⾯,要唤起⽀付。
然后⽀付的时候,我判定了如果是浏览器则只展⽰⽀付,如果是外部浏览器则展⽰⽀付宝、H5⽀付 2个选项。
⼩提⽰:(⽀付分了⽀付和H5⽀付,H5⽀付是后期才出的,早期没有。⽀付是在浏览器内访问H5页⾯发起⽀付,H5⽀付是外部⼿机浏览器唤起客户端发起⽀付。)
嵌套好了以后,⼀切没问题,但是在⽀付这块有问题,调⽤⽀付没法⽤,⼀⽚空⽩,调⽤H5⽀付,提⽰我需要在外部浏览器打开。
然后我在此不得不吐槽⼀下⽀付,⾃家的产品,⾃家的⼩程序,为什么不能让我们开发者⽤得省⼼点?明明是web-view组件,嵌套H5页⾯,也满⾜了内部浏览器访问才对,愣是不给我调⽤⽀付,还得⾃⼰去实现新的⽀付。醉了。按道理来说,开发者调⽤你的jssdk,最省⼼的就是,我不需要管我当前的环境,只负责调⽤你的jssdk的某个⽅法,你⾃⼰管好当前是浏览器,还是外部浏览器,选择合适的⽅式弹出⽀付确认框即可。但是,特么的为了集成你⼀个⽀付,我愣是对接了⼀个
⽀付,H5⽀付,现在⼜要多⼀个⼩程序⽀付,明明明明他们都是⼀个H5⽀付⽽已。吐槽完毕,步⼊正题。他们这样做毕竟有他们的道理,我等开发者只有⽼⽼实实按别⼈说的做就可以了。
可以知道是⽀持不了⽀付的。其实,⽀付,也就是统⼀下单后,再调⽤  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="res.wx.qq/open/js/jweixin-1.3.2.js"></script>
<script type="text/javascript">
Env(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:" + derId);
var openid = wx.getStorageSync("openid"); //我在app.js⾥⾯登录然后换好了openId保存在了本地缓存中了
var derId; //这是我商城系统的orderId
var username=option.username; //这是我商城系统鉴权的username
var ken; //这是我商城系统鉴权⽤的 token
console.log("orderId:" + orderId + "|username:" + username + "|token:" + token);
/
/这个请求是去拿⼩程序⽀付需要的相关参数⽤的,具体怎么获取这些参数,看⽂档吧兄台。
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=' + Msg;
webviewUtils.GoToWebViewWithUrl(urlTemp);
}
else{  //如果相关参数请求正确的话,就开始发起⼩程序⽀付
{
'timeStamp': '' + res.data.timeStamp + '',支付分怎么开通
'nonceStr': '' + Str + '',
'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 (Msg.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 的
onLaunch ⽅法中调⽤了 wx.login 拿到code,然后⽤ wx.request 请求我⾃⼰的⼀个接⼝去调⽤  code2Session ⽅法换好openId返回给⼩程序,让它保存在缓存中备⽤。
还有,⼩程序开通⽀付,你肯定是和我⼀样绑定之前那个⽀付商户,然后签名的时候,⽤的key是商户⽀付的key,是你⾃⼰设定的那个东西,不是⼩程序的appkey也不是appsecret。
对接⼩程序⽀付整个流程就是这样,有问题可以留⾔给我
仅记录⼀下⾃⼰开发碰到的问题,同时也给各位马上和我⼀样的情况的⼈的⼀点提⽰,以免各位开发者和我⼀样⾛弯路。