今天是五一的第三天假,咱来聊聊微信支付吧,现在网上的微信支付的相关文章不是直接照搬官网就是互抄,如果刚接触微信支付时候去搜相关文章时你会发现很混乱,所以特此总结一篇微信支付的文章,写下自己踩过的坑,也给需要的人一些帮助,我的项目是在vue移动端的项目上,所以我会总结两种微信支付的方式(JSAPI:在微信浏览器上的微信支付,MWEB:在微信以外的浏览器上的支付)。
项目是用vue+ts的,如果项目上没有ts的就把一些类型声明去掉,下面就开始步入正题了。
1.如果你的下一个页面要进行微信支付,那就要在上一个页面提前判断是否在微信里面,如果在微信里面是要获取到code值才能进行JSAPI支付的。
// 判断是否在微信浏览器 1为微信浏览器 2为其他 这个方法定义在外面,后面也会用到
_isweixin() {
return new Promise((resolve: any) => {
const ua: any = window.navigator.userAgent.toLowerCase();
//userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。
if (ua.match(/MicroMessenger/i) == "micromessenger") {
resolve(1);
} else {
resolve(2);
}
});
}
注意:hostUrl是对应参数redirect_uri的,我刚开始踩坑的时候是redirect_uri域名与后台配置不一致,所以一定这个要跟配置网页授权域名的人拿,如果没有配置是拿不了code值,就没法进行第二步了,获取code的步骤在这里
//然后下面这个方法是跳转到需要微信支付的页面
async _nextTournamentPackage({ bagId }: any) {
const isweixin = await this._isweixin();
if (isweixin === 1) {
//这里我是外部引入,需要的话自己引入APPID,hostUrl
const appid = APPID;
const redirecturi: any = encodeURIComponent(
`${hostUrl}/#/package?data=${JSON.stringify(
Object.assign({}, { bagId })
)}`
);
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirecturi}&response_type=code&scope=snsapi_base#wechat_redirect`;
} else {
this.$router.push({
name: "package",
query: { data: JSON.stringify(Object.assign({}, { bagId })) },
});
}
}
2.第二步是拿到code值,后面就是要获取签名之类的,文档在这里,这个签名这些可以后台配置给你,也可以前端自己生成。具体看文档。
// wechatPay.ts文件
import { Vue } from "vue-property-decorator";
declare let WeixinJSBridge: any // 解决 WeixinJSBridge 在TS编译会报错
export interface Res { // 微信需要传入的数据,数据格式定义
appId?: string;
timeStamp?: string;
nonceStr?: string;
package?: string;
signType?: string;
sign?: string;
}
export default class WechatPay extends Vue {
public payType = ''
public res: Res = {} // 数据由后端返回
/**
* 微信JS支付,在点击支付时启用
*/
public WeChartJSBridge(callback:any):void {
if (typeof WeixinJSBridge === 'undefined') { // WeixinJSBridge 在TS编译会报错,因为该对象只在微信浏览器中存在,在文件头部声明 declare let WeixinJSBridge: any 即可
if (document.addEventListener) {
// 监听调用,可有可无
document.addEventListener('WeixinJSBridgeReady', () => {
this.onBridgeReady(this.res, callback)
}, false)
}
else if ((document as any).attachEvent) { // attachEvent()只在IE中有用,IE11已经不再支持
(document as any).attachEvent('WeixinJSBridgeReady', this.onBridgeReady);
(document as any).attachEvent('onWeixinJSBridgeReady', this.onBridgeReady);
}
} else {
this.onBridgeReady(this.res, callback)
}
}
public onBridgeReady(res: Res,callback:Function): void {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId: res.appId,
// 公众号名称,由商户传入
timeStamp: res.timeStamp,
// 时间戳,自1970年以来的秒数
nonceStr: res.nonceStr,
// 随机串
package: res.package,
signType: res.signType,
// 微信签名方式:
paySign: res.sign
// 微信签名
},
(res: any) => {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
// 使用以上方式判断前端返回,微信团队郑重提示:
// res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
callback()
}
if (res.err_msg === 'get_brand_wcpay_request:cancel') {
// 支付取消
}
if (res.err_msg === 'get_brand_wcpay_request:fail') {
// 支付失败
}
})
}
}
//这是跳转过来的package的页面
// 引入上面那个文件
import WechatPay from "@/utils/wechatPay";
// 确认人民币付款
async confirmRmbPay() {
const params: any = {
id: '你请求接口传的id',
payType: "wechatPay"
};
const isweixin = await this._isweixin();
if (isweixin === 2) {
alert("请在微信以外的浏览器里打开并支付!");
// params.payScenes = "MWEB";
// orderPay(params)
// .then((res: any) => {
// if (Number(res.code) === 0) {
// 调用直接跳转后台返回给你的url地址,类似下面的地址
// // window.location.href =
// // "weixin://wap/pay?prepayid=xxxxxxxxx&package=xxxxxx";
// } else {
// Toast.info(res.msg);
// }
// })
// .catch(() => {
//
// });
} else {
// 这个是在微信浏览器里的支付,获取code值后调用支付
const search: any = window.location.search;
const searchString = search.length > 0 ? search.substring(1) : "";
const args = searchString.length > 0 ? searchString.split("&") : [];
const items: any = {};
for (let i = 0, length = args.length; i < length; i++) {
const name = decodeURIComponent(args[i].split("=")[0]);
const item = decodeURIComponent(args[i].split("=")[1]);
items[name] = item;
}
if (!items["code"]) {
Toast.info("生成订单错误");
return;
}
params.code = items["code"];
params.payScenes = "JSAPI";
//orderOay是调用支付的接口,自己定义
orderPay(params)
.then((res: any) => {
if (Number(res.code) === 0) {
const wechatpay = new WechatPay();
const payParams: any = {
appId: APPID,
timeStamp: res.result.timeStamp,
nonceStr: res.result.nonceStr,
package: `prepay_id=${res.result.prepayId}`,
signType: "MD5",
sign: res.result.paySign
};
wechatpay.res = Object.assign({}, payParams);
//下面wechatpay.WeChartJSBridge里面是一个成功支付的回调,在里面你可以做回调成功的操作
wechatpay.WeChartJSBridge(() => {
return (window.location.href = `${hostUrl}/#/ordergroup2`)
});
} else {
Toast.info(res.msg);
}
})
.catch(() => {
});
}
}
所有过程都结束了,如果喜欢的可以点个赞哦,谢谢各位,有不懂的欢迎私信!
网友评论