pealdevDOCS
Back to peal.dev

STRIPE STARTER · OVERVIEW

Overview

Stripe is the easy bit — until you wire the webhook for the third time. This template ends that loop.

Here's the honest pitch: every Stripe integration starts the same way. Read the docs, copy the quickstart, build a card form, hit a webhook signature bug on day three, redo it. We got tired of repeating that loop — so we wired Stripe Checkout the way we'd wire it for our own apps and made it the template we wish existed when we started.

This is NOT a "build your own card form" template. Stripe Checkout is the page Stripe maintains — taxes, addresses, Apple Pay, 3D Secure, every payment method, every edge case Stripe ships. You send a price ID, you get a URL, you redirect. The complexity is in the webhook handler — and we've already written its skeleton with signed events and typed stubs for the four events you actually care about.

What's wired in

  • Hosted Stripe Checkout — one-time, subscription, or both via one config flag.
  • Webhook handler — signature verification, mode-aware event filtering, typed stubs for 4 events.
  • Customer Portal — toggle on, point at a Customer ID, Stripe handles cancel/upgrade/invoices.
  • Server Actions for everything (createCheckoutSession, createPortalSession). No bespoke API routes.
  • Pricing UI — PricingTable adapts to your payment mode. Monthly/yearly toggle, savings calc, highlighted plan.
  • Zod validation on every external input. Open-redirect prevention on portal return paths.
  • Rate limiting via Upstash Redis. Graceful no-op when Upstash isn't configured.
  • Type-safe env via T3 Env + Zod. Refuses to boot with a typo or a pk_ where sk_ belongs.
  • Success page that fetches the session server-side, renders line items, totals, billing interval.
  • Test suite — 70 unit tests + 5 Playwright E2E specs. CI-ready.

What this template is NOT

  • It's not a SaaS-in-a-box. No auth, no database, no user accounts. Stripe is the source of truth here — wire it into whatever auth/DB you bring.
  • It's not Stripe Connect. This is for selling YOUR product. Marketplaces need a different template.
  • It's not Stripe Elements. We use hosted Checkout — Stripe.js is preloaded for the day you need Elements, but the default flow is a redirect.
  • It's not a billing engine. Stripe handles plan changes, proration, taxes, invoices. The template just wires the calls and listens to the events.

How these docs are written

Founder voice, on purpose. Anything marked "the bug we hit" cost us an evening. Anything marked danger will cost you one if you ignore it. Anything marked tip is a shortcut we wish we'd known sooner.