Every subsystem billing needs, built for the failure mode that costs a team real money. Composable behind a single, versioned interface.
Flat, tiered, volume, graduated, and per-seat pricing on one model. Upgrade, downgrade, pause, and resume mid-cycle with proration that reconciles.
subscription.update()proration: credit + debiteffective: now | period_end→ invoice.draft
Ingest raw events over the API, deduped on an idempotency key. Aggregate by sum, max, or unique count inside a locked period, then rate into invoices.
POST /api/v1/usage{ customer_id, records: [{ price_id, quantity, action }] }→ 201 deduped · period-locked→ usage.recorded
Every cent is a double-entry journal in minor units, so debits equal credits on every write. Settlements reconcile against the processor one to one.
journal: DR cash / CR ARreconcile == gatewayrecognize revenue→ ledger.posted
The entire payment edge sits behind adapters. Pick a gateway per tenant, per currency, or per rule. Charge, clear 3DS, retry soft declines, normalize webhooks.
route → { adyen | stripe }charge · 3ds · retrywebhook → normalized→ payment.succeeded
Marketplace splits and scheduled payouts, gateway-neutral. Hold, release, and reverse with the same ledger discipline as inbound money.
payout.create(splits)hold → releasescreen → clear→ payout.paid
Configurable retry schedules with smart backoff and a past-due state machine that stops charging when it should. Test and live never mix.
retry: [1d, 3d, 5d]backoff · jitterpast_due → canceled→ recovered | churned