重点:微信小程序不能直接用h5里边的支付,必须用小程序原生支付才可以!!!
起因:公司有一个h5的业务要对接到小程序上面,因为小程序是第三方的,所以遵循尽量少改动小程序的原则,最好就是h5把所有的事情都干完,然而理想很丰满,现实却很骨感;
经过:因为之前有接触过小程序,事先不确定小程序是否直接支持h5支付,所以上网上查了一番,大致给的结果就是h5不能直接支付,但也没有说那么清楚,就抱着试试的态度,所以话不多说直接开干 1:拿着自己申请的小程序后台帐号就开撸,写了一个小程序的demo,公司这个h5在微信环境里打开是直接可以支付的,然后我把公司提供的h5链接往小程序的webview上一放,点击真机调试,奇迹发生了,一切完美,竟然可以支付,这也太神奇了吧!
结果:果然我还是太年轻,低估了微信的套路,被微信玩的体无完肤,不过在哪里跌倒我们就在哪里站起来,不搞定誓不罢休
爬坑路漫漫---------------------------------------------------------------------------
第一坑:微信小程序后台,一定要认证过的,不认证不能有支付功能,主体不能是个人,个人的帐号不能填写业务域名,也就是不能加载h5网页
第二坑:关联商户号,有支付就要有收钱的商户,到微信商户后台添加关联小程序,注意不同主体下的需要审核1-3个工作日,审核通过之后要在小程序后台点击确认关联,到此变成以下状态
第三坑:开始码代码
1、跳转到webview之前
data: {
bsPageUrl: "https://www.***du.com"//此处以某度为例
}
wx.navigateTo({
url: '../bswebview/bswebview?bsPageUrl='+encodeURIComponent(this.data.bsPageUrl)
})
问号后边表示是用传递参数的模式把我们要加载的url传递给webview页面 最好是encode以下 避免有些路径上拼的数据传不过去,
2、跳转到webview页面之后,接收url数据,并加载
布局文件中 <web-view src="{{src}}"></web-view>
js文件中:
data: {
src:""
},
onLoad: function (options) {
console.log(options)
this.setData({
src: decodeURIComponent(options.bsPageUrl)//接收url数据并decode
})
},
到此为止webview 是可以正常加载我们的h5页面了,注意这里有坑,直接在开发环境下webview可能显示为白屏,在真机预览环境可以显示网页
3、重点来了,既然h5不能直接支付,h5直接支付会报“支付失败” 提示,那我们就写一个微信小程序的原生支付页面,然后h5直接跳转路由,打开小程序的支付页面并传递支付所需要的参数,进行支付,此时要和h5同学约定好传递那些参数过来
/** 生命周期函数--监听页面加载*/
onLoad: function (options) {
/** 调用微信支付*/
wx.requestPayment({
timeStamp: options.timeStamp,
nonceStr: options.nonceStr,
package: decodeURIComponent(options.package),//此处需要 decode 传递
signType: options.signType,
paySign: options.paySign,
success(res) {
wx.navigateBack({
delta: 1 //返回上一页
})
},
fail(res) {
wx.navigateBack({
delta: 1 //返回上一页
})
}
})
}
4、至此我们已经完成了最最关键的支付功能,但是怎么实现最完美的支付成功后回调功能呢,如果在支付成功之后再重新跳转一个新的页面的话会导致h5的用户信息丢失,因为不在一个webview容器里面,所以最好的办法就是返回上一页,然后替换我们的链接地址为回调地址
var pages = getCurrentPages(); //当前页面
var prevPage = pages[pages.length - 2]; //上一页面
prevPage.setData({
//直接给上一个页面赋值
srcCallback: options.returnPageUrl,
});
在上一个页面中写入以下代码
onShow: function () {
let pages = getCurrentPages();
let currPage = pages[pages.length - 1];
if (currPage.data.srcCallback) {
this.setData({
//将携带的参数赋值
src:decodeURIComponent( currPage.data.srcCallback),
});
console.log(this.data.src, '回调地址')
}
}
这样就完美实现了,最后注意一点,如果想用小程序的支付,必须用小程序下的用户的openId和小程序appId来统一下单