- WooCommerce
- Magento
- Shopify Soon
Payment failure codes
Understand what each Reservepay failure code means for card payments, including the 3D Secure authentication step.
Overview
When a payment reaches FAILED status, Reservepay attaches a failure_code that tells you why. These failure codes are canonical across payment methods: insufficient_funds means the same thing no matter how the customer paid. Underneath, each payment method's bank or provider returns its own response code or message, and Reservepay maps that raw response onto one of these shared codes.
This guide lists the failure codes Reservepay produces for card payments, split between the card authorization itself and the 3D Secure authentication step that precedes it.
Where to read the failure code
Failure codes live on the payment object as two fields:
| Field | Type | Description |
|---|---|---|
failure_code |
string |
A machine-readable identifier for the failure (e.g., insufficient_funds). |
failure_message |
string |
A short description of why the payment failed. |
Both fields are null unless the payment failed. Retrieve them with find-payment. The payment list and search endpoints such as list-payments and filter-payments return the same payment object, so the same two fields are available there.
The payment_completed webhook fires when a payment transitions to either SUCCESSFUL or FAILED, but its payload carries only status, not the failure code. When you receive payment_completed with a status of FAILED, call find-payment with the payment_id from the event to read failure_code.
Failure codes are separate from the API error triples returned when a request itself is rejected. See Error Handling for those. A failed payment is a successful API call describing a declined payment.
How to handle failure codes
Branch your logic on the machine-readable failure_code, not on the human-readable failure_message. Messages exist for surfacing to users, and codes are stable across bank wording changes. A few codes are worth handling distinctly from a plain decline:
issuer_not_availablemeans the card issuer couldn't be reached, so the payment was never authorized. This is often transient, so it's reasonable to let the customer retry immediately.generic_declineis Reservepay's catch-all for a raw response that doesn't map to anything more specific yet. Treat it the same as any other decline, and don't build logic that depends on it disappearing over time.- Everything else, including
insufficient_funds,invalid_cvv,expired_card, andlimit_exceeded, is a terminal decline for that attempt. Show the customer the message and let them choose a different payment method or card.
Card
| Failure code | Message |
|---|---|
call_issuer |
The payment was declined by the issuer. |
do_not_honor |
The payment was declined by the issuer. |
expired_card |
The card has expired. |
generic_decline |
The payment was declined for an unknown reason. |
incorrect_pin |
The PIN entered is incorrect. |
insufficient_funds |
The card has insufficient funds to complete the purchase. |
invalid_account |
The card, or account the card is connected to, is invalid. |
invalid_amount |
The payment amount is invalid, or exceeds the amount that’s allowed. |
invalid_cvv |
The CVV number is incorrect. |
invalid_transaction |
The transaction is invalid. |
issuer_not_available |
The card issuer couldn’t be reached, so the payment couldn’t be authorized. |
limit_exceeded |
The customer has exceeded the balance or credit limit available on their card. |
lost_card |
The payment was declined because the card is reported lost. |
no_action_taken |
The payment was declined by the issuer. |
not_permitted |
The payment isn’t permitted. |
pickup_card |
The payment was declined because the card is reported lost or stolen. |
pin_try_exceeded |
The allowable number of PIN tries was exceeded. |
processing_error |
An error occurred while processing the card. |
reenter_transaction |
The payment couldn’t be processed by the issuer for an unknown reason. |
restricted_card |
The customer can’t use this card to make this payment. |
revocation_of_authorization |
Recurring charge stopped at customer request. |
stolen_card |
The payment was declined because the card is reported stolen. |
suspected_fraud |
The payment was declined because the card issuer suspects that it’s fraudulent. |
violation |
The payment violates terms of service, program rules, or applicable laws. |
Card (3DS step)
These codes come from the 3D Secure authentication step, before the card network authorizes the payment itself.
| Failure code | Message |
|---|---|
3ds_authentication_declined |
3DS authentication was declined for an unknown reason. |
3ds_authentication_failed |
3DS authentication failed. |
3ds_authentication_not_completed |
3DS authentication wasn't completed by the cardholder. |
3ds_authentication_not_performed |
3DS authentication wasn't performed by the cardholder. |
expired_card |
The card has expired. |
invalid_card |
The card is invalid. |
limit_exceeded |
The cardholder has exceeded authentication frequency limit. |
non_enrolled_card |
The card isn't enrolled. |
not_permitted |
The payment isn’t permitted. |
processing_error |
An error occurred while authenticating. |
stolen_card |
The payment was declined because the card is reported stolen. |
suspected_fraud |
The payment was declined because the card issuer suspects that it’s fraudulent. |
Dive deeper into these advanced integration topics to unlock Reservepay's full potential with our in-depth guides.
Issue refunds, void transactions before they settle, and reverse authorizations when needed.
Read the guideSeparate authorization from capture to hold funds without charging. Perfect for pre-orders or reservations
Read the guideBuild your own POS, or work with our app by sending commands or using deep links.
Read the guideBuild profiles by attaching customer data. Gain insights, reduce fraud risk, and create experiences that drive loyalty.
Read the guideSend payouts to your primary bank account or to your contacts via bank account, mobile number or national ID.
Read the guideStay informed about payment events with real-time webhooks. Automate your order processing, and more...
Read the guideLook up what each Reservepay failure code means when a payment is declined.
Read the guideNo account yet?
Start integrating all these amazing features into your app or website by creating your own merchant account today. It's free to sign up and only takes a few minutes to get started.
