Skip to content

1. The system in one picture

Generated from a canonical source

This page is a read-only projection of docs/solution-review/01-system-in-one-picture.md. Edit the canonical file, then run npm --prefix tools/project-knowledge-derive run derive.

What is being built, and for whom

bc-subscriptions is a subscription-management engine built natively on the BigCommerce platform. It owns the parts a commerce platform does not: the subscription agreement, the recurring-charge history, plan configuration, eligibility rules, dunning policy, entitlement state, and an event/audit log. Everything a store already knows — the product catalog, base pricing, customer profiles, orders, checkout — stays in BigCommerce and is read through, consumed by webhook, or referenced by pointer. The design principle is "a system of systems, not a second commerce platform."

It reaches merchants today as a BigCommerce Marketplace app: OAuth install per merchant, an admin UI that loads inside BigCommerce's control panel, all platform reads and writes over public v3 REST and Storefront APIs, webhooks in both directions. That shape is a deliberate destination, not scaffolding — the app is "marketplace-first, native-ready" per ADR-0029 (marketplace destination, not waypoint; graduation to native is an option, not a commitment). The same work also stands as a reference implementation of the capability restated in BigCommerce-native terms, so a decision to build it first-party later has a bounded lift rather than a rewrite. Deep dive: ../decisions/0029-marketplace-first-native-ready.md.

Context: the system and the outside world

flowchart TB
    Merchant["Merchant staff<br/>(person)"]
    Subscriber["Subscriber<br/>(person)"]
    Support["Support / Ops<br/>(person)"]

    Platform["bc-subscriptions<br/>(system in focus)<br/>Subscriptions, charges, plans,<br/>eligibility, dunning, events"]

    BC["BigCommerce platform<br/>Catalog, pricing, customers,<br/>orders, checkout, webhooks"]
    Processor["Payment processor<br/>BC Payments vault / Stripe<br/>Tokens, settlement"]
    Email["Email delivery<br/>Transactional notifications"]

    Merchant -->|"configures plans, dunning"| Platform
    Subscriber -->|"self-serves via portal"| Platform
    Support -->|"reconciles failed renewals"| Platform
    Platform -->|"read-through: catalog / pricing / customers;<br/>webhook-consume: orders"| BC
    Platform -->|"pointer-reference: vault token"| Processor
    Platform -->|"sends notifications"| Email

bc-subscriptions is the system of record for subscription, charge, and rule data. BigCommerce owns catalog, pricing, customers, orders, and hosted checkout. The payment processor owns the card vault and settlement — the app holds only a token reference, never card data (see 04-money-movement.md). Adapted from ../architecture/c4-context.md.

Runtime: the deployed pieces

flowchart TD
  Merchant((Merchant / Staff))
  Subscriber((Subscriber))

  Admin["Admin UI (apps/admin)<br/>Vite + React + BigDesign<br/>CF Pages"]
  API["subs-api<br/>OAuth, webhooks, REST, scheduler<br/>CF Workers"]
  Portal["subs-storefront-svelte<br/>Subscriber portal + cart/checkout<br/>CF Workers + Pages"]
  Widget["Storefront widget (apps/storefront-catalyst)<br/>Subscribe affordance / intent capture<br/>CF Pages"]
  EmailC["subs-email-consumer<br/>Transactional email<br/>CF Workers (queue consumer)"]
  Assistant["subs-assistant<br/>Ask-the-substrate chat<br/>CF Workers"]

  DB[("subs-api-d1<br/>D1 (SQLite)")]
  Q{{"EVENTS_QUEUE<br/>Queue: subs-events"}}

  Merchant -->|"BC control-panel iframe"| Admin
  Subscriber -->|"hosted portal"| Portal
  Subscriber -->|"storefront widget / PDP"| Widget
  Admin -->|"REST, signed JWT"| API
  Portal -->|"service binding"| API
  Widget -->|"REST"| API
  API --> DB
  API -->|"produces"| Q
  API -->|"assistant handoff token"| Assistant
  Q -->|"consumes"| EmailC
