因业务需要,开发微信支付功能,涉及三种支付方式: - JSAPI 支付:微信内网页支付,需要开通微信服务号
- 小程序支付:在小程序中支付,需要开通小程序
- H5 支付:在手机浏览器(出微信内网爷)中网页支付
使用微信支付的前提必开通微信商户号,要使用到那种的支付方式要前需在商户平台开通(要审核)。 支付的钱最终都会到商户号里(一般由公司财务开通)。 开发微信支付的过程中大大小小坑还是踩了不少,终于做完了,整理下开发流程。 参考: 小程序支付开发流程- 小程序端请求创建订单接口,后端统一下单获取
orderId 并返回 - 小程序端获取通过wx.login()获取
code - 小程序端拿这
code 和orderId 请求后端接口,获取支付所需数据 - 获取支付所需数据之后,小程序端调用wx.requestPayment()接口,直接调用起支付页面
- 判断是否支付成功后的逻辑
伪代码async function wxPay(goodId) {
let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
goodId,
});
let code = await wxlogin();
let payData = await ajax("POST", "/api/OrderProgram/WxXcxPay", {
orderId,
code,
});
let res = await payment(payData);
let payResult = res.errMsg;
if (payResult == "requestPayment:ok") {
console.log("支付成功");
} else if (payResult == "requestPayment:fail cancel") {
console.log("用户取消支付");
} else {
console.log("支付失败");
}
}
注意事项- 申请微信小程序账号
申请成功可拿到 AppID(小程序 id)和 AppSecret(小程序密钥) 申请类型为企业性质,否则无法接入微信支付 - 微信小程序认证
通过认证的小程序才能接入微信支付和绑定商户平台 - 申请商户平台账号
需要第一步申请的 AppID 申请成功可拿到 MchID(商户 id)和 MchKey(商户密钥) - 信小程序关联商户号
微信和商户都认证成功后,在微信后台微信支付菜单中进行关联 - 接入微信支付
在微信后台微信支付菜单中进行接入
参考H5 支付开发流程- 前端端请求创建订单接口,后端统一下单获取
orderId 并返回 - 前端带着
orderId 请求支付接口,获得 mweb_url , - 然后跳转
mweb_url 会跳转微信自动调用微信支付 - 支付后返回支付页,判断是否支付成功(需发送请求后端查询)
4.1 刷新页面,获取最新的支付(订单)状态。 4.2 设置一个的按钮"我已支付",让用户点击自动查询状态。
伪代码async function wxH5Pay(goodId) {
let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
goodId,
});
let mweb_url = await ajax("POST", "/api/OrderProgram/WxH5Pay", { orderId });
if (mweb_url) {
location.href = mweb_url;
} else {
console.log("回调地址出错");
}
}
注意事项- 在商户平台设置正确的支付域名
- 调试需要在线上,如果嫌麻烦可以使用内网穿透(Ngrok 或花生壳)
- 需对
redirect_url 进行urlencode 处理 - H5 支付不能直接在微信客户端内调起,请在外部浏览器调起。
参考JSAPI 支付(微信内网页支付)开发流程- 前端商品页创建订单,在后端统一下单后获取
orderId - 前端带着
orderId 跳转到支付页,
获取 code - 第一次进入页面,判断是否路径中有
code - 没有
code ,请求数据跳转授权页面,code 会通过回调地址一起返回回来 - 拿到
code ,发送给后端,后端解析到 openid ,保存好。
点击确定支付按钮,触发 wxPay() 方法 - 发送
orderId 给后端,获取 wxData wxData 中包含 wx.config 和 wx.chooseWXPay 两个接口的数据。- 先调用
wx.config() 然后在调用 wx.chooseWXPay() ,如果一切正常,支付页面就会弹出。
- 支付状态通过后端去查询
伪代码
let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
goodId,
});
this.$router.push({ name: "wx_pay_page", params: { orderId: id } });
import wx from "weixin-js-sdk";
<template>
<div>
<button @click="wxPay">点击支付button>
div>
template>
支付页 JS
data(){
return {
orderId: this.$route.params.orderId,
url: '',
wxData: null,
}
},
mounted(){
this.getCode()
}
methods: {
getCode() {
var code = this.getUrlPram("code");
if (code != null) {
this.code = code;
this.sendCode(code);
} else {
this.getUrl();
}
},
getUrl() {
this.axios
.post("/api/OrderProgram/GetOpenidAndAccessToken", {
orderId: this.orderId,
})
.then((data) => {
this.url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${data.appId}&redirect_uri=${data.redirect_uri}&response_type=${data.response_type}&scope=${data.scope}&state=${data.state}`;
window.location.href = this.url;
})
.catch((err) => {
console.log(err);
});
},
sendCode(code) {
this.axios
.post("/api/OrderProgram/GetOpenidAndAccessTokenFromCode", {
code: code,
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
},
wxPay: async function() {
this.wxData = await this.axios.post(
"/api/OrderProgram/WxJSAPIPay",
{ orderId: this.orderId }
);
let wxConfigData = this.wxData.wxConfigData
let wxPayData = this.wxData.wxPayData;
this.$wx.config({
debug: false,
appId: wxConfigData.appId,
timestamp: wxConfigData.timeStamp,
nonceStr: wxConfigData.nonceStr,
signature: wxConfigData.paySign,
jsApiList: [
"chooseWXPay",
],
});
this.$wx.chooseWXPay({
timestamp: wxPayData.timeStamp,
nonceStr: wxPayData.nonceStr,
package: wxPayData.package,
signType: wxPayData.signType,
paySign: wxPayData.paySign,
success: (res) => {
this.$toast("支付成功");
},
fail: (err) => {
this.$toast("支付失败");
},
});
},
}
同时支持 H5 支付和 JSAPI 支付
if (isWx()) {
this.WXPay(orderId);
} else {
this.H5Pay(orderId);
}
function isWx() {
let uAgent = navigator.userAgent.toLowerCase();
reutrn(/micromessenger/.test(uAgent)) ? true : false;
}
注意事项- 开通微信商户号 - 设置支付目录(如果是 Vue 这类 SPA 页面,到根目录即可,也就是#号之前的地址)
- 开通微信公众号(服务号) - 设置安全域名、设置授权域名
- 收集参数:appId 和 AppSecret
- 添加 Web 开发工具开发者(需要开发者同时开发者关注开发的微信公众号和微信公众账号安全助手)
[图片上传失败...(image-b07878-1605777597831)] - 设置回调域名(例如:
www.xx.com/pay ,最后获取的 code 会拼在此回调地址后返回,返回后如www.xx.com/pay?code=xxxx )
 获取 code - 参考获取 code 文档
- 在微信客户端网页打开授权地址,跳转之后,在返回的回调地址之后拿到
code :
https://open.weixin.qq.com/connect/oauth2/authorize
?appid=你的appid
&redirect_uri=你的回调地址(拿到code后返回)
&response_type=code(返回类型,默认code)
&scope=snsapi_base(授权范围,静默授权拿到openid)
&state=STATE(自定义状态,非必填)
redirect_uri 参数要和你在微信公众号里设置的回调域名一致(例如:www.xx.com/pay ),需要注意的是这 url 需要urlEncode 。
请求这个地址之后,code 会以你设置的redirect_uri 地址里的参数带回来,拿到之后传给后端就行了。 前端引入 js-skd - 使用
script 引入js-sdk - 下载使用
npm 包weixin-js-sdk
参考总结整个流程走下来,给我的体验是:小程序支付最方面(因为配置少),其次是 H5,JSAPI 支付最麻烦(文章一多半都在写它) 在微信支付功能开发过程中,其实最麻烦的不是开发流程,而是他的各种配置和授权流程,为了拿到所需的参数而来回折腾。 开发过程中的一些参数是经常用到的,如 appid、openid、orderId 支付流程大径相同,先获取到用户的 openid,知道你是谁,然后统一下单拿到 orderId 再去处理不同平台的支付方式 开发时候用到的相关文档,一定要仔细阅读二遍以上为止!! |