import { ApiRequestOptions } from './client.js'; import { PaymentIntentResponse, CompleteReservationResponse, CancelReservationResponse, CreateOrderResponse, ValidatePaymentRequest, ValidatePaymentResponse, ExtendSessionResponse, SessionStatus, Order } from './types.js'; /** * Create a payment intent for the cart * * This initiates the Stripe payment flow by creating a PaymentIntent * on the backend. The response includes the client_secret needed * for Stripe Elements. * * @param cartId - The cart/order UUID * @param quantities - Map of ticketId -> quantity * @param donationAmounts - Map of ticketId -> donation amount in dollars (for type=2 tickets) * @returns Payment intent data including client_secret, or null on error */ /** The buyer, sent ONLY on the $0 finalize call. See createPaymentIntent. */ export interface FreeOrderBuyer { firstName: string; lastName: string; email: string; /** * The venue's checkout-settings answers. The paid path persists both at * validate-payment-intent, which a $0 order never reaches — so for a free * order this call is the only place they can land. */ phone?: string; questionAnswer?: string; mailingList?: boolean; } export declare function createPaymentIntent(cartId: string, quantities: Record, donationAmounts?: Record, buyer?: FreeOrderBuyer, uiLocale?: string, req?: Pick): Promise; /** What the server said about a submission's checkout answers. */ export interface CheckoutAnswersResult { /** * The venue's refusal, worded by the SERVER, or null when there was none. * * It NAMES the missing field, which is why it is carried as the message * itself rather than as a boolean the caller then has to write copy for: a * house string would put the buyer in front of a checkout that refuses * without saying what is wrong. Truthiness is the whole contract -- a caller * that finds a string here must not charge. */ refusal: string | null; /** * The PaymentIntent this cart is payable against, when nothing was refused. * The caller compares it with the secret its Stripe element is mounted on. */ clientSecret?: string; } /** * Put the buyer's checkout answers in front of the server on the CARD path, * before anything is charged. * * WHY THIS CALL EXISTS. The venue's `requiredPhoneAtCheckout` / * `requiredCustomCheckout` flags are enforced in orders-service, and that guard * fires on any payment-intent request that identifies the buyer. The card path * never made such a request: the PaymentIntent is minted on checkout MOUNT, * deliberately anonymous so no order is created before the buyer has typed * anything, and nothing after it is refusable -- ValidatePaymentIntent runs * against a PaymentIntent Stripe has already reported `succeeded`, so a refusal * there would take the money and withhold the ticket. PaymentIntent creation is * the last door, so the answers are sent to it, and the server's existing guard * then covers the card path with no change on its side. * * SENT UNCONDITIONALLY, not gated on the widget's own reading of the flags. The * point is that the SERVER decides; a client that only calls when it already * believes a field is required is back to the form being the only gate. * * SAFE TO REPEAT. The Stripe idempotency key orders-service derives covers every * charge-determining field (amount, fees, destination, promo, gift card, reprice * generation) and no buyer field, so an unchanged cart resolves to the SAME * PaymentIntent and the mounted Stripe element stays valid. `clientSecret` is * handed back anyway so the caller can assert that rather than assume it. * * FAILS OPEN on anything that is not the explicit refusal -- a network blip must * not block a checkout that would otherwise have gone through, the same way the * server's own guard lets an unreadable venue pass. */ export declare function submitCheckoutAnswers(cartId: string, quantities: Record, donationAmounts: Record | undefined, buyer: FreeOrderBuyer, uiLocale?: string, req?: Pick): Promise; /** * Fetch an existing cart by UUID (cross-device pre-fill — §1.3). * * Returns the server's authoritative view of a cart so a second device * visiting the tickets page can see the in-progress reservation it created * on another device. Returns `null` if: * - the cart no longer exists (404) * - the cart belongs to a different event than `expectedEventID` (when * supplied) — we don't want to mix carts across events * - the cart status is no longer `reserved` / `active` (e.g. expired, * completed, abandoned) — caller should treat the local cookie as stale * - any network/decode failure (caller falls back to localStorage only) * * Returned shape matches the orders-service `GET /v2Public/cart/{uuid}` * response: a Cart model with embedded Reservations. */ export interface CartReservationView { ticketID: number; quantity: number; priceAtReservation: number; status: string; } /** One gift card already applied to the cart, as the server will describe it. */ export interface CartGiftCardView { giftCardId: number; /** Last four only — the server never returns the code. Display, not identity. */ maskedCode: string; /** * Allocated amount in DOLLARS (the wire carries cents), or null when the * server sent nothing usable — never 0, which would understate coverage. */ amount: number | null; } export interface CartView { uuid: string; eventID: number; status: string; expiresAt: string; reservations: CartReservationView[]; giftCards: CartGiftCardView[]; } export declare function getCartByUUID(cartUUID: string, expectedEventID?: string | number, req?: Pick): Promise; /** * Update cart quantities after the cart already exists. * * Replaces all reservations on the cart with the new quantities. * The orders-service handler releases old reservations (returning * inventory) and creates new ones (decrementing inventory) atomically. * * Use this when the user changes ticket counts AFTER the initial * cart was created via initiateOrder. The cart UUID is preserved, * so the timer and extension state stay intact. * * @returns true on success, false on failure */ export declare function updateCartQuantities(cartId: string, quantities: Record, donationAmounts?: Record): Promise; /** * Complete reservation after successful payment * * Called after Stripe confirms the payment to finalize the order * and generate tickets. * * @param orderUuid - The order UUID * @returns Success status and message */ export declare function completeReservation(orderUuid: string, req?: Pick): Promise; /** * Cancel reservation and release tickets back to inventory * * Called when user abandons checkout or session expires. * * @param orderUuid - The order UUID * @returns Success status and message */ export declare function cancelReservation(orderUuid: string, req?: Pick): Promise; /** * Request a refund for a completed order (buyer self-service). * * Public, login-less: the buyer reaches their tickets page from the order UUID in * their confirmation link, so the same UUID authorizes the request. This does NOT * move money — it flags the order (RefundRequested + an optional buyer message) * for the venue/operator to action from their dashboard, exactly as the backend * RequestRefund handler records it. Replaces the "email the venue" dead-end that * was the only way to ask for a refund from the ticket page (MIC-1795). * * @param orderUUID - The order UUID * @param message - Optional note to the venue (why they want a refund) * @returns Success status, with an error message on failure */ export declare function requestOrderRefund(orderUUID: string, message?: string, req?: Pick): Promise<{ success: boolean; error?: string; }>; /** * Create a new order/cart * * This creates an empty order that can be used for checkout. * The order UUID is used for all subsequent operations. * * @param eventId - The event ID * @param promoCode - Optional promo code to apply * @returns The order UUID, or null on error */ export declare function createOrder(eventId: string | number, promoCode?: string, req?: Pick): Promise; /** * Get order details (public, no auth required) * * Fetches the order details for displaying on the success page. * * @param orderId - The order UUID or ID * @returns The order details, or null on error */ export declare function getOrder(orderId: string, req?: Pick): Promise; /** * Validate payment intent and complete the order * * This is an alternative to completeReservation that accepts * additional payment details. Used by micdrop-frontend. * * @param cartId - The cart/order UUID * @param payload - Payment validation payload * @returns Validation result */ export declare function validatePaymentIntent(cartId: string, payload: ValidatePaymentRequest, uiLocale?: string, req?: Pick): Promise; /** * Extend the checkout session by 15 minutes * * Users get a limited number of extensions (typically 2-3). * * @param orderUuid - The order UUID * @returns Extension result with new expiry time */ export declare function extendCheckoutSession(orderUuid: string, req?: Pick): Promise; /** * Get current session status including expiry time * * Used to display countdown timer and check if extensions are available. * * @param orderUuid - The order UUID * @returns Session status including expiry time */ export declare function getSessionStatus(orderUuid: string, req?: Pick): Promise; /** * Initiate a new order (alias for createOrder) * * This function provides backwards compatibility with micdrop-frontend. * It accepts the same parameters as the legacy initiateOrder function. * * @param cartData - Object containing eventID and optional quantities/promoCode * @returns The order UUID, or null on error */ export declare function initiateOrder(cartData?: { eventID: string | number; promoCode?: string; quantities?: Record; }, req?: Pick): Promise; /** * Track UTM source for analytics * * Records the traffic source (utm_source parameter) for marketing analytics. * * @param venueId - The venue ID * @returns Promise that resolves when tracking is complete */ export declare function trackUTMSource(venueId: string | number): Promise;