"""支付模块路由(/payments/* + /callbacks/*,对应《03-接口文档》第 8 章)""" import redis.asyncio as aioredis from fastapi import APIRouter, Depends, Header, Request from fastapi.responses import JSONResponse, PlainTextResponse from sqlalchemy.ext.asyncio import AsyncSession from app.core.response import ok from app.database import get_db from app.deps import Identity, require_user from app.redis_client import get_redis from app.schemas.payment import RechargeReq from app.services import payment_service router = APIRouter(prefix="/payments", tags=["支付"]) router_callbacks = APIRouter(prefix="/callbacks", tags=["支付回调"]) @router.get("/packages") async def list_packages(db: AsyncSession = Depends(get_db), redis: aioredis.Redis = Depends(get_redis), identity: Identity = Depends(require_user)): return ok(await payment_service.list_packages(db, redis)) @router.post("/recharge") async def create_recharge(req: RechargeReq, db: AsyncSession = Depends(get_db), redis: aioredis.Redis = Depends(get_redis), x_platform: str | None = Header(default=None), identity: Identity = Depends(require_user)): return ok(await payment_service.create_recharge(db, redis, identity.user_id, req, x_platform)) @router.get("/orders/{order_no}") async def get_order(order_no: str, db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): return ok(await payment_service.get_order(db, identity.user_id, order_no)) @router.post("/orders/{order_no}/cancel") async def cancel_order(order_no: str, db: AsyncSession = Depends(get_db), identity: Identity = Depends(require_user)): await payment_service.cancel_order(db, identity.user_id, order_no) return ok() @router_callbacks.post("/alipay", include_in_schema=False) async def alipay_callback(request: Request, db: AsyncSession = Depends(get_db)): """支付宝异步通知:平台要求纯文本 success/failure""" form = dict(await request.form()) result = await payment_service.handle_alipay_callback(db, form) return PlainTextResponse(result) @router_callbacks.post("/wechat", include_in_schema=False) async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)): """微信支付 V3 异步通知:{"code": "SUCCESS"} 或 {"code": "FAIL"}""" body = await request.body() result = await payment_service.handle_wechat_callback(db, dict(request.headers), body) return JSONResponse(result)