Add your ticket to your phone wallet
Turn a pass into an Apple or Google wallet card, and understand the QR that changes every 15 seconds.
Owned by Member · 8 steps · about 12 minutes
Why this exists
A ticket and a pass are two different rows on purpose. The ticket is the entitlement — it survives being sold to someone else. The pass is the door credential minted from it, and it must not survive that, because the person walking in has to be the person who currently owns the ticket.
The pass carries two credentials. The NFC payload is a compact signed blob: the zones and identity are signed with a venue key that can be rotated without invalidating what is already in people's wallets. The QR fallback is a rotating code derived from a per-pass secret and the current 15-second time step, with one step of tolerance either side. That short window is the entire anti-screenshot design: a code someone photographed and sent to a friend is worthless within half a minute, so the venue never has to argue about whether a picture of a ticket is a ticket.
Your phone renders that code itself. The wallet page fetches the pass secret once — from an endpoint only the owner can call, admins included — caches it in the browser, and computes codes locally, so the QR keeps rotating with no signal in a basement venue.
Corrected 2026-08-24 (end2end). This paragraph used to say that paying for a ticket does not mint a pass, that a freshly bought ticket can legitimately show an empty wallet, and that the remedy is to re-run the seed. All three are wrong now, and the last one is worse than wrong — re-seeding a live instance destroys the feedback overlay, which is the input to the whole plan pipeline.
Paying mints the pass. Settlement issues it inside its own SAVEPOINT, so a credential failure rolls back only the half-written pass rows and the sale still commits — because a customer charged with no order, no ticket and no ledger record is strictly worse than a paid ticket whose pass is a moment late. Issuance is idempotent per ticket and a failed attempt leaves no pass row at all, in particular no revoked one. The scheduler tick payments.backfill_ticket_passes is the recovery arm: it mints the missing pass on the next tick for any purchased ticket that has none. Comp tickets are deliberately excluded — the guest-list module owns comp credential policy and mints their passes itself.
Before you start
- A member session holding at least one issued ticket that has a pass (the seeded demo accounts do).
- An admin session only for the last step.
Practise with
| Persona | Password | Note | |
|---|---|---|---|
| member | member@club.test | member123 | holds a seeded membership card |
| member | nova@demo.club | nova-pass-123 | holds event tickets on the demo event, with passes after a second seed run |
| admin | admin@club.test | admin123 | owns the signing keys and the wallet push log |
Steps 1–7 — Member
their manual →-
1Start from your tickets and find the one you are travelling with.Expected result Your tickets grouped into upcoming and past, with event, tier and serial.Watch out for This page shows tickets, not credentials. It links to your wallet rather than showing a code — do not try to scan anything from here.
-
2Open your wallet. Every credential you hold lives here: event passes and, if you have one, your membership card.Expected result One card per pass, with its status, the zones it opens and a live rotating code.Watch out for A pass showing Suspended means the ticket is listed on the resale exchange. A pass showing VOID has been revoked and is never coming back.
-
3Look at the same list as JSON when you need to see exactly what you hold.Expected result Your passes with kind, status, serial and zones.
-
4Add the pass to Apple Wallet.Expected result A pass file, and a wallet registration recorded so the venue can push updates to it later.Watch out for A revoked pass returns 410 rather than a broken file. The wallet copy is not a snapshot — if the pass is later suspended or revoked, a push updates or voids the copy on your phone.
-
5Do the same for Google Wallet.Expected result A signed token for the Google pass.
-
6Fetch the current QR payload and watch the seconds remaining tick down.Expected result A payload plus how long it is valid and the 15-second period it rotates on.Watch out for A pass suspended for resale returns a 409 here instead of a code. You cannot list a ticket for sale and also carry a working code for it.
-
7Understand how the offline code works: this endpoint hands the pass secret to the phone once, and the page computes every future code locally.Expected result The secret, the digit count, the algorithm and the 15-second period.Watch out for Owner only. An admin calling this for your ticket gets a 403 — the secret is the credential, and staff never need it. Treat a leaked secret exactly like a leaked password: it is worth a revocation.
Steps 8 — Admin
their manual →Owns the signing keys behind every credential and the log of wallet pushes.
-
8As an admin, look at the wallet push log and the signing keys behind all of this.Expected result Readers, keys with their status, the revocation list and recent wallet traffic.Watch out for Rotating a signing key keeps existing payloads valid — retired keys still verify — so rotation is safe to do mid-season. Marking a key compromised is the one that starts failing credentials.