Skip to content
Rapcsány Krisztián Rapcsány Krisztián
hu
← All projects Web application and API

Ticketing and community platform for clubs and events

This is the biggest system I have built so far: a ticketing platform for clubs and events. Catalogue, cart, payment, ticket issuing, invoicing, a mobile API and everything that goes around them. I have been building it since February 2025, and it keeps growing.

PHP 8.3 Laravel 12 MySQL Redis Queue workers WebSockets REST API Online payments Feature flags
The challenge
My role

I have designed and built it from the start.

Selling a ticket is only the first step. After that the buyer needs the ticket by email, an invoice, entry at the door, and ideally a reminder before the event. These are usually separate systems, and that is where data gets lost.

My goal was to make all of it one system. The website, the mobile app, the app used at the door, the admin and the point-of-sale systems all work from the same place, and when something breaks, there is one place to look.

The solution
01

Catalogue and SEO

Clubs, organisers, events, line-ups and search, with search-friendly URLs, automatic sitemaps and multilingual content with machine-translation support.

02

Cart and payment

Guest and signed-in carts (merged on login), coupons, and a payment model where revenue goes straight to the organiser, with orders closed on the payment provider callback.

03

Tickets and invoices

PDF tickets by email, ticket transfer to another person, automatic invoicing through the provider each organiser uses, and retries for failed invoices.

04

Mobile API and push

A versioned API for the mobile app: sign-up, catalogue, cart, tickets, push notifications, deep links, and hand-off from the app to web checkout.

05

Loyalty and VIP cards

Discount cards with their own landing pages, a loyalty wallet with balance and transactions, and lookups and charges tied to an external point-of-sale system.

06

Community layer

Friends, following, posts, 24-hour stories and real-time chat. Behind a feature flag, so it can be rolled out gradually per user.

Screenshots
Home page

Search by time and place, quick access to your own QR codes, featured events.

Events

A calendar, venue, category and organiser filters, and events as cards with date and music styles.

Venue page

The venue presented with rating, music styles, age limit, opening hours and a gallery.

Event page

Description, dress code, age limit, the tickets and the venue in one place.

With brand and customer names and personal data removed (except the app store screenshots).

What makes it special

Many clients, one system

The website, the customer mobile app, the check-in app, the admin and an external point-of-sale system all use the same API and data model.

The money goes to the organiser

I built payments so that revenue goes straight to the organiser or the club. An order is closed by the payment callback, not by the buyer returning to the site, because that is not reliable.

Gradual rollout

I put the community features (friends, posts, stories, chat) behind a feature flag. I can switch them on per user, and if something is wrong I do not have to roll back a whole release.

Challenges I ran into
01

VIP tickets vanished from the admin statistics

At one point I noticed the VIP ticket was missing from the per-event statistics in the admin. A guest checked in with a VIP card went in on a ticket type the admin did not know yet. Now the ticket type is synced automatically at the first VIP entry. I filled in the earlier gaps with two recovery commands.

02

A zero-forint order needs no invoice

At first the invoicing job threw an error for every on-site sale, because those have no billing address, and it also tried to invoice fully discounted orders. Now the amount actually paid decides, not the list price, and on-site sales take a separate path.

03

Anything slow or external goes on a queue

Invoicing, email, push and sync do not run inside the user's request. They run on a queue, with retries. If an external provider does not answer, the purchase still goes through, and the invoice follows later.

Under the hood

Reliable background work

Slow or third-party-dependent tasks (invoicing, email, push, sync) run on queues with retries, and recovery commands can backfill anything that was missed.

Connecting systems

Two-way sync with the admin interface, a separate media server, a door-check API and an external point-of-sale partner interface, all built on one shared data model.

Deliverable communication

Email log and suppression list, delivery tracking, abandoned-cart reminders, pre-event push and post-event rating requests.

Operability

Health monitoring and alerts, scheduled maintenance, a documented API and feature flags, so new features go live without risk.

Real code

Guarding against a wrong invoice

Before invoicing, it checks in order whether an invoice is needed at all. The amount actually paid is authoritative, not the list price, so a fully discounted order never produces a pointless invoice.

CreateInvoiceJob.php
public function handle(): void
{
    $order = Order::with(['billingAddress', 'user', 'items'])->find($this->orderId);

    // On-site (POS) sales are invoiced through another flow and have no billing address.
    if (Str::startsWith($order?->order_number ?? '', 'POS-')) {
        return;
    }

    // What was actually paid is authoritative, not the list price of the items:
    // a fully discounted order has total_amount = 0 and must not be invoiced.
    if ((float) ($order?->total_amount ?? 0) <= 0) {
        Log::info('Invoice skipped: order total is zero', ['order_id' => $this->orderId]);
        return;
    }

    if (empty($order?->billingAddress)) {
        Log::error('Invoice skipped: billing address is empty', ['order_id' => $this->orderId]);
        return;
    }

    // ... build the invoice and hand it to the provider configured for this organiser
}
Result

A live system that has served hundreds of events and keeps growing. The mobile API, the loyalty programme, the community layer and the recommendation system were all added later, without having to take it down.

Would you build a ticketing or events system?

Tell me about the plan, and we will work out what it takes and what to build first.

More projects

Get a quote →