Global Payment

Stripe Payment Failed: What's Causing It and How to Fix It

James Carter
Business Finance Writer

Stripe payment failures fall into three categories — issuer declines, Radar blocks, and API errors. Identify which type triggered the failure, and fix it with the right approach.

2026.10.15 03:44:23 · 5minute(s)
Key Takeaways
  • Stripe payment failures fall into three distinct types — issuer declines, Stripe Radar blocks, and invalid API calls — each requiring a different response.
  • Most card declines originate with the customer's bank, not with Stripe. Stripe passes the decline message along but doesn't control the outcome.
  • Stripe Radar can block legitimate transactions. Knowing how to review and override these blocks prevents unnecessary revenue loss.
  • API-level errors typically won't appear in your Stripe Dashboard — they surface in your server logs and need to be caught there.
  • Persistently high failure rates on international transactions often point to a structural gap that cannot be fixed through retries or rule adjustments.
A "payment failed" message in Stripe doesn't tell you much on its own. The fix depends entirely on which of Stripe's three failure types triggered it — and each type requires a completely different response. Treating a Stripe Radar block the same way you'd handle an expired card won't resolve anything. This guide covers how to identify what went wrong and what to do about it.

Why Did the Stripe Payment Fail? Start Here

Before jumping to fixes, identify which failure type you're dealing with. The Stripe Dashboard's Charge outcome field tells you which category triggered the failure. Here's a quick reference:
What you see in Stripe
Root cause
Where to look
card_declined + decline code
Customer's card issuer declined the charge
Decline codes section below
payment blocked + Radar reason
Stripe Radar's fraud prevention triggered
Radar section below
HTTP 4xx / API error response
Integration or configuration error on your side
API errors section below
High failure rate on international cards
Structural coverage or 3DS friction
International payments section below
Each category needs a different response. The sections below walk through all three, with specific actions for each.

Issuer Declines: What the Bank Is Telling You

Issuer declines are the most common type of Stripe payment failure. They happen when the customer's bank or card network rejects the charge during the payment authorization process — Stripe never gets to charge the card. Stripe receives a decline code from the issuer and passes it back to you, but has no ability to override the bank's decision.
The decline code tells you the reason. Here are the most common ones and what each means:
Decline Code
What It Means
What to Do
insufficient_funds
Card balance too low
Ask the customer to use a different card
expired_card
Card has passed its expiry date
Ask the customer to update their card details
do_not_honor
Generic decline — bank doesn't specify a reason
Ask the customer to call their bank
authentication_required
Card issuer requires 3DS verification
Enable 3DS in your Stripe integration
authentication_failure
3DS was required but the attempt failed
Have the customer retry; verify your 3DS setup
card_velocity_exceeded
Too many charge attempts on this card
Wait 24 hours before retrying
lost_card / stolen_card
Card flagged as compromised
Do not retry; treat as potential fraud risk
card_not_supported
Card type doesn't support this transaction type
Customer needs to use a different card or payment method
The card_not_supported code is worth noting separately. Prepaid cards and some virtual cards don't support certain types of purchases — particularly subscription billing or international transactions. If you're seeing this code frequently, it may signal a mismatch between your payment setup and the card types your customers tend to use.

What to Do When a Customer's Card Is Declined

For one-off card declines, the most effective action is clear, specific error messaging. "Your payment didn't go through" is less useful than "Your card was declined — please try a different card or contact your bank." Customers who know what's wrong are more likely to complete the purchase.
For subscription businesses, Stripe Billing's Smart Retries uses machine learning to time retry attempts when authorization is more likely to succeed. It's enabled by default on Stripe Billing and can recover a meaningful percentage of failed recurring charges without any manual intervention.

The "do_not_honor" Code

do_not_honor is a catch-all decline that gives no specific reason. The issuing bank has decided to decline but won't say why. Common triggers include an unusual transaction pattern for the cardholder, the bank's internal fraud model flagging the charge, or a temporary system issue on the bank's side.
There's no configuration change on your end that will fix this. The only path forward is the customer calling their bank to understand the block and, if everything is legitimate, asking the bank to approve future transactions.

Stripe Radar Blocks: When Stripe Rejects the Payment

Stripe Radar is Stripe's fraud prevention layer. When it blocks a payment, it does so before contacting the issuing bank — which means the customer's card is never actually charged, and no decline code comes from the bank. The block originates entirely within Stripe.
Radar evaluates every payment against a risk score built from signals including IP address, device fingerprinting, email address, and address verification (AVS) data. Payments that exceed a risk threshold — or match a custom rule you've configured — get blocked. You can see which outcome type and reason triggered the block in the Dashboard under the payment's Radar outcome section.
Common reasons a legitimate payment gets flagged by Radar:
  • Customer is using a VPN, which creates an IP-country mismatch
  • First-time purchase from a location or device outside the customer's typical pattern
  • High transaction value that deviates from the card's normal spending history
  • Billing address doesn't match the card's registered address (AVS mismatch)
  • Email domain associated with disposable or high-risk accounts in Radar's training data

When Radar Blocks a Legitimate Transaction

If you review a blocked payment in the Dashboard and recognize it as legitimate, click Add to allow list. This overrides the matching rules for future attempts from that source. It does not automatically retry the payment — the customer will need to try again.
If you're seeing a pattern of Radar blocks on customers you'd expect to be legitimate, review your custom rules. Overly broad rules — for example, blocking all payments from a particular country or above a blanket dollar amount — can generate false positives at scale. Test any rule changes in Stripe's review mode before enabling them on live payments.

