小程序支付
Jeff的技术栈 人气:0
[TOC]
# 一、小程序支付官方文档
# 接口
# 二、小程序支付流程
```
1 用户发起请求下单支付
2 我们要保证用是登入状态。
3 组织数据,请求统一下单接口,微信官方会同步返回一个prepay_id
4 重新组织数据,进行签名,将重新组织的数据返回给小程序,小程序在吊起支付。
5 用户就可以进行支付,支付结果会同步返回给小程序
6 后台修改订单支付状态是通过微信官方服务器的异步通知
```
# 三、支付流程图(下方有接口)
## 业务流程时序图
小程序支付的交互图如下:
![小程序支付时序图](http://pay.weixin.qq.com/wikihttps://img.qb5200.com/download-x/doc/api/img/wxa-7-2.jpg)
商户系统和微信支付系统主要交互:
1、小程序内调用登录接口,获取到用户的openid,api参见公共api【[小程序登录API](https:/https://img.qb5200.com/download-x/developers.weixin.qq.com/miniprogramhttps://img.qb5200.com/download-x/dev/api/open-api/login/wx.login.html)】
2、商户server调用支付统一下单,api参见公共api【[统一下单API](http://pay.weixin.qq.com/wikihttps://img.qb5200.com/download-x/doc/api/wxa/wxa_api.php?chapter=9_1&index=1)】
3、商户server调用再次签名,api参见公共api【[再次签名](http://pay.weixin.qq.com/wikihttps://img.qb5200.com/download-x/doc/api/wxa/wxa_api.php?chapter=7_7&index=3)】
4、商户server接收支付通知,api参见公共api【[支付结果通知API](http://pay.weixin.qq.com/wikihttps://img.qb5200.com/download-x/doc/api/wxa/wxa_api.php?chapter=9_7)】
5、商户server查询支付结果,api参见公共api【[查询订单API](http://pay.weixin.qq.com/wikihttps://img.qb5200.com/download-x/doc/api/wxa/wxa_api.php?chapter=9_2)】
# 四、签名
```python
# 签名
def get_sign(self):
data_dict = {
"appid": self.appid,
"mch_id": self.mch_id,
"nonce_str": self.nonce_str,
"body": self.body,
"out_trade_no": self.out_trade_no,
"total_fee": self.total_fee,
"spbill_create_ip": self.ip,
"notify_url": self.notify_url,
"trade_type": self.trade_type,
"openid": self.openid,
}
# 列表推导式,
sign_str = "&".join([f"{k}={data_dict[k]}" for k in sorted(data_dict)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
print("sign_str", sign_str)
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign = md5.hexdigest()
return sign.upper()
```
# 五、xml解析模块
```
{.child.text}
child.tag表示appid
import xml.etree.ElementTree as ET
如果我们要解析一个xml文件
tree = ET.parse('country_data.xml')
root = tree.getroot()
如果解析字符串
root = ET.fromstring(country_data_as_string)
这个root是 Element
for child in root:
print(child.tag, child.attrib)
#child.tag表是标签名,child.attrib表示获取属性
#child.text就表示获取内容
```
```python
# 拼接的xml数据
body_data = f'''
{self.appid}
{self.mch_id}
{self.nonce_str}
{self.body}
{self.out_trade_no}
{self.total_fee}
{self.spbill_create_ip}
{self.notify_url}
{self.trade_type }
{self.openid }
{self.sign}
'''
```
## 接收xml二进制数据,转换为字典
```python
# 接收xml二进制数据,转换为字典
def xml_to_dict(self, xml_data):
import xml.etree.ElementTree as ET
xml_dict = {}
root = ET.fromstring(xml_data)
for child in root:
xml_dict[child.tag] = child.text
return xml_dict
```
# 六、再次签名
```python
# 再次签名
def get_two_sign(self, data):
data_dict = {
"appId": settings.AppId,
"timeStamp": str(int(time.time())),
"nonceStr": data['nonce_str'],
"package": f"prepay_id={data['prepay_id']}",
"signType": "MD5"
}
sign_str = "&".join([f"{k}={data_dict[k]}" for k in sorted(data_dict)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign = md5.hexdigest()
return sign.upper(), data_dict['timeStamp']
```
# 七、前台吊起支付接口
```python
wx.requestPayment(
{
'timeStamp':e.data.data.timeStamp,
'nonceStr': e.data.data.nonceStr,
'package': e.data.data.package,
'signType': e.data.data.signType,
'paySign': e.data.data.paySign,
'success':function(res){
console.log("成功",res)
},
'fail':function(res){
console.log("失败",res)
},
})
```
# 八、小程序支付总结
```python
1 接收到支付请求。我们先组织数据,然后进行统一下单前的签名
- 请求的数据与响应的数据都是xml.请求的时候,xml数据要变成二进制,heards中的content-type:"application/xml"
-响应的数据也是xml,我要用xml.etree.ElementTree将他转化为字典
2 拿到统一下单数据,最重要的prepay_id,进行再次签名。把一下数据发送给小程序。
"timeStamp": 时间戳
"nonceStr":随机字符串
"package": f"prepay_id={data_dict['prepay_id']}",统一下单中的到的prepay_id
"signType": "MD5",
"paySign":通过上面数据进行加密的结果
3 小程序掉用wx.resquestPayment()吊起支付
```
加载全部内容