微信app支付python版
首先看一下微信支付的流程图,微信开放平台链接:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3
流程:
1.用户选择商品下单,会传数据给后台,请求生成支付订单
2.后台接受到数据后,做整理签名,然后访问微信服务端生成预付单号,返回给后台
3.后台接受到预付单号后,再把所有的数据(加上预付单号)整理以下,签名,然后给前端,这样就可以支付了
4.异步回调通知先不写
接下来写代码
# 微信支付随机生成字符串
def createNoncestr(length=32):
"""产生随机字符串,不长于32位"""
chars = "abcdefghijklmnopqrstuvwxyz0123456789"
strs = []
for x in range(length):
strs.append(chars[random.randrange(0, len(chars))])
return "".join(strs)
#排序 , 更改格式
def get_sign_contents(all_params):
sign_content = ""
for (k, v) in sorted(all_params.items()):
value = v
if not isinstance(value, str):
value = json.dumps(value, ensure_ascii=False)
sign_content += ("&" + k + "=" + value)
sign_content = sign_content[1:]
return sign_content
# 微信md5加密
def MD5(str):
md5 = hashlib.md5()
md5.update(str.encode('utf-8'))
return md5.hexdigest()
#微信支付代码 我只把必须填的数据加到了字典里,如果有需要再自行添加
def weixinpay( recordid(单号), subject(商品标题), total_amount(金额)):
#第一次签名用
model = {}
#第二次签名用
prepay = {}
weixinkey = '''你的微信密钥'''
#微信服务端,访问它会返回预付单号
url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
# 应用id
model['appid'] = '你的应用id'
# 商户id
model['mch_id'] = '你的商户id'
# 生成的随机数32位
model['nonce_str'] = createNoncestr()
# 商品描述,前端传给你的商品标题
model['body'] = subject
# 签名类型
model['sign_type'] = 'MD5'
# 商户订单号
model['out_trade_no'] = recordid
# 总金额,微信金额单位为分,所以需要乘100
model['total_fee'] = str(int(float(total_amount) * 100))
# 终端ip
model['spbill_create_ip'] = '123.12.12.123'
# 通知地址,异步回调的地址
model['notify_url'] = '你的服务器地址'
# 交易类型
model['trade_type'] = 'APP'
#把model字典格式改成微信需要的格式
models = get_sign_contents(model)
#把你的微信密钥加上
models = models + '&key=' + weixinkey
#把排序号的数据做签名,md5加密
sign = (MD5(models)).upper()
#签名完后加到model字典里
model['sign'] = sign
#改成xml格式
xml = "<xml>"
for k, v in model.items():
if type(v) == int:
v = str(v)
xml += '<' + k + '>' + v + '</' + k + '>'
xml += "</xml>"
#然后用post请求,去获取预付单号
response = requests.post(url, xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
#获取下来更改格式
msg = response.text.encode('ISO-8859-1').decode('utf-8')
#把xml格式改为字典格式,需要第三方库,自行下载
xmlresp = xmltodict.parse(msg)
#如果两次判断都正确,说明请求到了预付单号
if xmlresp['xml']['return_code'] == 'SUCCESS':
if xmlresp['xml']['result_code'] == 'SUCCESS':
#然后把数据添加到prepay字典里
prepay['prepayid'] = xmlresp['xml']['prepay_id']
prepay['appid'] = xmlresp['xml']['appid']
prepay['partnerid'] = xmlresp['xml']['mch_id']
#生成随机字符串
prepay['noncestr'] = createNoncestr()
prepay['timestamp'] = str(int(time.time()))
prepay['package'] = 'Sign=WXPay'
#再一次排序
prepays = get_sign_contents(prepay)
modelss = prepays + '&key=' + weixinkey
#再一次加密
sign = MD5(modelss).upper()
#把签名加到字典里
prepay['sign'] = sign
prepay['code'] = '00'
prepay['msg'] = '获取成功'
#返回数据
return prepay
else:
prepay['code'] = '01'
prepay['msg'] = '获取失败'
return prepay
else:
prepay['code'] = '01'
prepay['msg'] = '获取失败'
return prepay