164 lines
4.4 KiB
TypeScript
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,
|
|
);
|
|
},
|
|
};
|