FloPayFloPay
Guides

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:

  1. Select the customer's most-recently-used active, vaulted payment methods.
  2. 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.
  3. 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.
  4. 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 reasonActionWhy
USER_ERRORNext cardWrong CVV / PIN — the bank already gave this card a chance; try the next method.
AVS_FAILNext cardAddress mismatch — re-charging the same card won't pass AVS. See AVS.
INSUFFICIENT_FUNDSNext cardThis card is short; another card may clear.
DO_NOT_HONOURNext cardGeneric issuer decline — try the next method.
EXCEEDS_CARD_LIMITNext cardOver the card's limit; another card may clear.
RETRYABLE_DECLINENext cardThe issuer signalled the charge is reasonable to retry elsewhere.
PAYMENT_GATEWAY_ERRORNext cardA gateway-side error on this charge; the next method may route cleanly.
TECHNICAL_ERRORNext cardA technical failure on this attempt; try the next method.
UNKNOWN_DECLINE_REASONNext cardAn unclassified decline — move on rather than stop the run.
3DS_FAILStopThe cardholder failed or declined the 3DS challenge — burning through more cards won't help and risks tripping fraud alarms.
TOO_MANY_ATTEMPTSStopThe bank has rate-limited this customer — stop.
CLIENT_ERRORStopAn unclassified client-side error from the gateway — stop and surface it.
UNSUPPORTED_CARD_PURCHASEStopThe 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:

ResultActionBehaviour
SuccessThe charge cleared. The cascade returns success with the method that worked.
3DS requiredPauseThe 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 cardVault refreshThe saved token is stale. On a card this triggers a single vault refresh and retry; PayPal moves on instead.
Transient errorRetryA blip. The cascade waits briefly and retries the same method.

Cascade outcomes

A whole run resolves to exactly one outcome:

OutcomeCarriesMeaning
successthe payment method that workedA method charged successfully.
three_ds_requiredthe payment method, a redirect URLPaused for a 3DS challenge; hand the redirect URL to the SDK. Interactive mode only.
haltedthe payment method, the decline reasonA "Stop" decline ended the run. The classified reason is surfaced.
exhaustedthe reason it ran outNo 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 with three_ds_required and 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.

  • Automatic Payment Buttons — the saved-payment / auto checkout surface the cascade backs.
  • Stripe Payment Methods — how the Stripe gateway resolves and charges methods.
  • Error Handling — the FloPayError and decline shapes returned when a charge fails.
  • AVS — why an AVS_FAIL decline moves on rather than retrying the same card.

On this page