文章内容

2023/5/25 17:02:41,作 者: 黄兵

Python 使用支付宝支付相关问题总结

最近需要支付宝支付,但是查询了官网和公开的一些资料,大部分是 Java 和 php 实现,使用 Python 实现的资料很少。

在接入的过程中,参考了一些资料,中间遇到的一些问题,记录下来,方便其它人遇到同样的问题快速解决。

首先我参考的是这篇文章:关于Python下的支付宝App支付,其中有几个地方需要注意的,如下:

RSA 私钥的生成的这里,文章应该是 Windows 系统,在 Windows 系统上安装 OpenSSL 比较麻烦,我直接在云服务器上的 Ubuntu 系统生成密钥文件。

直接这样执行命令就可以了:

openssl genrsa -out app_private_key.pem 2048

其它的命令也相同,生成完成密钥文件之后,直接复制到本地就可以了。

其它没有什么特别需要注意的地方。

这篇文章使用的是 RSA 签名的方式,如果我们使用的是 MD5 加密方式,文章中的方法就无法使用了。

下面是 MD5 签名方式的总结:

使用 MD5 签名,不需要私钥文件,而使用的是商户密钥,对字典的 key,value 按照字母表的顺序,还是可以按照上面那片文章的代码复用,不用更改。

def request_alipay(self):
submit_url = 'http://sample.com/submit.php'
payload = {'pid': self._dict_data['pid'], 'type': self._dict_data['type'],
'out_trade_no': self._dict_data['out_trade_no'], 'notify_url': self._dict_data['notify_url'],
'return_url': 'https://www.test.com/pay', 'name': self._dict_data['name'],
'money': self._dict_data['money'], 'sitename': '吉米的小店'}
unsigned_string = self.get_unsigned_string(payload) + 'dCzDC6u01cLL'
get_sign_string = self.md5_sign(unsigned_string=unsigned_string)
payload['sign'] = get_sign_string
payload['sign_type'] = 'MD5'
result = requests.post(url=submit_url, data=payload, timeout=5)
print(result.text)

def md5_sign(self, unsigned_string):
"""
MD5数据加密
:param unsigned_string: 未签名的字符串
:return: 返回32 16进制 大写
"""
md5 = hashlib.md5()
md5.update(unsigned_string.encode('utf-8'))
sign = md5.hexdigest()
return sign

def get_unsigned_string(self, data):
unsigned_items = self.ordered_data(data)
unsigned_string = "&".join("{}={}".format(k, v) for k, v in unsigned_items)
return unsigned_string

def ordered_data(self, data):
complex_keys = []
for key, value in data.items():
if isinstance(value, dict):
complex_keys.append(key)

# 将字典类型的数据单独排序
for key in complex_keys:
data[key] = json.dumps(data[key], sort_keys=True).replace(" ", "")

return sorted([(k, v) for k, v in data.items()])

这里贴出了主要的代码,实现一个 MD5 签名的代码。

有一段代码需要说明一下:

unsigned_string = self.get_unsigned_string(payload) + 'dCzDC6u01cLL'

后面的 dCzDC6u01cLL 也就是我们商户的密钥,可以通过控制台找到。

再来一个 MD5 签名简单示例如下:

import hashlib
def generate_md5_sign(data, secret_key):
# 按照支付宝要求拼接字符串
data = '&'.join([f"{key}={value}" for key, value in data.items()])
data += secret_key
# 创建MD5对象
md5 = hashlib.md5()
# 更新MD5对象内容
md5.update(data.encode('utf-8'))
# 获取加密后的结果
sign = md5.hexdigest()
return sign
# 示例数据
data = {
'app_id': 'your_app_id',
'out_trade_no': 'your_order_no',
'total_amount': '100.00',
'subject': 'Test',
'body': 'This is a test',
}
secret_key = 'your_secret_key'
# 生成签名
sign = generate_md5_sign(data, secret_key)
print(sign)

请注意替换示例中的your_app_idyour_order_no100.00TestThis is a testyour_secret_key为实际的值。这个示例将按照支付宝的要求,将数据拼接成字符串后再进行MD5加密,生成最终的签名。

同时我说一下 MD5 签名的原理:

原理

请求方对请求数据按一定的规则排序,加上 appkey 拼接一起通过 MD5 加密生成签名,然后把请求数据和签名发给服务方,服务方拿到数据后,找到请求方的 appkey,然后按同样的规则处理数据,并加上 appkey 通过MD5加密也生成签名,然后和请求方生成的签名去对比,如果值一样,签名验证通过。


第一次使用支付宝支付接入,可能有些理解不是很透彻,如果有问题欢迎下面讨论。


参考资料:

1、关于Python下的支付宝App支付

2、python实现MD5签名和验签

3、请求参数签名


其它相关推荐:

1、Payssion 支付代码片段

2、ERROR: Failed building wheel for pycrypto

3、Windows 下openssl安装与配置

4、git config --global http.sslBackend "openssl"

5、Flask 测试的时候如何设置headers


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - Python 使用支付宝支付相关问题总结

分享到:

发表评论

评论列表