Your Cart
Loading

Stripe Checkout + Webhook Starter — Node/TypeScript, Exactly-Once Fulfillment

On Sale
$29.00
$29.00
Added to cart

A tested Node/TypeScript + Express starter that takes payments with Stripe Checkout, verifies webhooks, and delivers each order exactly once.


Most Stripe tutorials stop at "payment succeeded". The hard part is everything after: verifying webhook signatures on the raw body, handling retries and duplicate events, waiting for delayed payments, and making sure each buyer gets exactly one delivery email.


This starter handles all of that in a small, readable TypeScript codebase you can understand in 20 minutes. Clone it, paste in your test keys, run `stripe listen`, and you'll see a full purchase, from checkout to download email, on your machine. Then deploy it to any Node host.


Features:

- Stripe Checkout Session creation (303 redirect for forms, or JSON for SPAs)

- Webhook signature verification on the raw request body

- Idempotent fulfillment keyed on the Checkout Session ID: no double emails on retries or duplicate events

- Correct handling of delayed payments (`async_payment_succeeded`)

- Failed deliveries release the lock and return 500, so Stripe retries automatically

- Pluggable email providers: console (dev) and Resend (prod), with an interface for adding Postmark, SES, SendGrid and others

- Swappable idempotency store (memory and JSON file built in; Redis/Postgres recipe in the README)

- 14 unit tests (Vitest + Supertest) with a mocked Stripe client, so they need no network or keys

- Strict TypeScript, dependency-injected app factory, about 300 lines of source


What you get:

- Full source code (TypeScript, Express 4, official `stripe` SDK)

- Test suite and `.env.example`

- A detailed README covering setup, every env var, step-by-step Stripe CLI test-mode walkthrough, production deploy, and customization recipes (subscriptions, multiple products, license keys)

- MIT license, for unlimited personal and commercial projects

- Instant download (.zip)

You will get a ZIP (38KB) file