Skip to main content
An HTTP request can succeed while the created financial object later reaches a failed state. Handle transport and request failures separately from object status.

Four failure surfaces

  • HTTP error: no successful operation response was returned. Use error.code and the HTTP error catalogue. If retrying a create operation, preserve the original Idempotency-Key and an equivalent operation-specific effective request identity unless the catalogue requires a corrected request. Keep card-data retries inside the approved PCI boundary.
  • Payment FAILED: the create call may have returned 201. Use the Payment’s failure_code and failure_message. This Payment is final; a customer retry creates a new Payment with a new key.
  • Refund FAILED: the Refund exists. Use failure.code and failure.message, retrieve the parent Payment, and check the remaining refundable amount and business intent before creating a new Refund.
  • Payout FAILED: the Payout is terminal. Use its public failure_code and failure_message, retain the Payout ID and request ID, and reconcile the result before deciding on a distinct business Payout.

Payment and Refund failure codes

Payment failure_code and Refund failure.code use the same public vocabulary below. The meaning column applies to both objects; the action column applies only to a failed Payment. Do not apply that Payment action to a Refund. Keep customer-facing text short and neutral. A Refund never requires a shopper browser action: if a Refund carries a 3D Secure-labelled terminal code, treat it only as a failure reason and do not redirect the customer. An unknown failure_code is still a terminal Payment failure. Show a neutral decline, offer another card, retain the IDs, and do not expose raw processor details.

Refund failures

When a Refund is FAILED, use the nested failure.code and failure.message for developer handling. The Refund object remains part of the parent Payment’s refunds[] history. Never ask for another card or initiate a browser action from the shared failure code. An unknown failure.code is still a terminal Refund failure: retain the Refund, Payment, and request IDs, show neutral text, and reconcile the parent Payment before deciding whether to create another Refund. Before another Refund:
  1. retrieve the parent Payment;
  2. reconcile amount_refunded and amount_refundable;
  3. confirm that the business still intends to return the amount;
  4. create a distinct Refund with a new key only when appropriate.

Payout failures

FAILED records a definitive Payout failure. Read failure_code and failure_message; these fields are omitted in other states. They use the public operation-failure vocabulary, not raw provider codes. Keep customer copy neutral and retain the Payout ID and the Request-Id from the relevant request. For a known or unknown failure code, do not automatically create another Payout. Retrieve the operation, confirm the business intent and destination, and use a new key only for a deliberately new Payout. An uncertain or lost HTTP response is different: preserve the original key and follow Idempotency.