Check payment before generating ticket

This commit is contained in:
Roba Boru
2026-07-16 15:44:47 +03:00
parent fa7a517410
commit 0142c94bb0
2 changed files with 34 additions and 1 deletions

View File

@@ -68,7 +68,7 @@ export default function ConfirmationPage() {
import("@/lib/generate-voucher");
}, []);
const { data: _booking } = useQuery<BookingWithTicket>({
const { data: _booking, refetch: refetchBooking } = useQuery<BookingWithTicket>({
queryKey: ["booking", bookingId],
queryFn: async (): Promise<BookingWithTicket> => {
try {
@@ -88,6 +88,23 @@ export default function ConfirmationPage() {
enabled: !!bookingId,
});
// Poll the payment intent every 10 s while the booking is PENDING_PAYMENT.
// The backend auto-confirms (and generates tickets) when the payment-api reports
// SUCCEEDED, so detecting that here means the booking is now CONFIRMED — refetch
// to update the UI without requiring the user to refresh.
const { data: intentStatus } = useQuery<any>({
queryKey: ["payment-intent-status", bookingId],
queryFn: () => apiClient.get(`/payments/intents/${bookingId}`),
enabled: _booking?.status === "PENDING_PAYMENT" && !!bookingId,
refetchInterval: 10_000,
});
useEffect(() => {
if (intentStatus?.status === "SUCCEEDED") {
refetchBooking();
}
}, [intentStatus?.status]);
// Only trust an actually-confirmed booking to show ticket numbers / a "CONFIRMED" badge —
// a gateway redirect back here does not mean payment succeeded (see payment return pages).
// Ticket generation itself is never triggered from this page — the payment webhook

View File

@@ -125,6 +125,22 @@ function BookingDetailContent() {
booking?.status === "PENDING_PAYMENT" || booking?.status === "DRAFT",
});
// When the booking is PENDING_PAYMENT, poll the payment intent endpoint every 10 s.
// The backend auto-confirms the booking when it finds a SUCCEEDED intent, so detecting
// SUCCEEDED here means the booking is now CONFIRMED — refetch to update the UI.
const { data: intentStatus } = useQuery<any>({
queryKey: ["payment-intent-status", booking?.id],
queryFn: () => apiClient.get(`/payments/intents/${booking!.id}`),
enabled: booking?.status === "PENDING_PAYMENT" && !!booking?.id,
refetchInterval: 10_000,
});
useEffect(() => {
if (intentStatus?.status === "SUCCEEDED") {
refetch();
}
}, [intentStatus?.status]);
const selectedPaymentMethod =
(paymentMethods || []).find((m: any) => m.type === selectedMethod) || null;