Case study
live
TutorTab
A Stripe Connect platform where independent tutors accept their own payments and parents run autopay across every tutor. Magic-link sign-in, two-way Google Calendar sync, an automated reminder cascade, and the same engine white-labeled as TrainerTab for personal trainers.
The problem
Independent tutors want to take money, keep their calendars synced, and stop chasing invoices, but wiring Stripe, Google Calendar, autopay, reminders, and a self-serve profile is a stack of projects on its own. Parents, meanwhile, want one account that handles autopay across every tutor they work with instead of a collection of payment links.
What I did
- 01
Set up other people to accept money: a real Stripe Connect platform
The payment layer is a platform: each tutor is onboarded as a payment-accepting sub-merchant. Stripe Connect Express handles KYC and payouts, destination charges route session fees directly to the tutor, and platform-fee caps enforce per-invoice and per-month limits so the platform never over-takes. Idempotency keys on every autopay, double-payment prevention against existing PaymentIntents, autopay-to-manual fallback on failure, and full chargeback handling with auto-block after 5 lost disputes in 6 months.
- 02
Two-way Google Calendar sync that doesn't eat itself
Webhook endpoint plus incremental sync via syncToken, with detection of platform-managed events to avoid echo loops. Sync failures escalate through immediate → 24h → 48h → 7d deactivation. Student-name parsing from event titles and returning-parent pre-fill on the public booking page.
- 03
Automated invoicing, reminders, and autopay collection
Invoices generate from completed sessions; payment reminders cascade through five escalating tiers (day 1/3/7/14/28). Parents on autopay get charged automatically; failures fall back to manual with email notification. Pre-session reminders at 24h and 1h are deduped via a notifications collection so nobody gets double-pinged. Eleven cron jobs handle the recurring collection work.
- 04
One login for parents, one for tutors, one codebase
Parents magic-link in; tutors use Google OAuth. A single auth layer routes to the right dashboard via role auto-detection, so families with multiple tutors manage everything from one place. Refresh tokens are AES-256-GCM encrypted at rest with a transparent migration path. The age gate stores only `isOver18`, never raw DOB.
- 05
Self-serve booking-page CMS for each tutor
Tutors edit their public profile, subjects, rates, availability, and booking page without touching code or filing a support ticket. Content changes propagate immediately to a fast, shareable booking page that tutors hand to new parents.
- 06
White-labeled the same engine as TrainerTab for personal trainers
The same codebase powers TrainerTab at trainertab.net, a white-label version for independent personal trainers. Tenant branding, domain, and copy flip via config; the Stripe Connect onboarding, calendar sync, autopay, and booking-page CMS are shared. Fixes land in both products at once.
The outcome
TutorTab runs as a true Stripe Connect platform: tutors accept their own payments, parents run autopay across every tutor they work with, calendars stay in sync, and invoices collect themselves. The same engine also powers TrainerTab for independent personal trainers under a separate brand. The platform takes 2.5% (capped) on top of Stripe fees, so sellers keep the session price they quoted.
Under the hood
Next.js 16 + TypeScript + MongoDB + NextAuth, with Stripe Connect Express, the Google Calendar API, Brevo for transactional mail, and node-cron for the eleven scheduled jobs. CSRF via Origin/Referer middleware, input sanitization on every public route, and ~430 tests across Vitest and Playwright keeping the production payment flows honest.