docs
IntegrateErrors

Introduction

XPay surfaces failures in two distinct places: the response body of an API call you made, and the lastPaymentError field on a payment that failed. Pick the surface that matches your problem.

XPay surfaces failures in two distinct places, and they're handled with two different patterns. Pick the one that matches what just went wrong:

  • An API call your server made returned a non-2xx. The error is in the HTTP response body. You handle it where the call happens. → API errors.
  • A customer's payment failed. The error sits on the lastPaymentError field of the Payment Intent for the rest of its life. You read it after the payment attempt, in your webhook handler or in the dashboard. → Payment errors.

These two surfaces don't share a code list and don't share a documentation URL namespace. The rest of the Errors group is split along this line.

The two surfaces at a glance

API errorsPayment errors
When you encounter itSynchronously, as the response to an API callAsynchronously, on the Payment Intent that failed
Where it livesThe HTTP response body: { error: { type, code, ... }, request_id }The Payment Intent's lastPaymentError field
What caused itYour request was rejected (validation, auth, missing resource, conflict)The customer's card was declined, or the processor failed
Who's the audience for the messageYour engineersYour customer (sometimes), your support team (always)
Code spacesOne: ApiErrorCodeThree: PaymentErrorCode, DeclineCode, raw network code
Handler shapetry / catch, branch on error.type and error.codeRead lastPaymentError, branch on adviceCode, pick customer-safe copy
ReferenceAPI error codesPayment error codes, Decline codes

Two things every error gives you

A request_id

Every API response (whether 2xx or error) includes a request_id like req_3STkwmFGhGHoO0IX13BRo5iU. On error responses it's at the top level alongside error. Quote it in support tickets, log it next to every error your handler catches, and use it to look up the failing call in Workbench → Logs where you can see the full request and response.

A failed payment also has a request_id on the underlying API call that triggered it (the POST /checkout/sessions/.../pay from the customer's browser). The lastPaymentError.chargeId plus the time of failure are usually enough to find that log if you need it.

A docUrl

Every error code has a deep link to its row on a code reference page in this docs site:

  • API error codes → https://docs.xpay.app/integrate/errors/api-error-codes#<code>
  • Payment error codes → https://docs.xpay.app/integrate/errors/payment-error-codes#<code>
  • Decline codes → https://docs.xpay.app/integrate/errors/decline-codes#<code>

The dashboard surfaces this link in transaction tooltips and in Workbench → Logs so you can click straight from a failed event to its explanation. In your own ops UI, render the docUrl as a "Learn more" link next to the error message.

Pick where to go next

On this page