Sender payment flow — non-orchestration

This page is for developers of existing sender integrations that already use the API operations that pre-date Ripple orchestration payments.

Note

If you are developing a new integration, you should instead use the orchestration API operations. See Send a payment.

Also, if you want to use webhooks notifications with your integration, you must use the orchestration API operations. The Accept quote and Settle payment operations described on this page do not support webhooks. For more information about webhooks, see Webhooks.

Overview

Note

Before you read this tutorial, make sure you're familiar with the concepts presented in the Payment flow article.

Payment flow for senders

The following table describes the task flow that a sender must complete to successfully send a payment using the Accept quote and Settle payment API operations.

Payment flow step Related API operation Role Description
Authentication Authentication sender and receiver Request a bearer token for authentication and authorization for use with authorized RippleNet API operations.
Fetch Quotes Create quote collection sender The sender supplies payment parameters with a request for all available quotes from RippleNet. Any quotes matching the request return a quote_id in the response.

Quotes for payments using On-Demand Liquidity expire after 70 minutes. Be sure to allow enough time for payment settlement when you accept a quote.
Accept quote Accept quote sender The sender accepts the terms of one quote using a quote_id. Accepting the quote creates a payment and its payment_id.
Settle payment Settle payment sender The sender initiates payment settlement in RippleNet, passing in the payment_id for the payment they want to settle.
Check the status of a payment Get Payment by ID sender and receiver The sender can use this operation to check the status of a payment, for example, payments in the COMPLETED or FAILED states. The sender or receiver of the payment can request the status of the payment at any part of the payment flow, typically to check a payment's status while waiting for a counterparty to process a payment step.

API operations

For detailed information about API operations, see RippleNet Server API.

Send a payment - instructions

The combined steps in this tutorial simulate sending one 10-USD payment from the sender, North Bank, to the receiver, South Bank. The payment in this tutorial sends USD with no FX conversion. There are no FX exchange rates applied to the payment.

Mock instance auto-responder

If you are working in a test environment with a test harness, that environment has a mock RippleNet instance set up with an auto-responder that performs several functions:

  • Any payments that you accept will be automatically locked.
  • Any payments that you settle will be automatically completed.

For On-Demand Liquidity customers, Ripple provides an ODL Test Mode environment complete with live market data to test your business integration. The digital asset exchanges in this environment auto-lock quotes you accept and simulate completed payments to facilitate testing of your implementation. Reach out to your Ripple integration engineer to get ODL Test Mode set up.

Prerequisites

Before you begin, you must have the following:

  • Access to your RippleNet test instance.
  • Access to a counterparty instance; either a test harness server that Ripple provides or a counterparty's UAT instance.
  • Credentials to authenticate API authorization to your RippleNet test instance.
  • A way to make API requests and view the responses. For example, you can use a REST client like Postman, or cURL from the command line.

Authentication

To use RippleNet you need a valid access token for all operations except the Authentication operation itself. For more information, see Authentication.

Fetch quotes

The first step in executing a payment is searching RippleNet for available quotes by making a Create quote collection request.

Required information

The Create quote collection request must include the following information:

  • sending_address — RippleNet account name and address of the sender , in the format {ACCOUNT_NAME}@{RIPPLENET_ADDRESS} . For example, new_york@rn.usa.north_bank.new_york . See also, RippleNet addressing scheme .
    Tip

    Find the RIPPLENET_ADDRESS portion of the sending_address in the Ripple Payments UI.
    Select Accounts and then the account you want to use for the payment. The value you see under Owner, is the RIPPLENET_ADDRESS.

    Example:

    Ripplenet address

  • receiving_address — RippleNet address of the receiver . This is not the beneficiary 's account. It is the address of the last RippleNet member institution that processes the final leg of the payment. For example, the institution that provides the payment delivery over local rails. The field should use the following format: {ACCOUNT_NAME}@{RIPPLENET_ADDRESS} . See also, RippleNet addressing scheme .
  • amount — Amount of the payment. If you specify sender_amount for quote_type , this amount is debited from your account. If you specify RECEIVER_AMOUNT for amount_type , this amount is delivered to the beneficiary .
  • quote_type - Specifies how RippleNet calculates the quote. Valid values are SENDER_AMOUNT , RECEIVER_AMOUNT , SENDER_INSTITUTION_AMOUNT , or RECEIVER_INSTITUTION_AMOUNT .

