docs
IntegrateErrors

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

On this page