- 微信支付
- H5支付
- 微信里面用PC扫码支付(其他项目中试了试,发现可以吊起支付,但是支付不成功)
产品需求 推广页微信支付功能
推广页访问入口
1.公众号底部栏入口可以打开推广页进行支付
2. 从百度推广的链接进入到推广页进行支付
公众号底部栏作为访问入口
针对从微信公众号内部进入到推广页并完成支付的情况,顾支付采用微信支付。微信官方支付文档:developers.weixin.qq.com/doc/offiacc…
绑定域名
首先先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。绑定下域名。
微信SDK配置
微信sdk的配置工作,在项目初始化或者需要支付的页面完成配置就可以。
相关代码
export default {
// 在初始化的时候执行此函数来进行sdk的配置。具体的微信支付相关配置字段说明可以查看文档即可
getConfig (url, wx) {
axios.get('/wechat/jssdk', { url: url }).then((res) => {
if (res.data.errcode === 0) {
const data = res.data.data
const { appId, timestamp, nonceStr, signature, image_url } = data
wx.config({
debug: false, // 测试环境可以写成true,来查看是否配置成功
appId,
timestamp,
nonceStr,
signature,
jsApiList: [
'chooseWXPay', // 支付
'onMenuShareTimeline', // 分享到朋友圈
'onMenuShareAppMessage', // 分享给朋友
'updateTimelineShareData',
'updateAppMessageShareData',
'showMenuItems',
'hideMenuItems
]
})
wx.ready(function () {
wx.checkJsApi({
jsApiList: ['chooseWXPay'],
success: function () {}
})
})
wx.error((res) => {
const { errMsg } = res
if (errMsg.includes('require subscribe')) {
alert('请先关注公众号')
}
})
}
})
}
}
复制代码
传到测试环境下,如果配置失败请查看微信错误文档。配置成功后,就可以去写支付页面的业务了。移动到支付的页面,里边有一个支付的按钮。点击支付去生成订单然后判断是否是微信浏览器然后吊起微信支付,代码如下:
async pay () { // 点击支付按钮执行的函数
this.payLoading = true
const res = await api.pay.createOrder({
id: this.moneyInfo.id,
dealer_id: this.dealer_id,
pay_way: this.isWX ? '' : 3
}).catch(() => {
this.payLoading = false
})
const { errcode, data, message = '' } = res
if (errcode === 0) {
if (this.isWX) { // 微信浏览器
this.chooseWXPay(data)
} else { // H5支付
this.chooseH5Pay(data)
}
} else {
this.$Toast(message)
this.payLoading = false
}
},
chooseWXPay (info) {
// this.$WX 是在项目初始化引入wxsdk的时候提前写入到全局里的 Vue.prototype.$WX = wx
let _this = this
const { timeStamp: timestamp, nonceStr, package: prepay_id, signType, paySign } = info
this.$WX.chooseWXPay({
timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr, // 支付签名随机串,不长于 32 位
package: prepay_id, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType, // 微信支付V3的传入RSA,微信支付V2的传入格式与V2统一下单的签名格式保持一致
paySign, // 支付签名
success: function () {
// 支付成功后的回调函数
_this.$Toast({
message: '支付成功',
duration: 1000
})
setTimeout(() => {
_this.jumpResultPage()
}, 1000)
},
cancel: function () {
_this.$Toast('已取消支付')
},
fail: function () {
_this.$Toast('支付失败,请重试')
}
})
this.payLoading = false
},
复制代码
支付逻辑写好后,上传到测试环境即可。
验证支付结果
支付失败:上传之后微信不能完成支付。原因是 测试环境下的公众号不能支付,需要后台将上面的sdk配置信息改成线上生成的配置信息及支付需要的openid(线上)写成你自己的。然后改完再去吊起支付就可以了。
从其他浏览器访问链接(h5)进入到推广页进行支付
针对从其他浏览器进入到推广页并完成支付的情况,支付采用H5支付。官方文档 pay.weixin.qq.com/wiki/doc/ap…
其实h5支付很简单,思路就是请求后台的接口,给前台返回一个地址,前台访问这个地址就能吊起微信支付
绑定域名
需要在商户平台账号里,在h5支付的功能模块加上测试和线上域名
相关代码
在非微信浏览器里调用此方法:
chooseH5Pay (data) {
const { order_id = '', url = '' } = data
this.visible = true
this.order_id = order_id
window.location.href = url // 其中url里边redirect_url回到地址可加可不加,这里后台没加
}
复制代码
基本上商户平台配置好,就都能吊起支付,完成支付。从官方文档查看到:
支付成功后回到这个页面,官方推荐给一个这样类似的弹层,去让用户手动去操作校验支付的状态(京东,美团也都这么做的)。基本上支付都走通了
测试环节问题
某一天产品测试发现了一个问题,用苹果自带的浏览器safari打开h5页面去支付,支付成功后跳回到了登录页(或者其他页面),之前都是用qq浏览器或者安卓自带的没有发现这个问题
排查问题阶段
1.网上查有的说是safari清理了cookie导致了登录失效,跳到登录页。试了试并没有清理cookie
2.想到有个redirect_url这个参数可以完成指定回调的地址。因为只有safari浏览器发现了这个问题,我这边就只对safria浏览器加上了这个回调地址,其他浏览器没有做改变(为了交互比较好)。相关代码如下:
async pay () {
this.payLoading = true
// 直接把回调的地址传给后台,后台拼接在h5支付访问的链接地址上就可以。
const redirect_url = `${location.origin}/wechat#/pay?dealer_id=${this.dealer_id}`
const res = await api.pay.createOrder({
id: this.moneyInfo.id,
dealer_id: this.dealer_id,
pay_way: this.isWX ? '' : 3,
redirect_url,
}).catch(() => {
this.payLoading = false
})
}
chooseH5Pay (data) {
const { order_id = '', url = '' } = data
this.visible = true
this.order_id = order_id
window.location.href = url // 其中url里边包含redirect_url重定向地址
}
复制代码
经测试没有问题哈哈搞定
产品添加分享功能,遇到的支付问题
其实这种情况加不加分享功能,只要复制链接用微信浏览器打开支付就会不成功,以为走微信支付获取不到openid(后期发现的)
分享功能
分享配置就不需要说了,也是微信sdk那里配置一下即可,文档上都有
验证结果
产品测试了一下分享没有问题,但是,产品访问了通过其他人分享的推广页分享链接,去完成支付时,提示用户缺少openId
查找问题
发现此提示,与后台沟通发现是通过链接进来的没有走微信公众号的授权绑定获取不到openid。这怎么解决呢。当时想到解决办法如下
解决问题
- 前台这边自己去静默授权,考虑到有些信息暴露到外界不安全并没有采用
- 将分享出的链接地址改成 经过微信授权绑定的授权url(目前采用)
const linkUrl = `${window.location.origin}/wechatRedirect?page_type=2` // 这个地址后台提供的
wx.onMenuShareAppMessage({
title: '知语Pro-快速诊断售后业务流失', // 分享标题
desc: '来知语,查看你的客户到底跑哪儿', // 分享描述
link: linkUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: image_url, // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
success: function () {
// 用户点击了分享后执行的回调函数
}
})
复制代码
验证分享出去,可以完成支付
复制h5链接,放到微信浏览器去访问,支付有问题
原因:发现复制链接去访问页面链接,还是没有走微信的授权,拿不到openid。此问题与上边分享功能支付不成功的本质问题是一样的
解决办法:
- 当时的想法是考虑到区分开页面是从分享链接打开的还是从微信公众号打开的即可,只有从分享链接进去的或者从H5复制链接进去的都去走授权。当时让后台在公众号授权的地址那里添加了openType字段,分享出去的链接不加。后台写代码发现后台那里区分不了入口,openType字段是一直有的,这种方法不可行
- 第二种方法在路由钩子函数beforeEach加个判断,凡是页面是从微信浏览里打开,并且没有授权过的去走授权(目前这样会导致从公众号底部入口进来的走俩次静默授权,不过不影响微信支付)
router.beforeEach((to, from, next) => {
const isWx = isWeiXin()
const sessionOpen = window.sessionStorage.getItem('openType')
if (isWx && (!sessionOpen)) { // h5链接用微信浏览器打开
window.sessionStorage.setItem('openType', 1)
window.location.href = `${window.location.origin}/wechatRedirect?page_type=2`
} else {
NProgress.start()
const {title = ''} = to.meta || {}
document.title = title
NProgress.done()
next()
}
})
复制代码
总结
1.前台页面自己走静默授权,不依赖后台
2.从京东,饿了吗的网站看到他们用的是另一种H5协议支付
href="weixin://wap/pay?appid%3Dwx2421b1c4370ec43b%26noncestr%3D3e84679af4efab5f32ee9ea01b2ec290%26package%3DWAP%26prepayid%3Dwx20160504154919fdacd7bc0d0127918780%26timestamp%3D1462348159%26sign%3DC40DC4BB970049D6830BA567189B463B"
复制代码
官方不推荐这种。有大厂再用可能与微信那边有合作才能用。网上查到这种方法可能还得预防刷单,攻击这种操作,配置成功之后未必能完成支付,顾未采用这种支付。