Recurring payments on top of the vault primitives. The design honors the
library's one hard rule — PayFanout persists nothing — by INJECTING the
storage: the host hands over a SubscriptionStore (its database) and a cron
trigger (chargeDueSubscriptions), and this manager supplies everything
else: period math, off-session charging with deterministic idempotency,
retry/dunning policy, and status transitions.
PSP-native billing products (Stripe Billing) are NOT wrapped —
most PSPs have no equivalent, and an abstraction over one PSP is not an
abstraction. This engine gives every vaulting-capable PSP identical
subscription behavior.
Recurring payments on top of the vault primitives. The design honors the library's one hard rule — PayFanout persists nothing — by INJECTING the storage: the host hands over a SubscriptionStore (its database) and a cron trigger (
chargeDueSubscriptions), and this manager supplies everything else: period math, off-session charging with deterministic idempotency, retry/dunning policy, and status transitions.host cron ──> manager.chargeDueSubscriptions() ──> service.chargeSavedPaymentMethod() │ │ host's SubscriptionStore PSP vault token
PSP-native billing products (Stripe Billing) are NOT wrapped — most PSPs have no equivalent, and an abstraction over one PSP is not an abstraction. This engine gives every vaulting-capable PSP identical subscription behavior.