Subscription Billing Cron
Subscription Billing Cron
Calmony Pay uses an Inngest cron function to automatically charge active subscriptions on a recurring schedule. This page describes how the billing cron works, what happens on success and failure, and how retries are handled.
Overview
The billing cron runs hourly and finds every active subscription whose current billing period has ended (currentPeriodEnd <= now). For each such subscription, it attempts to charge the customer's default payment method via a Payment Intent.
Hourly cron
└─ Find active subscriptions where currentPeriodEnd <= now
└─ For each subscription
├─ Create Payment Intent (default payment method)
├─ On success → extend period + create invoice
└─ On failure → retry (max 3x over 3 days) → past_due
Successful Charge
When a Payment Intent is confirmed successfully:
- The subscription's
currentPeriodEndis advanced by the billing interval (e.g. +1 month). - An invoice record is created and associated with the subscription and payment.
Failed Charge & Retry Logic
If the charge fails, the Inngest function retries automatically:
| Attempt | Timing |
|---|---|
| 1st retry | Shortly after initial failure |
| 2nd retry | ~1 day after initial failure |
| 3rd retry | ~3 days after initial failure |
After 3 failed retry attempts, the subscription status is updated to past_due and no further charges are attempted automatically.
NonRetriableError
Certain failure modes are treated as immediately unrecoverable — for example, a permanently declined card or a missing/invalid payment method. These are raised as NonRetriableError, which stops the retry cycle immediately without waiting for all three attempts.
Concurrency
The cron function applies a concurrency limit to control how many subscriptions are processed in parallel. This prevents a large batch of simultaneous renewals from overwhelming downstream services (Cardstream, Griffin, the database).
Subscription Statuses
| Status | Description |
|---|---|
active | Subscription is current; billing cron will charge on renewal |
past_due | All retry attempts exhausted; manual intervention or dunning required |
Notes
- The billing cron only processes subscriptions in
activestatus. - Subscriptions are not cancelled automatically when they become
past_due— downstream dunning or cancellation logic can be layered on top. - Each successful charge produces a linked invoice, queryable via the Invoices API.