Understanding payment failures can really help increase your acceptance rates and minimize the number of transactions rejected. While this post focuses on credit cards, the approach also works for any type of payment methods (ACH, hosted payment pages, e-wallets, etc.).

CardError is just one of many possible errors

A typical integration with a payment gateway such as Stripe looks like this:

In the error handling block, you may decide to email the customer, block his access to your website, etc. Hopefully, you also keep track of these errors and generate a daily report on how many transactions fail. After all, these directly impact your bottom line.

Is this good enough? Unfortunately, as we will see below, this approach is often too simplistic. In this particular example, the exception caught is only one of several possibilities.

Looking at Stripe’s documentation specifically, CardError is thrown only for 402 – Request Failed. Other exceptions can occur, such as RateLimitError, when 429 – Too Many Requests is returned: in this case, you went over your API quota and you will want to resubmit such requests later.

Let’s now assume we fix our code above to look like:

You should closely monitor errors like InvalidRequestError, AuthenticationError or APIError after each deployment, as they may be triggered by a recent code or configuration change.

Dig deeper into payment failures

But what about the black box of CardError? Let’s look at how we can further categorize CardError payment failures.

Transactions blocked by payment gateway

Some transactions get blocked by your payment gateway. For instance, Braintree refers to them as Gateway Rejections. A typical example is CVV rejections. When triggering an authorization, the issuing bank tells the gateway if the supplied CVV matches. If it doesn’t, you can configure most gateways to automatically void the transaction to prevent fraud.

Another typical scenario is when your provider offers fraud detection tools. If it determines that the transaction is suspicious, it can block it right away. It’s important to track these rejections separately and tweak your gateway settings according to the type of goods and services you offer, country of business, etc., to avoid fraud while ensuring your good customers can still check-out.

Transactions blocked by payment processor

Transactions are also blocked by the actual payment processor. (Most gateways are actually API wrappers to payment processors, who will in turn contact the issuing banks through the payment networks.)

Going back to Braintree, they are referred to as Declines. We can further break these down into two categories: hard declines and soft declines. You cannot retry hard declines (for example, Invalid Credit Card Number) because such transactions cannot succeed. However, you can retry soft declines (such as Insufficient Funds) at a later point.

Understanding processor errors

The goal of understanding processor errors is to increase acceptance rates and minimize the number of rejected transactions.

Let’s take a look at CyberSource (gateway) integrated with Chase Paymentech (processor):

Chase Errors 540 Declined – Under 18 Years Old and 542 – Declined – Bill To Not Equal Ship To. These are both returned by CyberSource as Error 203 – General decline of the card.

While the CyberSource general error is cryptic, the actual Chase error gives you a lot of information. So, by asking the customer to verify his personal information (such as billing address and age) early in the purchase funnel, you can minimize the number of transactions due to errors 540 and 542 that Chase rejects. You could not do this by looking at the CyberSource data because it labels such errors simply as Error 203 – General decline of the card.

Accessing raw error codes isn’t always easy, unfortunately. In the case of Chase Paymentech specifically, you can get them by looking at the Stratus documentation for the underlying processing platform.

You’ll need to do this for each payment processor you are using. As you support more and more payment methods in various countries, you will most likely integrate with more than one payment processor. For example, Chase Paymentech via CyberSource doesn’t support Maestro UK, so you would need to also configure Barclays in CyberSource to accept these cards.

Using Kill Bill to integrate with payment gateways

Doing all of this low-level work is one of the features that Kill Bill Payments platform offers, and why you would want to avoid integrating with a gateway directly. With Kill Bill, each payment transaction has a specific state:

  • SUCCESS, for when the payment went through
  • PAYMENT_FAILURE, for errors tied to the card (e.g. insufficient funds): these are the hard ones to understand, and often involve business discussions with your gateway, bank, etc. You may also need to try out a new processor for a subset of your traffic to optimize them
  • PLUGIN_FAILURE, for errors not tied to the card (configuration issue, gateway down, etc.): you should monitor them closely as these indicate problems that can be more easily fixed (e.g. lower fraud checks thresholds)
  • UNKNOWN, for everything else

Kill Bill communicates with payment gateways via plugins, which implement the mapping of these errors to these states. This separation of concern lets Kill Bill implement retries in a generic way. Similarly, the Analytics plugin can generate reports that are gateway agnostic.

Note that you should have very few UNKNOWN transactions: this is where Kill Bill doesn’t know if the payment went through. This can happen when receiving a timeout from the gateway. If the provider supports it, Kill Bill will attempt to fix the state automatically by fetching the payment state using the unique reference code it sent along with the transaction. You can read more about this in our documentation on payment states.

Simplify error handling with the Kill Bill payment platform

To summarize, integrating with a payment API is difficult, as there are often a lot of intermediaries in the chain. One of the goals of Kill Bill is to simplify this integration, even if you integrate with several gateways, directly with processors, or any combination thereof.