微信API-v3版本签名Python版本

微信API-v3版本签名Python版本的资料相对比较少,最近完成踩坑。

官方文档:链接: WechatPay-API-v3.

需要配置的依赖库:

  requests = "*"
  pycryptodome = "*"
  cryptodome = "*"
  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 + "\n" + url + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n"
    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("\n", "")
    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)
  
  mch_id:商户号
  nonceStr:随机字符串
  sign:签名字符串
  timestamp:时间搓
  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版本的API-v3的签名大概如此,官方也没有Python版本的SDK和具体示例,后台开发使用Python语言的小伙伴可以参考。

  补充说明:
  构造签名字符串的时候,body为空的接口,部分需要传空字符串,部分需要传空字典,签名报错的小伙伴可以都尝试一下

对接过程中有问题可加群:759898174

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值