To create a quote based on:

  • The amount the originator want to send, set to SENDER_AMOUNT .
  • The amount the sender institution will send, set to SENDER_INSTITUTION_AMOUNT .
  • The amount the receiver institution will receive, set to RECEIVER_INSTITUTION_AMOUNT .
  • The amount the beneficiary will receive, set to RECEIVER_AMOUNT .
  • currency — Currency code of the amount to be sent or received, depending on the quote_type value. If quote_type is set to SENDER_AMOUNT or SENDER_INSTITUTION_AMOUNT , this is the currency of the amount to be sent. If quote_type is set to RECEIVER_AMOUNT or RECEIVER_INSTITUTION_AMOUNT , this is the currency of the amount to be received. Use a valid ISO 4217 currency code.

Request a quote collection

To request quotes with the API operation, complete the following steps:

  1. Make a Create quote collection request to your RippleNet instance:

Create quote collection: HTTP request

Copy
Copied!
POST /v4/quote_collections/ HTTP/1.1
Host: south-bank.ripplenet.com
Content-Type: application/json
Authorization: Bearer eyJ0eXA ...

{
    "sending_address": "transactional_usd@test.north-bank.com",
    "receiving_address": "south_transactional_usd1@test.south-bank.com",
    "amount": 10.01,
    "currency": "USD",
    "quote_type": "SENDER_AMOUNT"
}

Create quote collection: cURL request

Copy
Copied!
curl -X POST \
  https://south-bank.ripplenet.com/v4/quote_collections/ \
  -H 'Authorization: Bearer eyJ0e ...' \
  -H 'Content-Type: application/json' \
  -H 'Host: south-bank.ripplenet.com' \
  -d '{
    "sending_address": "transactional_usd@test.north-bank.com",
    "receiving_address": "south_transactional_usd1@test.south-bank.com",
    "amount": 10.01,
    "currency": "USD",
    "quote_type": "SENDER_AMOUNT"
    }'
  1. If the request is successful, you should see a response similar to the following example:
Click to view the response ...
Copy
Copied!
{
    "quote_collection_id": "caf5fa87-61a6-4c27-b46d-1c9da311c4f4",
    "quotes": [
        {
            "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
            "created_at": "2019-07-29T18:55:53.781Z",
            "expires_at": "2019-07-29T19:55:53.781Z",
            "type": "SENDER_AMOUNT",
            "price_guarantee": "FIRM",
            "sender_address": "transactional_usd@test.north-bank.com",
            "receiver_address": "south_transactional_usd1@test.south-bank.com",
            "amount": "10.01",
            "currency_code": "USD",
            "currency_code_filter": null,
            "service_type": null,
            "quote_elements": [
                {
                    "quote_element_id": "419456bf-2ff1-4f54-afc2-aefb791298df",
                    "quote_element_type": "TRANSFER",
                    "quote_element_order": "1",
                    "sender_address": "transactional_usd@test.north-bank.com",
                    "receiver_address": "north_nostro_usd@test.north-bank.com",
                    "sending_amount": "10.00",
                    "receiving_amount": "10.00",
                    "sending_fee": "0.01",
                    "receiving_fee": "0.00",
                    "sending_currency_code": null,
                    "receiving_currency_code": null,
                    "fx_rate": null,
                    "transfer_currency_code": "USD"
                },
                {
                    "quote_element_id": "346b3a55-cc17-456b-b612-7e9eb0603fd1",
                    "quote_element_type": "TRANSFER",
                    "quote_element_order": "2",
                    "sender_address": "south_vostro_usd@test.south-bank.com",
                    "receiver_address": "south_transactional_usd1@test.south-bank.com",
                    "sending_amount": "10.00",
                    "receiving_amount": "10.00",
                    "sending_fee": "0.00",
                    "receiving_fee": "0.00",
                    "sending_currency_code": null,
                    "receiving_currency_code": null,
                    "fx_rate": null,
                    "transfer_currency_code": "USD"
                }
            ],
            "liquidity_warning": null,
            "payment_method": null
        }
    ]
}
  1. Review the array of quotes returned in the response to your Create quote collection operation request, and record the quote_id from the quote that you want to use for a payment.

