Glossary

Stripe Decline Code

A Stripe decline code is the short string, such as insufficient_funds or expired_card, that Stripe attaches to a failed card payment to say why the issuer or Stripe refused it, so you can decide whether to retry, ask for new card details or stop.

14-day free trial · card required · cancel anytime

Definition

When a card payment fails, the issuer sends back a raw response code, and the code means different things on different card networks. Stripe translates it into its own vocabulary. Stripe describes its decline codes as covering many of the same reasons as issuer codes while “going into more detail about the specific reason for the decline.” That translated value is the decline code: insufficient_funds, expired_card, incorrect_cvc, do_not_honor and the rest of a list that runs to about fifty codes for cards alone.

The code sits in more than one place. On the error a failed API call returns, it is decline_code. On a PaymentIntent, it is the decline_code inside last_payment_error. On the Charge, the outcome object carries it as reason, next to the type of failure, the network’s own codes and a seller_message written for you rather than for the customer.

The practical value is triage. A decline code tells you which of three things to do next: ask the customer to fix a typo, ask them for a different payment method, or stop, because nothing you do on your side will change the answer.

Key points

  • +decline_code appears on the API error and on a PaymentIntent’s last_payment_error. On the Charge, the same value is outcome.reason.
  • +Stripe’s decline codes expand on raw issuer codes. The raw network values are kept separately as network_decline_code and network_advice_code.
  • +Most issuer declines come back as generic_decline, so the specific reason is often simply unknown.
  • +advice_code is the next-step field: do_not_try_again, try_again_later or confirm_card_data.
  • +Stripe Billing will not automatically retry nine hard decline codes, including incorrect_number, lost_card, stolen_card and authentication_required.
  • +For lost_card, stolen_card, fraudulent and merchant_blacklist, Stripe says to show the customer a generic decline, not the real reason.
  • +A blocked payment (outcome.type blocked) never reached the issuer. An issuer decline (issuer_declined) did.
  • +A declined card payment moves no money, so there is no sale, no Stripe fee and nothing in the next payout to record.

Where to find the decline code

In the Dashboard, a failed payment shows the reason and a short suggested resolution on the payment’s detail page.

In the API there are three places, and they carry the same answer from different angles. A failed confirmation returns an error object whose decline_code gives the issuer’s reason if one was provided. The PaymentIntent keeps the most recent failure in last_payment_error, so you can read decline_code there after the fact, and the payment_intent.payment_failed webhook fires when an attempt fails. The Charge itself records the full outcome: type, reason, advice_code, network_decline_code, network_advice_code, network_status, risk_level and seller_message.

Stripe’s own example of an expired card shows how the pieces fit: network_decline_code 54, network_advice_code 03, network_status declined_by_network, reason expired_card, advice_code confirm_card_data and type issuer_declined.

Decline code, network code and advice code

These three are easy to blur, and they answer different questions.

The network decline code is the raw value from the card network, 2 to 4 digits for cards. Stripe warns that its meaning differs by card network, so you have to read it alongside the card brand. If Stripe got no response code from the network, the field is null.

The Stripe decline code is Stripe’s normalized reason, the same across networks. It is the one to build logic and reports on.

The advice code is guidance on what to do next. Stripe’s advice_code has three values: do_not_try_again (do not use this card again for the same transaction), try_again_later (the issuer declined, but a retry is possible) and confirm_card_data (some of the card information was wrong). The network also sends its own network_advice_code, which Mastercard calls a Merchant Advice Code.

Hard declines, soft declines and retries

A hard decline means the issuer has rejected the transaction and retrying will not help. Stripe Billing lists nine codes it will not automatically retry: incorrect_number, lost_card, pickup_card, stolen_card, revocation_of_authorization, revocation_of_all_authorizations, authentication_required, highest_risk_level and transaction_not_allowed. After one of these on a subscription or invoice, retries stay on the schedule but only execute once Stripe detects a new payment method.

Everything else is retryable in principle, but not without limit. Stripe notes that card networks cap how many times a single charge can be reattempted, recommends a maximum of eight retries for charges that permit them, and warns that issuers may read extra retries as possible fraud.

authentication_required is the awkward one. Stripe’s decline code reference describes it as usually triggering an authentication flow when you use Stripe’s front ends, so an on-session customer can authenticate and pay. Off session, with nobody there to complete 3D Secure, the customer has to come back and retry, which is why it sits on the Billing hard decline list.

Codes that need special handling

Three groups are worth knowing by name.

Codes you must not repeat to the customer. For lost_card, stolen_card, fraudulent and merchant_blacklist, Stripe says not to report the detailed reason and to present the payment as a generic_decline instead. Your checkout messages and support replies should follow that.

Codes that are a typo, not a refusal. incorrect_number, incorrect_cvc, incorrect_zip, incorrect_address and the invalid_expiry codes all mean the customer can fix the details and try again.

duplicate_transaction. Stripe returns it when a transaction with identical amount and card information was submitted very recently, and its advice is to check whether a recent payment already exists. That is a bookkeeping signal: you may already have the money.