Invalid API Calls: Integration Errors on Your Side

Unlike issuer declines and Radar blocks, API errors don't represent a payment that was attempted and rejected — they represent a request that was malformed before Stripe could process it. These won't always appear in your Stripe Dashboard, which means they're easy to miss if you're only checking there.
The four most common categories:
  1. Expired or invalid API keys — the api_key_expired error means your integration is using a rotated or deleted key. Update your server environment with the current key from the Dashboard.
  2. Incorrect payment amount — amount_too_small and amount_too_large errors occur when the charge amount falls outside Stripe's permitted range for the currency. Check the amount calculation logic in your integration.
  3. Missing 3DS authentication flow — for off-session recurring charges, Stripe requires a SetupIntent or a PaymentIntent with the appropriate confirmation flow. If authentication_required returns on an automated charge, the initial setup didn't capture the mandate correctly.
  4. Wrong parameter types or missing fields — these produce generic 400 errors. Check the API reference for the specific endpoint and confirm the parameters your code is sending match the expected format.

How to Catch API Errors Before Customers Do

API errors surface in your server logs, not in the Stripe Dashboard. Set up error logging and alerting on your server side to catch these as they happen. Stripe's test mode provides specific test card numbers that simulate each decline and error scenario — run through them regularly when making integration changes to catch regressions before they reach production.

How to Track Your Stripe Failure Rate

Stripe shows authorization and failure rate data under Dashboard → Radar → Business overview. You can also filter the Payments list by failed status to see the volume and breakdown of failures over any period.
When reading the numbers, separate unique declines (first-attempt failures) from retry failures (failed re-attempts on already-declined charges). Mixing them inflates the apparent failure rate and makes diagnosis harder.
What to look for in the data:
  • A sudden drop in authorization rate — check for a recent Radar rule change or a new integration deployment
  • High do_not_honor rate clustered in a specific region — may indicate bank-level friction with a particular issuer or market
  • High authentication_required rate — your 3DS setup likely needs review
  • High blocked rate from Radar — custom rules may be too aggressive
Consistently tracking these metrics is the foundation for any effort to improve payment approval rates — spikes often point directly to the source of the problem.

When Stripe Keeps Failing on International Transactions

Not every Stripe failure problem can be solved with retries, rule adjustments, or better error messaging. When failures cluster specifically around international transactions — and the decline codes don't point to fixable card-level issues — the underlying cause is often structural.
Stripe's authorization rates are not uniform across markets. In parts of Southeast Asia, Latin America, and Africa, local card-issuing banks have lower acceptance rates for international card network transactions. Cross-border payments also trigger more frequent 3DS authentication requirements, and 3DS completion rates vary significantly by region — customers unfamiliar with the flow or on older devices tend to abandon it. For B2B use cases specifically, Stripe's product is optimized for online consumer checkout, not for high-value supplier payments or multi-currency local collection.
The signal that this is the issue: your failure rate is concentrated in specific countries, the decline codes don't match anything on the customer's side, and adjusting your Stripe configuration doesn't move the numbers.
For cross-border B2B payments — collecting from international clients, paying overseas suppliers — a platform designed specifically for that use case addresses the gap without requiring you to replace Stripe entirely. PhotonPay is built for cross-border B2B payment flows, supporting multi-currency accounts, global payouts across 200+ countries and regions, and local payment collection in markets where card-based flows hit structural limits. Businesses that find Stripe works well for domestic or consumer-facing payments but falls short for international B2B transactions use PhotonPay for those corridors specifically.

Frequently Asked Questions

Why does Stripe say "payment failed" but the customer's card shows no charge?
When Stripe Radar blocks a payment, it does so before contacting the card issuer — so no authorization attempt reaches the bank. The customer sees no pending charge on their statement. For issuer declines, the bank may briefly show a pending authorization that reverses within a few days, but no funds are actually moved.
What does "do_not_honor" mean on Stripe?
do_not_honor is a generic decline code that means the issuing bank refused the charge without specifying a reason. It's often triggered by the bank's internal fraud scoring, an unusual transaction pattern, or a temporary system issue. There's no fix on your integration side — the customer needs to call their bank to resolve it.
Can I retry a Stripe payment that was declined?
It depends on the decline code. For card_velocity_exceeded, Stripe recommends waiting 24 hours. For do_not_honor or insufficient_funds, retrying immediately rarely succeeds. For authentication_required, the retry should route through 3DS verification. Stripe Billing's Smart Retries handles optimal timing automatically for subscription payments.
How do I lower my Stripe decline rate?
Start by identifying which failure type is driving the rate — issuer declines, Radar blocks, or API errors. For issuer declines, improve your error messaging and enable Smart Retries for subscriptions. For Radar over-blocking, review and tighten your custom rules. For API errors, add server-side error logging to catch issues before they reach customers. For persistent failures on international transactions, evaluate whether your payment infrastructure covers those markets adequately.
What are alternatives to Stripe for international business payments?
For cross-border B2B payments — paying suppliers, collecting from international clients, managing multi-currency accounts — dedicated global payment platforms cover corridors and payment methods that Stripe's consumer-focused infrastructure doesn't prioritize. PhotonPay supports global payouts and local payment collection across 200+ countries and regions, which covers markets where standard card processing sees lower authorization rates.

Power Your Global Growth with PhotonPay