Error handling for the Create quote collection operation

Your integration logic should handle the following potential errors. Unsuccessful responses — that is, responses returned with an HTTP status code other than 201 — could indicate any of the following issues:

  • The partner RippleNet instance at your counterparty may not have received the request.
  • The request may have timed out.
  • The request may have been malformed.
  • The requesting client does not have the correct OAuth token.
  • The requesting client does not provide an Authorization header or does not have the correct credentials.
  • A RippleNet instance didn't receive a response from its partner instance.

Accept quote

To continue processing the payment you must choose one quote from the available quotes that RippleNet returned. The Accept quote operation confirms your intent to execute a payment described in a quote.

When you accept a quote, your request initiates a notification to RippleNet. If successful, this action updates the state of the payment to accepted and creates a unique, valid payment_id. You can use the payment_id to track the payment throughout its execution flow.

To accept a quote using the API operation, complete the following steps:

  1. Prepare the request by recording the quote_id and its value from the quote you want to use for a payment.

    Payment originators typically provide required compliance information about the originator and beneficiary in this step. You can add this supporting information in the request body user_info field of the Accept quote operation.

    For more information about the format of supporting information, see the Standard RippleNet Payment Object, or the RippleNet Rulebook, or consult with Ripple's Customer Engineers.

  2. Make the Accept quote request to your RippleNet instance, adding the quote_id and its value to the JSON body:

Accept quote: HTTP request

Copy
Copied!
POST /v4/payments/accept HTTP/1.1
Host: north-bank.ripplenet.com
Content-Type: application/json
Authorization: Bearer eyJ0eX ...
{
    "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
    "user_info": [ {
        "key": "ACCEPT",
        "value": "value"
    }
        ]
}

Accept quote: cURL request

Copy
Copied!
curl -X POST \
    -H 'Authorization: Bearer eyJ0eX ...' \
    -H 'Content-Type: application/json' \
    -H "Accept: application/json"  \
    https://north-bank.ripplenet.com/v4/payments/accept \
    -d '{
        "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
        "user_info": [ {
            "key": "ACCEPT",
            "value": "value"
        }
        ]
    }
  1. If the request is successful, you should receive a 200 OK status and see a response similar to the following example. Notice that the payment state is ACCEPTED and that the payment object contains a payment_id field.
