---
status: demonstration
audience: public-demonstration
fixture: kibble-and-co (fictional)
---

# 5. BigCommerce Platform Integration Contract

This is the platform-integration contract an estimator sizes against. It answers two questions:

- What BigCommerce capability the build consumes directly, and what role it plays (§5.1).
- What the build implements itself on top of that capability, and which of those items are the biggest estimation drivers (§5.2).

Payments/PCI posture, the gateway support matrix, integration surfaces, and the assumption register that follow narrow the estimate further (§5.3–§5.6). Capability-level requirements — what the solution must do — are specified in [02-capability-catalog.md](02-capability-catalog.md) and [03-user-journeys.md](03-user-journeys.md); this section is scoped narrowly to platform integration surface and contract. The subscriber-portal fork in §5.2.5 and the gateway-adapter scope in §5.4 are the two places a solution-approach position materially changes the estimate — size both explicitly (see [09-estimation-scaffold.md](09-estimation-scaffold.md)).

## 5.1 Platform capabilities the build consumes

| Capability | API surface | Role in the build |
|---|---|---|
| Admin APIs (V2/V3) | Products, Variants, Customers, Orders, Carts, Price Lists, Customer Groups, Channels, Webhooks, Store Information | Core CRUD and lookup surface the build uses to reconcile subscription state against Kibble's catalog, order, and customer records |
| Storefront GraphQL API | Product catalog queries, cart mutations | Powers the subscriber-facing storefront experience |
| App Extensions (GraphQL) | `PANEL` / `LINK` context on `PRODUCTS`, `PRODUCT_DESCRIPTION`, `ORDERS`, `CUSTOMERS` | Delivers the merchant-admin subscription-management surface inside Kibble's BigCommerce control panel on the product, order, and customer pages; the build delivers cart-side merchant UX through a Stencil widget, the Storefront Scripts API, or a customer-page deep link |
| Webhooks (registered) | `store/order/created`, `store/order/updated`, `store/cart/created`, `store/cart/updated`, `store/cart/deleted`, `store/customer/updated`, `store/product/updated`, `store/product/deleted`, `store/app/uninstalled` | Event backbone the build subscribes to for subscription creation, state sync, and lifecycle teardown |
| Custom Fields + Metafields | Product-level and cart-level key/value attachment | The build's channel for carrying subscription configuration and subscription intent alongside BigCommerce's native product and cart records |
| Price Lists | Price-list assignment scoped to customer group / channel | Delivers subscription-specific pricing ("Subscribe & Save") |
| Customer Groups | Group assignment feeding price-list, shipping, and tax rules | Segments subscribers for differentiated pricing, shipping, and tax treatment |
| Channels / Multi-Storefront | Channel-scoped catalog and pricing | Scopes subscription availability to specific sales channels, if Kibble sells across more than one |
| Scripts API / Stencil | Storefront script injection | Delivers subscription widgets on PDP and cart for Kibble's Stencil storefront |
| Stored Instruments vault + Payment Access Tokens | `POST /v3/payments/access_tokens`, `GET /v3/payments/methods`, the `payments.bigcommerce.com` charge endpoint, `GET /v3/orders/{id}/transactions` | The recurring-charge rail: vaults the card at checkout, surfaces a harvestable token on the resulting order, and executes merchant-initiated renewal charges without the build ever handling raw card data |

## 5.2 What the build implements on top of the platform

Eight capabilities below are build-owned regardless of approach — there's one way to size them. One, the subscriber portal (§5.2.5), is a genuine fork between two viable approaches, and both should be sized. Each item states the behavioral requirement and how the build delivers it against the platform surface in §5.1.

### 5.2.1 Recurring billing engine

