# Next.js boilerplate with Stripe

> Subscriptions and one-time payments on Stripe: hosted Checkout, the customer portal, refunds that revoke access, and a signature-verified webhook with event-id idempotency. Plans live in src/lib/pricing.ts and /pricing renders with no keys.

Hosted Checkout, a customer portal you never build, and webhooks you test locally.

- **Category:** Payments
- **Pricing:** 2.9% + 30c per successful US card charge. No setup or monthly fee. Stripe Billing adds 0.7% of billing volume. Stripe Tax is extra, charged per transaction where you are registered to collect.
- **Best for:** SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept.
- **Requires:** database, auth
- **Conflicts with:** polar, dodo
- **Vendor docs:** https://docs.stripe.com/billing/subscriptions/overview

## Trade-offs

- You are the merchant of record. You owe sales tax, VAT and GST yourself. Stripe Tax calculates and files, but the liability is yours. Merchant-of-record vendors (Polar, Dodo, Lemon Squeezy) take that liability, at a higher rate.
- Webhooks are mandatory. Every subscription change reaches you asynchronously, at least once and out of order. Skip idempotency and you will double-grant entitlements in production.
- Stripe is not available in every country, and some business types are not allowed. Check both before you build.
- The API is deeper than you need on day one. The failure mode is over-modelling billing before you have ten paying customers.
- The Stripe CLI's `stripe listen` forwards real webhooks to localhost, so you test the full loop before you deploy.

## Known fixes it ships

- [Free trials in Stripe that do not leak access](https://agenticboilerplate.com/cookbook/stripe/free-trials-that-do-not-leak): trialing is an entitled status and trial_will_end is not a payment. Where trials are configured, which events actually matter, and how to stop one person taking ten trials.
- [Idempotent Stripe webhooks, or claim the event id before you do the work](https://agenticboilerplate.com/cookbook/stripe/idempotent-stripe-webhooks): Stripe delivers at least once, retries for three days and arrives out of order. An event ledger claimed before the handler runs is what stops double grants and lost updates.
- [One-time payments with Stripe Checkout, from lifetime deal to refund](https://agenticboilerplate.com/cookbook/stripe/one-time-payments-with-stripe-checkout): A lifetime deal is a payment-mode Checkout Session, not a subscription. Which id to key it on, when it is really paid, how a receipt goes out, and how a refund or dispute takes the access back.
- [Proration when a customer changes plan, and why you should let the portal do it](https://agenticboilerplate.com/cookbook/stripe/proration-when-plans-change): Upgrades, downgrades and seat changes each want different proration behaviour. What Stripe actually does, how to preview the amount, and when to build the flow yourself.
- [Reconciling after a missed Stripe webhook](https://agenticboilerplate.com/cookbook/stripe/reconciling-a-missed-webhook): A customer paid and the app does not know. How to find the gap, replay or re-sync the affected subscriptions and one-time purchases, and build a reconciliation job so the next outage is boring.
- [Stripe Tax, and when you legally need to care](https://agenticboilerplate.com/cookbook/stripe/stripe-tax-and-when-you-need-it): With Stripe you are the merchant of record, so sales tax and VAT are your liability. What Stripe Tax does and does not do, the thresholds that trigger obligations, and when a merchant of record is the better answer.

## Generate it

[Build a repo with Stripe](https://agenticboilerplate.com/build?b=stripe)

---

Agentic Boilerplate: A Next.js repo your agent already knows. Free during launch, then $99 once.

- Site map for agents: https://agenticboilerplate.com/llms.txt
- Public API: https://agenticboilerplate.com/openapi.json
- Contact: agenticstudio@gmail.com