Click to view the response ...
Copy
Copied!
{
     "payment_id": "43-bba3-f52c40c91e-d8a05234-8dbbf844",
     "contract_hash": "30a58cb704ef66a2ef266687aab48320b455601941263dc9cce77e95127d84bc",
     "internal_info": {
         "connector_role": "SENDING",
         "labels": [],
         "internal_id": null
     },
     "payment_state": "ACCEPTED",
     "modified_at": "2019-07-29T18:55:56.725Z",
     "contract": {
         "sender_end_to_end_id": null,
         "created_at": "2019-07-29T18:55:56.617Z",
         "expires_at": "2019-07-29T19:55:53.781Z",
         "quote": {
             "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
             "created_at": "2019-07-29T18:55:53.781Z",
             "expires_at": "2019-07-29T19:55:53.781Z",
             "type": "SENDER_AMOUNT",
             "price_guarantee": "FIRM",
             "sender_address": "transactional_usd@test.north-bank.com",
             "receiver_address": "south_transactional_usd1@test.south-bank.com",
             "amount": "10.010000000",
             "currency_code": "USD",
             "currency_code_filter": null,
             "service_type": null,
             "quote_elements": [
                 {
                     "quote_element_id": "419456bf-2ff1-4f54-afc2-aefb791298df",
                     "quote_element_type": "TRANSFER",
                     "quote_element_order": "1",
                     "sender_address": "transactional_usd@test.north-bank.com",
                     "receiver_address": "north_nostro_usd@test.north-bank.com",
                     "sending_amount": "10.000000000",
                     "receiving_amount": "10.000000000",
                     "sending_fee": "0.010000000",
                     "receiving_fee": "0.000000000",
                     "sending_currency_code": null,
                     "receiving_currency_code": null,
                     "fx_rate": null,
                     "transfer_currency_code": "USD"
                 },
                 {
                     "quote_element_id": "346b3a55-cc17-456b-b612-7e9eb0603fd1",
                     "quote_element_type": "TRANSFER",
                     "quote_element_order": "2",
                     "sender_address": "south_vostro_usd@test.south-bank.com",
                     "receiver_address": "south_transactional_usd1@test.south-bank.com",
                     "sending_amount": "10.000000000",
                     "receiving_amount": "10.000000000",
                     "sending_fee": "0.000000000",
                     "receiving_fee": "0.000000000",
                     "sending_currency_code": null,
                     "receiving_currency_code": null,
                     "fx_rate": null,
                     "transfer_currency_code": "USD"
                 }
             ],
             "liquidity_warning": null,
             "payment_method": null
         }
     },
     "user_info": [
         {
             "node_address": "test.north-bank.com",
             "accepted": [
                 {
                     "json": [
                         {
                             "key": "accept",
                             "value": "value"
                         }
                     ],
                     "created_at": "2019-07-29T18:55:56.719Z",
                     "subState": ""
                 }
             ],
             "locked": [],
             "lock_declined": [],
             "retry_accept": [],
             "retry_settlement": [],
             "settlement": [],
             "settlement_declined": [],
             "failed": [],
             "executed": [],
             "completed": [],
             "forwarded": [],
             "returned": []
         }
     ],
     "ripplenet_info": [],
     "execution_condition": "PrefixSha256Condition{subtypes=[ED25519-SHA-256], type=PREFIX-SHA-256, fingerprint=HB5qYUfvQacxNn-eEpCsZ36WpG2-tCSvhJMegYNxXkE, cost=132360}",
     "crypto_transaction_id": null,
     "validator": "test.north-bank.com",
     "payment_type": "REGULAR",
     "returns_payment_with_id": null,
     "returned_by_payment_with_id": null,
     "execution_results": []
 }
  1. Store the JSON response. You must have the payment_id from this response to submit the originating payment instructions when you make the Settle payment request.
Note

If you are working in a test environment with a test harness, that environment has a mock RippleNet instance set up with an auto-responder. Any payments that you accept will be automatically locked by the mock instance.

Error handling for Accept quote

At this point in the payment execution, no funds have been transferred or put on hold. Accepting a quote only confirms the originating institution's intent to transfer funds.

If the accept quote request returns an HTTP error code of 412 Precondition failed, this indicates an expired quote. If network failures or other issues prevent you from accepting a quote before the quote expires, you can restart the process by requesting a new quote.

The receiving RippleNet instance generates the payment_id after it receives the Accept quote request. This means that you cannot check the status of the payment without a response from the receiving RippleNet instance. If you can't determine the status of the payment, the best workaround is typically to retry the request. If the quote was already accepted, RippleNet responds with this error message:

Copy
Copied!
{
 "error_type": "resubmitted_request",
 "message": "Payment with ID [{YOUR_PAYMENT_ID}] has already been accepted"
}

Settle payment

