H5呼起微信支付存在两种场景
第一种:其他浏览器呼起微信支付。
第二种:微信内部呼起微信支付。
项目说明:
我那边的项目要求的两种方法均要适用。产品要求是当支付失败时或则未支付情况是逗留在支付订单页面,可再度发起订单恳求(新订单),故我在这项目中,把支付成功页面和订单页面在同一页(根据订单状态去展示)。
前期打算:公众号设置:
内部呼起陌陌搭桥,需要配置一个网页授权域名,用于后端内部呼起陌陌生成对应的code给到前端。
需要注意的是,填入域名即可,不用在域名前加【】,不然会提示【域名或路径格式不正确,请参考注意事项】。别问我如何晓得的,因为我删除了我写的后面【】就配置通过了。
后端涉及到支付,要配置支付授权。
公众平台配置位置:微信支付-开发设置-支付授权目录
前端代码判定浏览器情况
初始化时判定浏览器内核,并针对不同情况做不同的事情。
init(){
this.wechatFlag = this.isWeChat();//本人项目提交时需要判断区分,所以就定义了全局
if(this.wechatFlag){
//当前在微信内部 do someThing
// 比方判断是否有授权code
let code = this.getQueryObject().code;
if (code == null || code == '') {
this.redirectPage();//重定向获取code
} else {
this.code = code;
}
}else{
//外部浏览器 do someThing
//项目里,我设置的支付订单页和成功页在同一个页面
//所以外部浏览器付费与否都回到这个页面
//所以我这要获取成功后的订单参数
if (this.$route.query.orderNumber) {//外部浏览器跳转重定向
//从微信里重定向回来
this.orderId = this.$route.query.orderNumber;//订单参数
//this.getMyOrder();//请求订单数据
}
}
}
复制代码
判断是否在陌陌内部浏览器(浏览器内核)isWeChat()
isWeChat(){
//判断是否为微信内部登录
var ua = window.navigator.userAgent.toLowerCase();
//console.log(ua);
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;//是微信内部
} else {
return false;
}
}
}
复制代码
外部浏览器成功反弹后url传参获取getQueryObject()【公用函数】
getQueryObject(url){////可当成一个公用方法
url = url == null ? window.location.href : url;
let search = url.substring(url.lastIndexOf("?") + 1);
let obj = {};
let reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, function (rs, $1, $2) {
let name = decodeURIComponent($1);
let val = decodeURIComponent($2);
val = String(val);
obj[name] = val;
return rs;
});
return obj;
}
复制代码
第一种:其他浏览器呼起微信支付。
思路:其他浏览器呼起微信支付,更多的是借助后台插口返回数据。
请求微信支付的插口 --> 接口返回一个链接 --> 跳转联接
async submitOrder(){
this.isDisabledSubmitBtn = true //防止用户点击多次
let params= {};//项目支付相关的参数
try {
let {
retBody,
retMsg
} = await requestPay (params)//请求接口
if (retStatus === 'success') {//成功判断依据
if (retBody) {//直接跳转链接
window.location.href = retBody;
}
} else {
this.$notify(retMsg || '提交订单失败')
this.isDisabledSubmitBtn = false //防止用户点击多次
}
} catch (error) {
this.error = true
this.$notify('提交订单失败' || error)
this.isDisabledSubmitBtn = false //防止用户点击多次
}
}
}
跳转回来之后就在会重新create了,获取与后台约定参数重新查询订单数据即可。
复制代码
第二种:微信内部浏览器
需要后端搭桥呼起浏览器外置方式
重定向获取用户code
redirectPage(){
//微信内部则重定向页面
let local = window.location.href;//当前地址
let appId = 'thisistheappid';//填写公众号APPID
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(local)}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect` //跳转授权链接
},
复制代码
提交函数
submitOrderInside(){
let params = {
code:this.code,
};//微信内部添加的订单,后台需要我传多一个用户code
//因为code有时效性,所以失效了或者使用过之后需要重新获取个新的code
try {
let {
retStatus,
retBody,
retMsg
} = await requestPayInside(params)//支付接口
if (retStatus === 'success') {
this.orderId = retBody.orderNumber;
this.weChatParameter = {//微信搭桥需要的数据
appid: retBody.appid,
timeStamp: retBody.timeStamp,
nonceStr: retBody.nonceStr,
packageValue: retBody.packageValue,
signType: retBody.signType,
paySign: retBody.paySign,
};
this.wechatPay();//微信内置对象判断
} else {
this.$notify(retMsg || '提交订单失败')
this.isDisabledSubmitBtn = false //防止用户点击多次
this.redirectPage();//重定向获取新的code
}
} catch (error) {
this.error = true
this.$notify('提交订单失败' || error)
this.isDisabledSubmitBtn = false //防止用户点击多次
this.redirectPage();//重定向获取新的code
}
}
复制代码
wechatPay()解决陌陌外置对象报错
//搭桥前先解决微信内置对象报错
weixinPay (params) {
var that = this;
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', that.onBridgeReady(params), false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', that.onBridgeReady(params));
document.attachEvent('onWeixinJSBridgeReady', that.onBridgeReady(params));
}
} else {
that.onBridgeReady();
}
},
复制代码
搭桥onBridgeReady()
//微信内置浏览器类
onBridgeReady () {
var that = this;
var timestamp = Math.round(that.weChatParameter.timeStamp).toString();
window.WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
debug: false,
"appId": that.weChatParameter.appid, //公众号名称,由商户传入
"timeStamp": timestamp, //时间戳,自1970年以来的秒数
"nonceStr": that.weChatParameter.nonceStr, //随机串
"package": that.weChatParameter.packageValue,
"signType": that.weChatParameter.signType, //微信签名方式:
"paySign": that.weChatParameter.paySign, //微信签名
jsApiList: [
'chooseWXPay'
]
},
function (res) {
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
if (res.err_msg == "get_brand_wcpay_request:ok") { //支付成功后的操作
that.isDisabledSubmitBtn = true;
//支付成功
that.getMyOrder();//请求成功后重新请求订单数据
} else if (res.err_msg == 'get_brand_wcpay_request:cancel') { //取消支付的操作
that.isDisabledSubmitBtn = false //按钮恢复高亮
that.redirectPage();//重定向获取新的code
//取消支付
} else {
//支付失败
that.isDisabledSubmitBtn = false //按钮恢复高亮
that.redirectPage();//重定向获取新的code
}
}
);
}
复制代码