Free through lesson 3

Intro to Stripe Payments & Subscriptions

From a design that never stores card data yourself, through Customer, Price, and Checkout, Webhook signature verification and idempotency, failed payments and cancellations, all the way to switching to live mode and reconciling revenue. Across 30 lessons you'll get to the point where you never trust the page you're redirected back to and keep billing state correct through Webhooks alone. All code and test results were run for real against Django 6.1.1, stripe 15.6.1, and Stripe's own stripe-mock — no real keys or billing account required.

Curriculum

The 30 lessons are split into 6 chapters. We recommend working through them in order starting from Chapter 1, but feel free to skim just the parts you're curious about. * Django and stripe-python can't run in the browser, so try them in your local virtual environment with stripe-mock. Parts that only need the standard library, like computing a signature or checking a key, can run right there in the browser.

Chapter 1 — The Big Picture of Payments (lessons 1–5)

Start by committing to a design that never stores card data yourself, then learn the difference between test and live mode and the four core objects: Customer, Product, Price, and Subscription. We finish by building a lookup that maps a subscription's price back to a plan on your own site.

Chapter 2 — Getting a Signup Through (lessons 6–11)

Define your own plans along two axes, rank and video, link your users to Stripe customers by ID, and send them to the payment screen through a Checkout Session. We finish by nailing down exactly who paid using client_reference_id.

Chapter 3 — Receiving State via Webhook (lessons 12–18)

Start with why you should never trust the page redirect and instead rely on Webhooks alone, then nail down signature verification, rejecting tampering and replays, idempotency, and handling retries one by one. We finish by using stripe listen to receive notifications locally before going live.

12

Why You Shouldn't Trust the Page Redirect

Two success_url weaknesses: it may never fire, and anyone can hit that URL. A test confirming the plan stays free there and flips to basic only once the Webhook arrives — updates go only via Webhooks.

🔒 Basic
13

Verify a Webhook's Signature

What's in the Stripe-Signature header (t, v1=HMAC-SHA256), and how "t.body" is what's signed. Verifying via construct_event, returning 200 for a valid signature, and never reconstructing the body.

🔒 Basic
14

Reject a Failed Signature Check with 400

Verification rejects a missing header, bad secret, or tampered body with a 400 or exception. Why this stops forged calls from rewriting a plan, and three spots to check if 400s persist in production.

🔒 Basic
15

Timestamp Tolerance and Replay Protection

A replay attack resending an old, valid notification, and how its signature timestamp stops it. The default 300-second tolerance, injecting a test timestamp, not waiting, and watching for clock drift.

🔒 Basic
16

Prevent Double-Processing the Same Notification with Idempotency

Build idempotency assuming Stripe will resend the same notification. Record each event.id in ProcessedEvent and skip repeats as duplicates, and what double-applying an update looks like without it.

🔒 Basic
17

Return 500 to Trigger a Retry, 200 ignored for Events You Skip

What a Webhook's response code means. Return 500 on a failed update so Stripe retries, and 200 with "ignored" for events you skip, and the mistake of swallowing a failure and still returning 200.

🔒 Basic
18

Receive Notifications Locally with stripe listen

Relaying Webhooks that can't reach localhost via the Stripe CLI's stripe listen. How the whsec listen prints differs from the dashboard's, testing via stripe trigger, and the six events received.

🔒 Basic

Chapter 4 — Handling a Subscription's Lifecycle (lessons 19–23)

Reflect every stage of a subscription — starting, upgrading, scheduling a cancellation, a failed payment going past_due, and reverting to free on cancellation — as each Webhook arrives. We finish by opening up the customer portal so users can handle cancellations and changes themselves.

Chapter 5 — Around the Edges of the Job (lessons 24–27)

Cover the practical work that always surrounds billing: coupons and discounts, reading the end of the current period from an invoice, a separate track for business customers, and the disclosures required under Japan's Specified Commercial Transactions Act. We finish by building a mechanical check that catches any missing required disclosure.

Chapter 6 — Going to Production (lessons 28–30)

Mechanically check your switch from test to live mode, and settle on key management and what to do if a key leaks. We close out the course by treating Stripe as the source of truth and catching drift against your own site's plans through revenue reconciliation.

Once you finish all 30 lessons, move on to Shipping and Running a Service, where you'll take your now-billable service live and keep it running. All courses unlock with a membership.