53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
"""
|
||
支付 API:创建订单、异步通知、状态查询
|
||
|
||
遵循 BACKEND_DEV.md 规范:router 只做参数校验、调用 service、返回统一响应
|
||
"""
|
||
from fastapi import APIRouter, HTTPException, Request, status
|
||
from fastapi.responses import PlainTextResponse
|
||
|
||
from app.core.response import success_response
|
||
from .schemas import CreateOrderRequest, CreateOrderResponse, OrderStatusResponse
|
||
from . import service
|
||
|
||
router = APIRouter(prefix="/api/payment", tags=["支付"])
|
||
|
||
|
||
@router.post("/create-order")
|
||
async def create_payment_order(request: CreateOrderRequest):
|
||
"""创建支付宝电脑网站支付订单,返回收银台 URL"""
|
||
try:
|
||
result = service.create_payment_order(request.payment_token)
|
||
except ValueError as e:
|
||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e))
|
||
except RuntimeError as e:
|
||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
|
||
|
||
return success_response(
|
||
CreateOrderResponse(**result).model_dump()
|
||
)
|
||
|
||
|
||
@router.post("/notify")
|
||
async def payment_notify(request: Request):
|
||
"""
|
||
支付宝异步通知回调
|
||
|
||
必须返回纯文本 "success"(不是 JSON),否则支付宝会重复推送。
|
||
"""
|
||
form_data = await request.form()
|
||
verified = service.handle_payment_notify(dict(form_data))
|
||
return PlainTextResponse("success" if verified else "fail")
|
||
|
||
|
||
@router.get("/status/{out_trade_no}")
|
||
async def check_payment_status(out_trade_no: str):
|
||
"""查询订单支付状态(前端轮询)"""
|
||
order_status = service.get_order_status(out_trade_no)
|
||
if order_status is None:
|
||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="订单不存在")
|
||
|
||
return success_response(
|
||
OrderStatusResponse(status=order_status).model_dump()
|
||
)
|