Python WeChat payment signature

Python WeChat payment signature

微信支付流程所有的请求都需要签名,然而文档里面没有python的SDK,
在做签名的时候总是提示签名错误,经过多次测试,终于完美请求成功。
from Crypto.PublicKey import RSA
import random
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import base64


class Authorization(object):
    def __init__(self):
        self.mchid = '商户号'
        self.serial_no = '证书序列号'

    # 生成欲签名字符串
    def sign_str(self, method, url_path, timestamp, nonce_str, request_body):
        if request_body:
        	# POST
            sign_list = [
                method,
                url_path,
                timestamp,
                nonce_str,
                request_body
                ]
            return '\n'.join(sign_list) + '\n'
        else:
        	# GET
            sign_list = [
                method,
                url_path,
                timestamp,
                nonce_str
            ]
            return '\n'.join(sign_list) + '\n\n'

    # 生成随机字符串
    def getNonceStr(self):
        data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP"
        nonce_str = ''.join(random.sample(data, 30))
        return nonce_str
        
	# 生成签名
    def sign(self, sign_str):
        with open('秘钥文件', 'r') as f:
  			# 这里要注意的秘钥只能有三行
  			# -----BEGIN PRIVATE KEY-----
			# ******************秘钥只能在一行,不能换行*****************
			# -----END PRIVATE KEY-----
            private_key = f.read()
            f.close()
            pkey = RSA.importKey(private_key)
            h = SHA256.new(sign_str.encode('utf-8'))
            signature = PKCS1_v1_5.new(pkey).sign(h)
            sign = base64.b64encode(signature).decode()
            return sign

	# 生成 Authorization
    def authorization(self, method, url_path, nonce_str, timestamp, body=None):
        # 加密子串
        signstr = self.sign_str(method=method, url_path=url_path, timestamp=timestamp, nonce_str=nonce_str, request_body=body)
        print("加密原子串:" + signstr)
        # 加密后子串
        s = self.sign(signstr)
        print("加密后子串:" + s)
        authorization = 'WECHATPAY2-SHA256-RSA2048 ' \
                        'mchid="{mchid}",' \
                        'nonce_str="{nonce_str}",' \
                        'signature="{sign}",' \
                        'timestamp="{timestamp}",' \
                        'serial_no="{serial_no}"'.\
                        format(mchid=self.mchid,
                               nonce_str=nonce_str,
                               sign=s,
                               timestamp=timestamp,
                               serial_no=self.serial_no
                              )
        return authorization

if __name__ == '__main__':
	method = "POST"
	url_path = "/v3/pay/transactions/jsapi"
	timestamp = str(int(time.time()))
	nonce_str = Authorization().getNonceStr()
	body = "{'appid': 'wx1443e8f52ef56d9b', 'mchid': '1602649761', 'description': '爱奇艺周卡', 'out_trade_no': 'LY1111111111', 'notify_url': '******', 'amount': {'total': 100, 'currency': 'CNY'}, 'payer': {'openid': '***************'}}"
	authorization = Authorization().authorization(method=method, url_path=url_path, nonce_str=nonce_str, timestamp=timestamp)
	print(authorization)

Reference document
WeChat signature document

Guess you like

Origin blog.csdn.net/weixin_46107949/article/details/114988293