最近公司在做支付相关的功能模块,突然发现,最难的不是支付问题,而是各种申请、审核,愣是一直卡在审核,还好老板的号多,有的号有h5支付、有的是app支付,这里先弄的是h5支付
背景
项目本来是小程序,通过打包为h5,然后将h5部署上线,再新建一个webapp项目,将入口文件地址打包进去,相对于整个app都是嵌入的h5,所以这里就有一个问题,这是h5项目还是app项目,走判断是走那一条路
// #ifdef H5
import paymentsByH5 from '@/components/payments/paymentsByH5.vue';
// #endif
// #ifdef MP-WEIXIN
import paymentsByWx from '@/components/payments/paymentsByWx.vue';
// #endif
// #ifdef MP-ALIPAY
import paymentsByAli from '@/components/payments/paymentsByAli.vue';
// #endif
// #ifdef APP
import paymentsByApp from '@/components/payments/paymentsByApp.vue';
// #endif
// #ifdef MP-TOUTIAO
import paymentsByTt from '@/components/payments/paymentsByTt.vue';
// #endif
后面做了标识,不管是浏览器还是app,都是走的h5这个判断,所以,这里还是做的h5支付
问题:当h5请求发送出去后,会返回一个mweb_url,这个url怎么跳转呢?
在h5中,可能就直接使用window.open(),或者document.location.href进行跳转了,但是这里虽然是h5,这个方法却不可用,用了就是这个错误
通过抓包发现,这个referer为空,后面想了一下,那我给他设置一个不就行了
document.referer = 'www.baidu.com' //h5支付绑定的地址
但是后面报了一个只读错误,说明这个是不可改的,通过其他路径,我又找到一个方法,通过app里面的plus去创建一个webview(这里终归来说还是app项目,所以plus也是能用的)
if (process.env.UNI_PLATFORM === 'h5' || process.env.UNI_PLATFORM === 'app') {
const webview = plus.webview.create('', 'custom-webview');
webview.loadURL(res.data.mweb_url +
'&redirect_url=https%3A%2F%2Fwww.baidu.com%2F',
{
'Referer': 'https://baidu.com'
})
} else {
location.href = res.data.mweb_url
}
问题就解决了
但是后续叒出问题了,这里的redirect_url 参数并没有用,因为虽然是h5,但是也是app啊,所以需要考虑这里配置成一个网站网址是否能跳转,很显然,不行
后面查资料、问大佬,都说不支持,需要自己实现,-_-!
解决思路
我首先想到的就是将后面的网址链接换成对应的URL scheme,毕竟遵循app的跳转原则,通过app去跳转微信支付,然后再跳转回来,这没毛病,但是失败了
然后,我想着,支付成功了,订单状态也改变了,那我直接暴力解决,轮询去判断这个订单状态不就行了,然后再进行跳转,很显然,这个是可以的,下面就是解决代码
this.$api.pay(data, res => {
console.log('微信支付', res)
if (res.status) {
var url = baseUrl + 'wap/pagesA/goods/payment/result?id='+res.data.payment_id
var redirect = encodeURIComponent(url)
const webview = plus.webview.create('', 'custom-webview');
webview.loadURL(res.data.mweb_url +
'&redirect_url=' + redirect, {
Referer': 'https://baidu.com'
})
// location.href = res.data.mweb_url
this.timer = setInterval(() => {
let data1 = {
order_id: this.orderId
}
console.log('一直在执行')
this.$api.orderDetail(data1, res => {
if (res.data.pay_status === 2 && res.data.status == 1) {
console.log('订单信息返回结果', res, data)
clearInterval(this.timer)
this.$common.redirectTo(
'/pagesA/goods/payment/result?id=' + res.data.payment_id
)}
})
}, 1000)
} else {
this.$common.errorToShow(res.msg)
}
})
但是这里的redirect_url我还是保留了,毕竟万一卡bug能跳了呢 ^_^
这里的定时器记得清楚,在哪里清楚?当然是生命周期钩子函数啦-->beforeDestory 或者 直接在destory,都可以,这是为了防止一直拿不到一直请求,对于服务器也是一个负担