from typing import List from fastapi import APIRouter, Depends, Request from fastapi.responses import PlainTextResponse from app.core.deps_types import CurrentUserDep from app.core.errors import BadRequestError from app.core.logging import get_logger from app.core.openapi import error_responses from app.features.payment.deps import get_payment_order_service from app.features.payment.order_service import PaymentOrderService from app.features.payment.schemas import ( CreateOrderRequest, CreateOrderResponse, OrderListResponse, OrderStatusResponse, ) from app.features.plan.deps import get_plan_service from app.features.plan.service import PlanService logger = get_logger(__name__) router = APIRouter( prefix="/api/payment", tags=["payment"], responses=error_responses(401, 404, 500, 502, 503, 504), ) @router.post("/create-order", response_model=CreateOrderResponse) async def create_order( request: CreateOrderRequest, current_user: CurrentUserDep, service: PaymentOrderService = Depends(get_payment_order_service), plan_service: PlanService = Depends(get_plan_service), ): plan = next( (p for p in plan_service.get_plans_for_api() if p.id == request.plan_id), None ) if plan is None: raise BadRequestError("无效的套餐 ID") return await service.create_order( user_id=current_user.id, user_subscription_type=current_user.subscription_type, plan_id=plan.id, plan_display_name=plan.display_name, plan_price=plan.price, plan_currency=plan.currency, payment_method=request.payment_method, ) @router.post("/notify/wechat", include_in_schema=False) async def wechat_notify( request: Request, service: PaymentOrderService = Depends(get_payment_order_service), ): try: headers = dict(request.headers) body = await request.body() return await service.handle_wechat_notify( headers=headers, body=body.decode("utf-8") ) except Exception as e: logger.exception("微信支付回调处理失败: {}", e) return {"code": "FAIL", "message": "处理失败"} @router.post("/notify/alipay", include_in_schema=False) async def alipay_notify( request: Request, service: PaymentOrderService = Depends(get_payment_order_service), ): try: form_data = await request.form() params = {key: value for key, value in form_data.items()} result = await service.handle_alipay_notify(params=params) return PlainTextResponse(result) except Exception as e: logger.exception("支付宝回调处理失败: {}", e) return PlainTextResponse("fail") @router.get("/order/{order_id}/status", response_model=OrderStatusResponse) async def get_order_status( order_id: str, current_user: CurrentUserDep, service: PaymentOrderService = Depends(get_payment_order_service), ): return await service.get_order_status(order_id, current_user.id) @router.get("/orders", response_model=List[OrderListResponse]) async def list_orders( current_user: CurrentUserDep, service: PaymentOrderService = Depends(get_payment_order_service), ): return await service.list_orders(current_user.id)