Understanding Declines and Failed Payments

    Learn why some payments fail and what you can do to decrease your decline rate.

    Payments can fail for a variety of reasons and it’s frustrating whenever they represent a loss of legitimate business. Certain failures are actually preventative measures–working to minimize the possibility of a fraudulent payment that otherwise may have resulted in a dispute.

    There are three possible reasons why a payment might fail, and there is a different way of handling each failure. The reason for a payment’s failure is provided within the payment’s details in the Dashboard and through the API as part of the Charge object’s outcome. This parameter includes the type of payment failure, along with additional information about the reason for it.

    Payments declined by card issuers

    When a charge is submitted to the issuer of your customer’s card, they have automated systems that determine whether or not to authorize it. These systems take various signals into account, such as your customer’s spending habits, account balance, and card information like the expiration date and CVC.

    If your customer’s card issuer declines a payment, Stripe shares with you as much information explaining the decline as we receive, both within the Dashboard and through the API. In some cases, card issuers also provide helpful explanations, such as the card number or expiration date being incorrect, or that the customer does not have enough funds available to make the payment. The card issuer may provide one of these more specific reasons to Stripe through the use of a decline code.

    Unfortunately, most declines are categorized as “generic” so it’s not always possible to know exactly why a payment was declined. If all of the card information seems correct, it is best to have your customer contact their card issuer and ask for more information. For privacy and security, card issuers can only discuss the specifics of a declined payment with their cardholders–they cannot discuss this with the merchant.

    Through the API, the outcome of a payment that has been declined contains the type of payment failure that’s occurred and provides the reason using the decline code received by the card issuer:

      network_status: "declined_by_network"
      reason: "expired_card"
      risk_level: "normal"
      seller_message: "The bank returned the decline code `expired_card`."
      type: "issuer_declined"

    Reducing card issuer declines

    Card issuer declines arising from incorrect card information (e.g., incorrect card number or expiration date) are best handled by guiding your customer to correct the error or even using another card or payment method. For instance, Checkout can provide feedback to the customer if the card they’re attempting to use is declined, allowing them to try again or use an alternative payment method.

    Card issuers’ suspicions of fraudulent activity are more challenging to manage, but having customers provide the CVC and ZIP code when checking out can significantly decrease the number of declines you’re experiencing. The influence of other data that you collect, like the full address, varies by card brand and country. If you are still experiencing a higher-than-expected number of declined payments, consider collecting this additional data.

    Some customers may find that their card has restrictions on the type of purchases it can make. FSA/HSA cards are often limited to certain types of businesses (e.g., healthcare providers), so any other type of purchase would be declined. In addition, some card issuers may not allow purchases from certain countries or outside of their own. In either case, your customer must contact their card issuer to check for any restrictions that may be in place.

    A token must be used within a few minutes of its creation as CVC information is only available for a short amount of time. Tokens themselves do not expire, but using them after a delay can result in a charge request that is performed without CVC information. The consequences of this can be higher decline rates and increased risk of fraud.

    Blocked payments

    Stripe’s automated fraud prevention toolset, Radar, blocks any payments that we identify as being high-risk. Radar can help you most effectively combat fraud, with features such as rules that block payments if the CVC or ZIP code doesn’t match the information on file with your customer’s card issuer.

    Using the API, the outcome of a blocked payment reflects the type of payment failure and the reason for it, along with the risk level that was evaluated.

      network_status: "not_sent_to_network"
      reason: "highest_risk_level"
      risk_level: "highest"
      seller_message: "Stripe blocked this charge as too risky."
      type: "blocked"

    A blocked payment is initially authorized by the card issuer and could be processed successfully. Instead, Stripe does not charge the card as it’s likely the payment is fraudulent and could result in a dispute.

    Depending on the type of card being used, some customers may see the card issuer’s authorization for the payment amount on their statement. This amount has not been charged and no funds have been taken. The authorization is removed from their statement by the card issuer within a few days.

    If Stripe Radar ever blocks a payment that you know is legitimate, you can remove the block using the Dashboard. To do this, view the payment in the Dashboard and click the Mark as safe button. Marking a payment as safe doesn’t retry the payment, but it does prevent Stripe Radar from blocking future payment attempts with that card or email address.

    Invalid API calls

    As you develop your Stripe integration, good testing should identify any potential bugs that would lead to invalid API calls. Consequently these failures should be rare in production. Invalid API calls typically don’t result in a payment appearing in your Dashboard. However, in a few edge cases you may see the payment appear.

      network_status: "not_sent_to_network"
      type: "invalid"

    Managing payment failures programmatically

    If you would like your integration to respond to payment failures automatically, you can access a charge’s outcome in two ways.

    • Handle the API error returned when a payment fails. For blocked and card issuer-declined payments, the error includes the charge’s ID, which you can then use to retrieve the charge

    • Make use of webhooks to listen for event notifications. When a payment fails, the charge.failed event is triggered, containing the Charge object

    When developing your integration, we recommend writing code that gracefully handles all possible API exceptions, including unanticipated errors.

    When using PaymentIntents, you can retrieve the last_payment_error property from the PaymentIntent object to obtain details about its most recent failed charge attempt. You can also iterate over the PaymentIntent’s attempted charges and inspect the failure message. We recommend that PaymentIntent integrations use webhooks to monitor status updates. The payment_intent.payment_failed event triggers when a payment attempt is unsuccessful.

    Next steps

    Congrats! You’ve now learned why some payments may fail or be declined. You may want to learn more about the reasons card issuers decline payments:


    We're always happy to help with code or other questions you might have! Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode

    Was this page helpful? Yes No


    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.