From 45b9409fe8c9dac6e7c682e914a17532b555ee1c Mon Sep 17 00:00:00 2001 From: GinHa <15201596918@163.com> Date: Tue, 11 Aug 2026 14:27:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=9A=E5=91=98=E7=A7=AF=E5=88=86=E6=94=B9?= =?UTF-8?q?=E7=89=88V9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- video-gen-api/app/cmd/migrate_user_credits.py | 2 +- video-gen-api/app/services/payment.py | 53 +++++++++++++++---- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/video-gen-api/app/cmd/migrate_user_credits.py b/video-gen-api/app/cmd/migrate_user_credits.py index a436a78a..1a512560 100644 --- a/video-gen-api/app/cmd/migrate_user_credits.py +++ b/video-gen-api/app/cmd/migrate_user_credits.py @@ -61,7 +61,7 @@ async def amain(argv: list[str]) -> int: description="历史用户积分迁移", source_type=CreditBalanceSourceType.LEGACY_MIGRATION.value, valid_from=migration_time, - expires_at=add_natural_months(migration_time, 1), + expires_at=add_natural_months(migration_time, 12), credit_level=CreditLevel.GENERAL.value, source_id=user_id, related_id=user_id, diff --git a/video-gen-api/app/services/payment.py b/video-gen-api/app/services/payment.py index c75eb6b4..f9aeadb8 100644 --- a/video-gen-api/app/services/payment.py +++ b/video-gen-api/app/services/payment.py @@ -625,9 +625,33 @@ async def _close_wechat_order(db: AsyncSession, order: PaymentOrder, db_configs: if code == 204: logger.info(f"WeChat order closed: order_no={order.order_no}") return True - else: - logger.error(f"WeChat close failed: order_no={order.order_no}, code={code}, result={result}") - return False + + data = _parse_wechat_result(result) + error_code = str( + data.get("code") + or data.get("err_code") + or data.get("error_code") + or "" + ).upper() + raw_result = str(result).upper() + + # 微信明确返回“订单不存在”时,同样视为没有远端订单需要继续关闭。 + # 只兼容明确的订单不存在错误,不吞掉签名、网络、系统等其他异常。 + if error_code in {"ORDER_NOT_EXIST", "ORDERNOTEXIST"} or ( + code == 404 + and ("ORDER_NOT_EXIST" in raw_result or "ORDERNOTEXIST" in raw_result) + ): + logger.info( + f"WeChat order not exist, treat as closed for local expiry: " + f"order_no={order.order_no}, code={code}, error_code={error_code or 'unknown'}" + ) + return True + + logger.error( + f"WeChat close failed: order_no={order.order_no}, " + f"code={code}, result={result}" + ) + return False except Exception as e: logger.exception(f"WeChat close exception: order_no={order.order_no}") return False @@ -885,13 +909,24 @@ async def _close_alipay_order(db: AsyncSession, order: PaymentOrder, db_configs: if response.is_success(): logger.info(f"Alipay order closed: order_no={order.order_no}") return True - else: - logger.error( - f"Alipay close failed: code={response.code}, " - f"msg={response.msg}, sub_code={response.sub_code}, " - f"sub_msg={response.sub_msg}, order_no={order.order_no}" + + # 支付宝明确返回“交易不存在”时,远端没有可继续关闭的交易。 + # 对本地已经达到超时时间的 pending 订单,可视为关单目标已经满足, + # 避免 Celery 每分钟对同一订单无限重复调用 trade.close。 + if str(response.sub_code or "").upper() == "ACQ.TRADE_NOT_EXIST": + logger.info( + f"Alipay trade not exist, treat as closed for local expiry: " + f"order_no={order.order_no}, code={response.code}, " + f"sub_code={response.sub_code}" ) - return False + return True + + logger.error( + f"Alipay close failed: code={response.code}, " + f"msg={response.msg}, sub_code={response.sub_code}, " + f"sub_msg={response.sub_msg}, order_no={order.order_no}" + ) + return False except Exception as e: if "TypeError" in str(e) and ("bytes" in str(e) or "str" in str(e)):