The flow
1
Show what's on sale
Render your event page from
GET …/ticket-types (names, prices, sale windows, statuses), …/availability (live remaining numbers), …/addons, …/bundles, …/venues, …/sessions (the agenda) and …/speakers. When the buyer enters a redemption code, preview it with GET …/redemption-codes/lookup?code= — the unlocked ticket, its perks and the discounted price, before anything is placed. Your cart is your own frontend state — Orriven first hears about it at settlement.2
Place the order
201 answers the pending order — it holds its places for 15 minutes. A buyer already registered in the event answers 200 with alreadyRegistered: true instead: acknowledged, never double-booked. A full ticket answers 412.3
Confirm — free settles, paid gets a Stripe page
- A free order (total 0) settles on the spot:
{"status":"paid", "registration":{…}, "created":true}— done, no Stripe involved. - A paid order answers
{"status":"awaiting_payment", "paymentUrl":"https://checkout.stripe.com/…"}. Redirect the buyer there;successUrl/cancelUrlare where Stripe sends them back on your site (required for paid orders, https only — plain http is allowed for localhost development).
4
Wait for settlement
Payment settles through the platform’s Stripe webhook, not through your call. When the buyer lands on your
successUrl, poll GET …/orders/{orderId} (or find it in GET …/orders) until status is paid and registrationId is set — that is the moment the seat, the perks and the check-in code exist.5
Build the buyer's account area
Everything a “my tickets” page needs is readable by your backend, filtered to the signed-in buyer’s email:
- Registrations (
GET …/registrations) — status, ticket type, and thecheckinCodeto render as their entry QR; - Perks (
GET …/registrations/{id}/perks) — the effective union of ticket ∪ code ∪ individual grants; - Check-ins (
GET …/checkins?registrationId=) — their usage history; - Orders — their purchase history.
Rules that bite
- One order, one seat. The registration model is one person per event, so an order carries at most one ticket seat (
412otherwise) — a buyer purchasing for friends places one order per person, each with that person’s email. Add-ons may repeat freely. - The order number is the order’s credential — keep it server-side with the same care as a session token for that buyer.
- A pending order holds capacity for 15 minutes; confirming a paid order stretches the hold to 35. Cancel (
POST …/orders/{orderNumber}/cancel) to release it early; cancelling twice acknowledges. - Never call confirm for a paid order without
successUrl/cancelUrl— it answers400before anything happens. - If payments are not configured for the Business Unit (no Stripe onboarding), placing a paid order answers
412; the free path works regardless. - Automations fire the same as the platform’s own checkout — order placed/expired/cancelled and registration triggers all behave identically.
Related
Endpoint reference
Exact schemas for place, confirm and cancel.
Orders (console view)
How the same orders look to the organizer.