Edit Page

restheart-stripe

RESTHeart
Note

restheart-stripe is available starting from RESTHeart v9.8.

restheart-stripe adds Stripe billing to any RESTHeart deployment. It supports two independent modes:

  • Subscriptions — recurring plans, seat licensing, Customer Portal

  • Products — one-time purchases, cart checkout, order ledger

Either mode can be enabled alone, or both together. They share credentials, webhook endpoint and the same stripeConfig block.

Architecture

flowchart LR
  subgraph Clients
    B[Browser / Mobile]
  end

  subgraph RS[restheart-stripe]
    direction TB
    SUB["Subscriptions\n/stripe/checkout  /stripe/portal\n/stripe/subscription  /stripe/plans\n/stripe/licenses"]
    PROD["Products\nPOST /orders\nGET /orders\nGET /catalog"]
    WH["/stripe/webhook"]
    ACL["@subscription ACL variable"]
  end

  subgraph Storage
    M[(MongoDB\nteams + orders + catalog)]
    E[Email\nemails module]
  end

  S[Stripe]

  B -- HTTP + JWT --> RS
  RS -- SDK calls --> S
  S -- signed webhooks --> WH
  SUB --> ACL
  RS --> M
  RS --> E

Subscriptions mode

Manages recurring billing backed by a configurable plan catalog.

Plans and seats — define plans with monthly/annual prices, seat caps or per-seat pricing, and optional limits. See Plans & Seats.

Endpoints — /stripe/checkout, /stripe/portal, /stripe/subscription, /stripe/plans, /stripe/licenses. Each is a separately enabled plugin.

Plan gating — the caller’s subscription state is exposed to ACL rules as @subscription. See Plan Gates.

Billing entity — by default the restheart-accounts team, from the JWT team claim. Replaceable via the SubscriptionOwnerProvider SPI.

See Subscription Lifecycle for the full flow.

Products mode

Sells one-time purchases through Stripe Checkout.

No custom endpoints — orders and catalog are ordinary MongoDB collections served by RESTHeart’s API. The module adds interceptors and webhook handlers.

How it works — the client sends product ids and quantities; the server resolves prices from the catalog collection, creates a Stripe Checkout session, and records the order. The client never sends a price.

Billing entity — always the team from the JWT. Only team owners can purchase.

See Products & Orders for the full details.

Webhooks

Both modes share a single webhook endpoint: /stripe/webhook.

Stripe delivers all events for an account to one URL. The module verifies the signature and dispatches to the appropriate handler (subscription or order).

See Webhooks.

Security

Authenticated endpoints — all endpoints except /stripe/webhook require authentication and follow your deployment’s ACL.

Subscriptions — checkout, portal and licence operations are gated on canManageBilling (team owner by default). Any member can read subscription state.

Products — only team owners can purchase. Order visibility is ACL-controlled.

Webhook — public by construction. Security is signature verification, not authentication.

Multi-tenancy

Every configuration value can be overridden per request, so a single RESTHeart instance can serve many tenants with different Stripe accounts, plan catalogs and databases.

The module never sets the Stripe API key globally: the effective key is passed explicitly to each SDK call, which is what makes per-tenant secret keys safe under concurrency.

Relationship to restheart-accounts

restheart-stripe works best alongside restheart-accounts, which provides the teams, roles and JWT claims the module reads.

The coupling is soft, not a hard dependency:

  • The module compiles against restheart-commons only.

  • accountsConfig is resolved at runtime if present, and the module falls back to sensible defaults if it is not.

  • Replacing the SPI removes the relationship entirely.

Next steps