Early Bird50% off SaaS Starter Kit — only for the first 100 buildersGrab it →
pealdev
Templates
BlogRoadmapOur StoryChangelogUI Kit
Get Started
pealdev

Premium Next.js templates built by two developers who actually use them in production.

TemplatesBlogOur StoryChangelogNewsletter

Dev stories, new templates, zero spam.

Subscribe →
Earn 20% — become a partnerJoin the community
Custom Development
Schedule a meeting →

Can't find what you need? We'll build it.

Custom features, weird integrations, full apps from scratch — we've done it all. Fair warning: we're not cheap, but we're fast, we don't ghost, and the code actually works in production. Shocking, we know.

Next.js & ReactAPI IntegrationsFull-stack AppsAuth & PaymentsDatabasesDeployment
Terms of ServicePrivacy PolicyRefund PolicyLicensing
© 2026 peal.dev. All rights reserved.
Built with caffeine not even jokingsomewhere around coffee #347 we said "let's start counting." we never did.if peal saved you a late night or two, you could fuel our next one buy us a coffeeMade in Romania yep, Romanialand of fast internet, Dracula's castle, and developers who ship at 3am because the mountains outside the window are too pretty to sleep through.seriously though — come visit sometime. the food alone is worth the flight Listen to this
All templates
Payments

Stripe Checkout Starter

Products, pricing page, checkout sessions, webhooks, and customer portal. Payments wired up so you don't have to read the Stripe docs for the 47th time.

50% off — early bird pricing

Limited

First 100 customers get 50% off. Only available at launch.

81/100 claimed
A
M
J
S
R

14 people purchased in the last 24h

Built with

Next.jsTypeScriptTailwindStripeESLint
Ștefan

Ștefan walks you through it

Honest breakdown — no marketing fluff

Stop building payment flows from scratch.

A production-ready Next.js 16 template that handles Stripe payments so you can focus on what actually makes your product unique. One-time purchases, subscriptions, or both — configured in a single file.


The Problem

You've got a great idea for a SaaS, a digital product, or a paid tool. You pick Next.js. You pick Stripe. And then you spend the next two weeks:

  • Reading Stripe docs at 2 AM trying to figure out webhook signatures
  • Debugging why checkout.session.completed fires but your success page shows nothing
  • Googling "stripe customer portal nextjs app router" for the 15th time
  • Wondering if your webhook handler is actually secure or just looks secure
  • Writing the same pricing card component you've written in every project since 2021

By the time payments work, your motivation is gone and your launch date is a memory.

We've been there. Multiple times. So we built this once — properly — and never looked back.


What You Get

One config file controls everything

// payments.config.ts — that's it, that's the whole decision
const config = {
  mode: "subscription",  // or "one-time" or "hybrid"
  customerPortal: { enabled: true },
  redirects: {
    success: "/checkout/success",
    cancel: "/checkout/cancel",
  },
}

Change mode and the entire app adapts — webhook events, UI components, checkout parameters. No hunting through 15 files to switch from subscriptions to one-time payments.

Not a tutorial project

This isn't a "build a Stripe integration in 10 minutes" blog post turned into a repo. This is what we actually use. That means:

  • TypeScript strict mode — zero any, noUncheckedIndexedAccess enabled. Your IDE will catch bugs before your users do.
  • ESLint with strictTypeChecked — zero warnings. Not "we disabled the rules that were annoying."
  • Zod validation on every input — form data, URL params, webhook headers. If it comes from outside, it gets validated.
  • Webhook signature verification — not optional, not a TODO comment. It's there and it works.
  • Rate limiting — Upstash Redis sliding window on checkout creation. Because someone will try to spam your checkout endpoint.
  • CSP + HSTS headers — with Stripe domains whitelisted. Not just "we'll add security headers later."

The boring stuff, done right

Nobody gets excited about error boundaries. But your users will notice when your app shows a blank white screen instead of a helpful error message.

  • Error boundaries on every route segment — global, marketing, checkout
  • Skeleton loading states on every page — not a spinner, actual layout-matching skeletons
  • Custom 404 page — with navigation back to useful pages
  • Inline error messages on checkout buttons — rate limit hit? Stripe error? The user sees exactly what happened

70 tests. Yes, for a template.

  • Vitest unit tests covering validation schemas, pricing logic, Stripe helpers, and utility functions
  • Playwright E2E tests covering the pricing page, checkout flow, success page, cancel page, and 404
  • Not because we wanted a badge in the README (ok, partly), but because when you change the pricing config at 11 PM before launch, you want to know nothing broke

Webhook handlers ready to implement

