Build SaaS Billing + Tax Core on nextjs-prisma-postgres

Production Stripe Billing core for a seat-based SaaS — plans, seats, proration, dunning, idempotent webhooks, Stripe Tax, invoices, customer portal — as a receipt-backed build pack for your own coding agent.

This build pack is pinned for nextjs-prisma-postgres, with verification pending. No pass rate is published until the harness runs it.

Coming soon — $149

nextjs-prisma-postgres versions lock

node24.18.1
next16.2.12
react19.2.8
react-dom19.2.8
stripe22.3.0
stripe-api-version2026-06-24.dahlia
prisma7.9.1
@prisma/client7.9.1
@prisma/adapter-pg7.9.1
typescript5.9.3
vitest4.1.10
tailwindcss4.3.3
@tailwindcss/postcss4.3.3
shadcn4.13.1
tailwind-merge3.6.0
clsx2.1.1
class-variance-authority0.7.1
@types/node24.3.0
@types/react19.2.2
@types/react-dom19.2.2
postgres17.10

What you get

A running Next.js service that is the complete billing spine of a seat-based B2B SaaS, with Stripe as the system of record.

**Features**

  • Plan catalog (flat + per-seat tiers), synced to Stripe Products/Prices by an idempotent setup script keyed on `lookup_key` — no hardcoded price IDs anywhere.
  • Subscribe via hosted Stripe Checkout with Stripe Tax: automatic tax calculation, B2B tax-ID collection (reverse charge), required billing address.
  • Seats: add seats now (prorated, charged immediately), remove seats at renewal (never mid-cycle refunds), guarded against dropping below seats in use or above plan max.
  • Plan changes: upgrades apply and invoice immediately (`always_invoice`, payment failure blocks the upgrade); downgrades apply at period end via a two-phase subscription schedule.
  • Dunning: webhook-driven billing state machine with a 14-day read-only grace window computed at request time — no cron, no drift; Stripe Smart Retries does payment recovery.
  • Webhooks: signature-verified, DB-enforced idempotent, out-of-order-safe processor for a deliberately minimal event set — including churn-and-return (a returning customer's new subscription cleanly replaces the canceled one). Honest limit: Stripe's `event.created` has 1-second resolution, so two distinct events inside the same second apply last-writer-wins; a same-second inversion cannot corrupt Stripe (the local row is a display/entitlement cache) and self-heals on the next subscription event.
  • Invoices: history from Stripe with hosted PDF links (nothing stored locally).
  • Customer portal: payment-method update, invoice history, cancel-at-period-end — plan switching deliberately disabled so your proration policy stays enforced in code.
  • Acceptance suite + `verify.sh`: 16 receipt-grade checks (including network-free behavior probes of every billing route), exit 0 = correct build.
  • Ops runbook for everything code can't do: Smart Retries settings, tax registrations, webhook endpoint, live smoke test.

**Screens / surfaces**

  • `/billing` — plan, seat count with change controls, billing-state banner (active / read-only grace / blocked), invoice list, portal button (Tailwind 4 + shadcn/ui, pinned).
  • Stripe-hosted Checkout (tax, tax IDs, addresses handled by Stripe).
  • Stripe-hosted customer portal (restricted feature set).
  • API: `POST /api/billing/{checkout,plan,seats,portal}`, `GET /api/billing/invoices`, `POST /api/stripe/webhook`.

Prescribed services

Disclosure: some links on this page are affiliate links. We may earn a commission if you sign up through them, at no extra cost to you. We only link to services the pack actually verified against.