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 when they result in the loss of legitimate business. Many payments fail for good reason and do so to minimize the possibility of a fraudulent payment.

    We continuously work to reduce decline rates for cards processed on Stripe with machine learning and experimentation, along with issuer and network outreach to optimize acceptance rates for all Stripe businesses—often without requiring any changes to your integration.

    There are three possible reasons why a credit card payment might fail:

    Each type of failure is handled differently. 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 and models that determine whether or not to authorize it. These systems analyze various signals, such as your customer’s spending habits, account balance, and card information such as the expiration date, address information 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 by the card issuer 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, or even with Stripe.

    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:

    ...
    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 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 postal code when checking out can significantly decrease the number of declines you’re experiencing. The influence of other data that you collect, such as the full billing 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. Additionally, using 3D Secure to authenticate payments may decrease decline rates in countries where it is supported.

    When investigating generic or do not honor declines, the accompanying data can give a better picture of why the card may have declined. For example, if CVC or AVS checks failed upon adding the card, resolving those issues and then re-attempting the charge may result in a successful authorization. However, if you notice a card issued in a different country from that which the client IP address corresponds to, that may indicate a legitimate decline due to potential unauthorized card use.

    Card restrictions

    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.

    Geographic location

    If your customers are using cards issued in a different country than where your Stripe account is registered, they may experience an increased rate of declines. The quickest way to resolve this is for your customers to contact their issuing bank to authorize the charge. If you have customers concentrated in different locations around the world, you might also consider setting up Stripe accounts in your larger markets, or those where you are experiencing higher decline rates to process those charges locally.

    Analyzing your decline rate over time

    Tracking your decline rate over time is a good way to flag proactive issues with fraud or potential integration bugs. We recommend analyzing unique declines and excluding failed retries as opposed to absolute numbers of declines as this can give a clearer picture of your overall authorization rates.

    Stripe Sigma, our interactive SQL reporting environment, includes pre-built queries to help you analyze your decline rate. If you’re investigating declines outside of Sigma you can exclude repeat attempts by looking at card fingerprints instead of charge IDs.

    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.

    ...
    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"
    },
    ...
    

    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 Add to allow list button. Adding a payment to allow list 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.

    ...
    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 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 the Payment Intents API, 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 integrations using Payment Intents API use webhooks to monitor status updates. The payment_intent.payment_failed event triggers when a payment attempt is unsuccessful.

    Retrying card issuer declines

    If your integration has retry logic in place to retry declined charges, be aware that card networks have rules in place for how many times you can reattempt a single charge. We recommend you not retry charges more than four times. Creating additional retries may be seen by issuers as potential fraud and could result in legitimate charges being declined more frequently.

    Stripe Billing users can take advantage of Smart Retries, a machine learning tool that retries card charges at the optimal time to increase the chance of a successful charge.

    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:

    Questions?

    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

    Send

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

    On this page