这段时间一直在忙,说好的微信支付嘛,肯定是要发的,直接切入正题。
微信支付分为:
- 客户端通知服务端发起微信支付。
- 服务端调用微信小程序支付接口,根据返回值进行组装数据。
- 将返回的数据发送给前端,前端根据返回的响应值调用微信组件,拉起支付框。
- 支付成功,微信平台会进行调用我们存储的回调地址,告诉我们支付的状态。
首先,我们去微信开放平台获取必要的参数:
-
微信支付商户号(直连模式)或服务商商户号。
-
商户证书序列号。
-
API v3密钥。
-
APPID,应用ID。
-
回调地址,这个是支付成功后微信通知我们的请求地址(必须是在公网部署的,局域网或本地是不行的)
-
商户证书私钥
这些参数均为微信支付必传,如果对参数不清楚的可以去微信开放平台了解。
微信开放平台:微信开放平台
然后我们,需要下载对应的三方模块,也就是微信的微信支付接口V3版python库
以下是下载资源地址:
https://www.cnblogs.com/mxhmxh/p/10763313.html
https://blog.csdn.net/qq_37193537/article/details/89497071
https://github.com/minibear2021/wechatpayv3 【推荐】
https://gitee.com/minibear2021/wechatpayv3
https://blog.csdn.net/jstony/article/details/115699372
接下来咱们可以去写代码了
1.使用WeChatPay类的构造函数创建一个名为wxpay的实例。
# 微信支付商户号(直连模式)或服务商商户号(服务商模式,即sp_mchid)
MCHID = '167*****'
# 商户证书序列号
CERT_SERIAL_NO = '441AB8BC***********'
# API v3密钥, https://pay.**********'
APIV3_KEY = 'Y**********1'
# APPID,应用ID或服务商模式下的sp_appid
APPID = 'wx7**********787'
# 回调地址,也可以在调用接口的时候覆盖
NOTIFY_URL = 'https://p**********/'
# 商户证书私钥
PRIVATE_KEY = """-----BEGIN PRIVATE KEY-----
....
-----END PRIVATE KEY-----"""
# 初始调试时可不设置,调试通过后再设置,示例值:'./cert'
CERT_DIR = None
# 接入模式:False=直连商户模式,True=服务商模式
PARTNER_MODE = False
# 代理设置,None或者{"https": "http://10.10.1.10:1080"},详细格式参见https://requests.readthedocs.io/en/latest/user/advanced/#proxies
PROXY = None
# 请求超时时间配置
TIMEOUT = (10, 30) # 建立连接最大超时时间是10s,读取响应的最大超时时间是30s
# 使用WeChatPay类的构造函数创建一个名为wxpay的实例。
wxpay = WeChatPay(
# 微信支付类型为NATIVE。
wechatpay_type=WeChatPayType.NATIVE,
mchid=MCHID,#商户号。
private_key=PRIVATE_KEY,#商户私钥。
cert_serial_no=CERT_SERIAL_NO,#证书序列号
apiv3_key=APIV3_KEY,#APIv3密钥
appid=APPID,#应用ID
notify_url=NOTIFY_URL,# 回调通知地址。
cert_dir=CERT_DIR,#证书目录。
partner_mode=PARTNER_MODE,#合作模式
proxy=PROXY,#代理
timeout=TIMEOUT#超时时间
)
2.定义函数发起微信支付
def we_chat_pay():
# 设置支付者信息
payer = {'openid': "发起支付的用户微信id"}
# 调用微信支付API
code, message = wxpay.pay(
description="商品描述", # 商品描述
out_trade_no="2021090112345678910", # 订单号
amount={'total': int(80)}, # 订单金额
pay_type=WeChatPayType.MINIPROG, # 支付方式:小程序支付
payer=payer # 支付者信息
)
# 解析微信支付API返回的结果
result = json.loads(message)
# 打印获取的值
print(result)
# 调用当前函数
we_chat_pay()
如果运行出来的结果为以下类型,说明咱们已经向微信发送支付请求成功了。
{'prepay_id': 'wx28132217.......140001'}
3.接下来需要对数据进行处理,前端需要根据这些参数才能进行唤起支付界面的操作。
接着上面的函数,进行扩展操作我
if code in range(200, 300):
# 提取必要的参数
prepay_id = result.get('prepay_id')
timestamp = str(int(time.time())) # 当前时间戳
noncestr = str(uuid.uuid4()).replace('-', '') # 生成一个随机字符串
package = 'prepay_id=' + prepay_id # 拼接prepay_id参数
# 生成签名
sign = wxpay.sign(data=[APPID, timestamp, noncestr, package])
signtype = 'RSA' # 签名方式
# 定义参数传入redis
order_data = {
'result': {
'appId': APPID, # 微信公众号ID
'timeStamp': timestamp, # 当前时间戳
'nonceStr': noncestr, # 随机字符串
'package': 'prepay_id=%s' % prepay_id, # 拼接的prepay_id参数
'signType': signtype, # 签名方式
'paySign': sign # 签名
}
}
return order_data
打印order_data,如果一切正常,打印出来的数据应该是以下类型:
{
"result": {
"appId": "wx7ba870******3787",
"timeStamp": "1******464",
"nonceStr": "2abdb9c******e4c11",
"package": "prepay_id=wx281******e6f390000",
"signType": "RSA",
"paySign": "o8RK1seAl1v******6qhRw1NeSWQ=="
}
}
我们需要讲这些参数返给前端,让前端根据这些参数唤起微信支付界面。
4.支付成功的回调
我们在第一步已经定义了的回调地址,然后我们需要编写接口接受微信返回的回调信息。
# wxpay是咱们第一步定义的对象。
# 定义函数
def notify():
# 调用 wxpay.callback 函数处理请求头和请求数据
result = wxpay.callback(request.headers, request.data)
# 如果处理结果存在且事件类型为 'TRANSACTION.SUCCESS'
if result and result.get('event_type') == 'TRANSACTION.SUCCESS':
# 从处理结果中获取资源信息
resp = result.get('resource')
# 在这里可以写我们的业务处理,必须要返回一个SUCCESS的回复,否则微信会视为没有调用成功,从而一直调用当前请求。
return jsonify({'code': 'SUCCESS', 'message': '成功'})
OK,微信支付到这里就结束了,有不动的活不明白的小伙伴可以在下面回复或者私信我,感谢支持。