Jetron TicketFluid

Checkout walkthrough

Build the full reserve → checkout → redirect flow with the SDK.

This walks through a complete white-label checkout with the SDK. See the checkout flow concept for how the pieces fit together server-side.

Show the event and its tickets

const { data: event } = await client.getEvent('my-event')
const { data: tickets } = await client.listTickets('my-event')

// Only offer purchasable tickets
const purchasable = tickets.filter((t) => t.status === 'AVAILABLE')

Each ticket carries live quantityLeft, formatted prices, and per-order limits (maximumPurchasableTicketCount) to enforce in your UI.

Reserve the cart

Use one stable UUID per attendee as the deviceId (persist it in the browser) so repeat calls refresh the same hold:

const deviceId = getOrCreateDeviceId() // e.g. crypto.randomUUID() in localStorage

const { data: reservation } = await client.createReservation(
  'my-event',
  {
    items: [{ sku: purchasable[0].id, quantity: 2 }],
    promoCode: coupon || undefined,
  },
  { deviceId },
)

Drive the countdown

clientExpiresAt is the client-facing deadline for the hold:

const msLeft = new Date(reservation.clientExpiresAt).getTime() - Date.now()
startCountdown(msLeft, {
  onExpired: () => promptToReserveAgain(),
})

Display the priced cart from reservation.items, reservation.total, and reservation.totalFees. Amounts are integers in the smallest currency unit (Money).

Create the order

const { data: order } = await client.createOrder(
  'my-event',
  {
    quoteReference: reservation.quoteReference,
    email: form.email,
    firstName: form.firstName,
    lastName: form.lastName,
    phone: form.phone,
    callbackUrl: 'https://your-site/checkout/callback',
    metadata: { seatPreference: 'front' }, // optional, echoed in the TICKET_PURCHASED webhook
  },
  { deviceId: reservation.reservationToken },
)

Handle the result

if (order.status === 'confirmed') {
  // Free order: fulfilled immediately, order.reference is set
  showConfirmation(order.reference)
} else {
  // Paid order: send the attendee to the payment gateway
  window.location.href = order.checkoutUrl
}

After payment, the gateway redirects to your callbackUrl with a reference query parameter. Verify it on your callback page and show the confirmation.

Abandoned carts

Release the hold if the attendee bails out, so the stock frees up immediately:

await client.releaseReservation('my-event', { deviceId })

Duplicate orders

Creating a second order for the same reservation returns a 409. Catch the ApiError and treat it as "payment already in progress".

On this page