Good Carder
Professional
- Messages
- 521
- 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:
| Barrier | Typical response time | Characteristic codes |
|---|---|---|
| 1. Shop | 0–500 ms | 400 Bad Request, invalid_number, expired_card |
| 2. Gateway | 500 ms – 2 sec | fraudulent, blocked, generic_decline |
| 3. Bank | 1–6 sec | do_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) | HTTP | Transcript | What to do |
|---|---|---|---|
| invalid_number | 400 | The card number does not pass the Luna algorithm or does not match the BIN | Check the card visually; the seller may have slipped you a random one. |
| invalid_expiry_month / invalid_expiry_year | 400 | Invalid month or year (last or 99) | Check the expiration date on the card. |
| invalid_cvc | 400 | CVV/CVC is not the correct length or is invalid | Recheck; if everything is correct - the card can be without CVV (rare) |
| expired_card | 402 | The deadline has expired | The map is junk |
| incorrect_number | 400 | Special case of invalid_number | Same |
| missing_payment_information | 400 | One of the fields (name, address, country) is not filled in | Automation is broken; check the script |
| invalid_request | 400 | Invalid 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
| Code | HTTP | Typical delay | Meaning | Action |
|---|---|---|---|---|
| do_not_honor | 402 | 0.8–2 sec | The 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_funds | 402 | 1.5–3 sec | The balance is less than the check amount | Reduce the amount to $1-5 for testing; if it doesn't work, the card is empty. |
| lost_card | 402 | < 1 sec | The holder reported the loss | Similar to do_not_honor |
| stolen_card | 402 | < 1 sec | The card is marked as stolen. | Don't use this BIN at all |
| pick_up_card | 402 | 1–2 sec | The bank asks the ATM to confiscate the card (compromise) | Dangerous BIN; stores may ban your IP |
| call_issuer | 402 | 2–5 sec | The bank wants voice confirmation | Useless for carding |
| transaction_not_allowed | 403 | 1–3 sec | The card is blocked for this type of transaction (e.g. only ATM withdrawals) | Look for cards with the Consumer or Retail flag |
| restricted_card | 403 | 1–2 sec | The card has country or channel restrictions. | Unlimited BIN required |
| invalid_transaction | 402 | 1–3 sec | Invalid amount or currency for this card | Change currency to USD/EUR/GBP depending on BIN |
| withdrawal_limit_exceeded | 402 | 1–2 sec | Daily limit exceeded | Put the card aside for 24 hours |
| hard_decline | 402 | 0.5–1 sec | Generalized failure without details (old gateways) | The card is probably dead. |
Group B. Antifraud failures (gateway or store) – time 0.5–3 sec
| Code | HTTP | Delay | Meaning | Action |
|---|---|---|---|---|
| fraudulent | 403 | 1–2 sec | The anti-fraud rule (Stripe Radar, Kount) was triggered. | Change your proxy, anti-detection, and fingerprint. |
| blocked | 403 | 0.5–1 sec | IP, BIN, or email is blacklisted by the store | Change proxy and email |
| generic_decline | 402 | 2–6 sec | Rejection without reason - usually due to scoring | Clean the environment thoroughly |
| do_not_honor (but delay >3 sec) | 402 | 3–5 sec | Mixed case: the store's anti-fraud system sent a request, but the bank refused. | Analyze both aspects |
| processing_error | 500 | 2–10 sec | Gateway error (rare) | Repeat in a minute |
| invalid_account | 403 | 0.5–1 sec | The store is not configured to accept cards of this BIN. | Not your fault |
Group G. 3D Secure
| Code | HTTP | Delay | Meaning | Action |
|---|---|---|---|---|
| authentication_required | 402 | 3–8 sec | The map requires 3DS completion. | No way around is a dead end |
| 3d_secure_failed | 402 | 4–10 sec | The 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:
- 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).
- 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 reason | Stripe (text) | Adyen | Braintree | Square | HTTP |
|---|---|---|---|---|---|
| Invalid number | invalid_number | Invalid Card Number | 2000 (code in response) | INVALID_CARD | 400 |
| Invalid CVV | invalid_cvc | Invalid CVC | 2001 | CVV_FAILURE | 400 |
| Insufficient funds | insufficient_funds | Not Enough Balance | 2004 | INSUFFICIENT_FUNDS | 402 |
| The card was stolen. | do_not_honor | Stolen Card | 2005 | CARD_DECLINED | 402 |
| Antifraud | fraudulent | Risk Score Too High | 2016 (fraud) | DECLINED_RISK | 403 |
| 3DS required | authentication_required | 3DS2 Required | 2038 | THREEDS_REQUIRED | 402 |
| General refusal | generic_decline | Declined | 2000 (total) | GENERIC_DECLINE | 402 |
| Overdue | expired_card | Expired Card | 2003 | EXPIRED_CARD | 402 |
| Withdraw the card | pick_up_card | Pick Up Card | 2006 | PICK_UP_CARD | 402 |
| The limit has been exceeded | withdrawal_limit_exceeded | Limit Exceeded | 2010 | LIMIT_EXCEEDED | 402 |
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
- Open the website with the payment form.
- Press F12 → Network tab.
- Clear logs (button
). - Fill out the card form and click Pay.
- 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 Headers → Request 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:- Capture the HTTP status and text code (from Response).
- Measure TTFB (from Timing).
- 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).
- 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.
- 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."