Component What it does Runtime
subs-api OAuth install handshake, inbound webhook receiver, merchant + portal REST API, and the billing scheduler on a scheduled() cron Cloudflare Workers
subs-storefront-svelte Subscriber self-service portal and the storefront cart/checkout integration Cloudflare Workers + Pages assets
subs-email-consumer Consumes EVENTS_QUEUE and sends transactional email Cloudflare Workers (queue consumer)
subs-assistant "Ask the substrate" chat over the project corpus; the API worker mints its handoff token Cloudflare Workers
Admin UI (apps/admin) Merchant admin SPA loaded inside BigCommerce's control panel Vite + React + BigCommerce BigDesign, Cloudflare Pages (not a Worker)
Storefront widget (apps/storefront-catalyst) Subscribe affordance and subscription-intent capture on the merchant storefront Catalyst / Stencil, Cloudflare Pages
subs-api-d1 System-of-record datastore: subscriptions, charges, plans, payment-method references, events Cloudflare D1 (SQLite)
EVENTS_QUEUE Event fan-out substrate feeding email and (designed) merchant webhooks Cloudflare Queues

The runtime view is adapted from ../architecture/c4-container.md, which is mechanically generated from the deploy configs. Note one intentional divergence: subs-assistant is a real product worker (apps/assistant/wrangler.jsonc) but does not appear in the generated container diagram, which parsed only wrangler.toml files.

Three UI surfaces, three host constraints

The product presents on three independently deployable surfaces. ADR-0005 (three-surface UI architecture) established the principle: each surface is its own deployment artifact and they communicate by contract only, never by shared bundle. A fourth artifact, the internal design prototype, is a reviewer-only reference, not a production surface.

Surface Who uses it Auth model BigCommerce embedding constraint
Merchant admin Merchant staff BigCommerce signed-JWT app-load (/api/load) over the store's OAuth grant Loads inside the control-panel iframe. An App Extension panel is limited to PANEL / LINK on the Products, Orders, and Customers pages — there is no cart or category context available to it
Subscriber portal Signed-in subscribers Portal session (magic-link / SSO handoff); subscribing requires a signed-in BigCommerce customer per ADR-0090 Hosted by the app on Cloudflare, outside the storefront. The subscriber crosses a domain boundary from the merchant storefront into the portal
Storefront widget Shoppers on the merchant storefront Per-merchant Storefront API token / anonymous cart Composed into the merchant's Catalyst/Stencil storefront. Because App Extensions have no cart context, subscribe intent cannot be captured from an admin extension — the widget lives in the storefront, where the cart is, and writes intent to cart metafields

The last row is the load-bearing one for the rest of this package: the widget exists specifically because the platform's admin-extension surface cannot see a cart. Intent captured there flows into the money and event mechanics described in 04-money-movement.md and 05-event-backbone.md. Deep dive: ../decisions/0005-three-surface-ui-architecture.md.

The runtime bet

Phase 1 runs entirely on Cloudflare: Workers for compute, D1 (SQLite) for the datastore, Queues for event fan-out, KV for caches, cron triggers for the billing scheduler. Phase 2 is a planned migration to Google Cloud — all web surfaces to Cloud Run (containerized), the datastore to Cloud SQL (PostgreSQL 15). The migration shape is ratified in ADR-0030 (the Cloudflare → GCP phasing authority, per ARCHITECTURE.md §0) with the managed-SQL engine chosen in ADR-0054. Nothing in Phase 1 forecloses the move: tenant isolation is enforced by mandatory store_hash scoping on every query, and the observability sink is abstracted for a Phase-2 cutover. Deep dives: ../decisions/0030-bigeng-pattern-alignment.md, ../decisions/0054-cloud-sql-engine.md.

Words you'll hear

One line each; the full list is at ../methodology/glossary.md.

Term In one line
Stored instrument A vaulted, tokenized card held by BigCommerce or Stripe; the app persists only the token, never the card.
Charge rail The single gateway-agnostic path all recurring charges take — payments.bigcommerce.com against a stored instrument (ADR-0037).
PAT Payment Access Token — a one-hour BigCommerce token, minted per order, that authorizes a stored-instrument charge.
MIT / MREC Merchant-Initiated Transaction; MREC is its recurring-renewal subtype, the flag every off-session renewal carries.
Vault The processor-hosted store of tokenized cards; "vault-at-checkout" is how a card first gets tokenized.
Off-session A charge run with no shopper present — every renewal — as opposed to the cardholder-initiated first purchase.
Dunning The retry-and-notify policy applied when a renewal charge fails, before a subscription is cancelled.
App Extension A BigCommerce control-panel embedding slot (PANEL/LINK) on Products/Orders/Customers — no cart or category context.
Metafield Arbitrary key/value data attached to a BigCommerce entity; subscribe intent rides a cart metafield the storefront widget writes.
Intent capture Recording, at add-to-cart time, that a line is meant to be a subscription — the seed the order-created webhook turns into a subscription.