From RippleWiki

Protocol: Payment

Ripple Payment Protocol

This page is a bit dated, but is still here for the descriptions of how the connection and payment processes work. The actual message fields are more accurately given on the work page.

Payment Work Page

Subprotocol name: ripple-payment.

Payments

To allow payments between two nodes that aren't neighbours, Ripple propagates value account-by-account along one or more paths of accounts in the network connecting payer and recipient.

The basic payment process consists of:

  1. Initializing payment between the payer and recipient nodes
  2. Preparing the paths to commit the transaction
  3. Committing the transaction

Requesting Payment

A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a payment-request message to that node containing:

{
  "payment-request": {
    "payment-id": (string),
    "amount": (decimal),
    "unit": (URI),
    "recipient-node-id": (Ripple ID),
    "note": (string)
  }
}

The payment-request may be followed by an payment-init message from the potential payer, or ignored.

The payment-request message may be authorized by signing it with a certain key, contained in the node owner's smart card, for example, for point-of-sale scenarios where the buyer is unable to communicate directly with his or her node. (Ideally, the smart card would display the payment amount and units to the buyer for approval, otherwise he or she must trust that the seller's terminal displays the same amount as it is asking the smart card to authorize in the payment-request message.)

Initializing Payment

The payer node contacts recipient node and communicates the following in a payment-init message:

{
  "payment-init": {
    "payment-id": (string),
    "amount": (decimal),
    "units": (URI),
    "note": (string)
  }
}

When generating payment-ids, nodes should make every effort to ensure they are globally unique in the Ripple network, although this is not strictly necessary for the system to function. Since the payment-id field may be an arbitrary string, this shouldn't be too difficult by following a convention such as appending the precise date & time (UTC) to each ID.

The recipient may accept the payment-init with an affirmative reply containing a payment-accept message with the following data:

{
  "payment-accept": {
    "payment-id": (string),
    "amount": (decimal),
    "units": (URI),
    "note": (string),
    "recipient-receipt-key": (public key data structure),
    "recipient-certificate": (certificate data structure)
  }
}

This must be signed by the recipient's identifying certificate key, whose certificate identifies the recipient in a way acceptable to the payer, such as being issued (i.e., signed) by an authority recognized by the payer. This message serves as evidence that the recipient participated in the transaction. Thus the signature of the recipient's receipt key on the payment receipts can be irrevocably connected the recipient, proving that the payment was indeed received. The explanatory text can contain text linking the payment to a real-world exchange of goods or services, such as "Payment for auction item #12345".

The recipient may reject the payment-init with an error code.

Making Promises (Commit-Request)

To prepare the payment paths, the payer sends a promise message to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of credit indicated on the receipt, if presented before the stated deadline.

{
  "promise": {
    "payment-id": (string),
    "path-id": [(ordered list of strings)],
    "path-amount": (decimal),
    "account-id": (string),
    "amount": (decimal),
    "onion": (routing onion data structure),
    "ttl": (date/time string),
    "penalty-deadline": (date/time string),
    "penalty-rate": (decimal),
    "deadline": (date/time string),
    "payer-receipt-key": (public key data structure),
    "recipient-receipt-key": (public key data structure),
    "timestamp": (date/time string)
  }
}

Since a promise must be fulfilled if a valid receipt is presented, it must effectively hold the required amount on the designated account in such a way that no other transaction may invalidate the payment.

Each node that receives a promise message updates its fields and passes it on to the next node in the path, as determined by data gleaned from the routing onion and/or by extension fields that inform a routing system defined in a protocol extension. At each step, the promise message is signed to the next node by the passing node's authentication key. This serves to establish the integrity and non-repudiability of the promise.

The path-id is defined as an ordered list of strings to accommodate routing systems that may use such lists to permit paths to fork into multiple directions while still allowing previous intermediaries in the path to recognize these subpaths and prevent loops from forming. Therefore, a path with ID [ A, B ] must be recognized as a forked continuation of the path the same payment-id and path-id [ A ]. For the purposes of promise and receipt routing, these are the same path.

The path-amount is invented by the payer and given in arbitrary units (path units) particular to each path. This figure gives each intermediary a reference against which to know the value of the receipt message that commits the transaction, which will contain a path-amount less than or equal to the promise path-amount.

The ttl (time-to-live) field allows the payer to specify a deadline for the promise to reach the recipient. If it should fail to reach the recipient by that time, the latest receiver of the promise should release the sender from its promise, and so on back to the payer (see Releasing Promises below). This field allows the payer to reasonably limit the amount of time it wishes to wait to see whether the path is viable.

The penalty-deadline is the time after which the promising node may begin charging a penalty to its partner for having to hold credit it could be using for payment. The penalty is charged continuously at the daily rate specified. Intermediaries should always set a shorter deadline and higher penalty rate on promises out than they have received on promises in, to ensure that they are compensated for overdue receipts. This provides incentive for the recipient to ensure quick completion or cancellation of each promise path, without requiring hard-and-fast deadlines to come into play so soon that minor delays relaying the receipt back along the path spawn major disputes.

Finalizing the Payment

As the recipient receives each promise, it reports it back to the payer with a promise-received:

{
  "promise-received": {
    "payment-id": (string),
    "path-id": [(ordered list of strings)],
    "deadline": (date/time string),
    "amount": (decimal)
  }
}

The recipient's receipt deadline to the payer should be well before the penalty deadline on the promise the recipient received.

The recipient can cancel the transaction at any time by sending the payer a payment-cancel and releasing its neighbours from their promises with a promise-release (see Releasing Promises). The payer can cancel the transaction by sending the recipient a payment-cancel, informing it that it can release its neighbours from their promises. Released promises should be propagated back down each payment path to free up those funds for other payments.

When the payer receives a satisfactory set of promise-received messages totaling the payment amount or greater, it generates one receipt message per promise-receiveds, authenticates it individually with the corresponding payer-receipt-key, and sends it to the recipient before the deadline for doing so:

{
  "receipt": {
    "payment-id": (string),
    "path-id": [(ordered list of strings)],
    "path-amount": (decimal)
  }
}

The collection of receipts signed by the payer represents the value of the payment, and once they are given to the recipient, the recipient is considered to have been paid. If any of the receipts is invalid (to be rigorously defined), the amount of that receipt is not considered to have been paid until a valid receipt is issued. The recipient must reply with an error code when receiving an invalid receipt.

The recipient redeems receipts with its neighbours that have issued promises to do so. Each receipt may only partially redeem the value of a single promise, and multiple receipts may be redeemed for a single promise. The unredeemed portion of the promise must be released before the penalty deadline or the penalty must be paid.

Payment Work Page

Retrieved from http://ripple.ryanfugger.com/Protocol/Payment
Page last modified on May 18, 2007, at 05:39 PM