Declined payment

A declined payment is a charge the card issuer or Stripe refuses. Learn hard vs soft declines, where Stripe shows the decline code, and what to do next.

Updated October 1, 2026

A declined payment is a payment attempt that doesn't go through. Either the customer's card issuer refuses to authorize it, or Stripe blocks it before it reaches the issuer. No money moves. Instead you get a reason code, and that code tells you whether to wait, retry, or ask the customer for a different card.

Where a declined payment shows up in Stripe

One decline appears in several places. The PaymentIntent fires payment_intent.payment_failed, and its status goes back to requires_payment_method so the customer can try again. The Charge fires charge.failed. If the payment was for a subscription or invoice, Stripe also fires invoice.payment_failed.

The details are on the Charge's outcome and the PaymentIntent's last_payment_error:

  • outcome.type is issuer_declined when the bank said no, blocked when Stripe Radar stopped it without asking the bank, and invalid for a bad API request.
  • The decline code, such as insufficient_funds, expired_card, incorrect_cvc or do_not_honor, gives the reason as far as the issuer shares it.
  • The advice code says what to do next. It is try_again_later, do_not_try_again or confirm_card_data.

Stripe notes that issuers label most declines generic_decline, so the real reason is often unknown. Issuers only explain a decline to their own cardholder, which is why "please contact your bank" is sometimes the only honest answer. The Stripe decline codes cheat sheet maps common codes to next steps.

Hard vs soft declines

A soft decline can clear later. Low funds, a temporary block by the issuer, or a network problem can succeed on a retry a few days on.

A hard decline won't clear on the same card. Stripe doesn't automatically retry codes such as incorrect_number, lost_card, stolen_card, pickup_card, transaction_not_allowed or authentication_required. Those retries stay on the schedule but only run once the customer adds a new payment method. For expired_card, Stripe's guidance is that the customer needs another card.

Retry limits matter too. Card networks cap how many times you can reattempt one charge, and Stripe recommends no more than eight retries. Issuers can read too many retries as possible fraud, which leads to more declines on your legitimate charges.

What a declined payment costs

On a one-off checkout, a decline is a lost sale unless the customer tries again. On a subscription, it is the first step toward involuntary churn. The customer still wants the product, but the renewal failed and the subscription moves to past_due. If retries run out, the subscription is canceled, marked unpaid or left past_due, depending on your Billing settings.

Many declines from different cards in a short window are a different problem. That pattern often means card testing, where fraudsters use your checkout to check stolen card numbers.

What to do when a payment is declined

  1. Read the codes. The decline code and advice code tell you whether to wait or act.
  2. Let automation handle soft declines. On subscriptions, Smart Retries picks retry times for you. Manual retries on top use up the network's retry limit.
  3. Contact the customer on hard declines. Ask for an updated card the same day. If Stripe's failed payment emails are on, the customer also gets a link to update their payment method.
  4. Look for patterns. A spike in blocked outcomes or many small failed attempts is a fraud signal. Whoever owns Radar rules should check it.
  5. Confirm the outcome. A recovered payment closes the case. An unanswered hard decline on a subscription turns into a cancellation a couple of weeks later.

How ChargeBell reports a declined payment

ChargeBell's failed payment alert fires on payment_intent.payment_failed. It posts the amount, the customer and Stripe's decline message, such as "Your card has insufficient funds." It doesn't label the decline as soft or hard, and it doesn't say whether Stripe will retry. Open the payment in Stripe from the alert to check the decline code and retry schedule. The alert is critical, so it skips quiet hours and can add an @channel prefix. Send it to a channel where someone handles billing, such as #billing or #founders. When a failed payment later succeeds, ChargeBell posts a payment recovered alert. ChargeBell's Stripe access is read-only, so it reports the decline and the fix happens in Stripe. The guide to failed payment alerts in Slack covers the setup.

Get alerted in Slack

Stripe events: payment_intent.payment_failed, charge.failed, invoice.payment_failed

# billing

ChargeBellAPP

⚠️ A $149.00 payment didn't go through

@channel

acme@example.com · Your card has insufficient funds.

Check Stripe to see if it will be retried.

Related terms