- **Behavioral requirement.** Subscriptions generate a new BigCommerce order automatically on each billing cycle, driven by the plan's cadence, without a shopper re-visiting checkout.
- **Build approach.** The build owns subscription and billing-cycle state in its own data store, runs the scheduling logic itself, and calls the Orders API to create each cycle's order once a charge succeeds. This scheduling and state-ownership layer — not the Orders API call itself — is the section's single largest estimation driver.

### 5.2.2 Subscription product configuration

- **Behavioral requirement.** A merchant must be able to mark a product (or variant) as subscribable and attach subscription-plan configuration — cadence options, discount, trial terms — to it.
- **Build approach.** Subscribability and plan configuration are carried in product metafields; subscription pricing is delivered through Price List assignment.

### 5.2.3 Dunning / payment-retry

- **Behavioral requirement.** A failed renewal charge must retry on a configurable cadence, notify the subscriber and merchant at the right points, and eventually pause or cancel the subscription if recovery fails.
- **Build approach.** The billing engine owns a retry state machine — attempt count, next-retry time, and outcome per charge — as domain logic that belongs to the build, not the platform.

### 5.2.4 Pause / skip

- **Behavioral requirement.** A subscriber must be able to pause a subscription (suspend future charges until resumed) or skip a single upcoming cycle, both self-service and merchant-admin-initiated.
- **Build approach.** Pause/skip state lives in the subscription's own record; the billing scheduler consults it before generating each cycle's charge and order.

### 5.2.5 Subscriber self-service portal

- **Behavioral requirement.** Subscribers need self-service access to view and manage their subscriptions — cadence, payment method, pause/skip/cancel — without contacting the merchant.
- **Build approach — size both.** Option (a): skin subscription management into Kibble's existing Stencil account-page templates, for tighter UX cohesion with the rest of My Account, at the cost of touching theme templates outside the subscription build's usual boundary. Option (b): ship a bounded, standalone portal (hosted or embeddable), for lower integration risk and a faster, proven UX pattern, at the cost of sitting visually and structurally apart from the rest of the account area. Both are viable; propose both, sized, with a recommendation.

### 5.2.6 Order-to-subscription traceability

- **Behavioral requirement.** Every order created by a subscription renewal must be traceable back to the subscription and billing cycle that produced it, for merchant reporting, support, and reconciliation.
- **Build approach.** Order-level custom fields and metafields carry a subscription reference ID, set by the build at order-creation time.

### 5.2.7 Capturing subscription intent at checkout

- **Behavioral requirement.** The build must know, at order-creation time, which line items in a completed order represent a subscription purchase, and which plan/cadence/discount was selected, so the correct subscription record can be created.
- **Build approach.** A storefront widget writes subscription intent into cart-level metafields (namespace `bc_subscriptions`, key `subscription_intents`); the `store/order/created` webhook handler fetches them via `GET /v3/carts/{cartId}/metafields` and creates the subscription from that payload. A post-purchase, thank-you-page JavaScript post is maintained as a fallback for storefronts that can't render the in-cart widget — resilient, but not atomic with order creation, so the primary path is preferred wherever the widget can render.

### 5.2.8 Prepaid / fixed-term plans

- **Behavioral requirement.** A subscriber must be able to purchase a fixed number of future cycles upfront, with the charge schedule for all cycles determined at the time of purchase.
- **Build approach.** Prepaid/fixed-term plans are modeled as a pre-computed charge schedule inside the billing engine, generated once at purchase and consumed by the same scheduler that drives open-ended subscriptions.

### 5.2.9 Store enablement

The build reaches Kibble's store through BigCommerce's app framework: install and OAuth token exchange, App Extensions registration for the admin panels described in §5.1, webhook subscription registration, and an uninstall hook for teardown. Per-store scope includes a provisioning/enablement record, the merchant-facing panels on the Products, Orders, and Customers admin pages, wiring for the order/customer/product events the build depends on, disablement cleanup with a recovery window, and provisioning-health verification with a merchant-visible recovery path.

## 5.3 Payments & PCI posture

