前几天公司要求做H5支付,所以在这里记录下,方便以后查看!
首先要做H5支付必须先做网页授权,授权拿到code,后台用code去换openid返给前端,之后前端才能调起微信内置的JSAPI完成支付(网页授权的准备工作这里就不说了,可以自行百度)
1.网页授权部分(静默授权)
思路:用户进入页面分2种情况,一种是第一次进入未授权过的用户,另一种是已授权过的用户。(用户同意网页授权会在路径中有一个重要的code,可以用过这个参数进行判断。)
未授权用户:没有code就去授权
已授权用户:拿到code发给后台,后台要通过code去换取openid
授权的官方文档:
授权代码
authorization() {
debugger;
var codeTemp = this.getQueryString() // 获取url参数的方法,因为我们还有其他参数,所以返回对象格式
if (!codeTemp.code) {
// 没有code就去授权
scId = codeTemp.scId //scId在之前声明过
var datas = {
redirectUri: "https://当前支付页面路径"
};
this.$http({
method: "POST",
url: "自己后台的接口地址",
data: this.$Qs.stringify(datas) // 接口要求传入form-data格式
}).then(res => {
window.location.href = res.data.data; // 拼接好的地址(我们这里是后台拼接的链接,前端只负责把redirectUri传过去就好了)
});
} else {
code = codeTemp.code;
// 将code发给后台换取openId
var codeData = {
code: code
};
this.$http({
method: "POST",
url: "自己接口",
data: this.$Qs.stringify(codeData)
}).then(res => {
var s = JSON.stringify(res);
window.sessionStorage.setItem("openId", res.data.data.openid); //存入本地
});
}
}
// 这个方法用来从window.location.href拿出来code
getQueryString() {
debugger;
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
var strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
}
return theRequest;
},
2.支付部分
官方支付文档:
link
拿到openid再去换取支付需要的参数
getPrePayId() {
var that = this;
var openId = window.sessionStorage.getItem("openId");
this.$validator.validate().then(valid => { // 这个是element-ui表单验证成功之后的回调,不需要可以将if 中的代码拿出来
if (true === valid) {
if (
this.formData.name == "" || // 支付人的信息
this.formData.mobile == "" ||
openId == ""
) {
return;
}
// 此处发请求,用openid换prepayid
var orderData = {
xyMpOpenid: openId, // 公众号openId
payUserName: this.formData.name, //支 付人名称【仅针对H5支付】
payUserPhone: this.formData.mobile, //支付人手机号
payRealAmt: 0.1, //实际支付金额
payTotalAmt: 0.1, // 订单总金额
};
this.$http({
method: "POST",
url: "自己后台下单的接口",
data: that.$Qs.stringify(orderData)
}).then(res => {
console.log("prePayId" + res);
var payData = {};
payData.appId = res.data.data.appId;
payData.timeStamp = res.data.data.timeStamp;
payData.nonceStr = res.data.data.nonceStr;
payData.package = res.data.data.package;
payData.signType = "MD5"; //微信签名方式(固定写死)
payData.paySign = res.data.data.paySign;
// 以下都是微信提供的方法,也可以去官方文档自行复制
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(payData); // 将支付参数传入微信提供的支付方法
}
});
} else {
console.log(this.$validator.errors.all()); // element-ui的表单验证
}
});
},
支付(微信提供的方法)
// 微信内置方法,调起支付
onBridgeReady(payData) {
WeixinJSBridge.invoke("getBrandWCPayRequest", payData, function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// 可以写自己的需求逻辑,可以给用户做提示
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
// '支付过程中用户取消!'
} else if (res.err_msg == "get_brand_wcpay_request:fail") {
// '支付失败!'
}
});
},