支付交互流程
这里呢,就不多说了,先上图

后台调用,只需要调用统一下单API,就可以了。
获取openid
这是第一步,openid是微信用户在你的小程序中的唯一标识,只需调用
vx.login
即可。
import requests
from config import APPID, SECRET
class OpenidUtils(object):
def __init__(self, jscode):
self.url = "https://api.weixin.qq.com/sns/jscode2session"
self.appid = APPID # 小程序id
self.secret = SECRET # 不要跟后面支付的key搞混
self.jscode = jscode # 前端传回的动态jscode
def get_openid(self):
# url一定要拼接,不可用传参方式
url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"
r = requests.get(url)
print(r.json())
openid = r.json()['openid']
return openid
支付请求
import requests
import json
import hashlib
import time
import random
import string
import xmltodict
class WX_PayToolUtil():
""" 微信支付工具 """
def __init__(self, APP_ID, MCH_ID, API_KEY, NOTIFY_URL):
self._APP_ID = APP_ID # 小程序ID
self._MCH_ID = MCH_ID # 商户号
self._API_KEY = API_KEY
self._UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 接口链接
self._NOTIFY_URL = NOTIFY_URL # 异步通知
def generate_sign(self, param):
'''生成签名'''
stringA = ''
ks = sorted(param.keys())
# 参数排序
for k in ks:
stringA += (k + '=' + param[k] + '&')
# 拼接商户KEY
stringSignTemp = stringA + "key=" + self._API_KEY
# md5加密,也可以用其他方式
hash_md5 = hashlib.md5(stringSignTemp.encode('utf8'))
sign = hash_md5.hexdigest().upper()
return sign
def getPayUrl(self, orderid, openid, goodsPrice, **kwargs):
"""向微信支付端发出请求,获取url"""
# key = self._API_KEY
nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 30)) # 生成随机字符串,小于32位
params = {
'appid': self._APP_ID,
'mch_id': self._MCH_ID,
'nonce_str': nonce_str,
"body": '艺术品订单',
'out_trade_no': orderid,
'total_fee': str(goodsPrice),
'spbill_create_ip': "127.0.0.1",
'notify_url': self._NOTIFY_URL,
'trade_type': "JSAPI",
"openid": openid,
}
# 生成签名
params['sign'] = self.generate_sign(params)
param = {'root': params}
xml = xmltodict.unparse(param)
response = requests.post(self._UFDODER_URL, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
# xml 2 dict
msg = response.text
xmlmsg = xmltodict.parse(msg)
# 4. 获取prepay_id
if xmlmsg['xml']['return_code'] == 'SUCCESS':
if xmlmsg['xml']['result_code'] == 'SUCCESS':
prepay_id = xmlmsg['xml']['prepay_id']
# 时间戳
timeStamp = str(int(time.time()))
# 5. 五个参数
data = {
"appId": self._APP_ID,
"nonceStr": nonce_str,
"package": "prepay_id=" + prepay_id,
"signType": 'MD5',
"timeStamp": timeStamp,
}
# 6. paySign签名
paySign = self.generate_sign(data)
data["paySign"] = paySign # 加入签名
# 7. 传给前端的签名后的参数
return data
当然你可能会遇到的错误有签名错误,一般的情况是你的appSecret和商户号的API密钥两个弄错了,当然如果不是还有可能是其他问题,解决方案链接https://www.cnblogs.com/wanghuijie/p/wxpay_sign_error.html。
很可能遇到的错误
比如返回invalid total_fee
,这是因为,微信支付和支付宝不同,他的计量单位是分,所以不能出现小数点。所以我们系统如果是以元为单位要处理下金额,即先乘以100,再去小数点
- Post link: https://www.godhearing.cn/wei-xin-xiao-cheng-xu-zhi-fu-hou-tai-diao-yong/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.