**Vaulting mechanism.** At standard checkout, the shopper enters card data into BigCommerce's own hosted checkout UI. When the shopper opts to save the card, BigCommerce's payment layer vaults the card with the underlying provider and returns an opaque token on the resulting order. The build never receives raw card data and makes no direct Stored Instruments API call at initial checkout — it harvests the vaulted token from the order's transaction record (`GET /v3/orders/{id}/transactions`) in response to the `store/order/created` webhook. A separate direct-token-entry flow exists only for the subscriber's own portal add/update-payment-method action, and for dunning recovery when a card is re-added after a decline — not for initial-checkout vaulting.

**Sign-in requirement.** A subscription's recurring charges bill a vaulted stored instrument, and BigCommerce only vaults a card at checkout for a signed-in customer — a guest checkout can complete an initial one-time charge but can't vault a card, which would leave a subscription with no instrument its renewals could ever charge. The build gates a cart containing subscription intent on customer identity: a guest adding a subscription is redirected to sign in first, while one-time-purchase carts remain guest-friendly. This is a gate on the subscribe path specifically, not a general storefront sign-in requirement. Gift-purchase flows (prepaid, single upfront charge, no recurring instrument) need no vaulted instrument and are exempt.

**Recurring (merchant-initiated) charge sequence.** Off-session renewals execute via a three-call sequence the build owns: (1) mint a Payment Access Token scoped for recurring use (`POST /v3/payments/access_tokens`, `is_recurring: true`); (2) discover the stored-instrument token for the order (`GET /v3/payments/methods?order_id=N`); (3) execute the charge against BigCommerce's payments endpoint (`payments.bigcommerce.com/stores/{hash}/payments`). BigCommerce's own gateway abstraction auto-classifies these as merchant-initiated. Two gateway families ride this rail today — BigCommerce Payments and Stripe; other gateways are gated by whether the gateway itself supports BigCommerce's stored-instrument model (§5.4).

**Stored-credential handling.** Card networks distinguish cardholder-initiated from merchant-initiated stored-credential transactions, each carrying distinct fraud, SCA, and authorization-rate treatment; sending the wrong classification on a recurring renewal measurably degrades decline rates and can forfeit the EU PSD2 recurring-charge exemption. Each processor adapter the build implements is responsible for sending the correct classification and chain-position marker (initial vs. subsequent) per its own gateway's documented API — Stripe's stored-card charges carry `payment_method_options.card.mit_exemption.recurring` plus `previous_network_transaction_id`; Braintree's carry `transactionSource: 'recurring'` with the prior network transaction ID in the external-vault reference. Every charge call the build makes must carry, at minimum: an idempotency key, the amount, a payment-method reference, the MIT type, the chain position, and the network transaction ID (null only when chain position is initial).

**Capture-timing configuration.** The three-call charge sequence above authorizes and captures in one call. That fits digital goods; it does not fit Kibble & Co.'s physical fulfillment, where capture should defer to shipment or fulfillment confirmation — both for warehouse deferred-capture workflows and to keep the door open on EU PSD2 requirements if Kibble ever sells into the EU. The build supports a capture-timing configuration axis (`immediate` | `on_fulfillment` | `on_ship`) from the first release, implemented as a split authorize/capture flow driven by `store/shipment/created` and `store/order/statusUpdated` webhook events, plus a sweep process that catches authorizations approaching the gateway's authorization-window expiry before they lapse unfulfilled. Deferring the full authorize/capture split to a later phase is a legitimate sequencing choice; the configuration surface existing from day one is not.

**Hard requirement — cardholder-data containment.** The build must never receive, transmit, or store raw card data at any point in its lifecycle. All sensitive card entry happens inside BigCommerce's own hosted checkout UI or its direct-token-entry flow, both of which keep raw PAN data out of the build's components entirely. Any solution design that routes raw card data through build-owned components, for any reason, is out of scope and must be flagged, not silently adopted.

