insufficient_funds
Normalised code insufficient_funds, class soft, scope card_global.
Soft because the condition is temporary: the card is valid and may work later. card_global
because the refusal is about this card's balance, not this route, so trying another MID declines for
the same reason.
What drives your handling
These are the fields on the decline block that a switch statement should read. They are not advice
in prose; they are the contract.
{ "decline": {
"code": "insufficient_funds",
"class": "soft",
"scope": "card_global",
"cascade_allowed": false,
"retry_later_allowed": true,
"do_not_retry": false,
"cool_down_seconds": null,
"merchant_action": "retry_later",
"message": "The card has insufficient funds.",
"provider_code": "51",
"provider_message": "Insufficient funds"
} }
cascade_allowedisfalse. We do not try another MID, because the balance follows the card, not the route. A cascade here is a second decline for the same reason.retry_later_allowedistrue,cool_down_secondsisnull. Retry on a later day, not in a tight loop. There is no fixed cool-down; "later" means the payer has likely been paid or topped up.
What you should do
merchant_action is retry_later. Retry the same card on a later date. For a subscription you do
nothing -- dunning retries this for you on the schedule you configured, and the
subscription sits past_due with access live through the window. Retrying within seconds
is the one thing not to do: it will decline again and it looks like card testing.
What to tell the payer
The payer copy is delivered through the decline's user_message_key field. The key's
value set is defined by the taxonomy's payer-copy catalog, not on this page -- no literal key value is
written here, because none is yet fixed in a source and inventing one is the trap that puts a wrong
identifier into a merchant's code (project rule 1). The copy this decline resolves to reads:
Your card was declined for insufficient funds. Please use a different payment method or try again later.
Do not invent your own wording. "Your bank declined this" is true and actionable; "our system had a problem" is neither, and it turns a routine decline into a support ticket about us.
Does the platform cascade on it
No. cascade_allowed is false: a cascade tries a different MID for the same card,
and the balance is a property of the card. Cascading would spend a second authorization to reach the
same answer.
Raw provider codes that map here
Searchable, because you may arrive holding a raw code:
- ISO 8583
51-- Insufficient funds - Common gateway text: Insufficient funds, Not sufficient funds, NSF
Mapping is keyed on the raw code and request context, and a code we cannot classify maps to
unmapped rather than to a guess.
Related
do_not_honor-- looks similar, but do not retry the same card- Handle declines before production does -- the quickstart's decline step
unmapped and do_not_honor are plain code spans rather than links because their pages are not built
yet. The rest of the taxonomy is still being written, and a code is shown as plain text until its
page exists -- the same convention the error pages use.