RippleNet coordinates transfers across several ledgers to settle each payment. The following example describes the transfers in a typical payment flow:

  1. The transfer on your RippleNet ledger. This is the originating transfer.
  2. The transfer on the beneficiary institution's RippleNet ledger. This is the intermediary transfer.
  3. The transfer on the beneficiary institution's ledger in its internal system to reflect the delivery of funds to the beneficiary 's account. This is the beneficiary transfer.
Note

RippleNet cannot update your core ledgers. The transfers in steps 1 and 3 require logic in your middleware to update balances in your institution's ledgers and your RippleNet instance's ledgers.

Your counterparty, any intermediary institutions, and the beneficiary institution (if different than the counterparty) settle your payment over RippleNet or local rails. To coordinate the transfers for settlement, make a the Settle payment operation request.

Note

Before you request to settle the payment, the receiving institution must lock the payment terms.

To submit the settle payment instructions, complete the following steps:

  1. In the Accept quote response, find the payment_id for the payment that you want to settle.
  2. Make a Settle payment request to RippleNet:

Settle payment: HTTP request

Copy
Copied!
POST /v4/payments/43-bba3-f52c40c91e-d8a05234-8dbbf844/settle HTTP/1.1
Host: south-bank.ripplenet.com
Content-Type: application/json
Authorization: Bearer eyJ0eXA ...

{}

Settle payment: cURL request

Copy
Copied!
curl -X POST \
  https://south-bank.ripplenet.com/v4/payments/43-bba3-f52c40c91e-d8a05234-8dbbf844/settle \
  -H 'Authorization: Bearer eyJ0eXA ...' \
  -H 'Content-Type: application/json' \
  -d '{}'
Tip

The Settle payment POST request must contain an empty JSON object: {}.

  1. If the request is successful, you should receive a 200 OK HTTP status and see a response similar to the following example. The payment instructions have been successfully sent. The payment begins settlement execution with the status of EXECUTING . For more information, see Payment states .
Click to view the response ...
Copy
Copied!
{
      "payment_id": "43-bba3-f52c40c91e-d8a05234-8dbbf844",
      "contract_hash": "30a58cb704ef66a2ef266687aab48320b455601941263dc9cce77e95127d84bc",
      "internal_info": null,
      "payment_state": "PREPARED",
      "modified_at": "2019-07-29T18:56:13.974Z",
      "contract": {
          "sender_end_to_end_id": null,
          "created_at": "2019-07-29T18:55:56.617Z",
          "expires_at": "2019-07-29T19:55:53.781Z",
          "quote": {
              "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
              "created_at": "2019-07-29T18:55:53.781Z",
              "expires_at": "2019-07-29T19:55:53.781Z",
              "type": "SENDER_AMOUNT",
              "price_guarantee": "FIRM",
              "sender_address": "transactional_usd@test.north-bank.com",
              "receiver_address": "south_transactional_usd1@test.south-bank.com",
              "amount": "10.010000000",
              "currency_code": "USD",
              "currency_code_filter": null,
              "service_type": null,
              "quote_elements": [
                  {
                      "quote_element_id": "419456bf-2ff1-4f54-afc2-aefb791298df",
                      "quote_element_type": "TRANSFER",
                      "quote_element_order": "1",
                      "sender_address": "transactional_usd@test.north-bank.com",
                      "receiver_address": "north_nostro_usd@test.north-bank.com",
                      "sending_amount": "10.000000000",
                      "receiving_amount": "10.000000000",
                      "sending_fee": "0.010000000",
                      "receiving_fee": "0.000000000",
                      "sending_currency_code": null,
                      "receiving_currency_code": null,
                      "fx_rate": null,
                      "transfer_currency_code": "USD"
                  },
                  {
                      "quote_element_id": "346b3a55-cc17-456b-b612-7e9eb0603fd1",
                      "quote_element_type": "TRANSFER",
                      "quote_element_order": "2",
                      "sender_address": "south_vostro_usd@test.south-bank.com",
                      "receiver_address": "south_transactional_usd1@test.south-bank.com",
                      "sending_amount": "10.000000000",
                      "receiving_amount": "10.000000000",
                      "sending_fee": "0.000000000",
                      "receiving_fee": "0.000000000",
                      "sending_currency_code": null,
                      "receiving_currency_code": null,
                      "fx_rate": null,
                      "transfer_currency_code": "USD"
                  }
              ],
              "liquidity_warning": null,
              "payment_method": null
          }
      },
      "user_info": [
          {
              "node_address": "test.north-bank.com",
              "accepted": [
                  {
                      "json": [
                          {
                              "key": "accept",
                              "value": "value"
                          }
                      ],
                      "created_at": "2019-07-29T18:55:56.719Z",
                      "subState": ""
                  }
              ],
              "locked": [],
              "lock_declined": [],
              "retry_accept": [],
              "retry_settlement": [],
              "settlement": [],
              "settlement_declined": [],
              "failed": [],
              "executed": [],
              "completed": [],
              "forwarded": [],
              "returned": []
          }
      ],
      "ripplenet_info": [],
      "execution_condition": "PrefixSha256Condition{subtypes=[ED25519-SHA-256], type=PREFIX-SHA-256, fingerprint=HB5qYUfvQacxNn-eEpCsZ36WpG2-tCSvhJMegYNxXkE, cost=132360}",
      "crypto_transaction_id": "46950817-9736-4fff-a2b7-50fb2510916e",
      "validator": "test.north-bank.com",
      "payment_type": "REGULAR",
      "returns_payment_with_id": null,
      "returned_by_payment_with_id": null,
      "execution_results": []
  }

