> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscription Retries & Payment Methods

> How Waffo retries a failed subscription deduction, when it stops retrying and what that does to the subscription, how the rolling retry window works, and the full rules for binding, ordering, replacing and deleting the payment methods on a subscription.

This page is the deep dive on what happens **after** a subscription deduction
fails, and on the payment methods bound to a subscription. For the shape of
the subscription APIs and which notifications to subscribe to, start at the
[Subscription FAQ](/docs/en/support/subscription-faq); for deferred starts and
amount updates see
[Subscription lifecycle](/docs/en/support/subscription-lifecycle-management).

## A subscription deduction failed. Will Waffo retry it automatically?

Yes. You never have to trigger a subscription retry yourself, and you should
not create a replacement order for the same period.

* The period's order moves into a *needs retry* state and Waffo re-attempts it
  on a schedule derived from your contract's retry strategy.
* Every attempt — including the failure reason and the attempt count — is
  pushed on the subscription payment order notification, so you can follow the
  sequence without polling.
* The **subscription itself keeps running** while retries are in flight. Its
  status does not change because a period failed.

## How is the retry schedule decided?

By a retry strategy on your acquiring agreement, and the strategy is selected
**per billing cycle** rather than one global setting. Waffo resolves the
strategy from the subscription's `periodType` and `periodInterval` into one of
six buckets. The mapping is by the **length** of the cycle, and the bucket
boundaries are not where the names suggest:

| `periodType` | `periodInterval` | Strategy bucket |
| - | - | - |
| `MONTHLY` | 1–3 | `MONTHLY` |
| `MONTHLY` | 4–11 | `QUARTERLY` |
| `MONTHLY` | 12 or more | `YEARLY` |
| `WEEKLY` | 1–3 | `WEEKLY` |
| `WEEKLY` | 4 | `MONTHLY` |
| `DAILY` | 1–6 | `DAILY` |
| `DAILY` | 7–29 | `WEEKLY` |
| `DAILY` | 30–119 | `MONTHLY` |
| `DAILY` | 120–364 | `QUARTERLY` |
| `DAILY` | 365 | `YEARLY` |
| any | no interval stored | `DEFAULT` |

Two consequences that surprise people: a **quarterly** subscription
(`MONTHLY` + `3`) uses the **`MONTHLY`** bucket, not `QUARTERLY`; and a
**half-yearly** one (`MONTHLY` + `6`) is the one that lands in `QUARTERLY`.
`DEFAULT` is also used when your agreement has no strategy configured for the
resolved bucket.

Each bucket carries three knobs: the **retry interval**, the **interval unit**
(days), and the **maximum number of attempts** for that period. The values are
commercial terms rather than platform constants — ask your Waffo contact for
the policy configured on your account, and do not hardcode an assumed schedule
in your reconciliation logic.

## Is there an overall cap on retries, on top of the per-period maximum?

Yes. Independently of your contract's per-period maximum, card retries are
capped by a **rolling window** across the account, so that Waffo stays within
card scheme rules on retry frequency.

* The window is rolling, not calendar-based: it always looks at the trailing
  period, not at a calendar month.
* When an attempt would breach the window, it is not failed — it is **deferred
  to the first date on which it fits**.
* Waffo does not publish the numeric ceiling, because it tracks card scheme
  requirements rather than a Waffo product decision. Treat the window as a
  reason a retry may land later than your contract's interval predicts.

Attempts made on a **backup** payment method are deliberately excluded from
this window (see below), so an immediate backup attempt never consumes the
allowance for the default method.

## When does Waffo stop retrying, and what happens to the subscription?

Retries end when any of the following holds:

| Condition | Effect |
| - | - |
| The period's attempts reach the contract maximum | The period's order is **closed**. |
| The subscription has been cancelled and your contract closes pending retries on cancellation | Pending retry orders are closed. |

The important part, and the most common source of confusion:

When retries are exhausted, **only that billing period's order is closed. The
subscription's own status is left untouched** — it does not move to a cancelled
or suspended state, and the next period will be attempted on schedule.

So a closed period order is not a signal to revoke the customer's access
permanently. If you want dunning behavior — suspend the entitlement after N
failed periods, cancel after M — you must implement that on your side from the
period-level notifications, and call the cancel API yourself when your policy
says so.

## Can I tell from the API response whether a particular failure is retryable?

Not from a dedicated flag. There is **no merchant-facing "retryable" field** on
the subscription failure response, the async notification, or the inquiry
response on the current release. Determine where you stand from:

* the period order's status (still retrying vs. closed), and
* the failure code returned for the attempt, and
* the attempt count on the notification against the strategy for your contract.

Do not build logic against a `retryPayment` or `retryAble` field — they are not
part of the merchant contract and are not populated for you.

## I cancelled a subscription while a retry was pending. Do those retries stop?

It depends on one setting in your agreement, and the scope is narrower than
"everything stops":

* **Orders waiting for their next retry** are closed on cancellation — but only
  if the *close-retries-on-cancellation* setting is enabled on your agreement.
  It is **off by default**, so confirm it with your Waffo contact if your
  requirement is that no further attempt is ever made after a cancellation.
* **Orders already submitted to a payment method** are never force-closed by
  cancellation. Waffo keeps listening for their result and reports the real
  outcome, because the money may already be moving. Expect that a cancelled
  subscription can still produce one final success or failure notification.
* Orders that were already in a final state are unaffected.

