Wiki · Devlog · Stripe & Firebase

Stripe & Firebase Integration

Archived (2026): This page documents the retired browser checkout stack. CONTRABAND now sells through Steam. The marketing site no longer runs epilogue or soundtrack purchases. The api/ folder in the repo remains as reference code, not an active store for visitors.

During the web prototype, monetization was a small-but-tricky problem: prove purchases server-side, sync entitlements across devices, and still let guests buy before creating an account. Stripe Checkout + Firebase Firestore + four Vercel Functions solved it.

Today: Steam owns commerce

Game keys, DLC, soundtrack, refunds, and regional pricing now live on Steam. This site is wiki/lore/press only — no “Buy epilogue” buttons, no Stripe return URLs on the homepage, no entitlement unlock flow for new players here.

If you are integrating payments today, start with Monetization Philosophy for product context, then read the archived technical sections below only as historical reference.

Browser-era stack (archived)

Everything below describes circa 2024–2025 behavior when /play was live. Wording is past tense on purpose.

Requirements we had to meet

SKUs included four paid epilogues ($4.99 each), a bundle ($12.99), and occasional $2.99–$2.99 cosmetics defined in api/checkout.js.

Four Vercel Functions

Total: ~280 lines of Node.js plus a shared Stripe/Firebase admin init module.

Firestore data model

Collection users (keyed by Firebase UID):

Guest-only purchases lived in guestEntitlements until link-purchase.js merged them.

Client purchase flow

  1. Player clicked “Buy epilogue” in the web game UI.
  2. Client called checkout.js with product ID + auth/guest token.
  3. Browser redirected to Stripe-hosted checkout.
  4. Webhook wrote entitlement; client polled verify-purchase.js on return.
  5. Epilogue scenes unlocked once Firestore confirmed the SKU.

Typical round-trip: 8–12 seconds (mostly Stripe UI). Server work was sub-500 ms.

Cache vs authority

localStorage cached the last server-confirmed entitlement list for offline UX. Firestore stayed authoritative — tampering with localStorage could fake UI state, not serve paid narrative payloads without a server check.

Pitfalls we hit

What still transfers

Even though Steam replaced this stack, the pattern holds for any web SKU: authoritative server ledger + client cache + never trust the browser for paid content gates. Stripe + Firebase + Vercel was cheap (<$10/mo at indie scale) and maintainable by one developer — a good fit for the browser prototype, not the final PC storefront.