To complete the payment, you must wait for the receiving institution to make the payout and mark the payment as Complete.

You can poll RippleNet for the payment status to verify when your payment completes. The next section describes how to check the payment status.

Note

If you are working in a test environment with a test harness, that environment has a mock RippleNet instance set up with an auto-responder. Any payments that you settle will be automatically completed by the mock instance.

Intermediary institutions, such as your counterparty, coordinate with the beneficiary institution to execute the payment.

The payment is marked complete when your counterparty acknowledges to RippleNet that the funds have been credited to the beneficiary's account in the beneficiary institution's internal systems. This process changes the payment's state from EXECUTED to COMPLETED.

The final step in the payment flow is to Check the status of a payment to determine if the payment's state is COMPLETED.

Check the status of a payment

You can fetch the details for an individual payment at any point in the payment flow. The payment state is one useful detail in a successful response.

These are the payment states for a successful payment flow:

  1. ACCEPTED - The sender , on behalf of the originator , has accepted the quote, which initiates a new payment.
  2. LOCKED - The receiver , beneficiary , and all intermediary institutions have agreed to the payment terms.
  3. PREPARED - The originator has requested to settle the payment.
  4. EXECUTED - The beneficiary RippleNet institution and all intermediary institutions have completed settlement.
  5. COMPLETED - The beneficiary has received final payout.

For more information about payment states, see Payment states.

Get payment by ID

To check the progress of the payment, use the Get Payment by ID operation. If the payment completes successfully, the payment's state will be COMPLETED.

To determine the status of a payment, complete the following steps:

  1. Use the payment_id to make a Get Payment by ID request to your RippleNet instance:

Get payment by ID: HTTP request

Copy
Copied!
GET /v4/payments/43-bba3-f52c40c91e-d8a05234-8dbbf844/ HTTP/1.1
Host: north-bank.ripplenet.com
Content-Type: application/json
Authorization: Bearer 5ld1y ...
Get payment by payment ID: cURL Request

Get payment by ID: cURL request

Copy
Copied!
curl -X GET \
  https://north-bank.ripplenet.com/v4/payments/43-bba3-f52c40c91e-d8a05234-8dbbf844/ \
  -H 'Authorization: Bearer 5ld1y ...' \
  -H 'Content-Type: application/json'
  1. If the request is successful, you should receive a 200 OK HTTP status and see a response similar to the following example. The example payment shows the status of completed .
