微信支付系列文章
vue demo: 下载地址文章底部
技术栈
- vue
- vue-cli
- weixin-js-sdk (微信jsSdk)
微信支付术语
- 微信jsSdk需要提前初始化完成
- 初始化加密参数需要通过后端计算后返回给前端
- 初始化url为在微信支付配置的前端url. (产品中心 => 开发配置 => JSAPI支付 => 支付授权目录添加)
支付流程
前端需要的核心操作, 总共分为以下几步:
- 请求后端接口,获取初始化所需参数(包含加密结果)。
- 初始化微信jsSdk(wx.ready()完成初始化)。
- 用户确认支付,调用后端下单接口,获取微信统一下单id,以及后端统一下单时加密信息。
- 前端调用微信jsSdk.chooseWXPay(),调起微信支付页面。
- 支付成功,jsSdk回调success
- 支付失败,jsSdk回调fail
- 支付取消,jsSdk回调cancel
- 触发回调机制,处理回调结果。
注意:微信jsSdk触发的成功结果回调同步不代表真正成功,业务结果还需请求后台拿到最终的支付状态。
代码
获取jsSdk初始化配置并完成初始化操作
created() {
<!--
微信支付
初始化微信支付jsApi配置,初始化参数由后端返回
url 为前端当前域名,需与微信后台配置相同
chooseWXPay 代表使用微信支付插件,还有很多其他插件,详情移步微信官方文档
-->
let config = {
url: 'https://app.*.com/'
};
let promises = Http.post('/wx/getSdkConfig', config);
promises.then((response) => {
let content = response.content;
config.nonceStr = content.nonceStr;
config.signature = content.signature;
config.timestamp = content.timestamp;
config.appId = content.appId;
config.debug = true;
config.jsApiList = [
'chooseWXPay'
];
wx.config(config);
wx.ready(() => {
this.wx = wx;
});
wx.error(function (res) {
console.info('error 验证失败', res);
});
});
}
发起支付、调起微信支付页面
<!--
微信支付
用户点击确认支付,请求后端发起下单,拿到后端的统一下单id, 调用微信jsApi.chooseWXPay 调起微信支付页面。
支付成功后会调用success方法
支付失败后会调用fail方法
取消支付会调用cancel方法
此处拿到的成功,不能作为支付成功依据,支付结果需要调用后端接口异步拿到
-->
pay() {
let params = {
payAmount: this.payAmount
};
let promises = Http.post('/transaction/do', params);
let that = this;
promises.then((response) => {
if (response.status === 0) {
let recordOrderGid = response.content.recordOrderGid;
try {
this.wx.chooseWXPay({
timestamp: response.content.timeStamp, // 支付签名时间戳,注意微信js sdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: response.content.nonceStr, // 支付签名随机串,不长于 32 位
package: 'prepay_id=' + response.content.prepayId, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: response.content.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: response.content.sign, // 支付签名
success: function () {
that.doWxPayCallback(recordOrderGid);
},
fail: function () {
that.doWxPayCallback(recordOrderGid);
},
cancel: function () {
console.info('取消支付,如需支付请继续。');
}
});
} catch (e) {
console.info('订单支付异常, 请稍后重试。');
}
} else {
console.info(response.message);
}
});
}
处理微信支付结果
<!--
微信支付结果处理
循环调用后端获取支付结果,查询一定次数后跳转到账单或者结果页面,依据个人业务需求即可
-->
doWxPayCallback: function (recordOrderGid) {
let taskCount = 0;
this.intervalid1 = setInterval(() => {
taskCount++;
if (taskCount > 5) {
clearInterval(this.intervalid1);
}
let statusPromise = this.queryOrderStatus(recordOrderGid);
statusPromise.then(sta => {
if (sta.status === 0) {
console.info(sta.content);
let orderStatus = sta.content.status;
if (orderStatus === 1) {
clearInterval(this.intervalid1);
this.$router.push({
path: 'resultOrder', query: {}
});
} else if (orderStatus === 2) {
clearInterval(this.intervalid1);
console.info('订单支付失败。');
} else if (orderStatus === 0) {
console.info('订单支付处理中');
}
}
});
}, 2000);
}
注意点
- 统一下单的签名和后续前端拉取微信支付的签名需要统一, 也就是都采用MD5加密, 如果2者不同, 会导致前端拉取微信支付fail, 这是一个巨大的坑, 因为这个原因调试了好久, 微信在文档里没有明确标出统一下单的签名校验方式 需要和前端拉取微信支付的签名校验保持一致.
- 微信jsSdk初始化信息需要后端加密
- 前端初始化jsSdk配置的url需与微信支付后台配置相同,且以"/"结尾。
vue支付业务流程文档
接口地址 | 描述 | 调用方 |
---|---|---|
src/components/index/Index.vue => created() | 初始化微信支付jsApi配置,初始化参数由后端返回, url 为前端当前域名,需与微信后台配置相同, chooseWXPay 代表使用微信支付插件,还有很多其他插件,详情移步微信官方文档 | 前端 => 后端 => 微信sdk |
src/components/index/Index.vue => methods.pay() | 用户点击确认支付,请求后端发起下单,拿到后端的统一下单id, 调用微信jsApi.chooseWXPay 调起微信支付页面。支付成功后会调用success方法, 支付失败后会调用fail方法, 取消支付会调用cancel方法, 此处拿到的成功,不能作为支付成功依据,支付结果需要调用后端接口异步拿到 | 前端 => 后端 => 微信sdk |
src/components/index/Index.vue => methods.doWxPayCallback() | 微信支付结果处理, 循环调用后端获取支付结果,查询一定次数后跳转到账单或者结果页面,依据个人业务需求即可 | 微信sdk => 前端 => 后端 |
博客
Demo
git clone https://github.com/wangjianan1103/pica_pay.git
联系方式
如果 Pica_pay 对你有帮助,可以关注作者支持一下,每天会不定时回复留言(有任何问题都可以留言哦)。
微信公众号 |
---|