1、前端提交申请获取用户授权
let ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") { //判断是微信端
window.location.href=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=http%3a%2f%2fm.test.demo.com%2fmoneyManage%2fwxpay&response_type=code&scope=snsapi_base&state=${this.moneyAmount}#wechat_redirect`
} else{}
注:
appid是微信公众号里设置的
redirect_uri需要UrlEncode编码处理,redirect_uri路径所在的域需要和公众号里设置的一致,一定要一致。
state在授权过后微信返回给你的url中也会携带,可以用来传参
2、拿到微信返回给你的url并进行处理(注:获取授权成功后会自动跳转至url页面,即此url页面也是微信支付调起的页面,你的其他操作可以放在此页完成)
拿到的url格式如下
redirect_uri/?code=CODE&state=STATE。
提取url里的code和state
getQueryString(name){
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
},
3、拿到code后去请求后台的处理接口,拿到相关数据
getWxData(){
let code=this.getQueryString("code")
let money=this.getQueryString("state")
let params=new FormData()
params.append('money',money)
params.append('bs',3)
params.append('code',code) //上传哪些参数看后台需要,但是code是必传的
this.$axios.post(`${common.orderApi}/amstc/demowxpay`,params).then(res=>{
if(res.data.code==200){
this.payparams=JSON.parse(res.data.data) //若后台返回的字符串格式,这里需要转为json格式
//准备调用微信内置支付函数,拉取微信内部的支付功能
//详情见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
let funtimes=setTimeout(()=>{ //为什么要用定时器?为了延迟加载微信内置的支付函数,因为页面初始化时不一定能拿到此函数
if(typeof WeixinJSBridge == "undefined") { //未能拿到内置的支付函数
if(document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if(document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else { //拿到了内置的支付函数,则将从接口拿来的数据提交到微信内置的支付函数
this.onBridgeReady();
}
clearTimeout(funtimes)
},1000)
}
}).catch(err=>{})
},
4、微信内置的支付函数
//微信内部调起支付功能的函数,只有在微信app里才会生效,在微信开发工具也不会生效,所以测试时需要真机测试。
onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":this.payparams.appid, //公众号名称,由商户传入
"timeStamp":this.payparams.time_stamp, //时间戳,自1970年以来的秒数
"nonceStr":this.payparams.nonce_str, //随机串
"package":`prepay_id=${this.payparams.prepay_id}`,
"signType":"MD5", //微信签名方式:
"paySign":this.payparams.sign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
this,message='充值成功'
this.isSuccess=1
} else{
this.message="未能完成充值"
this.isSuccess=2
}
});
},
说一说坑
- 微信浏览器内置的支付函数在vue的created()生命周期是拿不到的,所以可以设置定时器延迟加载该支付函数。或者在mounted里加载支付函数(没试过)
- 沙箱环境是实现不了支付功能的,切记,微信测试只能实实在在的去付钱,测试莫得用。当然除了最后一步拉取支付函数,其他步骤还是可以测试测试的。
- 公众号配置的域名一定要与前端的redirect_uri域名一致