这两天,在做的项目上遇到一个问题:接入微信支付。它有五种支付模式,如下所示:

支付模式

  由于项目采用h5的呈现方式,所以采用的是第三个支付模式,即JSAPI支付,相比第五种支付模式支持的范围更大一些。

  微信支付的限制还是挺多的,其中一点是一个微信支付账户只能设置五个支付目录,如果是有多个地方或者多个版本需要支付,这个配置还是会让人很头疼的。
  特别的一点,由于是采用vue的框架,页面的链接还因为是hash模式的,导致其地址也会不同于一般的url,单纯靠精准配置对应的url是不可行的。对于网上所说的将链接进行替换,这边采用后无法保证100%成功,故不建议此种方式。

常见错误
  针对我们的问题,对应到错误里就是一直报第三个,当前页面url未注册
  所以针对以上的问题,采取的折中方式(该方式是处于时间紧的情况下所采取的)解决如下:


1. 编写统一的支付页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 /**此页面无需其他过多样式,只是作为一个中介来调起支付,
故此处只写入采用JSAPI调起微信支付以及一些处理页面的跳转逻辑
其中执行完支付后返回原页面带的参数,是因为暂时没有较好的方法
只能借由原页面携带参数一起过来支付页面后,再返回回去,因为某些
页面需要这些参数进行后续的判断和处理。**/
<script>
export default {
data() {
return { //此处是一些重要参数的配置,包括页面跳转以及需要带的参数
tOrderID:0,
payInfo:{},
backUrl:"",
linkerNo:"",
type:0
}
},
mounted() {
this.tOrderID = parseInt(this.$route.query.tOrderID)
this.getPaymentParam()
this.backUrl = decodeURI(this.$route.query.backUrl)
this.linkerNo = this.$route.query.linkerNo
this.type = this.$route.query.type
},
methods: {
getPaymentParam(){
//此处为调用后台接口获取微信支付所需要的参数
//payInfo在此处进行赋值
},
onBridgeReady(){
let that = this
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":this.payInfo.appId, //公众号名称,由商户传入
"timeStamp":this.payInfo.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":this.payInfo.nonceStr, //随机串
"package":this.payInfo.packageStr,
"signType":this.payInfo.signType, //微信签名方式:
"paySign":this.payInfo.paySign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
console.log("点击成功");
uni.showToast({
title: '支付成功',
duration: 2000,
icon:'none',
mask: true
});
setTimeout(()=>{
uni.navigateTo({
url:that.backUrl+"?payCode=" + 0 + '&linkerNo=' + that.linkerNo + '&type=' + that.type
})
},2100)
} else if(res.err_msg == "get_brand_wcpay_request:cancel"){
console.log("点击取消");
uni.showToast({
title: '点击取消',
duration: 2000,
icon:'none',
mask: true
});
setTimeout(()=>{
uni.navigateTo({
url:that.backUrl+"?payCode=" + 1 + '&linkerNo=' + that.linkerNo + '&type=' + that.type
})
},2100)
}else{
console.log("支付失败");
uni.showToast({
title: '支付失败',
duration: 2000,
icon:'none',
mask: true
});
setTimeout(()=>{
uni.navigateTo({
url:that.backUrl+"?payCode=" + 2 + '&linkerNo=' + that.linkerNo + '&type=' + that.type
})
},2100)
}
});
},
}
}
</script>

2. 微信账户配置支付页面

  上面的页面建议写在根目录下,将页面链接记下,然后在微信账户上配置仅需配置根目录即可,防止出现其他奇怪的问题。


3. 在需要的地方设置页面跳转逻辑

  进行完上面两步后,即可在之前页面唤起微信支付处设置页面跳转,借由空白页面进行微信支付后,再跳回原来页面处理后续逻辑。具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**此处仅举例一个页面,且只截取调起微信支付的部分,大概逻辑如下
采用此种做法,对于取消支付的情况,如果后台有存储跳页面前的数据则没问题
如果没有的话,页面返回来的数据则都会清空,所以需要保存数据的
请调接口保存到后台数据库中,否则,请采用其他方法,不建议存入缓存。**/

success: (res, code, data, error) => {
wx.hideLoading();
if (code == 0) {
var url = encodeURI("/pages/earning/recharge")
/**只有个别需要判断的参数,可向下面页面如此,带过去支付页面后
再返回回来onShow里进行处理。**/
uni.navigateTo({
url:'/pages/pay?tOrderID=' + data+ "&backUrl="+url + "&linkerNo="+this.linkerNo
})
// WeixinJSBridge.invoke(
// 'getBrandWCPayRequest',
// {
// appId: res.appId, //公众号名称,由商户传入
// timeStamp: res.timeStamp, //时间戳,自1970年以来的秒数
// nonceStr: res.nonceStr, //随机串
// package: res.packageStr,
// signType: res.signType, //微信签名方式:
// paySign: res.paySign //微信签名
// },
// res => {
// if (res.err_msg == 'get_brand_wcpay_request:ok') {
// // 使用以上方式判断前端返回,微信团队郑重提示:
// //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// console.log('点击成功');
// wx.showToast({
// title: '支付成功'
// });
// this.getMemAccount();
// } else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
// console.log('点击取消');
// uni.showToast({
// title: '你已取消支付',
// duration: 5000,
// icon: 'none',
// mask: true
// });
// } else {
// console.log('支付失败');
// uni.showToast({
// title: '支付失败',
// duration: 5000,
// icon: 'none',
// mask: true
// });
// }
// }
// );
} else {
uni.showToast({
title: error,
icon: 'none',
duration: 2000
});
}
},

  上方是将之前唤起微信支付的地方,替换为跳转到统一的支付页面。而下方是关于一些完成支付后或者取消支付亦或是支付失败f的后续处理逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**onShow的生命周期,每次调该页面时都会执行,适用于
在支付完成、失败以及取消支付的后续逻辑处理,此处仅为一个简单例子**/
onShow() {
if(this.$route.query.payCode){
this.payCode = this.$route.query.payCode
this.linkerNo = this.$route.query.linkerNo;
if( this.payCode == 0 ){ //0 成功 1 取消 2 失败
console.log('点击成功');
wx.showToast({
title: '支付成功'
});
this.getMemAccount();
}else if(this.payCode == 1){
console.log('点击取消');
uni.showToast({
title: '你已取消支付',
duration: 5000,
icon: 'none',
mask: true
});
}else if(this.payCode == 2){
console.log('支付失败');
uni.showToast({
title: '支付失败',
duration: 5000,
icon: 'none',
mask: true
});
}
}
},

  以上只是在短时间里想到的比较折衷的方法,在跳转前后的数据保存方面,如处理不好会带来更大麻烦。
  能力有限,此处仅为一个总结,关于支付,较好的方法无疑是跳转统一的支付页面如有更好的方法,欢迎小伙伴们评论区留言,谢谢大家的阅读,如本篇文章对你有帮助,欢迎转发给更多需要的人儿们。


本文标题:微信支付

文章作者:JarryChen

发布时间:2020年01月03日 - 22:26

最后更新: 2020年01月04日 10:47

原始链接: https://jarrychen.xyz/archives/3ec27523.html

× 请我喝奶茶~
打赏二维码