Files
ticket-system/backend/api/routers/webhooks.py

44 lines
1.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from core.rabbitmq import publish_ticket_paid_event
from database.models import Ticket, TicketStatus
from database.session import get_db
from schemas.payment import PaymentWebhookRequest
router = APIRouter(prefix="/api/webhooks", tags=["webhooks"])
@router.post("/payment", status_code=status.HTTP_200_OK)
async def payment_webhook(
body: PaymentWebhookRequest,
db: AsyncSession = Depends(get_db),
) -> dict[str, str]:
result = await db.execute(select(Ticket).where(Ticket.id == body.ticket_id))
ticket: Ticket | None = result.scalar_one_or_none()
if ticket is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Ticket {body.ticket_id} not found",
)
# Idempotency guard: повторный запрос с тем же ключом — возвращаем 200 без действий
if ticket.idempotency_key == body.idempotency_key:
return {"detail": "Already processed"}
if ticket.status != TicketStatus.LOCKED:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Ticket is in '{ticket.status}' state, expected 'LOCKED'",
)
ticket.status = TicketStatus.PAID
ticket.idempotency_key = body.idempotency_key
await db.commit()
await publish_ticket_paid_event(ticket_id=ticket.id, user_id=ticket.user_id or 0)
return {"detail": "Payment processed"}