Understanding declines and failed payments
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. In some cases, the reason provided may take into account factors besides the issuer response code, such as a Radar rule evaluation that caused the charge to be blocked.
... 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 (for example, 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 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 (for example, healthcare providers), so any other type of purchase would be declined. In addition, some card issuers might 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 are 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 prebuilt 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 high-risk payments, such as those with mismatched CVC or postal code values, even if you are not subscribed to Radar. See our Fraud prevention doc for more information on how Radar can help you define rules to combat and prevent fraud and disputes.
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.
Don’t see the Add to allow list button? Contact Stripe to have this feature added to your Radar account.
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
There are several ways to handle payment failures:
- Retrieve the last_payment_error.decline_code property from the PaymentIntent object to see why the card issuer declined the payment attempt.
- Iterate over the PaymentIntent’s attempted charges and inspect the failure message.
- Use webhooks to monitor PaymentIntent status updates. For example, the
payment_intent.payment_failed
event triggers when a payment attempt is unsuccessful.
You may also need to handle additional payment failure scenarios such as when your customer is present in your checkout flow (on-session) or when they are not in your checkout flow (off-session).
On-session declines
If your customer is present in your website or application’s checkout flow, prompt them to try their payment method again or ask for a new payment method.
Off-session declines
If your customer isn’t available to make a payment or update a payment method, notify them (for example, send them an email or in-app notification) to visit your website or application to do so. If your business is affected by regulations like Strong Customer Authentication, payment attempts may also require authentication and fail with an authentication_required decline code. For more information on handling these scenarios, see off-session payments with saved cards.
When developing your integration, we recommend writing code that gracefully handles all possible API exceptions, including unanticipated errors.
Stripe Billing handles many of these payment failure scenarios with features like Automatic Collection and Hosted Invoices. See if Stripe Billing works for your business so that you don’t have to build these flows yourself.
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.