Payment states
This topic explains the payment state function in RippleNet integrated payments.
The state
field of the payment object defines the payment status. Each subsequent state overrides previous states.
RippleNet payment states
Refer to the following table for all possible states.
State |
Description |
---|---|
ACCEPTED |
The first state of the payment object. The sender has made a successful Accept quote request to its RippleNet instance, generating a payment_id , which is applied to the quote and persisted as a payment object. In this state, the receiver can lock, reject, or fail the payment. |
LOCKED |
The receiver has agreed to proceed with the payment by making successful Lock payment requests. When the payment is still in a partially LOCKED state (that is, not locked on all RippleNet nodes across the payment chain), the receiver can Reject Payment or Fail Payment. Once fully LOCKED across the payment chain, the sender can either Fail Payment or Settle Payment. |
LOCK_DECLINED |
The receiver has made a successful Reject payment request. For institutions that have not yet locked the payment, the state changes from ACCEPTED to LOCK_DECLINED . For institutions that have locked the payment, the state changes from LOCKED to LOCK_DECLINED . The sender must repair the rejected payment and make a Retry Accept Payment request. The sender can fail payments in the LOCK_DECLINED state. |
PREPARED |
The sender has made a Settle payment request, which created the crypto-transaction and put the payment within the "crypto-transaction boundary". In this state, funds have been transferred to the hold account on the sender's RippleNet ledger. A payment cannot expire in the PREPARED state; if the payment does not settle before the crypto-transaction expires, it moves to the SETTLEMENT_DECLINED state. When a payment is in the SETTLEMENT_DECLINED state, the sender can Retry Settle Payment which, if successful, moves the payment back to the PREPARED state and generates a new crypto-transaction. |
EXECUTED |
The receiver has signed the execution_condition creating a "payload" and sent an "execute payment transfer" message, which travels to all participants in the payment. When the payment is fully executed, funds have been transferred from the hold account to the receiver account on all RippleNet ledgers. Only the receiver can fail payments in the EXECUTED state. The general use case for failing an executed payment is to return the payment to the originating institution in fiat only transactions. |
SETTLEMENT_DECLINED |
The receiver has not been able to fulfill the payment due to insufficient liquidity. Once the problem is addressed, and if the payment has not expired, senders can resubmit the Settle Payment request. If this request is successful, RippleNet moves the payment back to the PREPARED state and generates a new crypto-transaction. Payments that expire before being settled move automatically to the FAILED state. |
FAILED |
The payment has been actively stopped by a participating institution, or the payment has failed automatically because the payment has expired. An institution can only fail a payment in turn. Failed payments can be returned in fiat flows. |
COMPLETED |
After verifying that the funds have reached the end beneficiary, the payment state gets updated to COMPLETED . Depending on your use case, this verification happens either outside the RippleNet payment flow by the receiver or within; hence, the COMPLETED state may be triggered outside of RippleNet but can still be returned in fiat flows. |
RETURNED |
For fiat payments only A final state. The receiver has sent a Return payment request, generating a new payment object, in reference to the original payment from the sender. Return Payment initiates a quote collection response and follows normal payment flow but in reverse order. When this new payment is successfully moved to the COMPLETED state and the money is returned, the original payment automatically moves to the RETURNED state from either the EXECUTED , COMPLETED or FAILED state. |
Request for payment states
The state
field of the RequestForPayment
object defines the end-to-end payment request status. Each subsequent state overrides previous states.
State |
Description |
---|---|
REQUESTED |
The first state of the RequestForPayment object. The payment beneficiary institution has made a successful Send request for payment request. In this state, the payment sender institution knows to initiate a payment to the beneficiary. |
ACCEPTED |
The final state of a successful request for payment. The payment sender has sent an Accept request for payment request and populated the RequestForPayment object with the payment_id of the settled payment. |
FAILED |
The request for payment had been actively terminated with a Fail request for payment request. |
Payment state transitions
Once all parties agree upon a payment contract and the payment state is LOCKED
, RippleNet uses a two-phase commit to execute the payment.
On all RippleNet ledgers in the payment chain (sender, intermediaries, receiver):
-
Funds transfer to a hold account and the payment state moves from
LOCKED
toPREPARED
. -
Funds transfer to a transactional account and the payment state moves from
PREPARED
toEXECUTED
.
Once a payment is PREPARED
it moves into a logical area called the crypto-transaction boundary. Within the boundary, payment state changes are determined by the state of the crypto-transaction, which can be PENDING
, EXECUTED
, EXPIRED
or CANCELLED
. Outside of the boundary, the payment succeeds or fails based on the payment expiration time.
Most payments are executed as expected and payment state transitions are near simultaneous on all RippleNet instances. There may be times, however, when each RippleNet instance temporarily reflects a different payment state. Whether the payment is successful or not, background processes ensure that the payment state is eventually consistent across all RippleNet instances.
Scenarios
Both scenarios below assume:
-
The payment chain is
Sender
>Receiver
. -
The payment is
LOCKED
on all nodes in the payment chain. - The validator on the sender's RippleNet host is used for the payment.
Happy path
The happy path assumes that all RippleNet ledgers have enough liquidity to execute the payment.
-
Sender sends a
Settle payment
request:
- The validator creates a crypto-transaction using the execution condition created with Accept quote .
- Funds on the sender RippleNet ledger transfer to a hold account.
-
Payment state on the sender RippleNet instance moves to
PREPARED
.
Payment states across payment chain:
Sender |
Receiver |
---|---|
PREPARED |
LOCKED |
-
The sender sends a message to the receiver that the payment is
PREPARED
:- Funds on the receiver RippleNet ledger transfer to a hold account.
-
Payment state on the receiver RippleNet instance moves to
PREPARED
(and all parties have consistent states). -
Receiver sends a
200 OK
response up the payment chain (and spawns a background process to send the fulfillment).
Payment states across payment chain:
Sender |
Receiver |
---|---|
PREPARED |
PREPARED |
-
The receiver creates the payment fulfillment (using its private key) and sends it to the
validator
.
- Validator cryptographically verifies the fulfillment.
-
Validator executes the crypto-transaction and the
crypto-transaction state moves to
EXECUTED
.
-
The
validator
sends the
EXECUTED
crypto-transaction to the receiver:- Funds on the receiver RippleNet ledger transfer from the hold account to the transactional account.
-
Payment state on the receiver RippleNet instance moves to
EXECUTED
.
Payment states across payment chain:
Sender |
Receiver |
---|---|
PREPARED |
EXECUTED |
-
The sender sends a message up the payment chain that the payment has been executed:
- Funds on the sender RippleNet ledger transfer from the hold account to the transactional account.
-
Payment state on the sender RippleNet instance moves to
EXECUTED
.
Payment states across payment chain:
Sender |
Receiver |
---|---|
EXECUTED |
EXECUTED |
Note
If a payment is in the PREPARED
state and within the crypto-transaction boundary, a background process continually queries the validator for the state of the crypto-transaction. If the crypto-transaction is EXECUTED
, but the happy path message does not reach the other RippleNet nodes so that they seem "stuck" in the PREPARED
state, the background process takes over and triggers payment execution.
Unhappy path
In this path, the receiving RippleNet ledger does not have enough liquidity to execute the payment and the crypto-transaction is cancelled.
-
Sender sends a
Settle payment
request:
- The validator creates a crypto-transaction (using the execution condition created with Accept quote ).
- Funds on the sender RippleNet ledger transfer to a hold account.
-
Payment state on the sender RippleNet instance moves to
PREPARED
.
Payment states across payment chain:
Sender |
Receiver |
---|---|
PREPARED |
LOCKED |
-
Sender sends a message to the receiver that the payment is
PREPARED
:- Funds on the receiver RippleNet ledger are not available and no funds move .
- The validator does not receive fulfillment from the receiver and the crypto-transaction state moves to CANCELLED .
-
Payment state on the sender and receiver instances moves to
SETTLEMENT_DECLINED
. - Funds on the sender RippleNet ledger rollback from the hold account.
Payment states across payment chain:
Sender |
Receiver |
|
---|---|---|
SETTLEMENT_DECLINED |
SETTLEMENT_DECLINED |
- Receiving institution repairs liquidity issue out-of-band.
Payment expiration
If the payment expires while waiting in the SETTLEMENT_DECLINED
state, it transitions to the FAILED
state on all RippleNet instances.
-
Sender resubmits a
Settle payment
request against the same payment ID.
- The validator creates a new crypto-transaction.
- Funds on the sender RippleNet ledger transfer to a hold account.
-
Payment state on the sender RippleNet instance moves to
PREPARED
and the happy path takes over.