Click to view the response ...
Copy
Copied!
  {
      "payment_id": "43-bba3-f52c40c91e-d8a05234-8dbbf844",
      "contract_hash": "30a58cb704ef66a2ef266687aab48320b455601941263dc9cce77e95127d84bc",
      "internal_info": null,
      "payment_state": "PREPARED",
      "modified_at": "2019-07-29T18:56:13.974Z",
      "contract": {
          "sender_end_to_end_id": null,
          "created_at": "2019-07-29T18:55:56.617Z",
          "expires_at": "2019-07-29T19:55:53.781Z",
          "quote": {
              "quote_id": "ef829465-62f3-4192-80c2-b04be8c84949",
              "created_at": "2019-07-29T18:55:53.781Z",
              "expires_at": "2019-07-29T19:55:53.781Z",
              "type": "SENDER_AMOUNT",
              "price_guarantee": "FIRM",
              "sender_address": "transactional_usd@test.north-bank.com",
              "receiver_address": "south_transactional_usd1@test.south-bank.com",
              "amount": "10.010000000",
              "currency_code": "USD",
              "currency_code_filter": null,
              "service_type": null,
              "quote_elements": [
                  {
                      "quote_element_id": "419456bf-2ff1-4f54-afc2-aefb791298df",
                      "quote_element_type": "TRANSFER",
                      "quote_element_order": "1",
                      "sender_address": "transactional_usd@test.north-bank.com",
                      "receiver_address": "north_nostro_usd@test.north-bank.com",
                      "sending_amount": "10.000000000",
                      "receiving_amount": "10.000000000",
                      "sending_fee": "0.010000000",
                      "receiving_fee": "0.000000000",
                      "sending_currency_code": null,
                      "receiving_currency_code": null,
                      "fx_rate": null,
                      "transfer_currency_code": "USD"
                  },
                  {
                      "quote_element_id": "346b3a55-cc17-456b-b612-7e9eb0603fd1",
                      "quote_element_type": "TRANSFER",
                      "quote_element_order": "2",
                      "sender_address": "south_vostro_usd@test.south-bank.com",
                      "receiver_address": "south_transactional_usd1@test.south-bank.com",
                      "sending_amount": "10.000000000",
                      "receiving_amount": "10.000000000",
                      "sending_fee": "0.000000000",
                      "receiving_fee": "0.000000000",
                      "sending_currency_code": null,
                      "receiving_currency_code": null,
                      "fx_rate": null,
                      "transfer_currency_code": "USD"
                  }
              ],
              "liquidity_warning": null,
              "payment_method": null
          }
      },
      "user_info": [
          {
              "node_address": "test.north-bank.com",
              "accepted": [
                  {
                      "json": [
                          {
                              "key": "accept",
                              "value": "value"
                          }
                      ],
                      "created_at": "2019-07-29T18:55:56.719Z",
                      "subState": ""
                  }
              ],
              "locked": [],
              "lock_declined": [],
              "retry_accept": [],
              "retry_settlement": [],
              "settlement": [],
              "settlement_declined": [],
              "failed": [],
              "executed": [],
              "completed": [],
              "forwarded": [],
              "returned": []
          }
      ],
      "ripplenet_info": [],
      "execution_condition": "PrefixSha256Condition{subtypes=[ED25519-SHA-256], type=PREFIX-SHA-256, fingerprint=HB5qYUfvQacxNn-eEpCsZ36WpG2-tCSvhJMegYNxXkE, cost=132360}",
      "crypto_transaction_id": "46950817-9736-4fff-a2b7-50fb2510916e",
      "validator": "test.north-bank.com",
      "payment_type": "REGULAR",
      "returns_payment_with_id": null,
      "returned_by_payment_with_id": null,
      "execution_results": []
  }

You have successfully completed the sender steps to send a payment using the RippleNet API!