**Compliance posture.** Because the build never touches raw card data, its payments-path components should stay outside the cardholder-data environment and be scoped for review against a standard PCI DSS self-assessment track for a merchant-commissioned application — components holding only tokenized references, connected to but not part of the cardholder-data environment. Kibble's own SAQ-A eligibility, earned through BigCommerce's hosted checkout, is preserved unchanged as long as containment holds. Estimators should price the data-flow documentation and secure-SDLC artifacts that assessment track typically requires.

## 5.4 Gateway support matrix

BigCommerce's public gateway directory lists dozens of supported payment gateways. The build's gateway-adapter scope is sized against which of them expose the four primitives a subscription engine needs: a stored-instrument vault, merchant-initiated/off-session charging, stable webhook events, and a refund API. Per BigCommerce's own Stored Instruments documentation, gateway support for stored-instrument charging varies — that variance is what the matrix below records:

| Gateway | Region | Vault | MIT / off-session |
|---|---|---|---|
| **BigCommerce Payments (PayPal/Braintree)** | US (expanding) | Yes, via BigCommerce's vault layer with Braintree provider tokens | Yes (via Braintree) |
| **Stripe** | Global | Yes, via BigCommerce's Stored Instruments vault | Yes — stored-card charge through BigCommerce's payments endpoint |
| **Braintree (standalone)** | Global | Yes | Yes (Braintree Transaction API) |
| **Authorize.net** | US/CA | Yes (CIM) | Yes |
| **Adyen** | Global (strong EU) | Yes | Yes |
| **Cybersource** | Global | Yes | Yes |
| **Worldpay / FIS** | UK/EU | Yes | Yes |
| **Checkout.com** | Global | Yes | Yes |
| **Square** | US/AU/UK/CA | Yes (Cards API) | Limited |
| **eWAY** | AU/NZ | Yes | Yes |
| **Klarna / Afterpay / Clearpay** | Global | N/A (BNPL) | No (regulatory) |
| **Amazon Pay** | US/EU/JP | No (session-bound) | No |
| **Apple Pay / Google Pay (wallet passthrough)** | Global | Via underlying card | Depends on processor |

**Adapter scope for this build.** Kibble & Co. processes cards through BigCommerce Payments today and holds Stripe as its candidate secondary processor, so the fixed bid sizes exactly two adapters — BigCommerce Payments as primary, Stripe as alternate — both riding the vault rail in §5.3. Adapters for any other gateway are out of scope and enter, if ever, through change control (see [08-scope-boundary-and-engagement-model.md](08-scope-boundary-and-engagement-model.md)). BNPL providers and session-bound wallets stay off the recurring rail entirely — they are structurally incompatible with unattended merchant-initiated charges — and wallet passthroughs inherit whatever the underlying processor supports.

**Merchant-facing consequence.** During install, the build detects the store's active gateway and surfaces a compatibility signal. If Kibble's gateway is unsupported, the merchant needs a clear path forward — switch to a supported gateway, add a supported secondary processor, or decline install — with no silent degradation of subscription functionality.

## 5.5 Integration surfaces

**Inbound BigCommerce webhooks.**

| Webhook | Behavior triggered |
|---|---|
| `store/order/created` | Fetch subscription intent from cart-level metafields; create the subscription and its first charge record |
| `store/order/updated` | Sync order status to the subscription's own view of order state |
| `store/order/refund/created` | Reconcile a refund event against the subscription's charge history. The build registers this webhook subscription itself as part of setup — it isn't active by default |
| `store/customer/updated` | Update the subscription's payment/shipping address if the customer's default changed |
| `store/customer/deleted` | Cancel all of that customer's subscriptions |
| `store/product/updated` | Detect price changes; flag affected subscription plans for review |
| `store/product/deleted` | Pause subscriptions on the affected product |
| `store/app/uninstalled` | Purge stored credentials; pause all subscriptions (fired automatically by the platform, no explicit registration needed) |

