Cascading Processing
How FloPay's auto-checkout cascade charges a returning customer's saved payment methods — the order methods are tried, how a stale saved card self-heals through the vault, which declines move on to the next card, and the interactive and unattended modes.
Cascading Processing
When a returning customer checks out with their saved payment methods, FloPay doesn't bet the whole sale on a single card. The auto-checkout cascade walks the customer's saved payment methods in most-recently-used order, retries the same card when that makes sense, self-heals a stale saved card by refreshing it through the vault, and stops the moment a charge succeeds — or the moment continuing would do more harm than good.
This guide explains how that works: how saved methods are chosen, the two ways each one is charged, exactly which declines move on to the next card versus stop the run, the interactive and unattended modes, and what you can observe when a cascade runs.
Availability. The interactive cascade described here is the live path for returning-customer auto-checkout: creating a session with checkoutMode=auto walks the customer's saved methods through the cascade in production — it is no longer a single most-recently-used attempt. unattended mode remains reserved (see Modes).
Overview
The cascade is a single run over a returning customer's vaulted payment methods:
- Select the customer's most-recently-used active, vaulted payment methods.
- For each method, attempt the charge — using the saved provider token directly first, then, for cards, refreshing the token through the vault as a self-heal.
- Classify the result. A success ends the run. Some declines mean "this card is a lost cause, try the next one"; others mean "stop the whole run." A 3DS challenge pauses the run and hands a redirect URL back to the SDK. A transient error retries the same card.
- Stop on the first success, a terminal decline, a 3DS pause, or once every eligible method has been tried.
Selection
The cascade only considers a customer's saved payment methods that are:
- Theirs — tied to the checkout session's signed-in customer. A guest session with no customer has nothing to cascade over and ends immediately.
- Active — methods the customer has removed, or that have been revoked, are skipped.
- Vaulted — only methods held in the vault can be charged again off-session.
Eligible methods are tried most-recently-used first, so the card the customer reached for last time is tried first. Only a handful of the most recent methods are walked in a single cascade; a customer with a long history of saved cards won't have every one tried on a single checkout.
Two ways each method is charged
Each saved method can be charged two ways. The direct attempt is the default; the vault refresh is a fallback the cascade reaches for only when a saved card's token has gone stale.
Direct — saved provider token
The first attempt always uses the token already saved with the payment method to charge the provider directly, with no vault round-trip.
- Card — uses the saved provider token to confirm the charge directly. This is fast and doesn't touch the vault.
- PayPal — the PayPal vault token is resolved server-side and doesn't go stale the way a saved card token can, so PayPal never needs a vault refresh.
Vault refresh — self-heal (cards only)
If a saved card's token has gone stale, the cascade refreshes it: it mints a fresh token from the card's vaulted details, saves the new token onto the payment method, and retries the charge so the next attempt uses the fresh token.
The vault refresh is card-only and happens in two situations:
- Self-heal after a stale token. When a direct attempt on a card reports a stale token, the cascade refreshes once and retries before giving up on that card.
- First charge with no saved token. A card that has never been charged off-session has no saved provider token yet, so it is refreshed through the vault before its first attempt.
The vault refresh is a self-heal, not the default path. It runs at most once per card. If the refresh fails, or the card is still reported stale after a fresh token, the cascade moves on to the next method rather than looping. PayPal methods never refresh and simply move on if their token is stale.
Decline classification
When an attempt comes back as a decline, the cascade decides what to do next based on the decline reason. The reason is gateway-agnostic — both the Stripe and PayPal flows translate their gateway's response into the same set of reasons — so the behaviour below is the same whichever gateway charged the card.
| Decline reason | Action | Why |
|---|---|---|
USER_ERROR | Next card | Wrong CVV / PIN — the bank already gave this card a chance; try the next method. |
AVS_FAIL | Next card | Address mismatch — re-charging the same card won't pass AVS. See AVS. |
INSUFFICIENT_FUNDS | Next card | This card is short; another card may clear. |
DO_NOT_HONOUR | Next card | Generic issuer decline — try the next method. |
EXCEEDS_CARD_LIMIT | Next card | Over the card's limit; another card may clear. |
RETRYABLE_DECLINE | Next card | The issuer signalled the charge is reasonable to retry elsewhere. |
PAYMENT_GATEWAY_ERROR | Next card | A gateway-side error on this charge; the next method may route cleanly. |
TECHNICAL_ERROR | Next card | A technical failure on this attempt; try the next method. |
UNKNOWN_DECLINE_REASON | Next card | An unclassified decline — move on rather than stop the run. |
3DS_FAIL | Stop | The cardholder failed or declined the 3DS challenge — burning through more cards won't help and risks tripping fraud alarms. |
TOO_MANY_ATTEMPTS | Stop | The bank has rate-limited this customer — stop. |
CLIENT_ERROR | Stop | An unclassified client-side error from the gateway — stop and surface it. |
UNSUPPORTED_CARD_PURCHASE | Stop | The card or purchase type isn't supported — stop. |
Conservative by default. Any decline reason not listed above moves on to the next card rather than stopping the run. A decline only stops the cascade if it is one of the explicit "Stop" reasons above.
Non-decline results
Not every attempt comes back as a decline. An attempt can also resolve one of these ways, which the cascade handles before the decline table applies:
| Result | Action | Behaviour |
|---|---|---|
| Success | — | The charge cleared. The cascade returns success with the method that worked. |
| 3DS required | Pause | The issuer wants a 3DS challenge. The cascade pauses with three_ds_required and surfaces a redirect URL for the SDK to render. Interactive mode only. |
| Stale card | Vault refresh | The saved token is stale. On a card this triggers a single vault refresh and retry; PayPal moves on instead. |
| Transient error | Retry | A blip. The cascade waits briefly and retries the same method. |
Cascade outcomes
A whole run resolves to exactly one outcome:
| Outcome | Carries | Meaning |
|---|---|---|
success | the payment method that worked | A method charged successfully. |
three_ds_required | the payment method, a redirect URL | Paused for a 3DS challenge; hand the redirect URL to the SDK. Interactive mode only. |
halted | the payment method, the decline reason | A "Stop" decline ended the run. The classified reason is surfaced. |
exhausted | the reason it ran out | No method cleared — either there were no eligible methods, or every eligible method was tried without success. |
Modes
The mode parameter is part of the contract from day one, so it stays stable as more capabilities land and callers don't have to refactor later.
interactive(live) — the buyer is on the page (full and auto checkout). 3DS challenges are recoverable: the cascade pauses withthree_ds_requiredand surfaces a redirect URL for the SDK overlay.unattended(reserved) — for off-session charges such as subscription renewals, where a 3DS challenge can't be resolved on the spot and the retry policy differs. The mode is reserved but not yet implemented.
Don't route real traffic through unattended mode yet. It is reserved so SDK and dashboard authors can see the surface, but it isn't implemented and will reject calls.
Observability
When a charge ultimately fails, the cascade surfaces the outcome to the SDK as a FloPayError or a decline event carrying the classified decline reason — so you can tell whether the run was halted by a terminal decline or exhausted every eligible method. See Error Handling for the shapes returned to the SDK.
Related
- Automatic Payment Buttons — the saved-payment /
autocheckout surface the cascade backs. - Stripe Payment Methods — how the Stripe gateway resolves and charges methods.
- Error Handling — the
FloPayErrorand decline shapes returned when a charge fails. - AVS — why an
AVS_FAILdecline moves on rather than retrying the same card.
Automatic Payment Buttons
Render one-click saved-payment buttons that create or reuse an auto checkout session and keep FloPay's shared processing modal on the page.
AVS (Address Verification)
Configurable Address Verification with per-field, per-country rules. Capture country, ZIP, street address, city, and state to improve auth rates.