Skip to content

Retries

Failed invoice charges use a default retry schedule from @autlantic/payments-recurring-core. Hosted Autlantic renewals and the billing engine follow this policy unless configured otherwise.

Default policy

ts
import { DEFAULT_RETRY_POLICY } from "@autlantic/payments-recurring-core";

// {
//   maxAttempts: 4,
//   retryDelaysDays: [0, 1, 2, 4],
// }
AttemptMeaningDelay after previous failure
1First charge try (attemptCount becomes 1 on failure)Immediate / due time
2First retry1 day later
3Second retry2 days after previous failure
4Final retry4 days after previous failure
After 4 failuresNo more automatic attemptsSubscription may move to past_due

Helpers:

ts
import {
  nextAttemptAtAfterFailure,
  hasMoreAttempts,
  shouldMarkPastDue,
  DEFAULT_RETRY_POLICY,
} from "@autlantic/payments-recurring-core";

const next = nextAttemptAtAfterFailure(failedAt, attemptCountAfterFailure);
// null when attempts are exhausted

hasMoreAttempts(invoice.attemptCount); // true while under maxAttempts
shouldMarkPastDue(invoice.attemptCount); // true at/after maxAttempts

Invoice fields

On RecurringInvoice:

FieldRole
attemptCountHow many charge attempts have run
nextAttemptAtWhen the next automatic attempt is scheduled
failureCodeLast failure (Error codes)
statusStays open during the retry window; may become uncollectible when giving up

What you should do as a merchant

  1. Listen for invoice.payment_failed and subscription.past_due.
  2. Message the member using failureCode (fund wallet, re-approve, etc.).
  3. Do not spam chargeInvoice on the same open invoice unless you intend a manual retry outside the schedule.
  4. After success, you get invoice.paid and the subscription period advances.

Sandbox

In-process sandbox can force declines with chargeInvoice(id, "insufficient_balance" | "allowance_revoked") so you can test retry messaging without waiting real days.

Autlantic Payments SDK