微信apiV3版本签名python版本的资料相对比较少,最近完成踩坑。
需要配置的依赖库:
requests = "*"
pycryptodome = "*"
pyopenssl = "*"
pycryptodomex = "*"
m2crypto = "*"
动态获取证书文件地址
import os
basedir = os.path.abspath(os.path.dirname(os.path.dirname("manage.py")))
KEY_PATH = os.path.join(basedir, "static", "apiclient_key.pem")
CERT_PATH = os.path.join(basedir, "static", "apiclient_cert.pem")
动态生成32位随机字符
def nonce_str(length=32):
char = string.ascii_letters + string.digits
return "".join(random.choice(char) for _ in range(length))
加签转义
@staticmethod
def b(s):
return s.encode("utf-8")
生成时间搓
def get_timestamp():
import time
return str(int(time.time()))
转json
def to_json(kwargs):
import json
return json.dumps(kwargs, separators=(",", ":"))
apiV3签名
def sign_v3(method, url, timestamp, nonceStr, body):
message = method + " " + url + " " + timestamp + " " + nonceStr + " " + body + " "
signer = PKCS1_v1_5.new(RSA.importKey(open(KEY_PATH).read()))
signature = signer.sign(SHA256.new(Utils.b(message)))
sign = encodebytes(signature).decode("utf8").replace(" ", "")
return sign
拼接请求头
def authorization(sign, nonceStr, timestamp):
"""
拼接api版本中请求头的authorization的值
"""
return "WECHATPAY2-SHA256-RSA2048 mchid="{michid}",nonce_str="{nonce_str}",signature="{signature}",timestamp="{timestamp}",serial_no="{serial_no}"".format(michid=mch_id, nonce_str=nonceStr, signature=sign, timestamp=timestamp, serial_no=serial_No)
发起请求
def requests_wx3(url, data, authorization, method="POST", ssl=False, key_path="", cert_path=""):
"""
apiV3 版本的微信支付请求
"""
headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": authorization}
response = ""
try:
if method == "POST":
if ssl:
response = requests.post(url, data=Utils.to_json(data), headers=headers, cert=(cert_path, key_path))
else:
response = requests.post(url, data=Utils.to_json(data))
if method == "GET":
if ssl:
response = requests.get(url, data=Utils.to_json(data), cert=(cert_path, key_path))
else:
response = requests.get(url, data=Utils.to_json(data))
except requests.exceptions.ConnectionError as e:
traceback.print_exc()
from pyexpat import ExpatError
try:
return eval(str(response.content, encoding="utf-8"))
except ExpatError:
return {}
Pyhton版本的apiV3的签名大概如此,官方也没有Python版本的SDK和具体示例。
`
原文链接:https://blog.csdn.net/fengdebeiyingzi/article/details/106280859