This commit is contained in:
doudou201703
2026-08-06 20:39:45 +08:00
parent 046fac6dc1
commit 3ff0faebb9
38 changed files with 1029 additions and 611 deletions
@@ -11,6 +11,7 @@ import os
import django
from sixGuoDjango.settings import base_dir_name
from wechat_微信支付证书.江苏六果科技服务商支付证书.江苏六果科技有限公司服务商支付参数 import six六果服务商支付参数
os.environ.setdefault(key="DJANGO_SETTINGS_MODULE", value=f"{base_dir_name}.settings")
django.setup()
@@ -35,8 +36,8 @@ from typing import Optional, Literal
import pydash
import xmltodict
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Hash import SHA1, SHA256
from Crypto.PublicKey import RSA
from Crypto.PublicKey.RSA import RsaKey
from Crypto.Signature import pkcs1_15
@@ -51,21 +52,13 @@ class paymentCategory(sixpay六果科技公司):
class wechatPay(BaseModel):
payment: type[paymentCategory] | type[sixpay六果科技公司]
payment: type[sixpay六果科技公司] | type[six六果服务商支付参数]
def 构造签名串(self, uri: str, body_data: dict | bytes | str | None = None,
method: Optional[Literal["GET", "POST"]] = "POST",
method: Optional[Literal["GET", "POST", "PATCH"]] = "POST",
):
"""
构造签名串
@param url:
@type url:
@param body:
@type body:
@param method:
@type method:
@return: 返回已经加密后并组装好的请求头;
@rtype:
"""
url_data = re.search(r'/v3.*', string=uri).group()
shi_jian_chou = str(int(time.time())) # 时间戳
@@ -91,7 +84,7 @@ class wechatPay(BaseModel):
# 加载商户私钥
# 调用了 RSA.import_key() 方法,它会从字符串或文件中导入一个 PEM 格式的 RSA 私钥,并返回一个 RsaKey 类型的对象
private_key: RsaKey = RSA.import_key(self.payment.private_key)
# 生成签名
# 生成签名 使用商户的 私钥进行签名
signature = pkcs1_15.new(rsa_key=private_key).sign(msg_hash=hash_obj)
# 对签名进行Base64编码,符合微信支付API要求
encoded_signature = base64.b64encode(s=signature).decode()
@@ -111,24 +104,16 @@ class wechatPay(BaseModel):
headers = {
"Content-Type": "application/json", "Authorization": Authorization,
}
# headers.update({"Wechatpay-Serial": self.payment.微信支付公钥ID})
return headers
def getpay_jsapi(self, uri, body_data: dict | bytes | str | None = None, method: Optional[
Literal["GET", "POST"]] = "POST",
):
"""
@param url: 请求支付的微信官方地址
@type url: str
@param pay_body: 小程序下单接口获取到发起支付的必要参数prepay_id
@type pay_body: str
@return:
@rtype:
"""
headers = self.构造签名串(uri=uri, body_data=body_data, method=method)
# 发送请求
response: Response = requests.post(url=uri, json=body_data, headers=headers)
print(response.json())
prepay_id = pydash.get(obj=response.json(), path="prepay_id", default=None)
# 验证请求后返回的数据是否为微信官方所发送;
验证签名结果 = self.验证签名串(response_data=response.json(), response_headers=response.headers)
@@ -170,6 +155,15 @@ class wechatPay(BaseModel):
回调解密数据: dict = orjson.loads(decrypted_data.decode(encoding="utf-8"))
return 回调解密数据
def modegmc解密电子发票邮箱账号(self, ciphertext):
pass
encrypted_bytes = base64.b64decode(ciphertext)
# 3. 构建 OAEP 解密器(SHA-1)
private_key: RsaKey = RSA.import_key(self.payment.private_key)
cipher = PKCS1_OAEP.new(key=private_key, hashAlgo=SHA1)
plaintext_bytes = cipher.decrypt(encrypted_bytes)
return plaintext_bytes.decode("utf-8")
def getpay_navite(self, navite_body: dict, ):
"""
@param navite_body:
@@ -316,6 +310,7 @@ class wechatPay(BaseModel):
@rtype:
"""
public_key = RSA.import_key(self.payment.wechat_certificate)
# public_key = RSA.import_key(self.payment.pem微信支付公钥)
Wechatpay_Timestamp = pydash.get(response_headers, "Wechatpay-Timestamp")
Wechatpay_Nonce = pydash.get(response_headers, "Wechatpay-Nonce")
Wechatpay_Signa = pydash.get(response_headers, "Wechatpay-Signature")
@@ -331,7 +326,6 @@ class wechatPay(BaseModel):
def v2签名返回XML(self, sign_data: dict):
"""v2版本的签名:将扫码支付的body转换为微信支付所要求的数据类型"""
# sorted_dict = dict(sorted(sign_data.items(), key=lambda item: item[0], reverse=False))
sorted_dict = dict(pydash.sort_by(collection=sign_data.items(), iteratee=0))
# 拼接字符串: (将密钥添加到最末尾)
params_str = "&".join(f"{k}={v}" for k, v in sorted_dict.items()) + '&key=' + self.payment.apiv2
@@ -397,14 +391,6 @@ class wechatPay(BaseModel):
def 解密群号(self, encryptedData, iv, sessionKey):
"""
对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
对称解密的目标密文为 Base64_Decode(encryptedData)。
对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
:param sessionKey:
:param encryptedData:
:param iv:
:return:
"""
try:
session_key_bytes = base64.b64decode(sessionKey)
@@ -447,7 +433,7 @@ class wechatPay(BaseModel):
def 发起退款(self, body):
pass
uri = f"https://api.mch.weixin.qq.com//v3/refund/domestic/refunds"
uri = f"https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"
heardes = self.构造签名串(body_data=body, uri=uri, method="POST")
print(heardes)
response_data = requests.post(url=uri, json=body, headers=heardes)