Test mode— use card 4242 4242 4242 4242, any future date, any CVC. No real money moves.

Inkwell
PricingDashboardLedger
Next.js 16 + Stripe Billing9 webhook event types, all replay-safe

Write without limits.Bill without surprises.

Inkwell is a fictional writing app used to demonstrate subscription billing done correctly: a 14-day trial, monthly and yearly plans with a proration preview, the customer portal, dunning, and a metered AI-credits add-on.

See pricing

One click creates a throwaway demo account. No password, no email — nothing real is charged.

What this demonstrates

For engineers reviewing the code: the interesting parts are the ones you don't see in the UI.

Replay-safe webhooks

Every event id is inserted into a ledger with a unique primary key before any work happens. A redelivery hits the conflict and returns 200 — no double upserts, no double emails.

INSERT … ON CONFLICT

Fresh state, not payloads

Subscription events trigger subscriptions.retrieve and an upsert from that snapshot, so out-of-order delivery is harmless. Side effects run after the response, guarded once-per-key.

after()

DB-first entitlement

Stripe owns the money; our database owns access. Every page and route asks getEntitlement(userId), which never calls Stripe in the request path.

getEntitlement

Verified with test clocks

A script creates a Stripe test clock, starts a 14-day trial, fast-forwards past it and replays every resulting event twice — for a good card and a failing one.

testHelpers.testClocks

Proration preview

Switching between monthly and yearly shows the exact invoice Stripe would create via invoices.createPreview, then applies it with the same proration date.

createPreview

Metered add-on

AI credits are reported to a Stripe Billing Meter with an idempotency identifier stored locally first, so a retried request never bills twice.

billing.meterEvents
Read the source on GitHub →Inspect the webhook ledger →