Take payments
This guide wires Stripe in test mode and ends with a real checkout from your own paywall. How the money moves:
The checklist
Section titled “The checklist”Run everything from backend/functions/, after
firebase use <your-project-id>. No Stripe CLI needed. Keep the order;
the webhook must exist before the first deploy
(why).
cp .env.example .env # non-secret knobs (return URLs, trial days)firebase functions:secrets:set STRIPE_SECRET_KEY # sk_test_…pnpm seed:stripe # creates the catalog by lookup_key (idempotent)pnpm stripe:webhook # registers the webhook + stores its signing secretpnpm firebase:deploy # ONE deploy: the api function + rulespnpm doctor # verifies the whole chain, points at any fixThen point the extension at your backend in apps/extension/.env:
WXT_API_URL=https://us-central1-<project>.cloudfunctions.net/apiVITE_PREMIUM=trueRestart pnpm dev and reload the extension.
Verify: the popup flips to premium
Section titled “Verify: the popup flips to premium”- In the popup, trigger the paywall (the Try a premium feature demo button, or your own gated feature).
- Click the wall’s upgrade button. Stripe Checkout opens in a tab.
- Pay with the test card
4242 4242 4242 4242(any future expiry/CVC). - Back in the popup: the wall clears and the Account tab shows your plan, no reload needed. The webhook recorded your payment server-side and the extension picked it up.
If anything is red, pnpm doctor names the broken link in the chain.
Deeper checks (Firestore docs, webhook deliveries, emulator loop):
Payments guide.
To sell a credit allowance with top-up packs instead, enable the credits model: same setup, plus metering.
Next: 4. Build your feature.