Summary: Subscription billing runs through Chargebee, with completely separate configurations (namespaces and API keys) for the 7Mind and 7Sleep products, managed by the monetization domain in elixir-backend. Sources: direct code inspection (config/runtime/prod.ex, lib/backend/monetization/, mix.exs — ex_chargebee 0.3.1) Last updated: 2026-05-15


Setup

Chargebee is the primary subscription and billing provider. The backend uses the ex_chargebee Elixir library (v0.3.1).

Two completely separate Chargebee accounts (namespaces) exist — one per brand:

BrandEnv var
7MindSEVENMIND_CHARGEBEE_NAMESPACE, SEVENMIND_CHARGEBEE_API_KEY
7SleepSLEEP_CHARGEBEE_NAMESPACE, SLEEP_CHARGEBEE_API_KEY

A “namespace” in Chargebee is the subdomain of the API endpoint (e.g., sevenmind.chargebee.com). Having separate namespaces means subscriptions, customers, plans, and billing events are fully isolated between brands at the Chargebee level.

Legacy providers

The monetization domain also integrates with:

  • Fastspring — legacy billing system, now only accessible via admin panel (FASTSPRING_ADMIN_PANEL)
  • Barmer — German health insurer integration (likely B2B2C provisioning)
  • Mondia — carrier billing integration

Coupon and gift flows

Based on domain naming in the CLAUDE.md documentation, the monetization domain handles coupons, trials, and gifts in addition to standard subscriptions.

ZPP / Prevention relationship

Insurance-related billing (ZPP certificates for German health insurance reimbursement) is handled by the prevention domain, not monetization. The two domains are separate. Prevention owns the PDF certificate generation and Cloud Storage upload; monetization owns the payment collection.

What agents should know

  • Always confirm which brand’s Chargebee account a change targets. The env vars and configurations are parallel, not shared.
  • Webhook events from Chargebee arrive as external events and should be processed through the event bus pattern — do not add direct Chargebee webhook handlers outside the monetization domain.
  • Fastspring is legacy. No new integrations should be built against it.
  • The monetization domain has its own database (BACKEND_MONETIZATION_DATABASE_URL). Subscription state lives there, not in the user identity database.

From 7mind-mobile-apps-monorepo

The Flutter app uses the official chargebee_flutter 0.4.8 SDK to interact with Chargebee directly from the device (subscription state, checkout, restoration). Server-side, elixir-backend uses the Elixir ex_chargebee 0.3.1 library. The two halves communicate through Chargebee, not directly:

  • Mobile collects payment and initiates the subscription via Chargebee SDK
  • Chargebee fires webhooks to the backend; the monetization domain processes them through the event bus pattern
  • Subscription state on the device should not be trusted as authoritative; always confirm against the backend on launch

The Flutter monorepo ships only the 7Mind brand, so it only carries the SevenMind Chargebee config — there is no 7Sleep flavor in this codebase (see dual-brand-routing for the brand split).

From nuxt-website

The web frontend integrates Chargebee via the chargebee npm package and a custom ChargebeeDialog.vue checkout component. Per-brand configuration is exposed at runtime through:

  • NUXT_ENV_CHARGEBEE_ID — the Chargebee site (namespace) the JS client opens. Prod: 7mind (7mind brand) / 7sleep (7sleep brand). Staging: 7mind-test / 7sleep-test.
  • NUXT_ENV_CHARGEBEE_API_KEY and NUXT_ENV_CHARGEBEE_API_KEY_7SLEEP_{LIVE,STAGING} — API keys used by checkout flows.

The web does not talk to the backend’s ex_chargebee directly. Instead it (a) opens the hosted Chargebee checkout via the JS SDK and (b) calls backend API routes for portal sessions and gift/coupon flows. Relevant backend endpoints (from config/routes.js):

  • POST /monetization/chargebee/self_serve_portal/session — creates the Chargebee customer portal session for the logged-in user
  • POST /monetization/coupon/resolve — coupon validation
  • POST /monetization/gift/claim — gift redemption
  • GET /monetization/subscriptions/status — subscription state probe

Legacy Fastspring is still surfaced via NUXT_ENV_FASTSPRING_STOREFRONT and pages/payments.vue; new checkout work goes to Chargebee.