Print it, scan it, and know it has not already walked in
Every ticket BallOBall issues is a QR code — on the holder's phone, or printed as a card you sell for cash at the table. At the gate, staff scan with a phone camera in the browser and get one of five answers back: valid, already scanned, cancelled, wrong match, or not recognised. Free tickets and door sales run end to end today; card payment online is built and waits on a connected payment provider.
Harbourside Ironsides
vs
Northgate Kings
Sat 14 Mar · Tip-off 7:30 PM
Kestrel Arena · Gate B
BOB-4K72-9X31
Sec
112
Row
H
Seat
14
Admitted
J. Okonkwo
Season pass · Adult · Transferable
Gate
B · North
Time
19:42:07
Steward
M. Alvarez
Already scanned
BOB-4K72-9X30 · admitted 19:38:52 at Gate B
A ticket is only worth what the door can check
Most gates run on a cash box and a roll of cloakroom tickets. A photo of a valid ticket looks exactly like the ticket, so the same code can walk in four times and nobody at the door can tell. Nobody can tell a ticket bought for tonight from one bought for last month's fixture either. And when the last person is through, the tin is the only record of who came in — so the attendance figure is a guess, the takings get counted twice on a kitchen table at midnight, and the season-ticket holder who forgot his card gets in because somebody recognises him.
Four steps, no configuration
Switch ticketing on, set the prices
An organisation admin turns Ticketing on from inside the product — self-serve, free, no sales call. Each fixture then gets its own ticket types: a name, a price, an optional capacity, and a draft / on-sale / closed status you move by hand.
Get the ticket into a hand
A free ticket type issues a scannable QR to the fan's device the moment they claim it. For cash, staff record the sale in the box-office panel, or print a batch of QR cards in advance — each carrying an HMAC-signed token the scanner checks before it looks anything up.
Scan at the gate
Staff open the scanner in a phone browser and point the camera, or paste the code by hand. Agents scan only for the fixture they are assigned to, and every scan is logged against the named gate or station they were placed at.
Watch the door, then count the night
The admission view for the match shows tickets sold, how many have scanned in, how many are still outstanding, a per-ticket-type split and the latest scans. Afterwards, insights roll up sold, gross, net after the platform fee, redeemed and sell-through per event.
From on-sale to the turnstile
Everything below is built and running today. Unbadged items are included on every plan; a badge means the capability needs a module added to your plan, a higher plan tier, or a piece of setup finished first.
11 of these are included on every plan. One group needs the Ticketing module. 1 are built and waiting on setup before they can be switched on.
Gate scanning (camera QR plus manual code entry)
Staff at the gate can scan a ticket QR with their phone camera in the browser, or paste the code manually, and the server redeems the ticket and reports valid, already-scanned, cancelled, wrong-event or not-recognized.
Requires a live network connection — every scan is a server call, there is no offline mode. Camera scanning uses the browser's native BarcodeDetector (Chromium and iOS 17+ Safari per the source comment); other browsers fall back to manual entry. Restricted to SUPER_ADMIN / PLATFORM_SUPPORT / LEAGUE_ADMIN plus GATE_AGENT on the scanner route, and a gate agent can only scan a match they hold an active gate assignment for.
Duplicate-scan and wrong-event protection at the gate
A ticket that has already been scanned is reported as already scanned with its entry time, a cancelled ticket is reported as cancelled, and a genuine ticket presented at the wrong fixture is rejected as being for a different match.
The redeem step uses a guarded update; the source notes a racing double-scan is resolved by the atomic guard so only one entry is admitted, but this is described as acceptable for gate use rather than a formal uniqueness guarantee.
Printed cash tickets with signed, offline-verifiable QR
An admin can mint a batch of physical admission tickets for one ticket type and print a sheet of QR cards, each carrying an HMAC-signed token that the gate scanner verifies cryptographically before any database lookup.
Batch size is capped per request in the schema. Reserved-seating ticket types cannot be printed in bulk. Printing is the browser's print dialog on a generated sheet — there is no ticket-stock or thermal-printer integration. Rotating the HMAC signing secret invalidates every already-printed ticket unless the old value is left in the secret's `previous` slot, which the scanner still accepts.
QR ticket generation and on-device ticket wallet
Every issued ticket carries a unique unguessable token that is rendered as a QR code the holder shows on their phone, reachable from the order page without signing in.
The order page is reached by possession of the order id / ticket token; there is no email or SMS delivery of tickets in the codebase.
Free / $0 ticket issuance with instant QR
For a free ticket type, an anonymous fan can claim tickets from the public event page and the tickets are issued immediately as scannable QR codes on their device.
Only the free path completes end to end without payment configuration; a priced ticket cannot be paid for online in the current production deployment.
Cash / box-office sale at the door
Staff can record an at-the-door sale in the box-office panel, which creates an already-paid order on a BOX_OFFICE channel, issues the tickets and posts the sale to the ledger.
Admin/ticketing-operator authorization plus the Ticketing entitlement are required. The money itself is collected outside the product; the app records the sale.
Will-call / pickup queue
Orders set aside for collection appear in a will-call list for the match, and marking one picked up stamps the pickup time and redeems that order's tickets.
Admin-only, behind the Ticketing entitlement.
Live gate / capacity dashboard for a fixture
Ticketing moduleAdmins can open a per-match admission view showing tickets sold, how many have scanned in, how many are still outstanding, a per-ticket-type split and the most recent scans.
Read-only, admin-only, entitlement-gated; the figures refresh when the page is loaded or refetched rather than being pushed to the browser.
Gates, stations and assigned gate agents
Admins can define named gates and stations for a fixture and assign gate agents to them; an agent can scan only for a match they are actively assigned to, and each scan is logged against the lane they were placed at.
Admin authorization to configure; the agent scanner requires the GATE_AGENT role or an admin role.
Ticket types (create, price, capacity, on-sale status)
Organizers can create ticket types for a fixture with a name, description, price, currency and optional capacity, and move each one between draft, on-sale and closed.
Requires the Ticketing module to be enabled for the organization (self-serve, free, but restricted to LEAGUE_ADMIN / SUPER_ADMIN / PLATFORM_SUPPORT). Ticket-type admin endpoints 403 when the module is off.
Promo / discount codes
Pro planOrganizers can create, edit and delete discount codes for an event, buyers can preview a code before checkout, and a redemption limit is claimed atomically so a capped code cannot be over-redeemed by concurrent buyers.
Codes are scoped to a single event. The discount applies to the ticket subtotal only, never to an added donation.
Presale access codes
A ticket type can be put in presale so it is only purchasable by a buyer who supplies the matching access code, and the code is re-validated on the server for every order.
A single shared code per ticket type, not per-buyer codes.
Reserved seating (seat chart plus seat-level holds)
Pro planOrganizers can define seating sections for a fixture, buyers see seat availability on the public page, and a reserved-seating purchase claims specific seats inside the same transaction that creates the order so two buyers cannot take the same seat.
Seat holds on an unpaid order are temporary and are released on cancellation or expiry. Seat-level inventory applies only to reserved-seating ticket types; general-admission capacity is not held while an unpaid order is outstanding.
Standalone tickets-only mode (create an event without running a league)
An organization that only wants to sell tickets can create a ticketed event from an opponent and a date and manage it from a dedicated tickets dashboard, without setting up scoring or league structure first.
Restricted to LEAGUE_ADMIN / SUPER_ADMIN / PLATFORM_SUPPORT and requires the Ticketing module to be enabled.
Ticketing insights (sold, gross, net after fee, sell-through, 30-day sales series)
Ticketing moduleOrganizations get a ticketing insights view with totals for tickets sold, gross sales, net after the platform fee, tickets redeemed, sold-out event count, sell-through percentage, a per-event breakdown and a daily sales series for the last thirty days.
Scoped to the signed-in user's own organization from their token, entitlement-gated, and the sales series window is fixed at thirty days in code.
Online card checkout via Stripe Checkout
Needs a connected payment providerThe product contains a complete Stripe Checkout integration for paid ticket orders, including an idempotency key per order and webhook-confirmed fulfilment, which activates once live Stripe keys are supplied.
DORMANT in the live deployment. The Stripe secret still holds placeholder values, so getStripe() returns null and createTicketCheckout returns mode OFFLINE. The live production endpoint GET /public/payment-config currently returns {"card":false,"paypal":false}, and a paid order is instead created PENDING_PAYMENT with a message telling the buyer the organizer will follow up to collect payment before the tickets are issued.
Before you ask
Can buyers pay by card online?
Not in the live deployment today, and this page will not pretend otherwise. Stripe Checkout and a PayPal redirect path are both built — an idempotency key per order, webhook-confirmed fulfilment — but they stay dormant until live payment keys are connected, and the public payment-config endpoint currently reports card and PayPal as off. What runs end to end right now is free ticket issuance, cash at the box office, and printed tickets.
Do tickets get emailed or texted to the buyer?
No. There is no email or SMS ticket delivery anywhere in the product, and it is better to know that before you plan a launch. A ticket is reached by its link instead: an anonymous buyer opens their order page by possession of the link, a signed-in fan finds every ticket they have bought in one place, and a ticket transfer hands you back a shareable link. Getting that link to the buyer is your job — a message, a group chat, whatever you already use.
What happens if the gate loses signal?
Scanning stops. Every scan is a server call and there is no offline gate mode, so plan for a connection at the door — a phone on mobile data if the venue Wi-Fi is unreliable. Printed cash tickets do carry a signature the scanner verifies cryptographically before any database lookup, which is what makes a printed token tamper-evident, but the redemption itself still goes to the server.
Someone screenshots their ticket and sends it to four friends. Then what?
The first one through is admitted. The rest come back as already scanned, with the time that ticket went in, so the person at the door knows what actually happened rather than staring at a vague error. A cancelled ticket reports as cancelled, and a genuine ticket for a different fixture is rejected as being for another match. Two scanners hitting the same code at the same instant are settled by a guarded update, which is designed to admit one and hand the other back as already scanned.
Can gate volunteers see the rest of our data?
A gate agent can scan only for a match they are actively assigned to, and each scan is logged against the named gate or station they were placed at. Configuring gates and stations, working the will-call pickup queue, cancelling or refunding an order and reading the admission dashboard all require an admin role. Refunds can also be put behind a second admin's approval before they execute.
Do we have to run a league here to sell tickets?
No. An organisation can create a ticketed event from an opponent and a date and run it from a dedicated tickets dashboard, without setting up scoring or league structure first. If you do run your season here as well, the league ticketing tab rolls up printed, sold and redeemed counts plus revenue across every ticket type in that league.
Put your next home fixture on sale
Public leagues need no account to open.