From 5faf42b4512192ec0b2fe346fe06292aab192ee8 Mon Sep 17 00:00:00 2001 From: wwwwwwwww <526125649@qq.com> Date: Mon, 15 Jun 2026 09:26:04 +0800 Subject: [PATCH] 1 --- video-gen-api/app/api/v1/payments.py | 64 +++++++++++++++++----------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/video-gen-api/app/api/v1/payments.py b/video-gen-api/app/api/v1/payments.py index 2a35cd01..17f5d95c 100644 --- a/video-gen-api/app/api/v1/payments.py +++ b/video-gen-api/app/api/v1/payments.py @@ -107,18 +107,16 @@ async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)): # 真实模式:使用 wechatpayv3 SDK 验证回调并解析数据 try: + from wechatpayv3 import Sign, AesCrypto + mch_id = db_configs.get("payment_wechat_mch_id", "") private_key = db_configs.get("payment_wechat_private_key", "") cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "") api_v3_key = db_configs.get("payment_wechat_api_v3_key", "") - appid = db_configs.get("payment_wechat_appid", "") public_key = db_configs.get("payment_wechat_public_key", "") - public_key_id = db_configs.get("payment_wechat_public_key_id", "") - notify_url = db_configs.get("payment_wechat_notify_url", "") - client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id) - if not client: - logger.error("WeChat client not initialized for callback") + if not all([mch_id, private_key, cert_serial_no, api_v3_key]): + logger.error("WeChat payment config missing for callback") return {"code": "SUCCESS", "message": "OK"} # 从请求头获取必要信息 @@ -128,31 +126,47 @@ async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)): signature = headers.get("Wechatpay-Signature", "") serial_no = headers.get("Wechatpay-Serial", "") - # 验证签名 - is_verified = client.verify( - timestamp=timestamp, - nonce=nonce, - body=body_str, - signature=signature, - serial_no=serial_no - ) + # 验证签名:使用平台公钥验证 + if not public_key: + logger.warning("WeChat platform public key not configured, skipping signature verification") + else: + is_verified = Sign.verify( + public_key=public_key, + timestamp=timestamp, + nonce=nonce, + body=body_str, + signature=signature + ) + if not is_verified: + logger.warning("WeChat callback signature verification failed") + raise HTTPException(status_code=400, detail="签名验证失败") - if not is_verified: - logger.warning("WeChat callback signature verification failed") - raise HTTPException(status_code=400, detail="签名验证失败") + # 解密回调数据:使用 API v3 key + crypto = AesCrypto(api_v3_key) + import json + body_data = json.loads(body_str) if body_str else {} + resource = body_data.get("resource", {}) - # 解密回调数据 - decrypted_data = client.decrypt(body_str) - if not decrypted_data: + if not resource: + logger.error("WeChat callback resource not found") + raise HTTPException(status_code=400, detail="数据格式错误") + + ciphertext = resource.get("ciphertext", "") + associated_data = resource.get("associated_data", "") + nonce_str = resource.get("nonce", "") + + decrypted_str = crypto.decrypt_gcm(ciphertext, associated_data, nonce_str) + if not decrypted_str: logger.error("WeChat callback decryption failed") raise HTTPException(status_code=400, detail="数据解密失败") + decrypted_data = json.loads(decrypted_str) + # 处理支付成功回调 - if decrypted_data.get("event_type") == "TRANSACTION.SUCCESS": - resource = decrypted_data.get("resource", {}) - order_no = resource.get("out_trade_no", "") - transaction_id = resource.get("transaction_id", "") - amount_info = resource.get("amount", {}) + if body_data.get("event_type") == "TRANSACTION.SUCCESS": + order_no = decrypted_data.get("out_trade_no", "") + transaction_id = decrypted_data.get("transaction_id", "") + amount_info = decrypted_data.get("amount", {}) total_amount = amount_info.get("total", 0) / 100 # 转换为元 if order_no: