Stripe
Stripe is the kit’s default payment provider. To have Polar take payments instead, as merchant of record, see its page.
Without Stripe keys the kit runs with billing off: everyone is on the free plan. This page connects Stripe. To decide what you sell and gate features by plan, see Charge for a feature.
Connect it on your machine
Section titled “Connect it on your machine”You need a Stripe account and the Stripe CLI.
-
Put your test secret key from the dashboard in
.env:Terminal window STRIPE_SECRET_KEY=sk_test_... -
Stripe cannot reach your machine, so forward its webhooks. Leave this running:
Terminal window bun run billing:listenIt prints a signing secret. Put it in
.envasSTRIPE_WEBHOOK_SECRET=whsec_.... The API refuses to start with the key and without this. -
Create your plans in Stripe:
Terminal window bun run billing:syncIt creates a product per paid plan with a price per interval, and for each meter a plan charges for, a meter and a metered price. Run it again whenever you change
PLANS. -
Restart
bun dev, open Settings → Billing and upgrade with the card4242 4242 4242 4242, any future date and any CVC.
The plan changes a moment after you return from Stripe, when the webhook arrives. If it
does not, billing:listen is not running. The receipt lands in
Mailpit.
Go live
Section titled “Go live”- In Stripe’s live mode, copy your live secret key.
- Add a webhook endpoint for
https://<your domain>/api/billing/webhookwith these events:checkout.session.completed- every
customer.subscription.*event invoice.paid, which sends receipts
- Set
STRIPE_SECRET_KEYto the live key andSTRIPE_WEBHOOK_SECRETto that endpoint’s signing secret in production. A secret from test mode, or from the CLI, will not verify. - Run
bun run billing:synconce with the live key in your environment. - Turn on the customer portal and allow plan changes. People change plan, update their card and cancel there.
- Buy a plan on the live site with a real card, change it, and cancel it.
Step 6 is the one that proves your own setup: your keys, your webhook and your prices together. Do it before you announce.
The units beyond a plan’s allowance are sent as meter events and appear on the next invoice, as a second line beside the plan’s. Stripe’s dashboard shows each customer’s events under Billing → Meters. Events can be sent up to 35 days late, so a day of retries loses nothing. How usage works: Charge for usage.
Changing a price
Section titled “Changing a price”Stripe prices cannot be edited. billing:sync creates a new price and archives the old
one. New subscriptions get the new price; people already subscribed keep paying the old one
until you move them in Stripe.
If something does not work, see Troubleshooting.