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 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, andRETURNED. - How funds in your account are affected at each state.
- How to track state changes using the API and webhooks.
The paymentState field appears on every payment object and state transition record. The following states are currently defined:
| State | Description | Terminal? |
|---|---|---|
INITIATED | The payment has been submitted and is awaiting validation by Ripple. | No |
VALIDATING | Ripple is validating the payment details and reserving funds from the originator's available balance. | No |
TRANSFERRING | The 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 |
COMPLETED | The payment has completed and the beneficiary has received the funds. | Yes |
FAILED | The payment could not be completed. Any funds previously reserved to complete the payment are released back to the available balance. | Yes |
RETURNED | The 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 |
DECLINED | The 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 |
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 typical, successful lifecycle of a payment follows this progression:

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.
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.
The state of a payment determines what has happened to the originator's funds:
| State | Fund status |
|---|---|
INITIATED | No funds reserved yet. The payment has been submitted but not yet validated. |
VALIDATING | Funds are reserved from the available balance. The originator cannot use reserved funds for other payments. |
TRANSFERRING | Funds are debited. The payment is in flight; the source amount has left the originator's account. |
COMPLETED | Funds remain debited. Settlement is confirmed. |
FAILED | Reserved funds are released back to the available balance. No debit occurred. |
DECLINED | Reserved funds are released back to the available balance. No debit occurred. |
RETURNED | Debited funds are credited back to the available balance. Ripple handles the return automatically. |
These three terminal states all indicate that a payment did not reach the beneficiary, but they have distinct causes and implications:
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 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 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.
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.
To retrieve the full history of state changes for a payment, use:
GET /v3/payments/{paymentId}/state-transitionsEach record in the response includes:
updatedFrom- the state before the transitionupdatedTo- the state after the transitionupdatedAt- 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"
}
]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"
}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.
When building integration logic that reacts to payment states, follow these guidelines:
- Treat all terminal states explicitly. Handle
COMPLETED,FAILED,DECLINED, andRETURNEDas distinct outcomes with different downstream behavior. - Do not assume state order from webhooks. Use
GET /v3/payments/{paymentId}/state-transitionsto confirm the authoritative sequence if delivery order matters. - For
FAILEDandDECLINED, 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
paymentIdandpaymentState. - Handle unknown states gracefully. Log and alert on unexpected state values, but do not discard the event.
| Operation | Method | Path |
|---|---|---|
| Create a payment | POST | /v3/payments |
| Get a payment by ID | GET | /v3/payments/{paymentId} |
| Get state transitions by payment ID | GET | /v3/payments/{paymentId}/state-transitions |
| Search payments | POST | /v3/payments/filter |
- 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.