SYSTEM OVERVIEW
The Event Pipeline
How 50,000–100,000 daily Stripe events become structured messages that drive billing decisions.
196 event types enter. Structured messages exit. The pipe resolves Stripe customer IDs to Cloudflare accounts via subs_customer, then forwards to the engine. Median latency from Stripe event receipt to engine delivery: under 1 second.
Nothing happens until Stripe fires an event. The billing platform does not poll, does not schedule billing decisions, and does not independently decide when to charge. Every state change — payment succeeded, invoice finalized, subscription updated — is a reaction to a Stripe webhook. This is why billing state can lag, why race conditions exist between handlers, and why the dunning brain must be idempotent.
billing-webhooks runs 27 handlers. Each handler receives a Stripe event, resolves the associated Cloudflare account, and forwards a structured payload to the engine. The design principle is strict: no decisions, just routing. The pipe is not allowed to know whether a customer should be flagged, banned, or cancelled.
customer.subscription.updated → subscriptions webhook. customer.subscription.deleted forwarded but ignored — subs-api database owns cancellation state.
invoice.paid, invoice.payment_failed, invoice.finalized, invoice.marked_uncollectible → dunning endpoint. Primary triggers for flag lifting and bad-debt marking.
mandate.updated, setup_intent.succeeded → mandates webhook. Covers payment method authorization and direct debit setup.
customer.updated, customer.source.updated → customers webhook. Keeps engine's view of customer metadata and payment method state current.
| Event | Trigger | What Happens |
|---|---|---|
invoice.payment_succeeded | Stripe payment clears | Engine evaluates flag lifting — removes dunning flags if conditions met — see Dunning & Recovery |
invoice.payment_failed | Stripe payment attempt fails | Engine evaluates retry schedule and escalation path |
invoice.marked_uncollectible | Stripe dunning exhausted | Engine marks bad debt, applies ban, cancels subscription — see Dunning & Recovery |
customer.subscription.updated | Stripe subscription state changes | Engine syncs OPE state — value phases, status, schedule alignment |
subscription_schedule.released | Stripe schedule phase transition fires | Engine applies delayed downgrade or SSLC — moves OPE to next value phase — see Subscription Lifecycle |
charge.refunded | Refund issued on a charge | Engine evaluates impact on dunning state and bad-debt flags |
The end state is simple: billing-webhooks resolves accounts and forwards events. subscriptions-api holds all billing intelligence. The current contamination is a historical artifact — decisions accumulated in the pipe before the engine had the infrastructure to handle them. Brain Expansion removes the contamination without changing the event flow.
The pipe is designed to be dumb — resolve accounts, route events. The engine holds the intelligence. That separation is the invariant Brain Expansion enforces.