Skip to content

Commit

Permalink
微调账单和图像下载接口
Browse files Browse the repository at this point in the history
  • Loading branch information
minibear2021 committed Sep 15, 2021
1 parent 09aa5ea commit adac74c
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 33 deletions.
8 changes: 0 additions & 8 deletions .gitignore

This file was deleted.

7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ def download_bill():
url='https://api.mch.weixin.qq.com/v3/billdownload/file?token=demo-token'
)
print('code: %s, message: %s' % (code, message))
if code in range(200, 300) and isinstance(message, bytes):
with open("demo.txt.gz", 'wb') as f:
f.write(message)

# 合单支付下单
def combine_pay():
Expand Down Expand Up @@ -566,7 +569,9 @@ def complant_image_download():
media_url='https://api.mch.weixin.qq.com/v3/merchant-service/images/xxxxx'
)
print('code: %s, message: %s' % (code, message))

if code in range(200, 300) and isinstance(message, bytes):
with open("demo.bmp", 'wb') as f:
f.write(message)
```

## 回调验证失败处理
Expand Down
6 changes: 6 additions & 0 deletions examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ def download_bill():
url='https://api.mch.weixin.qq.com/v3/billdownload/file?token=demo-token'
)
print('code: %s, message: %s' % (code, message))
if code in range(200, 300) and isinstance(message, bytes):
with open("demo.txt.gz", 'wb') as f:
f.write(message)


def combine_pay():
Expand Down Expand Up @@ -395,6 +398,9 @@ def complant_image_download():
media_url='https://api.mch.weixin.qq.com/v3/merchant-service/images/xxxxx'
)
print('code: %s, message: %s' % (code, message))
if code in range(200, 300) and isinstance(message, bytes):
with open("demo.bmp", 'wb') as f:
f.write(message)


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="wechatpayv3",
version="1.0.13",
version="1.0.14",
author="minibear",
description="微信支付 API v3 Python SDK(python sdk for wechatpay v3)",
long_description=long_description,
Expand Down
6 changes: 3 additions & 3 deletions wechatpayv3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ def __init__(self,
"""
:param wechatpay_type: 微信支付类型,示例值:WeChatPayType.MINIPROG
:param mchid: 直连商户号,示例值:'1230000109'
:param mch_private_key: 商户证书私钥,示例值:'MIIEvwIBADANBgkqhkiG9w0BAQE...'
:param mch_key_serial_no: 商户证书序列号,示例值:'444F4864EA9B34415...'
:param private_key: 商户证书私钥,示例值:'MIIEvwIBADANBgkqhkiG9w0BAQE...'
:param cert_serial_no: 商户证书序列号,示例值:'444F4864EA9B34415...'
:param appid: 应用ID,示例值:'wxd678efh567hg6787'
:param mch_apiv3_key: 商户APIv3密钥,示例值:'a12d3924fd499edac8a5efc...'
:param apiv3_key: 商户APIv3密钥,示例值:'a12d3924fd499edac8a5efc...'
:param notify_url: 通知地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php'
:param cert_dir: 平台证书存放目录,示例值:'/server/cert'
"""
Expand Down
18 changes: 9 additions & 9 deletions wechatpayv3/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
import requests

from .type import RequestType
from .utils import build_authorization, aes_decrypt, load_certificate, rsa_sign, rsa_verify, rsa_encrypt, rsa_decrypt
from .utils import (aes_decrypt, build_authorization, load_certificate,
load_private_key, rsa_decrypt, rsa_encrypt, rsa_sign,
rsa_verify)


class Core():
def __init__(self, mchid, cert_serial_no, private_key, apiv3_key, cert_dir=None):
self._mchid = mchid
self._cert_serial_no = cert_serial_no
self._private_key = private_key
self._private_key = load_private_key(private_key)
self._apiv3_key = apiv3_key
self._gate_way = 'https://api.mch.weixin.qq.com'
self._certificates = []
Expand Down Expand Up @@ -96,10 +98,9 @@ def request(self, path, method=RequestType.GET, data=None, skip_verify=False, si
headers.update({'User-Agent': 'wechatpay v3 python sdk(https://github.com/minibear2021/wechatpayv3)'})
if cipher_data:
headers.update({'Wechatpay-Serial': hex(self._last_certificate().serial_number)[2:].upper()})
method_str = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE']
authorization = build_authorization(
path,
method_str[method.value],
method.value,
self._mchid,
self._cert_serial_no,
self._private_key,
Expand All @@ -108,7 +109,7 @@ def request(self, path, method=RequestType.GET, data=None, skip_verify=False, si
if method == RequestType.GET:
response = requests.get(url=self._gate_way + path, headers=headers)
elif method == RequestType.POST:
response = requests.post(url=self._gate_way + path, json=data if not files else None, data=data if files else None, headers=headers, files=files)
response = requests.post(url=self._gate_way + path, json=None if files else data, data=data if files else None, headers=headers, files=files)
elif method == RequestType.PATCH:
response = requests.patch(url=self._gate_way + path, json=data, headers=headers)
elif method == RequestType.PUT:
Expand All @@ -120,7 +121,7 @@ def request(self, path, method=RequestType.GET, data=None, skip_verify=False, si
if response.status_code in range(200, 300) and not skip_verify:
if not self._verify_signature(response.headers, response.text):
raise Exception('failed to verify the signature')
return response.status_code, response.text
return response.status_code, response.text if 'application/json' in response.headers.get('Content-Type') else response.content

def sign(self, sign_str):
return rsa_sign(self._private_key, sign_str)
Expand Down Expand Up @@ -160,9 +161,8 @@ def _load_local_certificates(self):
for file_name in os.listdir(self._cert_dir):
if not file_name.lower().endswith('.pem'):
continue
f = open(self._cert_dir + file_name, encoding="utf-8")
certificate = load_certificate(f.read())
f.close()
with open(self._cert_dir + file_name, encoding="utf-8") as f:
certificate = load_certificate(f.read())
now = datetime.utcnow()
if certificate and now >= certificate.not_valid_before and now <= certificate.not_valid_after:
self._certificates.append(certificate)
Expand Down
14 changes: 7 additions & 7 deletions wechatpayv3/type.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-

from enum import Enum

from enum import Enum, unique

@unique
class RequestType(Enum):
GET = 0
POST = 1
PATCH = 2
PUT = 3
DELETE = 4
GET = 'GET'
POST = 'POST'
PATCH = 'PATCH'
PUT = 'PUT'
DELETE = 'DELETE'


class WeChatPayType(Enum):
Expand Down
13 changes: 9 additions & 4 deletions wechatpayv3/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,19 @@ def build_authorization(path,
method,
mchid,
serial_no,
mch_private_key,
private_key,
data=None,
nonce_str=None):
timeStamp = str(int(time.time()))
nonce_str = nonce_str or ''.join(str(uuid.uuid4()).split('-')).upper()
body = data if isinstance(data, str) else json.dumps(data) if data else ''
sign_str = '%s\n%s\n%s\n%s\n%s\n' % (method, path, timeStamp, nonce_str, body)
signature = rsa_sign(private_key=mch_private_key, sign_str=sign_str)
signature = rsa_sign(private_key=private_key, sign_str=sign_str)
authorization = 'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%s",serial_no="%s"' % (mchid, nonce_str, signature, timeStamp, serial_no)
return authorization


def rsa_sign(private_key, sign_str):
private_key = load_pem_private_key(data=format_private_key(private_key).encode('UTF-8'), password=None, backend=default_backend())
message = sign_str.encode('UTF-8')
signature = private_key.sign(data=message, padding=PKCS1v15(), algorithm=SHA256())
sign = b64encode(signature).decode('UTF-8').replace('\n', '')
Expand Down Expand Up @@ -68,6 +67,13 @@ def load_certificate(certificate_str):
return None


def load_private_key(private_key_str):
try:
return load_pem_private_key(data=format_private_key(private_key_str).encode('UTF-8'), password=None, backend=default_backend())
except:
raise Exception('failed to load private key.')


def rsa_verify(timestamp, nonce, body, signature, certificate):
sign_str = '%s\n%s\n%s\n' % (timestamp, nonce, body)
public_key = certificate.public_key()
Expand All @@ -91,7 +97,6 @@ def rsa_encrypt(text, certificate):


def rsa_decrypt(ciphertext, private_key):
private_key = load_pem_private_key(data=format_private_key(private_key).encode('UTF-8'), password=None, backend=default_backend())
data = private_key.decrypt(
ciphertext=b64decode(ciphertext),
padding=OAEP(mgf=MGF1(algorithm=SHA1()), algorithm=SHA1(), label=None)
Expand Down

0 comments on commit adac74c

Please sign in to comment.