From 2e0de7979924c231da8a3b60e8e1b193e4739144 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sun, 26 Jan 2025 00:35:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E8=B0=83=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/wechat.py | 104 +++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 27 deletions(-) diff --git a/app/core/wechat.py b/app/core/wechat.py index dce92b4..6151448 100644 --- a/app/core/wechat.py +++ b/app/core/wechat.py @@ -258,43 +258,93 @@ class WeChatClient: except Exception as e: raise Exception(f"创建支付订单失败: {str(e)}") - async def verify_payment_notify(self, request: Request) -> dict: - """验证支付回调通知""" - # 获取请求头 - headers = { - 'Wechatpay-Signature': request.headers.get('Wechatpay-Signature'), - 'Wechatpay-Timestamp': request.headers.get('Wechatpay-Timestamp'), - 'Wechatpay-Nonce': request.headers.get('Wechatpay-Nonce'), - 'Wechatpay-Serial': request.headers.get('Wechatpay-Serial') - } + def decrypt_callback_data(self, ciphertext: str, nonce: str, associated_data: str = None) -> dict: + """ + 解密回调数据 - # 读取请求体 - body = await request.body() + Args: + ciphertext: 密文 + nonce: 随机串 + associated_data: 附加数据,可选 - # 验证签名 - if not self.verify_response(headers, body): - raise Exception("回调通知签名验证失败") - - # 解析数据 + Returns: + dict: 解密后的数据 + """ try: - data = json.loads(body) - resource = data.get('resource', {}) + # Base64解码密文和随机串 + ciphertext_bytes = base64.b64decode(ciphertext) + nonce_bytes = base64.b64decode(nonce) + + # 处理附加数据 + associated_data_bytes = associated_data.encode('utf-8') if associated_data else b'' + + # 使用 API v3 密钥进行解密 + key_bytes = self.api_v3_key.encode('utf-8') + aesgcm = AESGCM(key_bytes) # 解密数据 - nonce = base64.b64decode(resource['nonce']) - associated_data = resource.get('associated_data', '').encode('utf-8') - ciphertext = base64.b64decode(resource['ciphertext']) - - aesgcm = AESGCM(self.api_v3_key.encode('utf-8')) decrypted_data = aesgcm.decrypt( - nonce, - ciphertext, - associated_data + nonce_bytes, + ciphertext_bytes, + associated_data_bytes ) + # 解析JSON数据 return json.loads(decrypted_data) except Exception as e: - raise Exception(f"解析回调数据失败: {str(e)}") + print(f"解密回调数据失败: {str(e)}") + raise Exception(f"解密回调数据失败: {str(e)}") + + async def verify_payment_notify(self, request: Request) -> dict: + """验证支付回调通知""" + try: + # 获取请求头 + headers = { + 'Wechatpay-Signature': request.headers.get('Wechatpay-Signature'), + 'Wechatpay-Timestamp': request.headers.get('Wechatpay-Timestamp'), + 'Wechatpay-Nonce': request.headers.get('Wechatpay-Nonce'), + 'Wechatpay-Serial': request.headers.get('Wechatpay-Serial') + } + + print("微信支付回调请求头:", headers) + + # 读取请求体 + body = await request.body() + print("微信支付回调请求体:", body.decode('utf-8')) + + # 验证签名 + if not self.verify_response(headers, body): + print("签名验证失败") + return None + + # 解密回调数据 + data = await request.json() + print("解析的JSON数据:", data) + + resource = data.get("resource", {}) + ciphertext = resource.get("ciphertext") + nonce = resource.get("nonce") + associated_data = resource.get("associated_data") + + if not all([ciphertext, nonce]): + print("缺少必要的解密参数") + return None + + # 解密数据 + decrypted_data = self.decrypt_callback_data( + ciphertext, + nonce, + associated_data + ) + + print("解密后的数据:", decrypted_data) + return decrypted_data + + except Exception as e: + print(f"处理支付回调异常: {str(e)}") + import traceback + print("详细错误信息:", traceback.format_exc()) + raise Exception(f"处理支付回调失败: {str(e)}") \ No newline at end of file