All work

03 / Case Study

Events & Booking Platform

Event creation, participant management, and payouts for a bookings platform, with identity verification and real-time admin alerting.

ClientPlayAce
Period2022 — 2025
RoleBackend Owner
−40%admin response time
5notification channels from one backend
3clients served: web, native, admin

The problem

Booking platforms live or die on trust: organisers need to get paid reliably, participants need identity verification before high-value events, and admins need to know when something needs attention without refreshing a dashboard all day.

Architecture

An Express and MongoDB service backing both a React web client and a React Native app. The domain is wider than 'events': hosts submit event requests that move through an approval workflow, participants join and are managed per event, hosts are paid out, and the whole thing is wrapped in a growth layer — influencers with their own trackable coupons, generic coupon campaigns, ad banners, brand placements, and newsletters. Reviews are collected after the fact by a scheduled job rather than prompted inline. Razorpay handles payouts, refunds, and participant transactions; Onfido verifies identity with webhook-driven status updates rather than polling; media goes to S3. Notification delivery is split across dedicated controllers per channel — SendGrid for email, WhatsApp, and Slack — and further scheduled jobs handle address normalisation and geocoding.

Webhook-driven verification, payouts, and admin alertingThe events API exchanges webhooks with Onfido for identity verification and Razorpay for payouts, fans notifications out across three channels, and routes operational alerts directly into Slack in real time rather than a dashboard admins had to check.Events APIExpress + MongoDBOnfidoKYC, webhook statusRazorpaypayouts + refundsNotification Fan-outSendGridemailFirebasepushWhatsApp / SMStransactionalSlackadmin alerts, −40% responseverifywebhookpayoutwebhookreal-time

The mobile client

The same backend serves a React Native app shipped to both stores, which is where most participants actually book. Payments and identity run through native SDKs rather than web views — Razorpay's native checkout and Onfido's native capture flow — because document capture and payment authorisation both degrade badly in an embedded browser.

  • —Firebase across three roles: analytics, push messaging, and Crashlytics for field crash reporting.
  • —i18next for localisation, Reanimated and a native gesture stack for the interaction work.
  • —Shipping one product across a web client, a native app, and the backend behind both meant API changes had to stay compatible with a store-review release cycle — the app can't be redeployed on demand the way the web client can.

Decisions

Webhook-driven verification, not polling

Onfido KYC status updates arrive as webhooks and update participant state directly, removing the need for the client or a cron job to poll for verification results.

Push the alert to where admins already are

Routing operational alerts into Slack in real time — rather than a page they had to check — cut admin response time by 40%.

Stack

Service
Express.jsMongoDBNode-cron
Payments
RazorpayPayoutsRefunds
Identity
Onfido KYCOTP
Notifications
SendGridFirebaseWhatsApp APISMSSlack
Mobile
React NativeRazorpay SDKOnfido SDKFirebasei18nextReanimated
Web
ReactRedux
Cloud
AWS S3
Observability
New RelicWinston