Eventbuzz_Web/src/api/publicEventTickets.ts

164 lines
4.4 KiB
TypeScript

import { apiGet, apiPost } from './client';
export type PublicTicketCatalogItem = {
_id: string;
name: string;
description?: string;
keyPoints?: string[];
basePriceMinor: number;
currency: string;
maxPerOrder?: number | null;
requiresBillingState?: boolean;
};
export type TicketQuote = {
ticketId: string;
quantity: number;
billingStateCode: string | null;
baseMinor: number;
taxMinor: number;
totalMinor: number;
platformFeeMinor?: number;
ticketName?: string;
eventName?: string;
taxLines: { label: string; rateBps: number; amountMinor: number }[];
currency: string;
};
export type PublicCheckoutOptions = {
onlineAvailable: boolean;
onlineGateways?: Array<{
id: string;
provider: string;
label: string;
isActive: boolean;
isPrimary: boolean;
testMode: boolean;
ticketCheckoutSupported: boolean;
}>;
manualUpi: {
manualQrMode: 'upload' | 'dynamic';
eventName: string;
upiQrImageUrl: string;
upiId: string;
payeeName: string;
instructions: string;
platformFeeInr: number;
} | null;
};
export type CheckoutOrderResponse = {
keyId: string;
orderId: string;
amount: number;
currency: string;
transactionId: string;
checkoutSource: string;
};
export type TicketAttendeePayload = {
firstName: string;
lastName: string;
email: string;
phone?: string;
organization?: string;
designation?: string;
displayName?: string;
formData?: Record<string, unknown>;
};
export type PublicEventSummary = {
name: string;
subtitle?: string;
startDate?: string;
endDate?: string;
location?: string;
locationType?: string;
image?: string;
};
export function loadRazorpayScript(): Promise<void> {
if (typeof window === 'undefined') return Promise.reject(new Error('No window'));
const w = window as unknown as { Razorpay?: unknown };
if (w.Razorpay) return Promise.resolve();
return new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = 'https://checkout.razorpay.com/v1/checkout.js';
s.async = true;
s.onload = () => resolve();
s.onerror = () => reject(new Error('Failed to load Razorpay'));
document.body.appendChild(s);
});
}
export const publicEventTicketsApi = {
getEventSummary(eventId: string): Promise<PublicEventSummary> {
return apiGet<PublicEventSummary>(`/public/events/${eventId}/summary`);
},
listTickets(eventId: string): Promise<PublicTicketCatalogItem[]> {
return apiGet<{ tickets: PublicTicketCatalogItem[] }>(`/public/events/${eventId}/tickets`).then(
(data) => data.tickets ?? [],
);
},
checkoutOptions(eventId: string): Promise<PublicCheckoutOptions> {
return apiGet<PublicCheckoutOptions>(`/public/events/${eventId}/tickets/checkout-options`);
},
quote(eventId: string, payload: { ticketId: string; quantity: number; billingStateCode?: string }): Promise<TicketQuote> {
return apiPost<TicketQuote>(`/public/events/${eventId}/tickets/quote`, payload);
},
manualQuote(
eventId: string,
payload: { ticketId: string; quantity: number; billingStateCode?: string },
): Promise<TicketQuote> {
return apiPost<TicketQuote>(`/public/events/${eventId}/tickets/manual-quote`, payload);
},
checkout(
eventId: string,
payload: {
ticketId: string;
quantity: number;
billingStateCode?: string;
purchaserEmail: string;
sourceFormId?: string;
attendees: TicketAttendeePayload[];
expectedTotalMinor: number;
idempotencyKey?: string;
orgGatewayId?: string;
},
): Promise<CheckoutOrderResponse> {
return apiPost<CheckoutOrderResponse>(`/public/events/${eventId}/tickets/checkout`, payload);
},
verifyPayment(
eventId: string,
payload: { orderId: string; paymentId: string; signature: string },
): Promise<{ verified: boolean }> {
return apiPost<{ verified: boolean }>(`/public/events/${eventId}/payment/verify`, payload);
},
manualSubmit(
eventId: string,
payload: {
ticketId: string;
quantity: number;
billingStateCode?: string;
purchaserEmail: string;
sourceFormId?: string;
attendees: TicketAttendeePayload[];
expectedTotalMinor: number;
screenshotDataUrl: string;
buyerNote?: string;
},
): Promise<{ orderId: string; message: string }> {
return apiPost<{ orderId: string; message: string }>(
`/public/events/${eventId}/tickets/manual-submit`,
payload,
);
},
};