微信支付功能涉及到很多接口以及安全性的处理,因为涉及到具体的接口和key,以下是一个简化模型,不适合直接运行使用。
需要注意的是,微信支付功能必须满足微信支付的相关规定,例如:必须是企业才可以申请微信支付接口权限,个人不具备该权限。
这里以Flask框架为例,发起微信支付的大概流程为:
1、接收前端传来的订单信息。
2、服务器端对订单信息进行处理,生成订单。
3、调用统一下单API获取预支付交易会话标识prepay_id。
4、将返回的数据再一次签名,然后返回给客户端。
5、客户端接收到数据后发起支付请求。
6、客户端支付完成后,微信会异步通知支付结果。
7、服务端收到支付结果,更新订单状态。
Python代码如下:
import hashlib
import requests
from flask import Flask, request, jsonify
from xml.etree import ElementTree as ET
def make_order_body(order_info):
"""生成订单XML格式体"""
body = ET.Element('xml')
for key, value in order_info.items():
e = ET.SubElement(body, key)
e.text = value
return ET.tostring(body, encoding='utf-8')
def sign(order_info, key):
"""创建签名"""
stringA = '&'.join('%s=%s' % (k, order_info.get(k, '')) for k in sorted(order_info))
stringSignTemp = '%s&key=%s' % (stringA, key)
return hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
def make_order(out_trade_no, body, total_fee):
"""生成订单"""
# 这里应换成自己申请的APPID和MCHID
order_info = {
'appid': 'wx.....',
'mch_id': '.....',
'nonce_str': '5K8264ILTKCH16CQ2502SI8ZNMTM67VS',
'body': body,
'out_trade_no': out_trade_no,
'total_fee': str(total_fee),
'spbill_create_ip': '123.12.12.123',
'notify_url': 'http://www.weixin.qq.com/wxpay/pay.php',
'trade_type': 'APP'
}
# 这里应换成自己的签名key
key = '192006250b4c09247ec02edce69f6a2d'
order_info['sign'] = sign(order_info, key)
headers = {'Content-Type': 'application/xml'}
r = requests.post('https://api.mch.weixin.qq.com/pay/unifiedorder',
data=make_order_body(order_info), headers=headers)
r.encoding = 'utf-8'
root = ET.fromstring(r.text)
return_code = root.find('return_code').text
if return_code == 'FAIL':
return root.find('return_msg').text
result_code = root.find('result_code').text
if result_code == 'FAIL':
return root.find('err_code_des').text
prepay_id = root.find('prepay_id').text
nonce_str = root.find('nonce_str').text
# 封装微信支付二次签名参数
wxPayParam = {
'appid': 'wx.....',
'partnerid': '.....',
'package': 'Sign=WXPay',
'prepayid': prepay_id,
'noncestr': nonce_str,
'timestamp': int(time.mktime(datetime.datetime.now().timetuple()))
}
wxPayParam['sign'] = sign(wxPayParam, key)
return wxPayParam
app = Flask(__name__)
@app.route('/make_order', methods=['POST'])
def wx_order():
"""
生成微信订单
"""
data = request.get_json(force=True) #获取前端传来的数据
out_trade_no = data.get('out_trade_no', '') #获取订单号,没有的话默认为空
body = data.get('body', '') #获取商品描述,没有的话默认为空
total_fee = data.get('total_fee', 0) #获取费用,没有的话默认为0
order = make_order(out_trade_no, body, total_fee) #生成订单
return jsonify(order)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)