Practical consequence: after you call cancel, keep your webhook handler able to
accept one more payment result for that subscription.

## Can one subscription have more than one payment method?

Yes. A subscription carries an ordered list: one **default** method plus any
number of **backups** in priority order. Users manage the list themselves on
the hosted subscription management page; the subscription detail response
returns `canChangePaymentMethod` and the bound list so you can render your own
view.

Each bound method has its own status:

| Status | Meaning |
| - | - |
| `IN_PROGRESS` | Added, authorization not yet completed. Not chargeable. |
| `ACTIVE` | Verified and chargeable. **The only status that can be used for a deduction.** |
| `EXPIRED` | Past the card's expiry date. Set by a daily check, not at charge time. |
| `SUSPENDED` | Not offered at checkout and cannot be the default. |
| `CLOSED` | Terminal. Includes methods whose authorization never completed. |

## Why does adding a payment method create a zero-amount order?

Because the method has to be proven chargeable before Waffo will bill it. When
a user adds a method:

1. Waffo creates a **zero-amount authorization order** dedicated to verifying
   the method.
2. The response returns a **checkout link** for the user to complete the
   authorization. The link is cached, so retrying the add for the same method
   returns the same link rather than opening a second attempt.
3. The method is stored as `IN_PROGRESS` and **not** as the default.
4. On successful authorization it flips to `ACTIVE`. If the credential cannot
   be resolved afterwards, it goes to `CLOSED` instead — it never silently
   stays pending.

The verification order is short-lived, so send the user to the link promptly
rather than storing it for later.

## What happens when the default payment method fails to charge?

If backups are bound, Waffo tries them **immediately, in priority order,
without waiting for the retry interval**. That is the whole point of a backup:
it converts a multi-day retry cycle into a same-moment second attempt.

* The next retry time for the backup attempt is set to *now*.
* Backup attempts are **not** added to the rolling window, so they do not
  consume the default method's allowance.
* Backup attempts do **not** trigger the retry-exhausted email to the user.
* Once every backup has been tried and failed, the default method is restored
  and the normal interval-based strategy resumes.

## Which payment-method changes are blocked?

| Attempt | Result |
| - | - |
| Change methods on a subscription that is not `ACTIVE` | Rejected. Cancelled and expired subscriptions are included, but so is every other non-active status. |
| Change methods on a not-yet-started subscription, before its first bind | Allowed — this is the one carve-out from the rule above. |
| Delete the **default** method of an `ACTIVE` subscription | Rejected. Set a different default first, then delete. |
| Delete or set-as-default a method that is not `ACTIVE` | Rejected. Only `ACTIVE` methods are valid targets. |

## The user's card is about to expire. Will Waffo warn them, or refresh the card?

Neither is safe to assume, and this is worth reading carefully because it is
the most common wrong expectation:

* **Waffo does not refresh stored cards from issuer-side card updates.** There
  is no automatic account-updater integration. When a bank reissues a card with
  a new number or expiry date, the stored credential does **not** silently
  follow — plan for re-binding.
* Waffo does surface an **expiring-soon flag** on the subscription detail
  response for methods approaching their expiry date, so you can prompt the
  user in your own product. Treat that flag, not an email, as the signal to
  act on.
* Once the expiry date passes, a daily check moves the method to `EXPIRED` and
  it stops being chargeable.
* Wallet-type saved methods are different: where the wallet itself notifies
  Waffo that a credential was updated or unlinked, that update is applied. This
  does not extend to plain stored cards.

The durable safeguard is to keep at least one **backup method** bound on every
subscription, and to prompt the user as soon as the expiring-soon flag appears.

## The shopper's card was rejected at checkout before any charge. Why?

Because some card products are not suitable for recurring billing, and your
agreement can carry a list of **blocked card sub-types** for subscriptions.
During checkout Waffo looks up the card's BIN, and if its sub-type is on that
list the card-based methods are removed from the options. If nothing is left,
the shopper sees a message along the lines of:

> Sorry, we do not accept this type of card for subscriptions. Please try a
> different card (e.g., standard Credit or Debit card).

Notes for handling this:

* The list is configured per agreement. There is no fixed platform-wide
  blocklist, so ask your Waffo contact what is configured for your account.
* The check happens at **checkout**, on the card the shopper actually enters —
  not when you create the subscription. So a subscription create can succeed
  and the shopper still be turned away on the checkout page.
* Your recovery path is the same as any decline: ask the shopper for a
  different card. Retrying the same card will not change the outcome.

## I did not pass `numberOfPeriod`. When does the subscription end?

An omitted `numberOfPeriod` does not mean "forever in practice" — your
agreement carries a **maximum duration in years** for a subscription, and Waffo
resolves the total period count from it:

* With `numberOfPeriod` omitted, the total period count and the end time are
  **derived** from the start time plus the agreement's maximum duration. The
  create request is accepted; nothing is rejected. The derived values are
  written when the first period succeeds, so read them back from the
  subscription rather than computing them yourself.
* With `numberOfPeriod` supplied but long enough that the last deduction would
  fall beyond that maximum duration, the create is **rejected** rather than
  truncated. The same check applies to `numberOfTrialPeriod`. You get a
  no-available-payment-method error, which in this case means "no agreement can
  carry a subscription this long", not "this card is unsupported".

Card expiry is **not** an input to either calculation. A card expiring next
year does not shorten the subscription; it just means the method will move to
`EXPIRED` and you will need a new one bound.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.