THE cron entry point — run it every few minutes/hours from the host's scheduler. Idempotent and crash-safe: renewal idempotency keys are derived from (subscription id, period, attempt), so a crashed run that re-charges after the store missed an update dedupes at the PSP.
Prefers store.listDue (host-indexed batches) when implemented, falling back to per-status list() scans (active, trialing, past_due); either way every candidate's due-ness is re-checked here before any charge.
Concurrent runs are safe for MONEY (charges converge at the PSP) but not for events (at-least-once, see onEvent) — hosts wanting single-run semantics should hold a lock around this call.
Optionalat: string | DateStarts a subscription. Immediate start charges the first period NOW (customer-present, credential-on-file "initial") — a failed first charge throws and persists nothing, so hosts never hold a subscription that never collected. A future startAt begins a trial window instead: the record is "trialing" until the first charge collects.
Optionalfilter: { pspCustomerId?: string; status?: SubscriptionStatus }Halts billing without ending the subscription: the cron skips paused records and dunning stops (nextRetryAt is cleared; failedAttempts and any pendingRenewal survive untouched — an unresolved renewal still resolves via resolvePendingRenewal, but a paused record is never re-charged). Pausing a paused record is a no-op; canceled records cannot pause.
Applies the final outcome of a renewal charge that resolved as "processing" (async rails). Wire it to the host's payment webhook ingress (payment.succeeded / payment.failed with a matching pspPaymentId) — until it runs, the subscription is frozen: chargeDueSubscriptions never charges on top of an unresolved renewal. Replay-safe: re-resolving an already-applied success is a no-op. Resolving never reactivates: a record paused (or canceled) in the meantime keeps its status — a success still advances the paid-through window (the money moved), a failure is recorded without entering dunning.
Optionalerror?: { code?: UnifiedErrorCode; message?: string }OptionalpspPaymentId?: stringFrom the webhook — guards against applying a different payment's outcome.
Reactivates a paused subscription. Still paid through -> just "active", nothing is charged. Lapsed -> ONE immediate charge (occurrence "recurring", the caller's idempotencyKey — retry a storage failure with the SAME key so the PSP replays instead of re-charging) re-anchors the billing cycle at the resume instant. A failed charge leaves the record paused with lastError — no dunning — and throws. A charge resolving as "processing" freezes the still-paused record under pendingRenewal: resolve it, then resume again (paid through by then, so no second charge).
Plan/instrument changes apply from the NEXT period (no proration — the already-paid window stands). Changing the token also clears dunning: a fresh card deserves a fresh chance at the next renewal. Emits "subscription.updated" (renewals never do).
Immediate cancel stops everything now (the rest of the paid window is forfeit — no refund is initiated; use refundPayment separately if owed). atPeriodEnd lets the paid window run out, then ends without charging.