Vue — 微信公众号内置h5支付相关
首先,在公众号后台配置h5页面地址
开发流程
1.通过配置h5地址,获取code。再通过code,获取openid
getOpenid(){
let url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx697881XXXXXXXX&redirect_uri=https://XXXXX.com&response_type=code&scope=snsapi_userinfo&state=access#wechat_redirect'
let self = this;
let access_code=this.GetQueryString('code');
let local = window.location.href;
if (access_code == null) {
window.location.href = url;
} else {
self.curCode = access_code;
self.$axios.get(self.baseUrl+'/api/weixin/openid/'+ self.curCode).then(res =>{
if(res.data.data.openid == ''){
window.location.href = url;
}
self.openid = res.data.data.openid;
self.token = res.data.data.token;
localStorage.setItem('openid',self.openid);
self.getCerList();
})
}
},
GetQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg)
if(r!=null)return unescape(r[2]); return null;
}
将获取到的openid和token保存起来(有时获取的openid为空,可以重新再获取一遍)
2.提交支付,获取 prepay_id 和 appid
saveForm: function () { var self = this; if(!self.checkForm()){ self.$toast.center('输入有误,请检查'); return false; } var data = { cert_id:self.curCertId, cert_name:self.curCertName, cert_type:0, wechat_id: localStorage.openid } self.$axios({ method:"post", url:self.baseUrl+'/api/v1/weixin/applicants/users', headers:{ 'Content-Type': 'application/json' }, data:data, }).then((res)=>{ if(res.data.success){ self.getOrderMsg(); }else{ self.$toast.center(res.data.msg); } }) }, getOrderMsg(){ let self = this; let openid = localStorage.getItem('openid'); self.$axios({ method:"get", url:self.baseUrl+'/api/v1/weixin/wxorder/'+ openid +'/'+ self.curCertId, }).then((res)=>{ if(res.data.success){ let data = res.data.data; let price = data.price; if(price == 0){//免费 this.$router.push({path:'/Wait'}); }else{ let appid = data.appid; let prepayid = data.prepay_id; let name = data.name; let apikey = data.apikey; let orderid = data.orderid; this.$router.push({path:'/Order',query:{appid:appid,prepayid:prepayid,price:price,name:name,orderid:orderid,apikey:apikey}}); } }else{ self.$toast.center(res.data.msg); } }) },
3.参见 微信开发文档,逐一获得相关参数
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
data() { return { prepayid:'', price:'', name:'', orderid:'', apikey:'', timestamp:'', time:0, orderData:{ appId:'', nonceStr:'', package:'', signType:'MD5', timeStamp:'', }, paySign:'', } }
getParams: function(){ var self = this; self.orderData.appId = self.$route.query.appid; self.orderData.package = 'prepay_id=' + self.$route.query.prepayid; self.price = Number(self.$route.query.price)/100; self.name = self.$route.query.name; self.orderid = self.$route.query.orderid; self.apikey = self.$route.query.apikey; self.getOrderData(); }, getOrderData(){ this.getTimeStamp();//获取时间戳 this.orderData.nonceStr = this.getNonceStr(32);//获取32位随机数 this.getPaySign(this.orderData);//生成签名 },
获取时间戳参数
getTimeStamp(){ const DATE = new Date(); this.orderData.timeStamp = Date.parse(DATE)/1000 + '';//秒数 例如:1414561699 this.time = this.formatDate(); }
formatDate() {//时间格式 let date = new Date(); let y = date.getFullYear(); let MM = date.getMonth() + 1; MM = MM < 10 ? ('0' + MM) : MM; let d = date.getDate(); d = d < 10 ? ('0' + d) : d; let h = date.getHours(); h = h < 10 ? ('0' + h) : h; let m = date.getMinutes(); m = m < 10 ? ('0' + m) : m; let s = date.getSeconds(); s = s < 10 ? ('0' + s) : s; return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s; }
获取随机数参数
getNonceStr(n){//生成 n 位随机数 let chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; let res = ""; for(let i = 0; i < n; i++) { let id = Math.ceil(Math.random() * 35); res += chars[id]; } return res; }
生成签名
getPaySign(obj){ let self = this; const params = []; Object.keys(obj).forEach((key) => { let value = obj[key] // 如果值为undefined我们将其置空 if (typeof value === 'undefined') { value = '' } // 对于需要编码的文本(比如说中文)我们要进行编码 // params.push([key, encodeURIComponent(value)].join('=')) params.push([key, value].join('=')) }) let stringA = params.join('&'); let stringSingTemp = stringA + '&key='+self.apikey; let sign = md5(stringSingTemp).toUpperCase(); self.paySign = sign;
var testparams = { "appId":self.orderData.appId, //公众号名称,由商户传入 "timeStamp":self.orderData.timeStamp, //时间戳,自1970年以来的秒数 "nonceStr":self.orderData.nonceStr, //随机串 "package": self.orderData.package, "signType":self.orderData.signType, //微信签名方式: "paySign":self.paySign, //微信签名 'key':self.apikey } }
可以通过 签名校验工具 进行验证
4.调起微信支付接口
pay(){ let self = this; if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady',self.onBridgeReady,false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', self.onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', self.onBridgeReady); } }else{ self.onBridgeReady(); } },
onBridgeReady(){ let self = this; var params = { "appId":self.orderData.appId,//公众号名称,由商户传入 "timeStamp":self.orderData.timeStamp,//时间戳,自1970年以来的秒数 "nonceStr":self.orderData.nonceStr,//随机串 "package": self.orderData.package, "signType":self.orderData.signType,//微信签名方式:MD5 "paySign":self.paySign,//微信签名 }; WeixinJSBridge.invoke('getBrandWCPayRequest',params ,function(res){ if(res.err_msg == "get_brand_wcpay_request:ok"){ self.$router.push('/Wait'); }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ self.$toast.center('取消支付!'); }else{ alert(JSON.stringify(res)); } }); },
这是调起支付密码页面
支付成功后跳转到wait等待页面