Finally, generic_decline covers two very different situations. It is used when the issuer gives no reason, and also when Stripe Radar or Adaptive Acceptance blocked the payment.

Declined, blocked or invalid

Stripe sorts failed payments into three kinds, and outcome.type tells them apart.

An issuer decline (issuer_declined) reached the card network and the issuer said no. A blocked payment (blocked) never went to the issuer: Radar stopped it as too risky, or Adaptive Acceptance stopped it as unlikely to be authorized, and network_status is not_sent_to_network. An invalid request (invalid) is an integration error and usually does not even appear as a payment in the Dashboard.

Stripe notes that a blocked payment can still show on some customers’ statements as an authorization, even though Stripe neither charged the amount nor withdrew funds. The issuer usually removes it within a few days. That explains the customer who says they were charged for a payment you can see failed.

What a decline means for your books

A declined card payment is a failed attempt, not a transaction. No money entered your Stripe balance, so there is no revenue, no processing fee on a sale and nothing in the next payout. The decline code is useful for collections and support, but there is nothing to post for it.

What can matter is the record the payment was meant to settle. A one-time checkout that fails simply never becomes a sale. A subscription invoice that fails stays open and keeps showing as owed while Stripe retries it, and whether it is eventually paid, left open, marked uncollectible or voided is the question that reaches Accounts Receivable.

Bank debits are different. An ACH Direct Debit payment is pending first and can fail later with a code such as insufficient_funds, bank_account_closed or debit_not_authorized. That failure arrives after the payment looked successful, so it can undo something already recorded.

How Acodei treats a declined payment

Acodei builds sales records from successful charges. On a real-time account, each charge.succeeded or charge.captured becomes a QuickBooks Sales Receipt by default, and on a daily-summary account successful charges are aggregated into one receipt per day. A declined card payment never succeeds, so there is no sales record for it.

With Invoice Sync on, the QuickBooks Invoice is created when the Stripe invoice is finalized, before any payment attempt. A decline leaves that invoice open, and Acodei creates the QuickBooks Payment when the invoice is paid (on invoice.paid or charge.succeeded), applying it to the invoice, which requires QuickBooks’ Automatic Application setting to be on.

Failed ACH payments are the case that does reach your books, because they were pending first. Acodei’s documentation describes recording the pending payment against the invoice as if it had succeeded. If it then fails, that payment is deleted, and a pending sale and its reversal are recorded on the Daily Balance Summary for the day of the failure.

Want to see this on your own Stripe data?

Start a free trial

14-day free trial · card required · cancel anytime

Frequently asked questions

What is a decline code in Stripe?

It is the short string Stripe attaches to a failed payment to say why it was refused, such as insufficient_funds, expired_card or do_not_honor. Stripe’s codes expand on the raw codes issuers send, so they are consistent across card networks. You find it as decline_code on the API error and on a PaymentIntent’s last_payment_error, and as outcome.reason on the Charge.

What is the difference between decline_code and network_decline_code?

network_decline_code is the raw code from the card network, and its meaning depends on the card brand. decline_code is Stripe’s normalized reason, which is the same whichever network the card is on. Build your handling on decline_code and keep the network code for investigating a specific case.

Which Stripe decline codes will not be retried?

Stripe Billing will not automatically retry nine hard decline codes: incorrect_number, lost_card, pickup_card, stolen_card, revocation_of_authorization, revocation_of_all_authorizations, authentication_required, highest_risk_level and transaction_not_allowed. Retries stay scheduled, but they only execute after Stripe detects a new payment method.

Why does Stripe say generic_decline?

Card issuers categorize most declines as generic, so often the specific reason is simply not given. generic_decline is also returned when Stripe Radar or Adaptive Acceptance blocked the payment. If the card details are correct, Stripe’s guidance is for the customer to contact their card issuer, which only discusses specifics with the cardholder.

Should I tell the customer the decline code?

Not always. For lost_card, stolen_card, fraudulent and merchant_blacklist, Stripe says not to report the detailed reason and to present the payment as a generic decline. For codes like incorrect_cvc or expired_card, telling the customer what to fix is the fastest way to get paid.

Does a declined Stripe payment need to be recorded in QuickBooks?

Not for a card. A declined card payment moves no money, so there is no sale or fee to record. If the payment was for an invoice, that invoice stays open until it is paid or otherwise closed. A bank debit that fails after being pending is different, because it can reverse a payment that was already recorded.

What customers say about running Stripe through Acodei

Stripe Verified Partner BadgeIntuit QuickBooks
★★★★★
“If you're testing out all the different Stripe/QuickBooks integration apps right now, let me save you some time. This one is the best one by far.”
RyanOwner at Indie Music Academy
★★★★★
“Works well and is really helpful for massive transactions. The support is really fast and helpful. 100% recommended.”
AndresCo-founder and CEO at Kanguro Collections and Reinsurance

Related reading

More glossary terms

See the full glossary

Ready to try Acodei?

Connect Stripe to QuickBooks Online in minutes and let the fees, refunds, and payouts land where your accountant expects them.

14-day free trial · card required · cancel anytime