Sell tickets with M-Pesa and scan them at the door: a Kenya-first ticketing platform with oversell-proof checkout.

Project Summary

  • Client: Suwavy
  • Industry: events
  • My role: Founder & Lead Engineer
  • Core tasks: Product architecture, Web app (SSR), Payments, Check-in scanning
  • Appointed date: Oct 2026
  • Completion: Ongoing
  • Team size: 1

Event organisers in Kenya juggle M-Pesa screenshots, spreadsheets and printed guest lists, while fans deal with checkouts that fail halfway and tickets that sell twice. Suwavy is ticketing designed around how Kenyans actually pay.

What I'm building

  • M-Pesa-first checkout. Daraja STK Push, with Paystack for cards, and idempotent payment confirmation, so a retried callback never issues a ticket twice.
  • No overselling. Capacity-safe reservations hold tickets during checkout and release them if payment doesn't complete.
  • QR tickets and door scanning. Every ticket carries a QR code, and staff check guests in from a phone browser.
  • Organiser tools. Event setup, sales analytics and a ledger of every payment and payout.
  • Admin console for running the platform.

Under the hood

A pnpm monorepo: a server-rendered SvelteKit app (Svelte 5, shadcn-svelte, Tailwind 4, Superforms and Zod), Cloud Functions v2 for the API, and a shared core package of Zod schemas and state machines used by both. Security rules have their own tests, Playwright covers the key flows, and GitHub Actions deploy main to staging and version tags to production.

Where it stands

In active development ahead of launch.

Tech stack

Frontend
  • SvelteKit 2
  • Svelte 5
  • TypeScript
  • shadcn-svelte
  • Tailwind CSS 4
  • Superforms
  • Zod
Backend
  • Cloud Functions v2 (Node 22)
Data
  • Cloud Firestore
Infrastructure
  • Firebase Hosting
  • GitHub Actions
Integrations
  • M-Pesa Daraja
  • Paystack
Other
  • QR codes
  • Playwright

Key decisions

  • Shared Zod schemas and state machines across the app and API
  • Idempotent payment confirmation and capacity-safe reservations

Challenges

  • Preventing oversells under concurrent checkouts
  • Handling retried and out-of-order payment callbacks

Have a similar problem to solve? Let's talk.

Start a conversation