diff --git a/views_api.py b/views_api.py index 35da0cd..f04f24e 100644 --- a/views_api.py +++ b/views_api.py @@ -623,6 +623,29 @@ async def api_ticket_create( ) +@tickets_api_router.post("/{event_id}/{payment_hash}") +async def api_ticket_payment_status(event_id: str, payment_hash: str) -> dict: + """Poll-style payment confirmation for a pending ticket. + + The webapp's `useTicketPurchase` polls this every 2s after firing + `Pay with Wallet` (or after presenting the QR for an external + wallet) until `paid: true` comes back, then advances to the + ticket-QR success state. The companion WebSocket at + `/tickets/ws/{payment_hash}` is more efficient for pushes — this + endpoint is the fallback for clients that can't open a relay-side + socket. + + Returns `{paid: bool, ticket_id?: str}` so the client can hand off + to the ticket-detail flow without an extra GET. A missing / + cross-event ticket returns `paid: false` rather than 404 so the + poll loop doesn't have to special-case the not-yet-created race. + """ + ticket = await get_ticket(payment_hash) + if not ticket or ticket.event != event_id: + return {"paid": False} + return {"paid": ticket.paid, "ticket_id": ticket.id} + + @tickets_api_router.websocket("/ws/{payment_hash}") async def websocket_endpoint(payment_hash: str, websocket: WebSocket) -> None: await websocket.accept()