Payment error codes
Every value of `lastPaymentError.code`, grouped by domain. Each entry's URL is the value of `lastPaymentError.docUrl`.
This page is the destination of every lastPaymentError.docUrl whose code came from PaymentErrorCode. Anchors here match the code value, so https://docs.xpay.app/integrate/errors/payment-error-codes#card_declined lands directly on the row below.
For the issuer's specific decline reason on a card payment (lastPaymentError.declineCode), see Decline codes. For the model and the handler pattern, see Payment errors.
Card validation
The customer entered card details that don't pass basic validation. paymentMethodType: "card". Advice: confirm_card_data (have the customer re-enter their details).
invalid_number
The card number isn't in a valid format (wrong length, fails Luhn check, etc.).
invalid_expiry_month
The expiration month isn't a valid value.
invalid_expiry_year
The expiration year isn't a valid value.
invalid_cvc
The CVC/CVV isn't in a valid format (wrong length).
incorrect_number
The card number passed format validation but the issuer says it's wrong.
incorrect_cvc
The CVC/CVV doesn't match what the issuer has on file.
incorrect_zip
The postal code doesn't match the billing address on file with the issuer.
expired_card
The card expired. The customer needs a different card.
Processing
Errors that came back during the actual charge attempt. Mix of card errors and processor outcomes.
card_declined
The issuer declined the charge without a more specific reason. Pair with lastPaymentError.declineCode for the issuer-level reason when present.
processing_error
An error occurred during processing, but the issuer didn't reject the charge outright. Often transient. Advice: try_again_later.
authentication_required
The issuer requires additional authentication (3D Secure) to complete the payment. The customer needs to re-attempt and complete the challenge.
Account and balance
insufficient_funds
The customer's card doesn't have enough available balance for the charge.
card_velocity_exceeded
The card has been used too many times in a short window. Advice: try_again_later.
Fraud and risk
The issuer rejected the charge for risk reasons. Advice: do_not_try_again for all three.
fraudulent
The issuer (or XPay's own risk signals) flagged the payment as fraudulent. Don't retry; this attempt is logged on the issuer's side.
stolen_card
The card was reported stolen. Don't retry. Notify your support team if the rate is unusual.
lost_card
The card was reported lost.
Processor
issuer_not_available
XPay couldn't reach the card's issuing bank. Advice: try_again_later.
processor_timeout
The payment processor didn't respond in time. The request may have succeeded on their side; check the dashboard before retrying. Advice: try_again_later.
processor_declined
The processor declined the charge for a reason that didn't translate into a more specific code.
Request
amount_too_large
The charge amount exceeds the maximum allowed for this payment method.
amount_too_small
The charge amount is below the minimum required for this payment method.
currency_not_supported
The currency isn't supported by this payment method.
duplicate_transaction
The processor detected a similar transaction recently. Wait, then retry.
Refund
charge_already_refunded
You tried to refund a charge that's already been fully refunded.
charge_disputed
You tried to refund a charge that's currently under dispute. Disputed charges are out of your control until the dispute resolves.
refund_disputed_payment
You tried to refund a payment that's been disputed. Same rule.
Non-card payment methods
payment_declined
A non-card payment method (BNPL, kiosk, wallet, bank transfer) declined the payment. Specifics depend on the provider; check the dashboard for details.
Generic
When the processor or issuer doesn't return a specific reason, XPay falls back to one of these.
generic_decline
The payment was declined without a specific reason.
do_not_honor
The issuer returned "do not honor", which usually means the customer should contact their bank. Advice: try_again_later.
call_issuer
The issuer told the customer to call them. Show the customer a clear "contact your bank and try again" prompt.
Where to next
Decline codes
The issuer's decline reason in lastPaymentError.declineCode. More granular than the codes on this page.
Payment errors
The model: how lastPaymentError is shaped and how to handle it.
API error codes
The other reference: codes returned in error.code on a failed API call.
API errors
The synchronous API error envelope.
Errors introduction
Back to the top. The two-surfaces map.
Payment errors
When a customer's payment fails, the error sits on the Payment Intent's lastPaymentError field. The shape, the adviceCode, and how to split copy between your customer and your team.
Decline codes
Issuer-level decline reasons returned in `lastPaymentError.declineCode`. Plus how to read the raw `networkDeclineCode` passthrough.