diff --git a/video-gen-api/app/api/v1/payments.py b/video-gen-api/app/api/v1/payments.py index 18294e51..92c09466 100644 --- a/video-gen-api/app/api/v1/payments.py +++ b/video-gen-api/app/api/v1/payments.py @@ -176,8 +176,10 @@ async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)): decrypted_data = json.loads(decrypted_str) + event_type = body_data.get("event_type", "") + # 处理支付成功回调 - if body_data.get("event_type") == "TRANSACTION.SUCCESS": + if 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", {}) @@ -190,6 +192,30 @@ async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)): f"transaction_id={transaction_id}, amount={total_amount}" ) + # 处理退款回调 + elif event_type == "REFUND.SUCCESS": + order_no = decrypted_data.get("out_trade_no", "") + refund_id = decrypted_data.get("refund_id", "") + refund_status = decrypted_data.get("status", "") + + if order_no and refund_status == "SUCCESS": + # 更新订单状态为已退款 + from app.models import PaymentOrder + from sqlalchemy import select + + result = await db.execute(select(PaymentOrder).where(PaymentOrder.order_no == order_no)) + order = result.scalar_one_or_none() + + if order and order.status == "refunding": + order.status = "refunded" + order.transaction_id = refund_id + await db.commit() + + logger.info( + f"WeChat refund callback processed: order_no={order_no}, " + f"refund_id={refund_id}, status={refund_status}" + ) + return {"code": "SUCCESS", "message": "OK"} except Exception as e: logger.exception(f"WeChat callback processing error: {e}") diff --git a/video-gen-api/app/services/payment.py b/video-gen-api/app/services/payment.py index 57b8e23c..b6c61ab3 100644 --- a/video-gen-api/app/services/payment.py +++ b/video-gen-api/app/services/payment.py @@ -565,7 +565,10 @@ async def _refund_wechat_order( refund_reason: str, db_configs: dict[str, str] ) -> dict: - """Call WeChat Pay refund API.""" + """Call WeChat Pay refund API. + + 微信退款是异步的,调用后会返回PROCESSING状态,实际退款结果通过回调通知。 + """ 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", "") @@ -599,18 +602,29 @@ async def _refund_wechat_order( data = _parse_wechat_result(result) - if code == 200 and data.get('status') == 'SUCCESS': - logger.info(f"WeChat refund succeeded: order_no={order.order_no}") - return {"success": True, "refund_id": data.get('refund_id')} - else: - logger.error( - f"WeChat refund failed: order_no={order.order_no}, " - f"code={code}, result={result}" - ) - return { - "success": False, - "message": f"微信退款失败: code={code}, {data.get('code', '')}" - } + # 微信退款是异步的,PROCESSING是正常状态,表示退款已受理 + if code == 200: + status = data.get('status') + if status in ('SUCCESS', 'PROCESSING', 'REFUNDCLOSE'): + logger.info( + f"WeChat refund initiated: order_no={order.order_no}, " + f"status={status}, refund_id={data.get('refund_id')}" + ) + return { + "success": True, + "refund_id": data.get('refund_id'), + "status": status, + "message": "退款申请已提交,等待微信处理" + } + + logger.error( + f"WeChat refund failed: order_no={order.order_no}, " + f"code={code}, result={result}" + ) + return { + "success": False, + "message": f"微信退款失败: code={code}, {data.get('message', '')}" + } except Exception as e: logger.exception(f"WeChat refund exception: order_no={order.order_no}") return {"success": False, "message": f"微信退款异常: {str(e)}"}