Skip to content

Every payment in Ripple Payments Direct 2.0 moves through a defined set of states from the moment a quote is accepted to final settlement. Understanding these states is fundamental to building a reliable integration. They determine when funds move, when an error has occurred, and what action (if any) your system should take next.


What you'll learn

  • What each payment state means and when it occurs.
  • How to follow the normal payment lifecycle from quote to completion.
  • The key differences between FAILED, DECLINED, and RETURNED.
  • How funds in your account are affected at each state.
  • How to track state changes using the API and webhooks.

Payment states reference

The paymentState field appears on every payment object and state transition record. The following states are currently defined:

StateDescriptionTerminal?
INITIATEDThe payment has been submitted and is awaiting validation by Ripple.No
VALIDATINGRipple is validating the payment details and reserving funds from the originator's available balance.No
TRANSFERRINGThe payment is being processed and funds are moving through the network toward the beneficiary. The source amount has been debited from the originator's account.No
COMPLETEDThe payment has completed and the beneficiary has received the funds.Yes
FAILEDThe payment could not be completed. Any funds previously reserved to complete the payment are released back to the available balance.Yes
RETURNEDThe payment was returned by a downstream institution after initially completing. Funds that were previously reserved and debited are returned and added back to the available balance.Yes
DECLINEDThe payment was declined due to user input errors or business rule violations. Any funds previously reserved to complete the payment are released back to the available balance.Yes
Future states

Additional states may be introduced in the future. Design your integration to handle unknown payment states gracefully. Do not fail hard on unexpected paymentState values.


The payment lifecycle

The typical, successful lifecycle of a payment follows this progression:

Payment lifecycle

A payment enters INITIATED as soon as it is submitted by accepting a valid quote. It then moves through VALIDATING while Ripple checks payment details and reserves funds. When validation succeeds, the payment enters TRANSFERRING as funds move to the beneficiary, and finally reaches COMPLETED when settlement is confirmed.

Terminal states

A terminal state means the payment lifecycle has ended and no further transitions will occur. There are four terminal states:

  • COMPLETED - the successful outcome.
  • FAILED - a processing or system error prevented completion.
  • DECLINED - a validation or business rule error prevented completion.
  • RETURNED - the payment completed but was subsequently reversed by a downstream institution.

Once a payment reaches a terminal state, the paymentId can no longer be used to initiate further activity. If you need to retry, you must create a new quote and payment.


How funds are affected at each state

The state of a payment determines what has happened to the originator's funds:

StateFund status
INITIATEDNo funds reserved yet. The payment has been submitted but not yet validated.
VALIDATINGFunds are reserved from the available balance. The originator cannot use reserved funds for other payments.
TRANSFERRINGFunds are debited. The payment is in flight; the source amount has left the originator's account.
COMPLETEDFunds remain debited. Settlement is confirmed.
FAILEDReserved funds are released back to the available balance. No debit occurred.
DECLINEDReserved funds are released back to the available balance. No debit occurred.
RETURNEDDebited funds are credited back to the available balance. Ripple handles the return automatically.

Understanding FAILED, DECLINED, and RETURNED

These three terminal states all indicate that a payment did not reach the beneficiary, but they have distinct causes and implications:

FAILED

FAILED indicates that Ripple Payments could not complete the payment due to a processing or system error, for example, a network failure, a timeout with a downstream rail, or an internal service error. The failure is not caused by an error in the payment data you provided.

  • Funds: Reserved funds are released. No debit occurred.
  • What to do: Check the errors[] field on the payment object for a reason code, then consider retrying the payment with a new quote after a delay.

DECLINED