**Inbound processor webhooks.** Consumed via BigCommerce's own webhook subscriptions where exposed, with gateway-native webhooks as fallback:

- BigCommerce Payments path: transaction settled / declined / disputed; payment method invalidated or expired; dispute opened (auto-pause the subscription, alert the merchant); merchant-initiated authorization revoked, where the gateway exposes it (flag the payment method, block further renewals — see §5.6 on visibility).
- Stripe path: `payment_intent.succeeded` / `payment_intent.payment_failed` (authoritative charge outcome); `payment_method.detached` / `payment_method.updated` (flag the payment method as invalid, trigger subscriber notification); `charge.dispute.created` (auto-pause the subscription, alert the merchant); `customer.updated` (detect default payment-method changes).

Each processor adapter normalizes its own webhook stream into a small shared event vocabulary — charge settled, charge declined, payment method invalidated, dispute opened — before it reaches the build's internal event handling; the billing engine and notification layer consume only that normalized vocabulary, never gateway-specific event shapes directly.

**Outbound webhooks and events.** The build exposes a merchant-facing REST API for subscriptions, charges, and events; merchant-configurable webhook subscriptions mirroring those event types; and an internal event stream feeding notification and integration consumers. See [02-capability-catalog.md](02-capability-catalog.md) for the notifications/external-integrations and developer-facing API/webhook/SDK domains this belongs to, and [07-work-breakdown.md](07-work-breakdown.md) for per-story acceptance detail.

## 5.6 Assumption register

The following platform behaviors are assumed true as of this document's as-of date. Each is a candidate for a vendor solution-design validation step — bid diligence, not a discovery phase — before the estimate is finalized.

1. BigCommerce's Stored Instruments vault continues to expose the three-call access-token → instrument-discovery → charge sequence in §5.3 for BigCommerce Payments and Stripe, without material contract changes before build start.
2. Card vaulting at checkout remains contingent on signed-in customer context; guest checkout does not vault a payment instrument, and this constraint does not change before build start.
3. The general cardholder-initiated/merchant-initiated stored-credential model described in §5.3 remains the correct compliance frame for renewal charges.
4. The gateway vault/MIT support matrix in §5.4 reflects BigCommerce's currently published gateway-compatibility documentation and does not change materially before build start.
5. Refund reconciliation depends on a dedicated order-refund webhook subscription the build registers itself (§5.5); it should not be assumed already active for Kibble's store.
6. App Extensions continue to ship `PANEL`/`LINK` contexts on `PRODUCTS`, `PRODUCT_DESCRIPTION`, `ORDERS`, and `CUSTOMERS`, and the build's cart-side merchant UX continues to ride the Stencil-widget/Scripts path described in §5.1.
7. Cart-level metafields remain writable from a storefront widget and readable server-side, within the timing window of `store/order/created` webhook handling.
8. BigCommerce's own payments dashboard continues to surface settlement for vault-rail charges without additional merchant-side reconciliation work.
9. The multi-phase capture in §5.3 is entirely build-owned — driven by shipment and order-status webhooks and the build's own authorization-window sweep — and the bid sizes it as such.
10. Klarna/Afterpay/Clearpay, Amazon Pay, and session-bound wallet gateways remain structurally excluded from recurring/off-session charging for regulatory or design reasons — no solution should attempt to bring these onto the recurring rail.
11. The build treats merchant-initiated authorization-revocation signals (§5.5, BigCommerce Payments path) as best-effort per gateway — consumed where present, never depended on as a guaranteed control.

Any assumption the vendor's solution design finds to be false or changed should be raised as a scoped change request against the affected sections of this contract, not silently absorbed into the estimate.

---

Kibble & Co. is a fictional demo merchant. This package is an independent demonstration by Nino Chavez of a scoping method — not a BigCommerce product, and not a real procurement.
