The Anatomy of a Bank Refusal: How to Read Error Codes and Timings Like an X-ray

Good Carder

Professional
Messages
517
Reaction score
411
Points
63

Introduction: Why the error code is more important than the card itself​

A beginner sees the phrase "Your card was declined" and is stunned. A pro can quickly look at three numbers: the HTTP status, the text response code, and the response time (TTFB). Using these, they can determine exactly where the issue is: the card is dead, the proxy is blacklisted, the store's antifraud system worked, or the issuer's bank simply blew the transaction.

In this article, we'll delve into the inner workings of payment gateways. You'll learn how to decipher over 20 error codes, distinguish between an issuer's decline and an antifraud system's decline, and use the browser console as a professional tool.

Part 1. How the Payment Path Works: Three Filters That Reject a Transaction​

Before reading the codes, understand the verification sequence. The request from your browser to the issuing bank passes through three hurdles:
Code:
[Your browser]
→ 1. Validation on the merchant side (data format, basic anti-fraud)
→ 2. Payment gateway (Stripe, Adyen, etc.) – checks fingerprints, proxies, and BIN lists
→ 3. Issuing bank (the bank that issued the card) – checks balances, stop lists, and 3DS

Which barrier was rejected is determined by the delay time and code:
BarrierTypical response timeCharacteristic codes
1. Shop0–500 ms400 Bad Request, invalid_number, expired_card
2. Gateway500 ms – 2 secfraudulent, blocked, generic_decline
3. Bank1–6 secdo_not_honor, insufficient_funds, pick_up_card, call_issuer

Key skill: you see a delay – you already know in which third to look for the problem.

Part 2. Complete Dictionary of Error Codes (20+ Error Codes with Explanations)​

All codes below are provided as they are provided by payment gateways (Stripe, Braintree, Adyen, Square). They may differ slightly in text, but the meaning is the same.

Group A. Data format errors (store or gateway, < 1 sec)​