Four event handlers with typed parameters, JSDoc comments, and TODO markers exactly where your logic goes:

  • onCheckoutSessionCompleted — provision access, send confirmation
  • onInvoicePaid — extend access on renewal
  • onSubscriptionUpdated — handle plan changes, detect cancellation intent
  • onSubscriptionDeleted — revoke access when the period ends

The customer ID is already extracted. The subscription ID is already extracted. You just add your database call.


The Stack

Next.js 16 (App Router) · TypeScript (strict) · Tailwind CSS 4 · shadcn/ui · Stripe SDK v20 · Zod · Vitest · Playwright

No experimental packages. No beta APIs. Nothing that will break in a month.


What's NOT included (on purpose)

  • No database — Stripe is your source of truth. Add Prisma/Drizzle/whatever when you need it.
  • No auth — Add NextAuth/Clerk/Lucia when you're ready. The webhook handlers have a clear spot for connecting auth to Stripe customers.
  • No email service — The TODO comments tell you exactly where to send emails. Pick Resend, Postmark, whatever you like.

This is a payments template, not a full-stack boilerplate. It does one thing and does it well. You bring the rest.


How fast can you launch?

  1. Clone the repo
  2. Add your Stripe keys
  3. Replace the placeholder price IDs with yours
  4. Implement the webhook handlers (database writes, emails)
  5. Deploy to Vercel

Steps 1-3 take about 5 minutes. Step 4 depends on your business logic, not on figuring out Stripe. Step 5 is one click.


"But I can just follow the Stripe docs..."

You absolutely can. And in about 20-30 hours you'll have something similar — if you remember to:

  • Handle the case where session.customer is an expanded object, not a string
  • Validate the returnPath parameter against open redirect attacks
  • Mock the @t3-oss/env-nextjs module in tests because it validates env vars at import time
  • Add overflow-visible to the pricing card so the "Most Popular" badge doesn't get clipped
  • Use safeParse instead of parse for Zod validation in Server Actions so errors don't crash the server
  • Check cancel_at_period_end in subscription updates, not just subscription deletions
  • Rate limit by IP using x-forwarded-for with proper fallback for when there's no proxy

We already made every one of these mistakes so you don't have to.


What people usually ask

Can I use this for just one-time payments? Yes. Set mode: "one-time" and you're done. Subscription UI and webhook handlers are automatically disabled.

Do I need Upstash for rate limiting? No. Rate limiting is optional. Without the Upstash env vars, the app works fine — Stripe has its own API rate limits as a fallback.

Can I use pnpm/npm instead of bun? Yes. Delete bun.lock, run your preferred install command. Nothing in the code is bun-specific.

Is this a one-time purchase or a subscription? Ironic question for a Stripe checkout template, but: one-time purchase. Buy it, own it, use it forever.

Do you provide support? Yes. We actually use this template ourselves, so any bug you find is a bug we want fixed too.


Built by Peal.dev

We're Robert and Stefan. We build tools for developers who'd rather ship their product than fight with payment integrations.

This template exists because we got tired of rebuilding the same Stripe setup for every new project. Now we don't. And neither do you.

What's included

Everything you need to go from zero to production.

Yours forever

One payment. No subscriptions, no renewals. Use it on every personal project you ever build.

A real repo, not a zip

Full git history, proper branches, and the ability to pull updates. The way code should be shared.

Built for production

We run these in our own apps. Every edge case has been caught, every handler stress-tested.

Updates on us

When we improve something, you get it for free. Just pull the latest changes.

Crafted by two developers who care about code quality

No startup hype, no investor money — just clean code we'd use in our own apps. Curious who we are? Read our story (it's fun).

Stripe Checkout Starter

Payments

$50$99

Skip the 2 weeks of wiring auth, webhooks, and email from scratch. This is the exact setup we use in production — tested, typed, and ready to go.

Sign in to purchase — we'll use your GitHub for repo access

Yours forever

One payment, no subscriptions

Full source code

Real git repo, not a zip file

Free updates

We improve it, you get it

Secure payment by Stripe

0 commits pushed to the repo

Last updated June 9, 2026

0 open issues — yay!

Live from GitHub
Robert

“We got mass-tired of copy-pasting the same Stripe webhook handler into every new project, so we packaged it properly. This is the exact code running in our own apps — not a tutorial, not a demo. Just the thing we wished existed when we started.”

Robert, co-founder

Real people, real support. No ticket queue — you email us, we answer. Usually the same day.

We use this ourselves. Every bug fix and improvement we make for our own apps, you get for free.

No subscriptions, ever. Pay once, own it forever. We don't believe in renting code.

Robert
Ștefan

Built by Robert & Ștefan

Read our story (it's fun) →

5.0from early adopters
100%Production ready
<5 minSetup time
0Refund requests

We don't have thousands of customers yet — we have a handful who actually use this in production and keep coming back for more.