Projects
White-label ticketing, zero to production

Backstage

Lead frontend on a white-label ticketing platform for international touring DJs, built from nothing to production on top of the Pretix ticketing framework — branded storefronts, an identity-bound checkout, and the console the promoter runs the night from.

Role
Lead frontend — Antártida
Period
2023 — 2025
Type
Client work
Status
production
9
Steps to an issued ticket
10
Ticket types on one night
2
Years owned end to end
0
Ticketing engines rebuilt
01

Walkthrough

Recorded in the product
  1. 01Branded event page — line-up, venue, age limit, price from
  2. 02Account: sign in, or register
  3. 03Profile: name, date of birth, nationality, ID number
  4. 04Phone verified by SMS code
  5. 05ID document photographed, front and back
  6. 06Tickets chosen against a ten-minute hold
  7. 07Service fee shown separately from face value
  8. 08Paid through Mercado Pago
  9. 09Ticket issued, and the clip ends on the door
The promoter’s own how-to-buy clip for a John Digweed date, which means this is the real checkout, filmed by the client to hand to their audience.
02

Overview

I started this one from an empty repository and took it to production as lead frontend. It is the event and ticketing surface for internationally touring DJs — the page a fan lands on, the checkout they go through, and the ticket they hold at the door.

Rather than building a ticketing engine, it sits on top of Pretix and puts a white-label front on it: each promoter or artist gets their own branded storefront over shared ticketing infrastructure. That split is the whole architecture — Pretix owns inventory, orders and the parts you must never reimplement, and the frontend owns everything the audience actually sees.

Two audiences share the codebase. Fans get the storefront, the checkout and a wallet of tickets they can transfer. Promoters get a console on the same events: ticket types, RRPPs, clients, memberships, invoices and the sales report for the night. Nightlife ticketing in Latin America is also a fraud problem, so identity runs through the whole thing — a ticket is bound to a person, not to whoever has the screenshot.

I owned the frontend end to end, including maintenance after launch.

03

Architecture

2 diagrams
01

One codebase, one brand at a time

PromotersLa Juanitaserif, magentaPM Open Airdisplay, cyanNext promoterBrand & contenttheme, copy, light and darkOne frontendstorefront, checkout,wallet, consolePretixinventory, orders

Scroll to pan

The promoter is configuration, not a fork. Everything the audience sees — wordmark, palette, both themes, copy — is data on top of a single frontend, and the ticketing engine underneath never learns there is more than one brand.
02

Identity before inventory

After the saleTen-minute holdBefore the clockFanAccountPhoneSMS codeID documentfront and backTickets andservice feeMercado PagoPretixissues the orderTicket bound toa named holderApple Wallet,or transferred on

Scroll to pan

The order of the steps is the anti-fraud design. Everything slow — account, phone code, photographed ID — happens before a ticket is held, so the ten-minute hold only ever covers choosing and paying. What comes out the other end is bound to a named holder and changes hands through a transfer, not a screenshot.
04

Screens

4 captures
La Juanita event page for a Barcelona pool party, with tags, description and a sticky ticket bar
01Storefront — La Juanita’s brand, the platform’s event page. Light and dark both ship per brand.
Purchase confirmation screen thanking the buyer and linking to their orders
02Confirmation — the order lands, and the ticket is already in the wallet.
Ticket detail with a QR code, a valid state, an Apple Wallet button and a transfer action
03The ticket — named holder, live state, Apple Wallet, and a transfer action so tickets move inside the system.
Producer dashboard with ticket totals, sales over time by ticket type and a breakdown pie chart
04Producer console — sales by ticket type over the run-up, on a Looker Studio report embedded in the app shell.
05

Modules

8 units
01

White-label storefront

One codebase, many brands — each promoter’s events presented under their own identity, in both themes, without a fork per client.

  • Wordmark, palette and typography as configuration
  • Light and dark for every brand, not just the flagship
  • Event page: line-up, venue, age limit, tags, share
  • Sticky price bar so the cheapest ticket is always in view
02

Identity before inventory

Account, profile, SMS-verified phone and a photographed ID document — all of it collected before a single ticket is held, because a ticket in this product belongs to a named person.

03

Checkout on a clock

Ticket selection runs against a ten-minute hold, with the service fee shown apart from face value and payment handed to Mercado Pago. Everything slow was moved out of the window on purpose.

04

The ticket after the sale

A QR bound to a holder, a live validity state, an Apple Wallet pass, and a transfer action — so a ticket changing hands is a recorded event rather than a forwarded screenshot.

05

Ticket types as pricing strategy

Early bird, three rounds of preventa, invitations, general admission, VIP standing and tables — ten-plus types on a single night, each with its own window, price and allocation.

06

Producer console

Where the promoter actually works: events, RRPPs, clients, memberships, invoices and notifications, with the sales report for the night embedded in the same shell.

07

Pretix integration

The ticketing framework underneath, handling inventory and orders while the frontend owns presentation and checkout flow.

08

Zero to production, then maintained

Set up the project, the frontend architecture and the conventions, then kept it running once real events were selling through it.

06

Engineering

What was hard
01

The screenshot is the attack

A QR in a chat thread can be sold four times before anyone reaches the door, and the door is the worst possible place to discover it. The answer was to stop treating a ticket as a bearer token: an account, an SMS-verified phone and a photographed ID stand between a fan and a purchase, the ticket carries the holder’s name, and passing it on is a transfer inside the product rather than a forward outside it. Every one of those steps is friction added deliberately to a funnel, which is not a decision a frontend gets to make quietly.

02

Everything slow has to happen before the clock starts

Held inventory is the one thing a ticketing frontend cannot be relaxed about — the hold is ten minutes, and a fan who spends it photographing the back of their ID loses the ticket to someone else. So the flow front-loads: account, profile, phone code and document all resolve before ticket selection is reachable. The sequence looks like a long onboarding and is actually a scheduling decision.

03

One codebase that must never look like one codebase

A promoter’s storefront is their brand, so a shared platform that reads as a shared platform has failed. La Juanita is a serif wordmark and magenta; PM Open Air is a display face and cyan; both run the same components, the same checkout and the same wallet, in both light and dark. Theming is the easy half — the hard half is keeping a checkout flow identical enough to debug once, and different enough that nobody notices it is the same one.

04

Ten ticket types, one night, one screen

Nightlife pricing is not two tiers. A single event runs early bird, three rounds of preventa, gendered invitations, general admission, VIP standing and tables — each with its own window, price, allocation and rules about who may buy it. The interface has to present that without turning into a spreadsheet, and the promoter’s report has to break sales down by every one of them, because which round sold out and when is the whole business.

05

Analytics the promoter would actually open

The console needs sales over time, split by ticket type, with date and event filters — and rebuilding that as bespoke charting would have bought a maintenance burden and no advantage. Embedding a Looker Studio report inside the app shell put a full analytics surface behind the promoter’s own navigation, which is the sort of trade a lead frontend should be making rather than defending a hand-rolled chart library two years later.

07

Stack

11 entries
  • 01React
  • 02Next.js
  • 03TypeScript
  • 04Tailwind CSS
  • 05Pretix
  • 06PostgreSQL
  • 07Python
  • 08Google Cloud
  • 09Mercado Pago
  • 10Apple Wallet
  • 11Looker Studio