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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions