Skip to content

[Commercial Gap] Build monotonic, auditable Stripe subscription lifecycle #488

Description

@seonghobae

Buyer problem

ScopeWeave exposes billing and entitlement concepts but does not yet have a release-safe Stripe subscription lifecycle. A production integration must not upgrade or downgrade an organization from a replayed, out-of-order, oversized, host-header-influenced, or incompletely mapped provider event.

Required vertical slice

Trusted configuration and Checkout

  • validate complete billing configuration at production startup;
  • use an operator-configured canonical public origin for success/cancel URLs;
  • model a durable checkout attempt with an opaque UUID, organization, expected price, lifecycle state, and a stable Stripe idempotency key;
  • bound provider connect, total time, redirects, response bytes, and JSON parsing;
  • canonicalize and validate the returned Checkout host with URL, not string-prefix logic;
  • store Stripe customer, checkout-session, subscription, and price identifiers in normalized tables.

Webhook trust boundary

  • enforce Content-Length where present and a streaming hard limit before buffering beyond the cap;
  • verify Stripe-Signature over exact raw bytes with a bounded timestamp tolerance and constant-time digest comparison;
  • persist event ID, provider creation time, object ID/type, API version, request ID where available, payload hash, received time, processing result, and replay state without retaining raw sensitive payloads indefinitely;
  • deduplicate exact event IDs;
  • reconcile out-of-order events using the latest authoritative Stripe object state or a monotonic per-object cursor rather than arrival order;
  • never trust mutable client plan state or metadata as the only durable identity link.

Entitlement state machine

  • model customer, subscription, invoice/payment, and organization-entitlement state separately in third normal form;
  • define trialing, active, past_due, unpaid, paused, canceled, and incomplete-state policy explicitly;
  • provision initial access from successful Checkout/subscription state and renewal access from authoritative invoice/subscription state;
  • keep entitlement changes transactional, idempotent, auditable, and reversible;
  • fail unknown organization/customer/subscription links closed.

Verification

  • real database migration tests, not request-time DDL;
  • true API tests for unsigned, malformed, stale, oversized, chunked, and replayed bodies;
  • out-of-order event permutations that converge to the same final entitlement;
  • concurrent duplicate delivery tests;
  • provider timeout, invalid JSON, oversized response, wrong host, and retry tests;
  • test-mode Stripe live smoke through protected NVIDIA_NIM_API_KEY-independent CI secrets only when explicitly configured;
  • production statement/branch/function/line coverage and public docstrings at 100% for the billing modules;
  • CHANGELOG, operations, incident/rollback, privacy, and APA 7th doctoring records.

Authoritative baseline

Use Stripe's current Checkout Sessions, subscription webhook, webhook-signature, idempotency, API-version, and event-ordering documentation. Preserve useful raw-body HMAC and constant-time verification work from closed PR #456, but do not copy its request-time DDL, request-derived origin, unbounded body/provider transport, random per-call idempotency, or arrival-order entitlement overwrite.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: apiAPI, protocol, event, or external contractarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionpriority: mediumNormal-priority or P2 workscope: commercial-readinessProduction, enterprise, release, or commercial readinessstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions