Amend outbound instructions
When an exchange cannot deliver a payment due to incorrect or missing beneficiary_info details, On-Demand Liquidity allows you to amend the outbound_instructions object using the RippleNet Add payment sub state operation.
The reasons for a non-deliverable payment may be due to a missing field required by the payout outlet for KYC or compliance checks, a misspelled beneficiary's first or last name, or an address that doesn't match the address on the ID of the beneficiary picking up the payment.
The following diagram shows the flow for situations where an exchange cannot deliver a payment, and how On-Demand Liquidity handles the payment. On-Demand Liquidity provides functionality for a sender to amend the outbound_instructions for a payment.

Labels for outbound instructions
The following labels are used by On-Demand Liquidity as a RECEIVING node to inform the SENDING node that a payment cannot be delivered by a payout outlet.
Depending on the label added to the RippleNet Payment Object (RPO), you can either amend the outbound_instructions for the payment and try to complete the payment, or you can recover the funds manually from the destination exchange.
| Label | Description |
|---|---|
OUTBOUND_TRANSFER_FAILED_RECOVERABLY |
Payments with this label are in an EXECUTED payment state. When present, the SENDING node can update the outbound_instructions object with the "Add Payment Sub-State" operation, adding an AMEND sub-state to the payment. The exchange will reattempt a payout to the beneficiary. If the amended outbound_instructions result in a successful payout to the beneficiary, On-Demand Liquidity transitions the payment state to COMPLETED. |
OUTBOUND_TRANSFER_FAILED_IRRECOVERABLY |
When set, the exchange could not make the payment to the beneficiary, and transitioned the payment to a FAILED payment state. On-Demand Liquidity adds this label when the number of AMEND retries has been exhausted. In this case, the SENDING node must recover the funds manually from the destination exchange. |
Amend a payment's outbound instructions
To amend outbound instructions, configure your middleware as follows:
-
Check for payments that require corrections to the
outbound_instructionsusing the Get Payments operation. Pass in query parameters to return payments with anOUTBOUND_TRANSFER_FAILED_RECOVERABLYlabel. Make a note of any RippleNetpayment_ids that match the query.
Example:GET https://{{target.example_url_string}}/v4/payments?with_labels=OUTBOUND_TRANSFER_FAILED_RECOVERABLY
Note:
You should also check for payments that failed and the exchange has determined the issue cannot be fixed by amending the
outbound_instructions. Use the "Get Payments" operation, passing in query parameters to return payments with anOUTBOUND_TRANSFER_FAILED_IRRECOVERABLYlabel.
Here's an example of a payment with the label `OUTBOUND_TRANSFER_FAILED_RECOVERABLY` set by On-Demand Liquidity:
Get payments (HTTP request)
GET /v4/payments?with_labels=OUTBOUND_TRANSFER_FAILED_RECOVERABLY HTTP/1.1 Host: https://{{target.example_url_string}} Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Get Payments (cURL request)
curl -X GET \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' \ -H 'Content-Type: application/json' https://{{target.example_url_string}}/v4/payments?with_labels=OUTBOUND_TRANSFER_FAILED_RECOVERABLY
Response (success)
Response has been shortened to show pertinent information.{ "payment_id": "98d08b9e-4885-48e4-9e09-8f457859e142", "contract_hash": "abc65fad5e00aac237a44f22e7919046bc2ac2df3b955", "payment_state": "EXECUTED", "internal_info": { "internal_id": "6b0a4263-f9b9-48f3-910d-005b6873cb5e", "connector_role": "RECEIVING", "labels": [ { "label": "OUTBOUND_TRANSFER_FAILED_RECOVERABLY" } ] }, "modified_at": "2020-01-08T00:58:49.129Z", ...
-
Make a call to the "Add Payment Sub-State" operation. Provide the corrected
outbound_instructionsobject and add anAMENDsub-statein the request. This call updates beneficiary information for the exchange to reattempt making the payout. You can provide amemoin the request body of your API call.
Note:
You must include the complete
outbound_instructionsobject in your request body for this call.
Add payment sub-state (HTTP request)
POST /v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142/sub_state HTTP/1.1 Host: https://{{target.example_url_string}} Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 { "sub_state": "AMEND", "memo": "updates recipient given names value", "info": { "outbound_instructions": { "outlet_id": "spei", "beneficiary_info": [ { "field_name": "recipient_family_names", "field_value": "Minuarez" }, { "field_name": "recipient_given_names", "field_value": "Jorge" }, { "field_name": "clabe", "field_value": "014027000005555558" } ] } } }
Add payment sub-state (cURL request)
curl -X POST \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' \ -H 'Content-Type: application/json' \ https://{{target.example_url_string}}/v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142/sub_state -d '{ "sub_state": "AMEND", "memo": "updates recipient given names value", "info": { "outbound_instructions": { "outlet_id": "spei", "beneficiary_info": [ { "field_name": "recipient_family_names", "field_value": "Minuarez" }, { "field_name": "recipient_given_names", "field_value": "Jorge" }, { "field_name": "clabe", "field_value": "014027000005555558" } ] } } }
-
Use the
Delete payment labels
operation to delete the
OUTBOUND_TRANSFER_FAILED_RECOVERABLYlabel from the RippleNet payment you just amended. It's good practice to remove the label to ensure the amended payment won't appear in a subsequent search for payments that require amendments. On-Demand Liquidity may add this label again if there's still an issue delivering this payment, and you haven't reached the retry limit.
Format:DELETE {ripplenet_base_url}/v4/payments/{payment_id}/labels?label={label_name}
Delete payment label (HTTP request)DELETE /v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142/labels?label=OUTBOUND_TRANSFER_FAILED_RECOVERABLY HTTP/1.1 Host: https://{{target.example_url_string}} Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Delete payment label (cURL Request)
curl -X DELETE \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' \ -H 'Content-Type: application/json' \ https://{{target.example_url_string}}/v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142/labels?label=OUTBOUND_TRANSFER_FAILED_RECOVERABLY
-
If the update to the
outbound_instructionsobject in your RippleNet Payment Object results in a successful payout to the beneficiary, On-Demand Liquidity transitions the payment toCOMPLETED. Check the status of the payment by calling the Get payment by payment ID operation using thepayment_id.
Get payment by ID (HTTP request)
GET {{target.example_url_string}}/v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142 HTTP/1.1 Host: https://{{target.example_url_string}} Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Get payment by ID (cURL request)
curl -X GET \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' \ -H 'Content-Type: application/json' \ https://{{target.example_url_string}}/v4/payments/98d08b9e-4885-48e4-9e09-8f457859e142
-
If the
RippleNet Payment Object
contains
OUTBOUND_TRANSFER_FAILED_RECOVERABLYlabel, retry.
If the payout attempt is unsuccessful and you can still amend the outbound instructions, On-Demand Liquidity adds anOUTBOUND_TRANSFER_FAILED_RECOVERABLYlabel to the RippleNet payment object and the payment remains in theEXECUTEDstate. Repeat steps one through four until successful or until you have reached the retry limit.
{ "payment_id": "98d08b9e-4885-48e4-9e09-8f457859e142", "contract_hash": "abc65fad5e00aac237a44f22e7919046bc2ac2df3b955", "payment_state": "EXECUTED", "internal_info": { "internal_id": "6b0a4263-f9b9-48f3-910d-005b6873cb5e", "connector_role": "RECEIVING", "labels": [ { "label": "AMEND" }, { "label": "OUTBOUND_TRANSFER_FAILED_RECOVERABLY" } ] }, "modified_at": "2020-01-08T00:59:23.129Z", ...
-
If the
RippleNet Payment Object
contains
OUTBOUND_TRANSFER_FAILED_IRRECOVERABLYlabel, recover funds.
If the payment is not successful, you have reached the amend retry limit, and the exchange determines the payment cannot be made to the beneficiary, On-Demand Liquidity adds anOUTBOUND_TRANSFER_FAILED_IRRECOVERABLYlabel to the payment object, and transitions the payment state toFAILED. Manually recover the funds from the destination exchange, in this case.
{ "payment_id": "98d08b9e-4885-48e4-9e09-8f457859e142", "contract_hash": "abc65fad5e00aac237a44f22e7919046bc2ac2df3b955", "payment_state": "FAILED", "internal_info": { "internal_id": "6b0a4263-f9b9-48f3-910d-005b6873cb5e", "connector_role": "RECEIVING", "labels": [ { "label": "OUTBOUND_TRANSFER_FAILED_IRRECOVERABLY" }, { "label": "AMEND" } ] }, "modified_at": "2020-01-08T00:59:23.129Z", ...
-
If the
RippleNet Payment Object
contains