Code (text)HTTPTranscriptWhat to do
invalid_number400The card number does not pass the Luna algorithm or does not match the BINCheck the card visually; the seller may have slipped you a random one.
invalid_expiry_month / invalid_expiry_year400Invalid month or year (last or 99)Check the expiration date on the card.
invalid_cvc400CVV/CVC is not the correct length or is invalidRecheck; if everything is correct - the card can be without CVV (rare)
expired_card402The deadline has expiredThe map is junk
incorrect_number400Special case of invalid_numberSame
missing_payment_information400One of the fields (name, address, country) is not filled inAutomation is broken; check the script
invalid_request400Invalid API request format (not your case if you're using a browser)The problem is with the store integration, not yours.

Group B. Issuer (card bank) refusals – time 1–6 sec​

CodeHTTPTypical delayMeaningAction
do_not_honor4020.8–2 secThe card is on the bank's stop list (stolen, expired, blocked for fraud)Throw the card in the trash. Don't waste your time.
insufficient_funds4021.5–3 secThe balance is less than the check amountReduce the amount to $1-5 for testing; if it doesn't work, the card is empty.
lost_card402< 1 secThe holder reported the lossSimilar to do_not_honor
stolen_card402< 1 secThe card is marked as stolen.Don't use this BIN at all
pick_up_card4021–2 secThe bank asks the ATM to confiscate the card (compromise)Dangerous BIN; stores may ban your IP
call_issuer4022–5 secThe bank wants voice confirmationUseless for carding
transaction_not_allowed4031–3 secThe card is blocked for this type of transaction (e.g. only ATM withdrawals)Look for cards with the Consumer or Retail flag
restricted_card4031–2 secThe card has country or channel restrictions.Unlimited BIN required
invalid_transaction4021–3 secInvalid amount or currency for this cardChange currency to USD/EUR/GBP depending on BIN
withdrawal_limit_exceeded4021–2 secDaily limit exceededPut the card aside for 24 hours
hard_decline4020.5–1 secGeneralized failure without details (old gateways)The card is probably dead.

Group B. Antifraud failures (gateway or store) – time 0.5–3 sec​

CodeHTTPDelayMeaningAction
fraudulent4031–2 secThe anti-fraud rule (Stripe Radar, Kount) was triggered.Change your proxy, anti-detection, and fingerprint.
blocked4030.5–1 secIP, BIN, or email is blacklisted by the storeChange proxy and email
generic_decline4022–6 secRejection without reason - usually due to scoringClean the environment thoroughly
do_not_honor (but delay >3 sec)4023–5 secMixed case: the store's anti-fraud system sent a request, but the bank refused.Analyze both aspects
processing_error5002–10 secGateway error (rare)Repeat in a minute
invalid_account4030.5–1 secThe store is not configured to accept cards of this BIN.Not your fault

Group G. 3D Secure​

CodeHTTPDelayMeaningAction
authentication_required4023–8 secThe map requires 3DS completion.No way around is a dead end
3d_secure_failed4024–10 secThe attempt was successful, but authentication failed.The map is alive, but the 3DS can't be beaten using standard methods.

Part 3. How to distinguish between an issuer's refusal and an antifraud refusal based on timing and patterns​

This is the key skill. Compare the two situations:

Situation A (issuer's refusal):
  • Response time: 1.8 sec
  • Code: do_not_honor
  • Background: The card is new, BIN 414720 (Chase), proxy is US resident.
    Conclusion: Chase bank blocked the card (stolen). We're replacing the card.

Situation B (anti-fraud failure):
  • Response time: 0.9 sec
  • Code: fraudulent
  • Background: The proxy is a cheap data center, WebRTC is not disabled.
    Conclusion: Stripe Radar blocked the fingerprint. Change the proxy and anti-detection settings.

How can you accurately determine if a code is ambiguous (for example, generic_decline)?
Run an A/B test:
  1. Try the same thing with a known live card(for example, your own debit card with a low balance).
    • If your card goes through, the problem is with someone else’s card.
    • If your card also receives generic_decline, the problem is in the environment (proxy/antidetect).
  2. Try with the same profile but on a different site(with the same gateway, for example, two stores on Stripe).
    • The refusal is the same everywhere → the environment is bad.
    • Denial on only one site → the store bans your BIN or IP.

Rule of thumb:
  • Delay < 1.5 sec and code from group A or B → store/gateway anti-fraud.
  • Delay > 1.5 sec and code from group B → issuer bank.
  • Exception: insufficient_funds can arrive quickly if the balance is checked by the gateway's local cache (but rarely).

Part 4. HTTP status and text message mapping table for popular gateways​

Different gateways may refer to the same actual failure differently. Below is a summary table for Stripe, Adyen, Braintree, and Square.
The real reasonStripe (text)AdyenBraintreeSquareHTTP
Invalid numberinvalid_numberInvalid Card Number2000 (code in response)INVALID_CARD400
Invalid CVVinvalid_cvcInvalid CVC2001CVV_FAILURE400
Insufficient fundsinsufficient_fundsNot Enough Balance2004INSUFFICIENT_FUNDS402
The card was stolen.do_not_honorStolen Card2005CARD_DECLINED402
AntifraudfraudulentRisk Score Too High2016 (fraud)DECLINED_RISK403
3DS requiredauthentication_required3DS2 Required2038THREEDS_REQUIRED402
General refusalgeneric_declineDeclined2000 (total)GENERIC_DECLINE402
Overdueexpired_cardExpired Card2003EXPIRED_CARD402
Withdraw the cardpick_up_cardPick Up Card2006PICK_UP_CARD402
The limit has been exceededwithdrawal_limit_exceededLimit Exceeded2010LIMIT_EXCEEDED402

How to use the table:
If you see the CARD_DECLINED message on the website (Square) and a 0.5 sec delay, look in the table: this is the equivalent of Stripe's do_not_honor, meaning the card is on the stop list.

Part 5. Practice: Reading the Network Console Like an X-ray​

5.1 Where to find the payment request​

  1. Open the website with the payment form.
  2. Press F12Network tab.
  3. Clear logs (button 🚫).
  4. Fill out the card form and click Pay.
  5. The logs will show multiple queries. Find the one that contains:
    • payments, create-payment-intent, charge, transactions, authorize
    • Or POST method with response 402, 400, 403.

Example for Stripe: look for a request to https://api.stripe.com/v1/payment_intents/.../confirm or https://m.stripe.com/6

5.2. What to look for in request details​

Click on the required query → tabs will open:
  • Headers → see Status Code (e.g. 402 Payment Required).
  • Preview or Response – contains the text error code and message.

Screenshot (description):
The Headers tab shows:
Status: 402 Payment Required
The Response tab:
{ "error": { "code": "insufficient_funds", "message": "Your card has insufficient funds." } }

Plus the Timing tab shows the exact time: Waiting (TTFB): 2.3 sec. This is the delay.

5.3. Explanation of a real example​

Example 1 (issuer's refusal):
  • Запрос: POST /v1/payment_intents/pi_123/confirm
  • Status: 402
  • Response: {"error":{"code":"do_not_honor","decline_code":"do_not_honor"}}
  • Timing: TTFB: 1.2 sec

Diagnosis: The issuing bank declined due to a stop list. The card is dead.

Example 2 (Stripe antifraud):
  • Запрос: POST /v1/payment_intents/pi_456/confirm
  • Status: 403
  • Response: {"error":{"code":"fraudulent","message":"Your payment was blocked by Radar."}}
  • Timing: TTFB: 0.6 sec

Diagnosis: Gateway antifraud was triggered. The issue is in the environment (proxy, fingerprint).

Example 3 (3DS):
  • Request: POST /payments
  • Status: 402
  • Response: {"error":{"code":"authentication_required","payment_intent":{"next_action":{"type":"redirect_to_url"}}}}
  • Timing: TTFB: 4.1 sec

Diagnosis: the map requires 3DS. Without a bypass, it's impossible to pass.

5.4. Advanced Technique: Looking at Request Headers​

In the same Network tab, go to HeadersRequest Headers. Note:
  • User-Agent – does it match your anti-detection profile?
  • Accept-Language – does it match the proxy country? (e.g. en-US,en;q=0.9 for the USA)
  • Origin and Referer must lead to the same website.
  • CF-Ray (if the site is behind Cloudflare) – the presence of this header indicates that Cloudflare has verified your request. If you see CF-Ray after a rejection and the response time is around 0.3 seconds, you were blocked by Cloudflare WAF, even before reaching the payment gateway.

Part 6. Diagnostic checklist by code and time​

Print or save. If rejected, follow these steps:
  1. Capture the HTTP status and text code (from Response).
  2. Measure TTFB (from Timing).
  3. Compare with the table above:
    • 4xx (400, 402, 403) – client/payment error.
    • 5xx – problem on the server side (your proxy may not be at fault).
  4. Identify the group:
    • Time < 1 sec and code from group A (invalid_number, expired_card) → input error or card is fake.
    • Time 1-3 sec and code do_not_honor/insufficient_funds → issuer refusal.
    • Time < 1.5 sec and code fraudulent/blocked → gateway antifraud.
  5. Confirm with a test:
    • Replace the card with a known good one (your own) - if the error is the same, the problem is not with the card.
    • Change the proxy to a residential one and try again. If the error goes away, the problem was with the proxy.

Part 7. Beginner Mistakes When Reading Code​

Mistake 1: They see generic_decline and assume "the card is bad." In reality, a generic_decline with a 3-second delay often means that the store's anti-freeze system rejected the payment without bothering to provide the exact code.

Mistake 2: They ignore the response time. The same do_not_honor code in 0.8 seconds and in 4 seconds are completely different stories. The first is that the card is on the bank's blacklist. The second is that the bank took a long time to figure out, perhaps the balance was close, but then rejected it anyway.

Mistake 3: They don't check the decline_code in Stripe. Stripe often returns two fields: code (generic) and decline_code (bank-specific). For example, code: generic_decline, decline_code: insufficient_funds – this is the real reason. Always check the decline_code, if it exists.

Conclusion: Turning Refusal into a Diagnosis​

Now you can:
  • Using the code and time, you can determine who exactly rejected the payment: the store, the gateway, or the bank.
  • Distinguish between 20+ types of failures and know what to do in each case.
  • Use the Network console to collect accurate data.
  • Distinguish between antifraud and lack of funds.

In the next article (your choice), we'll cover how to verify a card with micropayments and create your own checker.

For now, save this article as a cheat sheet. Open it and check it every time your card is rejected. After 20-30 attempts, reading codes will become automatic.

A quick one-line reminder:
"Time <1 sec + invalid/expired → crooked hands or fake; 1-3 sec + do_not_honor → card dead; <1.5 sec + fraudulent → dirty environment; >3 sec + generic_decline → store anti-freed."
 
Top