DECLINED indicates that the payment was rejected due to user input errors or a business rule violation, for example, invalid beneficiary account details, a compliance rule block, or a field that fails downstream validation.

  • Funds: Reserved funds are released. No debit occurred.
  • What to do: Review the errors[] field for a specific error code and description. Correct the underlying issue (for example, update the beneficiary's financial instrument) before retrying.

RETURNED

RETURNED indicates that the payment initially reached COMPLETED (funds were debited and settlement was confirmed) but was subsequently returned by a downstream institution or payout partner. For example, the destination bank may have rejected the transfer after it was processed, or a compliance review may have triggered a return.

  • Funds: Debited funds are credited back to your available balance automatically by Ripple.
  • What to do: Check the errors[] field on the payment object for the return reason code. In many cases, you will need to correct the beneficiary's details before retrying. No manual fund recovery action is needed.
Note

Webhook notifications for PAYMENT_STATE_TRANSITION events do not include error details such as reason codes. To retrieve error details for FAILED, DECLINED, or RETURNED payments, call GET /v3/payments/{paymentId} and inspect the errors[] array.


Tracking state changes

Using the state transitions endpoint

To retrieve the full history of state changes for a payment, use:

GET /v3/payments/{paymentId}/state-transitions

Each record in the response includes:

  • updatedFrom - the state before the transition
  • updatedTo - the state after the transition
  • updatedAt - the timestamp of the transition

Example response (excerpt)

[
  {
    "updatedFrom": "INITIATED",
    "updatedTo": "VALIDATING",
    "updatedAt": "2026-03-01T14:22:10.123Z"
  },
  {
    "updatedFrom": "VALIDATING",
    "updatedTo": "TRANSFERRING",
    "updatedAt": "2026-03-01T14:22:18.456Z"
  },
  {
    "updatedFrom": "TRANSFERRING",
    "updatedTo": "COMPLETED",
    "updatedAt": "2026-03-01T14:22:45.789Z"
  }
]

Using webhooks

Ripple Payments Direct 2.0 sends a PAYMENT_STATE_TRANSITION webhook notification each time a payment changes state. This is the recommended approach for monitoring payment progress in production integrations, as it eliminates the need to poll.

The webhook payload uses a "thin-plus" design: it includes the paymentId and the new paymentState, along with additional context fields such as sourceCurrency, sourceAmount, destinationCurrency, payoutAmount, and beneficiaryToken.

Example webhook payload

{
  "id": "4d3f90cf-b70f-5ff1-827a-f8aa9cf84ab9",
  "eventType": "PAYMENT_STATE_TRANSITION",
  "eventVersion": 1,
  "eventData": {
    "paymentId": "5ce2c433-a96d-48d0-8857-02637a60abf4",
    "paymentState": "COMPLETED",
    "sourceCurrency": "USD",
    "sourceAmount": 100.00,
    "destinationCurrency": "BRL",
    "payoutAmount": 518.50,
    "beneficiaryToken": "cb207125-73a7-4a94-8502-a7780f1cae78",
    "createdAt": "2026-03-01T14:20:00.000Z",
    "expiresAt": "2026-04-30T14:20:00.000Z"
  },
  "createDate": "2026-03-01T14:22:46.000Z"
}
Out-of-order delivery

Webhook delivery order is not guaranteed. Notifications may arrive out of sequence if retries occur. Always use updatedAt timestamps from the state transitions endpoint (not webhook arrival order) to determine the authoritative state sequence.


Designing a robust state handler

When building integration logic that reacts to payment states, follow these guidelines:

  • Treat all terminal states explicitly. Handle COMPLETED, FAILED, DECLINED, and RETURNED as distinct outcomes with different downstream behavior.
  • Do not assume state order from webhooks. Use GET /v3/payments/{paymentId}/state-transitions to confirm the authoritative sequence if delivery order matters.
  • For FAILED and DECLINED, fetch the full payment object to retrieve error details before deciding to retry.
  • Implement idempotency on state handlers. Webhooks may be delivered more than once. Your handler should be safe to call repeatedly for the same paymentId and paymentState.
  • Handle unknown states gracefully. Log and alert on unexpected state values, but do not discard the event.

Relevant API operations

OperationMethodPath
Create a paymentPOST/v3/payments
Get a payment by IDGET/v3/payments/{paymentId}
Get state transitions by payment IDGET/v3/payments/{paymentId}/state-transitions
Search paymentsPOST/v3/payments/filter

Next steps

  • To learn how to create a payment and handle its lifecycle end-to-end, see Create a payment.
  • To understand what happens when a payment is returned and how funds are recovered, see Payment returns.
  • To set up webhooks for real-time state transition notifications, see Notification webhooks.