Fetching Tickets (Fulfillment)

This guide explains how to retrieve issued tickets / fulfillment after a checkout in three integration styles:

  • Webframe (hosted UI)
  • Headless (your frontend + our APIs)
  • Admin/Backend (server-to-server)

Summary

⏳ Fulfillment is async: how polling works

When you call a fulfillment endpoint:

  • 202 Accepted → Not ready yet. Read Retry-After (seconds) and poll again after that delay.
  • 200 OK → Tickets are ready. Render or store them.
  • 404 Not Found → Unknown checkout_id or no results for the filter.
  • 429 Too Many Requests → Back off and retry after the given Retry-After.
  • 503 Service Unavailable → Temporary; retry later (honor Retry-After if present).
📘

Best practice: use exponential backoff (e.g., 3s → 5s → 8s → 13s, capped at ~30s) and always honor Retry-After.


🧭 Which endpoint should I call?

You have three options, depending on where you are in the flow and which token you hold:

ContextToken to useEndpoint
Headless frontend (you exchanged a session code yourself)Public bearerGET /v1/checkouts/checkout_id/fulfillment or GET /v1/me/fulfillments
Webframe (hosted exchange; you typically don’t see the public token)Backend OAuth (client credentials)GET /v1/admin/fulfillments with filters (e.g., external_user_id=... or checkout_id=...)
Back-office/admin systems (reconcile, support)Backend OAuth (client credentials)GET /v1/admin/fulfillments with filters
📘

If you’re embedding the webframe, we redeem the code → token. You usually won’t have a public bearer in your app. If you still need the tickets server-side, use the admin endpoint with your Backend OAuth token.


Integrations

🧩 Headless: fetch fulfillment from your frontend (Public bearer)

sequenceDiagram
  participant FE as User Frontend
  participant PBE as Partner Backend
  participant AUTH as Auth Server
  participant FTAPI as Funtrips API

  FE->>PBE: start flow
  PBE->>AUTH: oauth2 client credentials
  AUTH-->>PBE: backend bearer
  PBE->>FTAPI: POST session headless
  FTAPI-->>PBE: session code pkce required
  PBE->>FTAPI: exchange code and verifier
  FTAPI-->>PBE: public bearer
  PBE-->>FE: send public bearer
  FE->>FTAPI: call api with public bearer
  FE->>FTAPI: get fulfillment
  FTAPI-->>FE: 202 retry after
  FE->>FTAPI: get fulfillment
  FTAPI-->>FE: 200 tickets ready

Typical flow:

  1. Your checkout completes and you have a checkout_id.
  2. Poll GET /v1/checkouts/checkout_id/fulfillment until 200 OK, or
  3. Use GET /v1/me/fulfillments to list recent fulfillments for the current user session.

API reference:

Expected responses:

  • 202 Accepted with Retry-After: 5 → wait 5 seconds, then poll again
  • 200 OK with fulfillment payload (tickets, barcodes/QRs, validity, etc.)

🪟 Webframe: fetch fulfillment from your backend (Admin)

sequenceDiagram
  participant User as Customer App
  participant PBE as Partner Backend
  participant AUTH as Auth Server
  participant FTAPI as Funtrips API
  participant FTWEB as Funtrips Web App

  User->>PBE: start flow
  PBE->>AUTH: oauth2 client credentials
  AUTH-->>PBE: backend bearer
  PBE->>FTAPI: POST session webframe
  FTAPI-->>PBE: session code and frame url
  User->>FTWEB: open frame with code
  FTWEB->>FTAPI: redeem code
  FTAPI-->>FTWEB: public bearer
  FTWEB->>FTAPI: create checkout
  FTWEB->>FTAPI: get fulfillment
  FTAPI-->>FTWEB: 202 retry after
  FTWEB->>FTAPI: get fulfillment
  FTAPI-->>FTWEB: 200 tickets ready

Typical flow:

  1. After the user completes checkout in the webframe, your backend wants to retrieve tickets.
  2. Call GET /v1/admin/fulfillments, filtering by:
    • checkout_id=... or
    • external_user_id=... (the ID you used when starting the session)

API reference:

Expected responses:

  • 202 Accepted with Retry-After during issuance
  • 200 OK with one or more fulfillment records for your filter
📘

Tip: If your POS or CRM needs the final tickets, poll on the admin endpoint using the checkout_id you persisted when creating the checkout.


🛡️ Admin/Back-office: reconcile or support lookups (Admin)

sequenceDiagram
  participant PBE as Partner Backend
  participant AUTH as Auth Server
  participant FTAPI as Funtrips API

  PBE->>AUTH: oauth2 client credentials
  AUTH-->>PBE: backend bearer
  PBE->>FTAPI: get fulfillments
  FTAPI-->>PBE: 202 retry after
  PBE->>FTAPI: get fulfillments
  FTAPI-->>PBE: 200 tickets ready
  PBE->>FTAPI: optional list merchants products
  FTAPI-->>PBE: data

Typical Flow:

  1. Use GET /v1/admin/fulfillments with filters like:
    • checkout_id=...
    • external_user_id=...
    • Optional time windows (if your spec supports them)

API reference:

Expected responses:

  • 202 Accepted with Retry-After during issuance
  • 200 OK with one or more fulfillment records for your filter

✅ Implementation checklist

  • Honor 202 Accepted and Retry-After on all fulfillment endpoints.
  • Implement exponential backoff + a sensible max polling time.
  • For webframe integrations, query admin endpoints from your backend (you won’t have a public bearer).
  • For headless integrations, query public endpoints from your frontend using the public bearer.
  • Cache avoidance: treat 202 responses as non-cacheable (Cache-Control: no-store may be returned).
  • Handle 429 similarly (use returned Retry-After).