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_instructions
using the Get Payments operation. Pass in query parameters to return payments with anOUTBOUND_TRANSFER_FAILED_RECOVERABLY
label. Make a note of any RippleNetpayment_id
s 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_IRRECOVERABLY
label.
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_instructions
object and add anAMEND
sub-state
in the request. This call updates beneficiary information for the exchange to reattempt making the payout. You can provide amemo
in the request body of your API call.
Note:
You must include the complete
outbound_instructions
object 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_RECOVERABLY
label 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_instructions
object 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_RECOVERABLY
label, retry.
If the payout attempt is unsuccessful and you can still amend the outbound instructions, On-Demand Liquidity adds anOUTBOUND_TRANSFER_FAILED_RECOVERABLY
label to the RippleNet payment object and the payment remains in theEXECUTED
state. 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_IRRECOVERABLY
label, 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_IRRECOVERABLY
label 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