from __future__ import annotations import logging from typing import Any from app.models.base import async_session from app.services.payment import expire_all_pending_orders from app.tasks.async_runner import run_async from app.tasks.celery_app import celery_app logger = logging.getLogger("payment") async def _expire_pending_payment_orders_once() -> dict[str, Any]: """服务端定时清理已超过支付时限的 pending 订单。 具体的支付渠道关闭确认、订单取消以及升级预留释放仍完全复用 ``expire_all_pending_orders``,这里不复制支付状态机,避免两套逻辑分叉。 """ async with async_session() as db: try: expired_count = await expire_all_pending_orders(db) if expired_count > 0: logger.info( "PAYMENT_EXPIRE_TASK_COMPLETED expired_count=%s", expired_count, ) return {"expired_count": int(expired_count)} except Exception: await db.rollback() logger.exception("PAYMENT_EXPIRE_TASK_FAILED") raise if celery_app: @celery_app.task( name="payment.expire_pending_orders", bind=True, soft_time_limit=540, time_limit=600, ignore_result=True, ) def expire_pending_payment_orders(self) -> dict[str, Any]: return run_async(_expire_pending_payment_orders_once()) else: class _DisabledTask: def delay(self, *args: Any, **kwargs: Any) -> None: raise RuntimeError("Celery is disabled") def apply_async(self, *args: Any, **kwargs: Any) -> None: raise RuntimeError("Celery is disabled") expire_pending_payment_orders = _DisabledTask()