流程梳理:
1.微信登录部分
在进行微信支付之前,需要通过微信公众获取用户的openid
大致流程,前端用接口从后端获取appid和回调url,其中回调url是用来获取微信回传的参数的
前端核心代码如下:
function wxLogin() {
axiosx.get('/m/wxInfo/').then(response => {
if (response.data.code === 200) {
const appId = response.data.appid;
const redirectUri = response.data.redirectUri;
const state = 'wxlogin'; // 可以放置一些自定义的状态信息
// 微信授权URL
const weChatAuthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
// 重定向到微信授权页面
window.location.href = weChatAuthUrl
} else {
toast.error('微信配置获取失败')
}
})
}
后端在这个接口给传回来appid和回调地址,然后前端去请求微信的这个地址,这个时候微信页面会弹出一个授权请求弹窗,手动确认后微信会掉用刚才的回调地址
后端回调接口代码如下:
def get(self, request):
code = request.GET.get('code')
access_url = f'https://api.weixin.qq.com/sns/oauth2/access_token?appid={sys_info.wx_appid}&secret={sys_info.wx_secret}&code={code}&grant_type=authorization_code'
print(access_url)
response = requests.get(access_url)
print(response.json())
access_token = response.json()['access_token']
openid = response.json()['openid']
''' 省略其他代码 '''
return redirect(前端地址)
这一步,主要是接收微信通过回调接口传过来的一个code参数,有了它你就可以通过这个url去获取用户的openid,这个id在每个公众号之下是唯一的,需要保存起来,可以用作唯一性鉴定。
2.微信支付部分
前端通过请求后端接口获取appId,预订单和签名等信息 -- >
前端代码:
import wx from 'weixin-js-sdk';
function wxPay() {
axiosx.post('mm/wxPayapi/', { 'oid': oid, 'pt': '商城订单' }).then(response => {
if (response.data.code === 200) {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,线上环境需要改为false
appId: response.data.appId, // 必填,公众号的唯一标识
timestamp: response.data.timeStamp, // 必填,生成签名的时间戳
nonceStr: response.data.nonceStr, // 必填,生成签名的随机串
signature: response.data.paySign, // 必填,签名
jsApiList: ['chooseWXPay'],// 必填,需要使用的JS接口列表
});
wx.ready(() => {
wx.chooseWXPay({
appId: response.data.appId, // 必填,公众号的唯一标识
timestamp: response.data.timeStamp,
nonceStr: response.data.nonceStr, // 支付签名随机串,不长于 32 位
package: response.data.package, // 统一支付接口返回的prepay_id参数值
signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: response.data.paySign, // 支付签名
success: function (res) { //支付成功回调
uni.showToast({
title: '订单支付成功',
icon: 'none',
duration: 2000,
})
// //成功后跳转到订单页
uni.navigateTo({
url: '/pages/wxSucess/wxSucess'
});
},
cancel: function (res) {
uni.showToast({
title: '取消支付',
icon: 'none',
duration: 2000,
})
alert('取消支付')
},
fail: function (res) {
uni.showToast({
title: '支付失败',
icon: 'none',
duration: 2000,
})
alert('支付失败')
}
});
});
这里面导入的包需要用npm 安装,下面是先从后台接口获取到这些值,然后先config,然后在ready之后发起支付请求,请求成功和失败这块都写了
后端用相关参数发起支付请求获得预订单信息 -- 获得签名信息 -- 将appid,预订单,签名等信息返回前端 -- 前端使用相关参数结合微信支付的js插件掉起支付 支付完成进行页面上的回调
后端代码:
from wechatpayv3 import WeChatPayType, WeChatPay
private_key = open(os.path.join(BASE_DIR, 'xxx', 'apiclient_key.pem')).read()
wxpay = WeChatPay(
wechatpay_type=WeChatPayType.MINIPROG, # 固定
mchid=sys_info.wx_mch, # 商户id
private_key=private_key, # 私钥
cert_serial_no=sys_info.serial_no, 证书id
apiv3_key=sys_info.wx_pass3, # v3的秘钥32位那个
appid=sys_info.wx_appid, # appid
notify_url=notify_url, # 回调地址
cert_dir=cert_dir) # 证书文件夹
code, message = wxpay.pay(
description='测试商品',
out_trade_no=random_str, # 订单号
amount={'total': int(float(order_info.order_money) * 100)}, # 金额-分
payer={'openid': user_info.wx_id} # 用户的openid
)
pre_order = json.loads(message).get("prepay_id") # 预订单信息
package = 'prepay_id=' + pre_order
time_stamp = int(time.time()) # 时间戳
pay_sign = wxpay.sign([sys_info.wx_appid, str(time_stamp), random_str, package]) # 签名信息
return Response(
{'code': 200, 'appId': sys_info.wx_appid, 'timeStamp': time_stamp, 'nonceStr': random_str,
'signature': random_str,
'package': package, 'paySign': pay_sign})
上面使用的是一个已经封装好的库,里面涉及的主要信息已经列出,查询出来后把这些值传给前端,前端封装的js就会发起请求。
三、其他事项
除此之外,还需要配置公众号相关的服务器域名,js域名等,ip白名单等,还有微信支付的jsapi里面要配置支付的授权目录,提示什么url没配置就配置相关的url即可。