Invariants
The package enforces a set of invariants fail-closed: when a precondition is not met, it refuses rather than proceeding on a guess. Each throws a typed exception at the point of failure.
- A webhook signing secret is required in production. No secret → the package refuses to boot, so the installation's own events are never rejected unseen. A payments-only installation without a Stripe key of its own has no own account that signs events and is not asked.
- A metered tier needs a driver that can report usage. A tier that bills for usage on a driver that cannot report it refuses to boot, rather than counting every unit and invoicing none.
- The money-eligibility gate is fail-closed.
CanTransactMoneysits in front of every money-moving surface; an owner it cannot clear is refused, not charged. - Holding funds is gated.
billing.marketplace.custody.platform_heldcannot be turned on by a flag alone — it requires a boundPaymentServiceLicenseAttestation(see Security). - A retention floor cannot be set below the statutory minimum without an explicit jurisdiction opt-in.
- An invoice correction carries positive amounts and, when it amends, an origin reference. A negative amount or an amendment with no reference is refused at construction.
- The audit ledger is append-only. An update or a delete made through the model throws. The package removes a row in two places only, the retention prune and an erasure request, and both delete by query, which this guard does not see.
When one of these fires, the Troubleshooting guide maps the error message to its cause.