Skip to content
Get the kit

Stripe

Stripe is the kit’s default payment provider. You are the merchant of record, which means the most control and the most reach; sales tax is your responsibility (Stripe Tax can automate it, BILLING_AUTOMATIC_TAX).

Setup, step 7 has the six commands, in order. No Stripe CLI is needed; the scripts drive the Stripe API. The webhook must exist before the first deploy binds its secret.

One command runs all of them in order, asking for the key without echoing it, and stops with that same command when the key or the Blaze plan is missing:

Terminal window
pnpm create extstart --payments-setup
  • seed:stripe creates the catalog by lookup key: premium_monthly, premium_yearly, premium_lifetime, premium_metered_monthly, and the packs credits_pack_small / credits_pack_large. Change amounts freely in the Stripe dashboard; the backend resolves by lookup_key only. The keys must match site.config.ts → pricing.plans.
  • stripe:webhook registers …/api/billing/webhook with the events the backend handles and stores the signing secret. Rerunning is a safe no-op.
  • firebase:deploy is the one deploy: the API function, the Firestore rules, and the Hosting pages (checkout success, cancel, and portal return pages, the sign-in fallback, and the uninstall survey), all from backend/firebase-hosting/public.
  • doctor checks project, secrets, deployed API, webhook, and seeded prices, and points at the fix for anything red. Run it whenever billing misbehaves.

Non-secret configuration lives in backend/functions/.env: BILLING_SUCCESS_URL, BILLING_CANCEL_URL, BILLING_PORTAL_RETURN_URL, BILLING_TRIAL_DAYS, BILLING_AUTOMATIC_TAX, BILLING_ALLOW_PROMO_CODES. Keep BILLING_TRIAL_DAYS in sync with site.config.ts → pricing.trialDays; the CTA advertises one number, Stripe enforces the other, and pnpm doctor flags a mismatch.

4242 4242 4242 4242 (success), 4000 0000 0000 9995 (declined), 4000 0027 6000 3184 (3DS challenge). Any future expiry/CVC.

backend/functions/.secret.local
STRIPE_SECRET_KEY=sk_test_…
STRIPE_WEBHOOK_SECRET=whsec_… # printed by `pnpm stripe:listen` on start
Terminal window
pnpm serve
pnpm stripe:listen

serve starts the functions, Firestore, and auth emulators; stripe:listen forwards test-mode events to the emulated webhook.

Point WXT_API_URL at http://127.0.0.1:5001/<project>/us-central1/api while testing locally. Prefer real Checkout sessions with test cards over stripe trigger; they exercise the uid-metadata path end to end.