What are decline codes?

When you create a payment via Primer, the request is sent to your chosen processor based on your payment workflows.

If the payment is not successful, the processor will return decline fields outlining why the payment was unsuccessful.

There are different reasons for payments being declined, such as:

  • Technical issues with the processor or payment method
  • Processor rejects the payment (typically due to fraud prevention rules)
  • Issuing bank declines the payment

Each processor has a very different way of responding and handling decline codes, which is where Primer comes in. We abstract this complexity and unify all the different decline code mappings into a single, standardized way of reasoning about declined payments.

Why are decline codes important?

Understanding why a payment is not authorized is crucial, serving as a key communication tool between payment systems, issuers, merchants and end customers.

They offer clarity and guidance when your payments encounter issues, enabling you to devise a strategy to achieve:

  • Enhanced customer experience - understanding the specific reason can help cardholders take appropriate action
  • Improved fraud prevention - help protect cardholders from unauthorized charges and your business from chargeback fees
  • Boost payment success - optimize your authorization rates by analyzing decline reasons and identifying areas of improvement

Decline codes on Primer

Below are the fields you need to consider when evaluating why a payment wasn’t successful:

FieldDescriptionPayment Object fields
Payment StatusThe status of the paymentstatus
transactions[x].processorStatus
Decision TypeThe decision behind why the payment was not successfulstatusReason.type
transactions[x].processorStatusReason.type
Decline TypeDetermines if the payment had a soft or hard decline when the decision type is ISSUER_DECLINEDstatusReason.declineType
transactions[x].processorStatusReason.declineType
Decline ReasonThe decline reason if the decision type is ISSUER_DECLINEDstatusReason.code
transactions[x].processorStatusReason.code
Error MessageThe error message provided by the processorstatusReason.message
transactions[x].processorStatusReason.message

What is the difference between the payment and transaction fields?

A Primer payment can have multiple processor transactions.

  • The payment fields represent the latest/final values
  • The transaction fields represent the values for that specific processor transaction

These fields are returned in the API response, as well as being included in the payment status webhook. For example:

12345678910111213141516171819202122232425
{    "id": "oWSlcuulG",    "date": "2023-11-01T13:04:15.704780",    "status": "DECLINED",        ...    "statusReason": {        "type": "ISSUER_DECLINED",        "declineType": "SOFT_DECLINE",        "code": "ISSUER_TEMPORARILY_UNAVAILABLE",        "message": "Processor Network Unavailable - Try Again"    },    "transactions": [        {            "date": "2023-10-25T12:23:20.568943",                        ...            "processorStatus": "DECLINED",            "processorStatusReason": {                "type": "ISSUER_DECLINED",                "declineType": "SOFT_DECLINE",                "code": "ISSUER_TEMPORARILY_UNAVAILABLE",                "message": "Processor Network Unavailable - Try Again"            }        }    ]}
json
copy

Payment Status

There are three possible payment statuses for unsuccessful payments:

StatusDescription
FAILEDThere is a technical problem that prevents the payment from being processed.
DECLINEDThe payment was processed and declined by one of the parties in the chain, such as the processor or card issuer.
CANCELLEDThe payment was canceled by the end customer. This is only used for some APMs.

Otherwise, CANCELLED is used when you choose to cancel an authorized payment.

Decision Type

There are 3 possible decision types behind why a payment is unsuccessful:

Decision TypeDescription
APPLICATION_ERRORThere is a technical problem that prevents the payment from being processed. This will only ever have status = FAILED.
GATEWAY_REJECTEDThe processor has rejected the payment and has not sent it downstream to be processed.
ISSUER_DECLINEDThe processor sent the payment to be processed but the card issuer has declined the payment.

Decline Type

There are two types of issuer declines:

Decline TypeDescription
SOFT_DECLINEThese payments can be retried under certain conditions
HARD_DECLINEThese payments should never be retried

You can face card scheme fines if you retry hard declines and over-retry soft declines, so it’s important to have a defined strategy here and ensure you aren’t breaching scheme rules.

Decline Reason

This should only populated when decision type is ISSUER_DECLINED.

Below are the decline reasons for hard declines:

Decline ReasonDescriptionMerchant Recommended Action
INVALID_CARD_NUMBERThe issuer does not recognize the card number that it’s received. Perhaps, the account number was never issued or has been permanently blocked/closedEvaluate for potential fraud and/or revalidate account number for accuracy
EXPIRED_CARDThe card is expired or the expiration date is invalidValidate the expiration date prior to reattempt and monitor reattempts for potential fraud
LOST_OR_STOLEN_CARDThe cardholder has reported the card stolen or lost, and as a result, the account is either fraud-compromised or closedRequest alternate payment method from cardholder and/or advise the cardholder to contact their issuer
SUSPECTED_FRAUDThe transaction does not pass risk monitoring detection systems or controlsAdvise the cardholder to contact their issuer
ERRORGeneric hard decline reason that groups a range of declinesCheck the error message for more information
UNKNOWNThe fallback decline reason if the decline code is not mapped. We conduct regular audits of this bucket of payments and update our mappings accordinglyCheck the error message for more information

Below are the decline reasons for soft declines:

Decline ReasonDescriptionMerchant Recommended Action
REFER_TO_CARD_ISSUERThe card issuer has indicated an issue with this card and requests contact from the customerThe shopper can try again after they resolved the issue with their bank/issuer
INSUFFICIENT_FUNDSTransaction amount exceeds the cardholder’s available balanceMay reattempt for a lesser amount or at a later date to allow the customer to fund their debit account or pay down their credit account
WITHDRAWAL_LIMIT_EXCEEDEDThe amount and/or count activity limit for the account has been exceededDo not reattempt the transaction the same day to allow limits to reset
ISSUER_TEMPORARILY_UNAVAILABLEThe issuer’s system is unable to perform the authorization due to system malfunction or critical message failureReattempts can occur within the same day
AUTHENTICATION_REQUIRED3DS is required for this paymentTrigger 3DS flow for this payment
DO_NOT_HONORThis is a generic refusal that card issuers provide that has several possible causesCheck the error message for more information
DECLINEDGeneric soft decline reason that groups a range of declinesCheck the error message for more information

Error Message

This is the error message provided by the processor so this does not have a predefined set of possible values. This can give extra information that’s useful when determining what’s the best action to pursue.

How decline codes are used within Primer’s ecosystem

Decline codes can be used in different ways to drive your payments strategy:

  • Create automated flows in Workflows to handle these scenarios, such as sending an automated email to the customer for every decline due to insufficient funds - learn more here
  • View aggregated data insights on all your declines in Observability to help identify broader trends and areas of improvement/focus - learn more here
  • Our Fallbacks feature is only triggered for certain decline scenarios - learn more here
  • Our Adaptive 3DS feature is only triggered for certain decline scenarios - learn more here
  • Create Monitors on Primer to track decline reasons, so you’re always alerted to changes in processor responses - learn more here