diff --git a/app/api/endpoints/wechat.py b/app/api/endpoints/wechat.py index 9b519d8..698563a 100644 --- a/app/api/endpoints/wechat.py +++ b/app/api/endpoints/wechat.py @@ -325,10 +325,10 @@ async def refund_notify( # 获取退款信息 out_trade_no = data.get("out_trade_no") # 订单号 - refund_status = data.get("refund_status") + status = data.get("status") success_time = data.get("success_time") - if not all([out_trade_no, refund_status]) or refund_status != "SUCCESS": + if not all([out_trade_no, status]) or status != "SUCCESS": return error_response(code=400, message="缺少必要的退款信息或退款未成功") # 根据订单类型处理退款 @@ -343,6 +343,8 @@ async def refund_notify( # 更新订单状态 order.status = MerchantOrderStatus.REFUNDED + order.refund_transaction_id = data.get("transaction_id") + order.refund_time = datetime.fromisoformat(success_time.replace('Z', '+00:00')) # 如果订单有赠送积分,则扣除积分 if order.gift_points > 0: diff --git a/app/core/wechat.py b/app/core/wechat.py index 11c635e..a3f59f4 100644 --- a/app/core/wechat.py +++ b/app/core/wechat.py @@ -385,45 +385,55 @@ class WeChatClient: Returns: dict: 退款结果 """ - url_path = "/v3/refund/domestic/refunds" - api_url = f"https://api.mch.weixin.qq.com{url_path}" - - # 构建请求数据 - body = { - "out_trade_no": order_id, # 原订单号 - "out_refund_no": order_id, # 退款单号使用原订单号 - "reason": reason, - "notify_url": f"{settings.API_BASE_URL}/api/wechat/refund/notify", - "amount": { - "refund": total_amount, # 退款金额 - "total": total_amount, # 原订单金额 - "currency": "CNY" - } - } - - # 生成签名 - nonce_str = str(uuid.uuid4()).replace('-', '') - timestamp = str(int(time.time())) - signature = self.sign_message("POST", url_path, body) - - # 构建认证头 - headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Authorization': ( - f'WECHATPAY2-SHA256-RSA2048 ' - f'mchid="{self.mch_id}",' - f'nonce_str="{nonce_str}",' - f'timestamp="{timestamp}",' - f'serial_no="{self.cert_serial_no}",' - f'signature="{signature}"' - ) - } - try: + print(f"开始申请退款: order_id={order_id}, amount={total_amount}") + # 生成随机字符串 + nonce_str = generate_random_string() + timestamp = str(int(time.time())) + + # 构建请求URL + url_path = "/v3/refund/domestic/refunds" + api_url = f"https://api.mch.weixin.qq.com{url_path}" + + # 构建请求体 + body = { + "out_trade_no": order_id, # 商户订单号,二选一 + "out_refund_no": f"refund_{order_id}", # 商户退款单号 + "reason": reason, + "notify_url": f"{settings.API_BASE_URL}/api/wechat/refund/notify", + "amount": { + "refund": total_amount, # 退款金额 + "total": total_amount, # 原订单金额 + "currency": "CNY" + } + } + + # 生成签名 + nonce_str, timestamp, signature = self.sign_message("POST", url_path, body) + + # 构建认证头 + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': ( + f'WECHATPAY2-SHA256-RSA2048 ' + f'mchid="{self.mch_id}",' + f'nonce_str="{nonce_str}",' + f'timestamp="{timestamp}",' + f'serial_no="{self.cert_serial_no}",' + f'signature="{signature}"' + ) + } + + # 打印签名相关信息 + print(f"签名字符串: {nonce_str}, {timestamp}, {signature}") + print(f"Authorization: {headers['Authorization']}") + async with aiohttp.ClientSession() as session: async with session.post(api_url, json=body, headers=headers) as response: + print(f"退款响应状态码: {response.status}") result = await response.json() + print(f"退款响应内容: {result}") if response.status != 200: raise Exception(f"退款申请失败: {result.get('message')}") @@ -435,6 +445,7 @@ class WeChatClient: return result except Exception as e: + print(f"申请退款异常: {str(e)}") raise Exception(f"申请退款失败: {str(e)}") async def send_subscribe_message(