前一阵在做公司小程序时,有个需要对接支付的功能。但是本着订单数据和支付统一入口的设计原则,计划是对接公司商城现有的支付体系。故本方案是分析对接商城支付几种可行方案以及每种方案的可行性,最后综合选出一种最佳的方案。
实现方式 | 跳转商城小程序支付 | 跳转商城H5支付 | 对接小程序支付API |
---|---|---|---|
优点 | 无需重新对接开发支付功能(可直使用商城小程序支付能力) | 直接嵌入h5页面,用户没有感知跳转的过程体验较好 | 不存在跳转问题,所有操作都是在小程序内部完成 |
缺点 | 1. 小程序之间跳转会出现询问弹窗不利于用户体验 2. 商城小程序还存在一些未知bug,目前还不是很稳定 |
1. 小程序需要主动唤起支付窗口 |
1. 重新对接小程序支付API 2. 订单无法统一商城入口 3. 综合开发工作量较大 |
综合用户体验、开发工作量等因素最终选择使用跳转商城H5支付的方案
由于经过测试发现小程序中嵌入商城H5后,无法正常调起微信h5支付的。所以采用曲线救国的方式,商城内部走微信小程序支付API,再有小程序唤醒小程序支付。具体实现步骤如下
在原有微信支付的逻辑上增加了现有业务的交互逻辑(若有遗漏或者错误的地方,还请在评论区和谐讨论)
由于使用postMessage方式传递数据,只有在小程序特殊操作下才可以触发,所以本方案采用get方式进行传参
<web-view
:src="'https://shop.XXX.com/Mobile/Index/wxchart?token=XXXXXXXXXX&name=youngRich'"
>web-view>
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
// 还要再次页面中判断是是否在小程序内打开
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
//ios的ua中无miniProgram,但都有MicroMessenger(表示是微信浏览器)
wx.miniProgram.getEnv((res)=>{
if (res.miniprogram) {
//在微信内,在小程序内。
console.log("小程序的支付业务")
let wxJson ={} // 微信返回的5个参数
wx.miniProgram.navigateTo({url: '"/pages/pay/pay?param=" + wxJson '});
return
}else{
//在微信内,不在小程序内。
console.log("微信H5的支付业务")
return
}
})
}else{
//不在微信内。
console.log("第三方浏览器支付业务")
return
}
以下代码均为示例,仅供参考。请结合自身业务逻辑进行处理
- 订单详情或者充值页面 携带金额等订单信息跳转到预支付页面(商城h5提供的地址用web-view嵌入)
- 预支付页面onLoad中调用uni.login获取code
- 把通行证token、code、user_id、account携带到商城h5给的url上(或者系统中其他参数)
<template>
<web-view src="{{shopUrl}}"></web-view>
</template>
<script>
export default {
data() {
return {
shopUrl:''
}
},
// 订单详情或者充值页面 携带金额跳转到预支付页面
onload(options){
uni.login({
provider: "weixin",
success: (res) => {
let params = {
code:res.code,
token:*********,
user_id:*****,
...options,
}
this.shopUrl = this.stringifyUrlArgs('https://XXX.XXXX.XXX',params)
},
fail: (res) => {
utils.showToast("获取授权信息失败");
},
});
},
methods:{
stringifyUrlArgs(url, params) => {
url += (/\?/).test(url) ? '&' : '?'
url += Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
return url
}
}
</script>
在商城h5跳转回小程序的页面中(可以是任何页面甚至是空白页)写入一下逻辑。此步骤主要是弹出授权支付弹窗
<template>
</template>
<script>
export default {
data() {},
onload(options){
let payData = {
provider: 'wxpay',
...options, // 商城h5携带五个用于支付的参数
}
uni.requestPayment({
...payData,
success(res) {
console.log('支付成功处理')
},
fail(err) {
console.log('支付失败处理')
}
})
},
</script>