Understanding Declines and Failed Payments

    Learn why some payments fail and what you can do to decrease your decline rate. If you need help after reading this, search our documentation or check out answers to common questions. You can even chat live with other developers in #stripe on freenode.

    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.

    Bank-declined payments

    When a charge is submitted to the bank or card 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 bank or 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, banks 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 bank 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 bank and ask for more information. For privacy and security, banks and 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 bank-declined charge contains the type of payment failure that’s occurred and provides the reason using the decline code received by the bank:

    ...
    outcome:
    {
      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 bank declines

    Bank 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.

    Banks’ 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. Using a CVC is only strictly necessary if your account is based in a European country, but it is still highly recommended. 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 banks may not allow purchases from certain countries or outside of their own. In either case, your customer must contact their bank 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 bank.

    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.

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

    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 call typically don’t result in a payment appearing in your Dashboard. However, in a few edge cases you may see the payment appear.

    ...
    outcome:
    {
      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 bank-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.

    Next steps

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