Retry / Past Due Flow

The retry and past-due flow handles failed subscription renewal payments.

When a renewal payment fails, the subscription does not remain active. Instead, it moves to PAST_DUE, access should be blocked, and the system retries payment within the configured retry/grace period.

When A Subscription Becomes Past Due

A subscription becomes PAST_DUE when an automatic renewal payment fails.

Common Reasons

ReasonDescription
Insufficient fundsCustomer’s card does not have enough balance.
Card declinedIssuer or processor declined the charge.
Expired cardSaved card has expired.
Invalid authorizationSaved card authorization can no longer be charged.
Provider failurePayment provider returned a failed charge response.

Past Due Behavior

When Payment Fails

  • subscription.status = PAST_DUE
  • subscription.isActive = false
  • invoice.status = PAYMENT_FAILED
  • pastDueAt = first failed payment date
  • retryCount += 1
  • nextRetryAt = next retry date
  • The customer should not have access while the subscription is PAST_DUE.

Default Retry Policy

By default:

  • maxRetryCount = 3
  • gracePeriodDays = 3

This means the system retries the failed renewal during a 3-day grace window.


Configuration

You can configure these values when creating the subscription:

{
  "maxRetryCount": 3,
  "gracePeriodDays": 3
}

Retry Timeline Example

For a monthly subscription due on May 1:

DateEventSubscription StatusAccess
May 1Renewal charge failsPAST_DUEBlocked
May 2Retry attempt failsPAST_DUEBlocked
May 3Retry attempt failsPAST_DUEBlocked
May 4Final retry fails / grace exhaustedCANCELLEDBlocked

If Any Retry Succeeds

  • subscription.status = ACTIVE
  • subscription.isActive = true
  • retryCount = 0
  • pastDueAt = null
  • nextRetryAt = null
  • invoice.status = PAYMENT_SUCCEEDED

Successful Retry

If a retry succeeds before the grace period is exhausted:

PAST_DUE → ACTIVE

 
Webhook Events  
invoice.payment_succeeded  
invoice.updated  
subscription.active

The customer can regain access.

Failed Retry After Grace Period

If retries continue to fail until the grace period is exhausted:

PAST_DUE → CANCELLED

invoice.payment_failed
invoice.updated
subscription.cancelled

The subscription will no longer renew automatically.

Card Update During Past Due

If a subscription is PAST_DUE, the customer can update their card:

POST /v1/subscriptions/:subscriptionIdOrCode/update-card

After the card is successfully updated, the next charge attempt can recover the subscription.

Manual Payment Methods

For manual methods such as:

  • mobile_money
  • bank_transfer
  • bank

The customer must complete checkout manually.

If payment is not completed, the subscription remains unpaid and should not be treated as active.

Webhook Events

The retry/past-due flow may emit:

EventDescription
invoice.payment_failedA renewal payment failed.
invoice.updatedInvoice retry/status information changed.
subscription.past_dueSubscription entered past-due state.
invoice.payment_succeededRetry payment succeeded.
subscription.activeSubscription recovered and became active.
subscription.cancelledSubscription was cancelled after retry/grace exhaustion.

Important Notes

  • PAST_DUE subscriptions should not receive service access.
  • nextRetryAt tells you when the next retry is scheduled.
  • retryCount tells you how many retry attempts have happened.
  • pastDueAt remains the original first failure date.
  • The system prevents duplicate charges for the same billing cycle using idempotency locking.
  • If all retries fail, the subscription becomes CANCELLED.