GarnerGuitar.com
A Stripe-powered guitar course platform
At a glance
Role
Owner-operator: design, engineering, content, and the business
Stack
- Next.js
- TypeScript
- Stripe Checkout + webhooks
- Supabase (Postgres, Auth, RLS)
- Cloudflare Stream
Overview
GarnerGuitar.com sells my guitar courses: structured video lessons with Stripe payments and gated content. Real students pay for it, which means it has to handle the messy cases a demo storefront never meets.

The pipeline
A free course (Guitar Basics) works with no account at all. Paid courses are gated server-side: getServerSideProps checks a user_purchases table before a lesson ever renders. Purchases flow through Stripe Checkout with signature-verified webhooks writing the purchase record, and duplicate-purchase guards on both ends.
Videos are served through Cloudflare Stream with short-lived, RS256-signed playback URLs, so paid content can't be hotlinked even if a page is shared.
The messy real-world case: guest checkout
People buy before they sign up. Stripe collects the email at checkout; when an account with that email is created later, the purchase is linked to it automatically. Getting this flow right, without leaking access or stranding a paid customer, was the trickiest part of the build.
What running it teaches
Running the platform end to end (design, engineering, content, and support) is a constant lesson in what actually breaks: auth sessions across SSR, webhook retries, content migrations (the platform moved from static TSX lessons to Supabase-backed Markdown), and the difference between what users say and what the purchase funnel shows.