How this was built

Built primarily with Claude Code (Anthropic's agentic coding tool), under direct human direction — the architecture, specification, and review decisions are the operator's; the AI generates code against that spec. The output is conventional TypeScript, Astro, and React — standard, maintainable code, not a proprietary format tied to the tool that helped write it. Quality claims here aren't self-assessed: every one is backed by an automated, regenerating verification ledger, not a status doc — see Verified Throughput. For a structured engineering review, see Code Review.

Bringing a new team up to speed

This is a subscription billing engine built for BigCommerce merchants — recurring charges, dunning (retrying failed payments), and a customer self-service portal, integrated into BigCommerce's own admin and storefront rather than running alongside it as a separate system. If you're picking this up cold, this page is the fastest path from zero to productive.

Before any estimate: what's the actual ask?

This page assumes none of the following are decided yet — confirm which applies before scoping any timeline or team size: (a) full path-to-GA delivery, (b) closing a specific named gap (see Known Limitations below), (c) the B2B Edition extension (approval workflows, purchase orders), or (d) extending the live BC Payments rail (e.g. PPCP confirmation, deferred capture) beyond what ADR-0082 already validated. Each is a different-sized engagement.

What's left to GA — the honest register

Sizing an engagement starts from three derived registers, not prose claims. Each is generated from the repo and re-derives on every deploy:

  • 16 acceptance criteriaacross 10 epics lack a passing automated scenario — the build-completion remainder, grouped by area inCode review.
  • 30 GA-blocking attestations pending — external/human sign-offs (pen-test, legal, accessibility validation) that gate GA regardless of code state. Full pack with per-item status:Security & Complianceand Operations.
  • The open engineering-decision register — traced, evidence-cited defects and adjudications surfaced by this project's own audit passes (each links the trace that found it):open issues. These are honest sizing input, not concealed debt — several were found by the same knowledge-transfer tracing that produced the per-capability deep dives below.

For the platform-dependency dimension (e.g. PayPal-specific confirmation), see each capability page's "Where intent and reality diverge" section — every divergence is typed and cited.

Requirements by role & tier

Every requirement below is derived from the BRD's own story headers (phase, priority, effort, persona) joined with the automated verification ladder — regenerated on every release, never hand-maintained. Personas bucket into the product's three external roles — Merchant, Subscriber, Support — plus two internal buckets (Developer-facing integration stories; System stories with no human actor, e.g. schedulers and webhooks).

How to read "verified": a story counts as verified only when a tagged automated scenario passes in CI (gate G4 of the five-gate ladder). "Not yet verified" is a test-evidence statement, not a claim the story is unbuilt — several are built and awaiting scenario coverage. Sizing should treat the verified column as the floor of what demonstrably works.

RoleMVPP1P2P3Verified / total
Merchant33 / 3614 / 1530 / 3118 / 1995 / 101
Subscriber30 / 317 / 118 / 87 / 852 / 58
Support / Ops6 / 75 / 56 / 61 / 118 / 19
Developer6 / 80 / 04 / 51 / 111 / 14
System22 / 222 / 22 / 20 / 026 / 26

Cells are verified / total stories. Phase is the BRD's delivery-phase field: MVP and P1 are the shipped-first scope; P2/P3 are the deliberately-later tranches.

Where P0 feedback lands

74 of 218 stories carry an explicit business-priority tier today (53 P0 · 17 P1 · 4 P2); the remaining 144 are untiered — they predate the priority field. Tiering that remainder is the open product-judgment pass this register exists to support: mark P0/P1 against the per-role lists below and the BRD headers get updated from that feedback (this page then re-derives).

Merchant — 101 stories
USPhasePriorityEffortVerifiedStory
US-1.1MVPP0MyesOAuth install handshake
US-1.2MVPP0SyesSigned payload JWT verification on app load
US-1.3MVPyesApp Extensions registered on install
US-1.5MVPP0MyesUninstall hook cleans up credentials and extensions
US-2.1MVPP0MyesAuto-detect BC Payments
US-2.2MVPP0LyesStripe Connect onboarding
US-2.3MVPP0MyesProcessor compatibility detection at install
US-2.4MVPyesSandbox/test mode
US-2.6P2yesMultiple processor connections
US-2.7P1P1XSyesCapture timing advisory at processor onboarding
US-3.1P2yesRecharge export import
US-3.2P2P0XLyesPayment method migration via Stripe/Braintree dataset import
US-3.3P2yesCycle-date preservation
US-3.4P2yesPayWhirl export import
US-3.5P3yesBold / MINIBC import
US-3.6P2P1MyesDry-run migration with impact report
US-3.7P2P2MyesPayWhirl API import (authoritative extraction)
US-4.1MVPP0Myes"Subscriptions" panel on a BC product
US-4.2MVPP0LyesSubscription-enable wizard
US-4.3MVPyesVariant-level subscription enablement
US-4.4MVPyesDeactivate subscription plan
US-4.5P2yesCopy plan between products
US-5.1MVPyesMultiple offered intervals
US-5.2MVPyesPricing strategy — fixed discount %
US-5.3MVPP0MyesPricing strategy — BC Price List
US-5.4MVPyesPricing strategy — fixed price
US-5.5MVPP1MyesFree or paid trial
US-5.6P2yesLock price at subscription creation
US-5.7P2yesCommitment (minimum cycles)
US-5.8P2yesCancel lock plan policy — minimum term + early-cancellation policy
US-5.9P2yesCalendar-anchored billing plan anchor
US-6.1P3P1XLyesGift subscriptions
US-6.4P1yesBundle subscriptions
US-6.5P1yesMembership subscriptions (access-based)
US-6.6P1yesUsage-based subscriptions
US-6.9P3yesAllotmentGrant — admin-granted recurring quota / wallet (PRD-COMPANION D18)
US-6.10P1yesMulti-actor subscription — payer / beneficiary / manager distinct from owner (PRD-COMPANION D19)
US-6.11P3yesCustom-field configuration on a plan (PRD-COMPANION D20)
US-7.1P2P0MyesPlan scoped to specific channels
US-7.2P2yesPlan scoped to customer groups
US-7.3P2yesPlan scoped to geographic region
US-7.4P2yesPlan scoped to Price List
US-7.5P2yesScope audit view
US-8.4MVPnot yetWidget theming
US-8.5P3yesA/B widget copy
US-10.9P1P1SyesCapture timing configuration per store
US-11.1MVPyesConfigurable dunning policy
US-11.7P2yesMerchant-side dunning digest
US-14.2MVPyesTag order with subscription metadata
US-14.4MVPyesOrder status mapping
US-14.5P2yesOrder edit sync
US-15.5P2yesFree shipping on subscription
US-15.6P2yesPre-renewal OOS check — proactive inventory scan before charge with Exception Queue escalation
US-16.3P1yesMerchant view of combined shipments
US-16.5P3yesDecoupled billing and shipping cadence — Phase 3 scaffold
US-17.3P3yesPortal custom domain
US-17.4MVPnot yetPortal theming
US-20.6P3yesIntervention A/B testing
US-21.1MVPyesKPI summary
US-21.2MVPyesUpcoming charges panel
US-21.4MVPyesSubscription list with search & filter
US-21.5P2yesBulk actions on subscriptions
US-21.6MVPP0LyesSubscription detail view
US-21.7P2yesExport subscription data (CSV)
US-21.8P1yesAnalytics beyond KPIs (cohort, LTV)
US-23.3MVPyesTemplate editor
US-23.4P2yesMerchant alerts & digests
US-23.5P2P1LyesKlaviyo integration
US-23.7P3yesAccounting integrations (NetSuite, QuickBooks, Xero)
US-23.9MVPP0LyesCustom sending domain
US-23.10MVPP0MyesDeliverability monitoring
US-23.17P2yesLocalization framework
US-24.1P3yesCompany-account subscriptions
US-24.5P3yesBuyer hierarchy & visibility
US-24.6P3yesVolume-tier renewal pricing
US-24.7P3yesContract-term commitments
US-24.9P3yesAdmin-only B2B subscription enrollment in Phase 1 (ADR-0023)
US-24.10P3yes`org_admin` actor role and multi-actor management on B2B subscriptions (PRD-COMPANION D19, ADR-0022)
US-25.1MVPP0LyesSubscription-only coupon codes
US-25.2MVPnot yetSubscribe-and-save auto-promotion
US-25.3MVPyesCycle-scoped discount
US-25.5P1yesPromotion stacking rules
US-25.6P2yesPromotional free shipping
US-25.7P3yesSubscription-exclusive bundles
US-25.9P2yesPromotion reporting
US-25.10P2P2MyesTime-tiered discount ladder
US-25.11P3P2Lnot yetCycle-discount ladder — admin propagation controls
US-26.1MVPP0MyesProduct inclusion by category
US-26.2MVPyesProduct exclusion
US-26.3MVPyesVariant-level eligibility
US-26.4P1yesCustom-field-based eligibility
US-26.5P1P1MyesCustomer-segment eligibility
US-26.6P1yesGeographic & channel restrictions
US-26.7P1yesQuantity min/max
US-26.8P3P2MyesMutual exclusion rules
US-26.9P3yesConditional dependency rules
US-26.10P1yesRule evaluation audit
US-27.2MVPyesAPI key management in admin
US-28.3P2yesAudit log export
US-28.6P2not yetData residency
US-28.7P1P0Mnot yetAuto-renewal disclosure policy & consent-record retention
Subscriber — 58 stories
USPhasePriorityEffortVerifiedStory
US-6.2P1P0LyesPrepaid fixed-term subscriptions
US-6.3P3P1XLyesBuild-a-box subscriptions
US-6.7P1yesSurprise-me / curation subscriptions
US-6.8P1yesReferral subscriptions
US-8.1MVPP0LyesWidget on Stencil PDP
US-8.2MVPnot yetWidget on cart
US-8.6P1not yetPre-purchase education panel
US-9.3MVPP0MyesPost-purchase fallback capture
US-9.4MVPyesMixed-cart checkout (subscription + one-time)
US-9.6P1P0MyesAffirmative consent capture at subscribe (auto-renewal disclosure)
US-10.5MVPyesPause/resume respects schedule math
US-10.6P1yesSchedule visualization
US-10.7P2yesFuture start date — pending_start state and deferred activation
US-10.8P2yesFirst-cycle proration for mid-year calendar-anchor sign-ups
US-11.5MVPyesSubscriber-initiated PM update resets retries
US-11.6MVPyesDunning notifications
US-14.6P2yesMid-cycle plan upgrade — delta-capture semantics
US-16.1P1yesSubscriber opts into combined shipments
US-17.1MVPP0MyesMagic-link email auth
US-17.2P2yesBC storefront SSO
US-18.1MVPP0SyesSkip next charge
US-18.2MVPP0LyesSwap product/variant
US-18.3MVPyesPause subscription
US-18.4MVPyesReschedule next charge
US-18.5MVPP0LyesCancel (with churn-prevention flow)
US-18.6MVPyesUpdate quantity
US-18.7P2yesReactivate cancelled subscription
US-18.8MVPyesChange cadence / interval
US-18.9P1yesTerm-end renewal nudge — registration-style re-up distinct from MIT renewal
US-18.10P2yesCancel lock — portal enforcement and CS-rep admin override
US-18.11P1P0Mnot yetClick-to-cancel — same-medium cancellation parity
US-19.1MVPP0LyesUpdate payment method
US-19.2MVPyesDefault vs per-subscription PM
US-19.3MVPyesUpdate shipping address
US-19.4MVPyesUpdate billing address
US-19.5P3yesSubscriber preferences
US-19.6MVPP1MyesUpdate payment method across all subscriptions
US-20.1MVPyesCancel reason capture
US-20.2MVPP0MyesIntervention: pause-instead-of-cancel
US-20.3MVPP0LyesIntervention: offer discount
US-20.4MVPyesIntervention: change cadence
US-20.5MVPyesIntervention: escalate to support
US-20.7P1P0Snot yetChurn-flow obstruction guard (save-attempt limit)
US-23.1MVPyesTransactional emails
US-23.2P2yesSMS notifications
US-23.11MVPP0MyesSuppression list management
US-23.12MVPP0LyesMagic-link email pipeline
US-23.13MVPP0MyesDecline-reason-translated dunning email
US-23.18P1P0Mnot yetAuto-renewal reminder notifications
US-24.2P3yesRole-based portal permissions
US-24.3P3P1XLyesApproval workflow for subscription changes
US-24.4P3yesPurchase order as payment method
US-24.8P3yesMulti-location shipping
US-24.11P3not yetCatalyst storefront + Buyer Portal + subscription widget composite PDP behaviour
US-25.4P2P1MyesTenure-based loyalty discount
US-25.8P3yesGift-with-subscription
US-28.1MVPP0MyesGDPR data subject access request (DSAR)
US-28.2MVPP0LyesGDPR/CCPA erasure
Support / Ops — 19 stories
USPhasePriorityEffortVerifiedStory
US-2.5MVPyesProcessor health check
US-12.1MVPP0MyesRefund a charge
US-12.2P2P1LyesStore credit as payment for next charge
US-12.3MVPyesSkip cycle without refund
US-12.4P2yesMerchant-initiated one-time charge
US-12.5P2yesChargeback dispute handling
US-13.1MVPyesEvent log per subscription
US-13.3MVPP1MyesReplay a failed workflow
US-21.3MVPP0LyesException queue
US-22.1P2P1LyesCreate subscription manually
US-22.2MVPnot yetCustomer lookup from BC App Extension
US-22.3P1yesImpersonate subscriber (view-only)
US-22.4P1yesBulk subscription creation via CSV
US-22.5P1yesForce-charge / force-refund
US-22.6P2yesMerchant note on subscription
US-22.7P1yesAllotmentGrant management (issue, refresh-override, suspend, revoke)
US-22.8P1yesCustom-field admin UI — view, edit, validate
US-22.9P3yesB2B Edition — admin-only subscription enrollment for buyer-orgs (ADR-0023)
US-23.6P2yesGorgias / Zendesk integration
Developer — 14 stories
USPhasePriorityEffortVerifiedStory
US-8.3MVPP0Lnot yetHeadless SDK
US-9.5P2yesThird-party checkout support declaration
US-13.4MVPyesStructured logs with correlation IDs
US-13.5P2yesMetrics dashboard for platform SRE
US-17.5MVPP0LyesHeadless portal SDK
US-23.8MVPP0LyesOutbound webhooks
US-27.1MVPP0XLyesPublic REST API
US-27.3MVPyesOutbound webhook subscriptions
US-27.4MVPnot yetHeadless SDK (TypeScript)
US-27.5P2yesGraphQL API
US-27.6P3yesApp Marketplace for extensions
US-27.7P2yesSandbox test stores
US-28.4MVPP0MyesPCI DSS scope maintenance
US-28.5P2not yetSOC 2 Type II readiness
System — 26 stories
USPhasePriorityEffortVerifiedStory
US-1.4MVPyesWebhook subscriptions registered on install
US-1.6MVPP1SyesPersist BC staff on first load
US-1.7MVPP1MyesStamp mutating events with `actor_user_id`
US-9.1MVPP0SyesLine-item custom fields carry intent
US-9.2MVPP0Lyes`store/order/created` → Subscription creation
US-10.1MVPyesNightly schedule scan
US-10.2MVPP0XLyesCharge executor workflow
US-10.3MVPP0MyesCharge anchor-date math
US-10.4MVPyesCharge jitter for rate limiting
US-11.2MVPP0LyesRetry execution
US-11.3MVPP0MyesHard vs soft decline classification
US-11.4P2yesAutomatic Card Updater integration
US-12.6MVPyesTax handling on refund
US-13.2MVPP0LyesDaily reconciliation sweep
US-14.1MVPP0LyesCreate BC order on successful charge
US-14.3MVPyesFirst-order linkage
US-14.7P2yesNTI verification charge before stale-NTI renewal (PRD-COMPANION D21)
US-15.1MVPyesInventory check before charge
US-15.2MVPyesPrice recalculation at renewal
US-15.3MVPyesTax recalculation at renewal
US-15.4MVPyesShipping cost recalculation
US-16.2P1yesSingle BC order per combined shipment
US-16.4P1yesShipping cost allocation
US-23.14MVPP0SyesFailed-render fallback
US-23.15MVPP0MyesIdempotent send + dedupe
US-23.16MVPP1MyesWebhook ingestion (bounce / complaint / open / click)

Derived by tools/brd-sizing-view from BRD.md as of commit 83be22a7. Full per-story acceptance criteria live in the BRD (repo access) or the product spec.

Where to start

Per-capability deep dives

The handoff corpus — as-built detail per capability, generated from the same source this page draws on, with as_of_commitfrontmatter so you know how fresh each page is.

Full section index: Handoff corpus

Stack map

SurfaceStackDeployed on
apps/apiCloudflare Workers + D1 — the charge/subscribe/dunning/cancel money pathCloudflare Workers
apps/adminReact + BigDesign (BigCommerce's own design system)Cloudflare Pages
apps/storefront-svelte, apps/storefront-catalystTwo storefront integrations — Svelte (the live demo) and Catalyst (BC's headless React stack)Cloudflare Pages
apps/portalAstro — this site; internal/stakeholder communication, not part of the shipped productCloudflare Pages

Full rationale: Architecture

Things that will trip you up

  • Two storefront implementations exist (Svelte and Catalyst) — confirm which one your scope actually targets before estimating; they aren't interchangeable.
  • prototype/ is design reference, not production code — it informed the shipped design but isn't part of what runs. Don't sample it for a code-quality read.
  • The canonical payment rail (BC Payments stored-instruments) is integrated and live-proven — but read the rail split before estimating. New subscriptions charge through BC's gateway-agnostic payments API (live-validated end to end with Stripe as the underlying gateway, ADR-0082); pre-existing demo subscriptions ride a sanctioned direct-Stripe fallback for their remaining life. PayPal-specific (PPCP) same-session confirmation remains an external dependency to size separately.
  • Canonical spec docs (PRD, BRD, Architecture) cross-reference internal decision records by ID (e.g. "ADR-0037") — each is hyperlinked to its actual content, so click through rather than treating the ID as something you need to already recognize.

Known limitations

16 acceptance criteria across 10 epics don't have a passing automated scenario yet — named, not estimated. Full list, grouped by area: Code Review.

Run the whole thing — day one

No single composed command starts every app — they're loosely coupled and mostly run independently. Below is the documented bootstrap plus the two apps most relevant to a first day (API + admin, wired together). Full detail, including the prototype-only fast path and per-app port list, is indocs/runbooks/local-dev-env.md.

git clone git@github.com:nino-chavez/bc-subscriptions.git
cd bc-subscriptions
git config core.hooksPath .githooks   # one-time per clone
npm install

# Terminal 1 — API (Cloudflare Workers, emulates D1/KV/R2/queues locally)
cd apps/api
npx --yes wrangler@4 d1 migrations apply subs-api-d1 --local --persist-to .wrangler/state
npx --yes wrangler@4 dev              # → http://localhost:8787

# Terminal 2 — admin, pointed at the local API
cd apps/admin
API_URL=http://localhost:8787 npm run dev   # → http://localhost:3000

Fastest cold-start path if you only need the design reference (no cloud access required):cd prototype && npm install && npm run devhttp://localhost:5174. Operator-only credentials (Cloudflare API token, BC sandbox creds, GH workflow_dispatch) are not needed for any of the above — only for deploys and BC-sandbox integration testing.

Integrate

  • @bc-subscriptions/reactrepo · team access
    Hooks + components for subscription PDPs, cart, and account portal.
  • @bc-subscriptions/storefront-catalystrepo · team access
    BigCommerce Catalyst bindings — server actions, storefront-framework queries, route handlers pre-wired for subscriptions.
  • @bc-subscriptions/storefront-webcomponentrepo · team access
    Framework-agnostic custom element for Stencil and other non-React storefronts.
  • @bc-subscriptions/design-tokensrepo · team access
    OKLCH-based tokens, framework-agnostic CSS variables. Tailwind preset + raw CSS exports.

Decision log: Decisions

Day-one checklist

  1. Get real repo read access (the operator arranges this directly — see Code Review for what "real access" means here).
  2. Touch the live system before reading a line of code — the demo is faster ground truth than any document.
  3. Run the test suite and typecheck yourself (commands at Code Review) — confirm the same pass/fail state this page implies.
  4. Read Architecture for the data model and integration seams before writing any code.
  5. Confirm scope against the four options above before sizing anything.
Owner: operator (Nino Chavez) · re-attest quarterly, or immediately after a stack-boundary or infra-phase change · last reviewed 2026-06-30