82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.dependencies import get_db, get_current_user
|
|
from app.models.user import User
|
|
from app.models.payment_order import PaymentOrder
|
|
from app.models.recharge_package import RechargePackage
|
|
from app.schemas.payment import RechargeRequest, PaymentOrderOut
|
|
from app.services.payment import create_recharge_order, verify_wechat_callback, verify_alipay_callback, process_payment_success
|
|
|
|
router = APIRouter(prefix="/payments", tags=["payments"])
|
|
|
|
|
|
@router.post("/recharge", response_model=PaymentOrderOut)
|
|
async def recharge(
|
|
req: RechargeRequest,
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(
|
|
select(RechargePackage).where(
|
|
RechargePackage.id == req.plan,
|
|
RechargePackage.is_active == True,
|
|
)
|
|
)
|
|
pkg = result.scalar_one_or_none()
|
|
if not pkg:
|
|
raise HTTPException(status_code=400, detail="无效的套餐")
|
|
order = await create_recharge_order(
|
|
db,
|
|
current_user.id,
|
|
credits=pkg.credits,
|
|
price=pkg.price,
|
|
label=pkg.name,
|
|
bonus_credits=pkg.bonus_credits,
|
|
)
|
|
return order
|
|
|
|
|
|
@router.post("/wechat/callback")
|
|
async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)):
|
|
data = await request.json()
|
|
if not await verify_wechat_callback(data):
|
|
raise HTTPException(status_code=400, detail="签名验证失败")
|
|
order_no = data.get("out_trade_no")
|
|
result = await db.execute(
|
|
select(PaymentOrder).where(PaymentOrder.order_no == order_no)
|
|
)
|
|
order = result.scalar_one_or_none()
|
|
if order:
|
|
await process_payment_success(db, order.id)
|
|
return {"code": "SUCCESS", "message": "OK"}
|
|
|
|
|
|
@router.post("/alipay/callback")
|
|
async def alipay_callback(request: Request, db: AsyncSession = Depends(get_db)):
|
|
data = await request.form()
|
|
if not await verify_alipay_callback(dict(data)):
|
|
raise HTTPException(status_code=400, detail="签名验证失败")
|
|
order_no = data.get("out_trade_no")
|
|
result = await db.execute(
|
|
select(PaymentOrder).where(PaymentOrder.order_no == order_no)
|
|
)
|
|
order = result.scalar_one_or_none()
|
|
if order:
|
|
await process_payment_success(db, order.id)
|
|
return "success"
|
|
|
|
|
|
@router.get("/orders", response_model=list[PaymentOrderOut])
|
|
async def list_orders(
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(
|
|
select(PaymentOrder)
|
|
.where(PaymentOrder.user_id == current_user.id)
|
|
.order_by(PaymentOrder.created_at.desc())
|
|
)
|
|
return result.scalars().all()
|