mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-13 00:05:49 +00:00
Merge pull request #257 from mDuo13/partial-payments
Add Partial Payments stand-alone page
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
283
concept-partial-payments.html
Normal file
283
concept-partial-payments.html
Normal file
@@ -0,0 +1,283 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>Partial Payments - Ripple Developer Portal</title>
|
||||
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="assets/vendor/jquery-1.11.1.min.js"></script>
|
||||
|
||||
<!-- Custom Stylesheets. ripple.css includes bootstrap, font stuff -->
|
||||
<link href="assets/css/ripple.css" rel="stylesheet" />
|
||||
<link href="assets/css/devportal.css" rel="stylesheet" />
|
||||
|
||||
<!-- Bootstrap JS -->
|
||||
<script src="assets/vendor/bootstrap.min.js"></script>
|
||||
|
||||
|
||||
<!-- syntax highlighting -->
|
||||
<link rel="stylesheet" href="assets/vendor/docco.min.css" />
|
||||
<script src="assets/vendor/highlight.min.js"></script>
|
||||
|
||||
<!-- syntax selection js -->
|
||||
<script src="assets/js/multicodetab.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$(".multicode").minitabs();
|
||||
hljs.initHighlighting();
|
||||
make_code_expandable();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="assets/js/expandcode.js"></script>
|
||||
<script src="assets/js/fixsidebarscroll.js"></script>
|
||||
|
||||
<!-- fontawesome icons -->
|
||||
<link rel="stylesheet" href="assets/vendor/fontawesome/css/font-awesome.min.css" />
|
||||
|
||||
</head>
|
||||
|
||||
<body class="page page-template page-template-template-dev-portal page-template-template-dev-portal-php sidebar-primary wpb-js-composer js-comp-ver-3.6.2 vc_responsive">
|
||||
<header role="banner" class="banner navbar navbar-default navbar-fixed-top initial_header">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a href="index.html" class="navbar-brand"><img src="assets/img/ripple-logo-color.png" class="logo"></a>
|
||||
</div><!-- /.navbar-header -->
|
||||
<div class="nav">
|
||||
<div class="draft-warning">DRAFT PAGE</div>
|
||||
</div><!-- /.nav -->
|
||||
|
||||
</div><!-- /.container -->
|
||||
|
||||
<div class="subnav dev_nav">
|
||||
<div class="container">
|
||||
<ul id="menu-dev-menu" class="menu">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">References <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="reference-rippleapi.html">RippleAPI</a></li>
|
||||
<li><a href="reference-rippled.html">rippled</a></li>
|
||||
<li><a href="reference-transaction-format.html">Transaction Format</a></li>
|
||||
<li><a href="reference-ledger-format.html">Ledger Format</a></li>
|
||||
<li><a href="reference-data-api.html">Ripple Data API v2</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorials <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="tutorial-multisign.html">How to Multi-Sign</a></li>
|
||||
<li><a href="tutorial-paychan.html">Payment Channels Tutorial</a></li>
|
||||
<li><a href="concept-issuing-and-operational-addresses.html">Issuing and Operational Addresses</a></li>
|
||||
<li><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
|
||||
<li><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
|
||||
<li><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
|
||||
<li><a href="tutorial-gateway-guide.html">Gateway Guide</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">RCL Features <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="concept-accounts.html">Accounts</a></li>
|
||||
<li><a href="concept-amendments.html">Amendments</a></li>
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
<li><a href="concept-transaction-cost.html">Transaction Cost</a></li>
|
||||
<li><a href="concept-transfer-fees.html">Transfer Fees</a></li>
|
||||
<li><a href="concept-noripple.html">Understanding the NoRipple flag</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Gateway Bulletins <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="gb-2015-06.html">GB-2015-06: Corrections to Autobridging</a></li>
|
||||
<li><a href="gb-2015-05.html">GB-2015-05: Historical Ledger Query Migration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Tools <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="ripple-api-tool.html">WebSocket API Tool</a></li>
|
||||
<li><a href="data-api-v2-tool.html">Data API v2 Tool</a></li>
|
||||
<li><a href="tool-jsonrpc.html">rippled JSON-RPC Tool</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><a href="https://github.com/ripple/ripple-dev-portal" title="GitHub">Site Source</a></li>
|
||||
</ul><!-- /#dev-menu -->
|
||||
</div><!-- /.subnav .container -->
|
||||
</div><!-- /.subnav -->
|
||||
</header>
|
||||
|
||||
|
||||
<div class="wrap container" role="document">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<div class="dev_nav_wrapper">
|
||||
<div id="cont">
|
||||
<h5>In this category:</h5>
|
||||
<ul class="dev_nav_sidebar">
|
||||
<li class="level-1"><a href="index.html">Category: RCL Features</a></li>
|
||||
<li class="level-2"><a href="concept-accounts.html">Accounts</a></li>
|
||||
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
<li class="level-2"><a href="concept-transaction-cost.html">Transaction Cost</a></li>
|
||||
<li class="level-2"><a href="concept-transfer-fees.html">Transfer Fees</a></li>
|
||||
<li class="level-2"><a href="concept-noripple.html">Understanding the NoRipple flag</a></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h5>In this page:</h5>
|
||||
<ul class="dev_nav_sidebar" id="dactyl_toc_sidebar">
|
||||
<li class="level-1"><a href="#partial-payments">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="#semantics">Semantics</a></li>
|
||||
<li class="level-3"><a href="#without-partial-payments">Without Partial Payments</a></li>
|
||||
<li class="level-3"><a href="#with-partial-payments">With Partial Payments</a></li>
|
||||
<li class="level-3"><a href="#partial-payment-limitations">Partial Payment Limitations</a></li>
|
||||
<li class="level-3"><a href="#the-delivered-amount-field">The delivered_amount Field</a></li>
|
||||
<li class="level-2"><a href="#partial-payments-exploit">Partial Payments Exploit</a></li>
|
||||
<li class="level-3"><a href="#avoiding-the-exploit">Avoiding the Exploit</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<main class="main" role="main">
|
||||
<div class='content'>
|
||||
<h1 id="partial-payments">Partial Payments</h1>
|
||||
<p>In the default case, the <code>Amount</code> field of a <a href="reference-transaction-format.html#payment">Payment transaction</a> in the Ripple Consensus Ledger specifies the exact amount to deliver, after charging for exchange rates and <a href="concept-transfer-fees.html">transfer fees</a>. The "Partial Payment" flag (<a href="reference-transaction-format.html#payment-flags"><strong>tfPartialPayment</strong></a>) allows a payment to succeed by reducing the amount received instead of increasing the amount sent. Partial payments are useful for <a href="tutorial-gateway-guide.html#bouncing-payments">returning payments</a> without incurring additional costs to oneself.</p>
|
||||
<p>The amount of XRP used for the <a href="concept-transaction-cost.html">transaction cost</a> is always deducted from the sender’s account, regardless of the type of transaction.</p>
|
||||
<p>Partial payments can be used to exploit naive integrations with the Ripple Consensus Ledger to steal money from exchanges and gateways. The <a href="#partial-payments-exploit">Partial Payments Exploit</a> section of this document describes how this exploit works and how you can avoid it.</p>
|
||||
<h2 id="semantics">Semantics</h2>
|
||||
<h3 id="without-partial-payments">Without Partial Payments</h3>
|
||||
<p>When sending a Payment that does not use the Partial Payment flag, the <code>Amount</code> field of the transaction specifies the exact amount to deliver, and the <code>SendMax</code> field specifies the maximum amount and currency to send. If a payment cannot deliver the full <code>Amount</code> without exceeding the <code>SendMax</code> parameter, or the full amount cannot be delivered for any other reason, the transaction fails. If the <code>SendMax</code> field is omitted from the transaction instructions, it is considered to be equal to the <code>Amount</code>. In this case, the payment can only succeed if the total amount of fees is 0.</p>
|
||||
<p>In other words:</p>
|
||||
<pre><code>Amount + (fees) = (sent amount) ≤ SendMax
|
||||
</code></pre>
|
||||
<p>In this formula, "fees" refers to <a href="concept-transfer-fees.html">transfer fees</a> and currency exchange rates. The "sent amount" and the delivered amount (<code>Amount</code>) may be denominated in different currencies and converted by consuming Offers in the Ripple Consensus Ledger's decentralized exchange.</p>
|
||||
<p class="devportal-callout note"><strong>Note:</strong> The <code>Fee</code> field of the transaction refers to the XRP <a href="concept-transaction-cost.html">transaction cost</a>, which is destroyed to relay the transaction to the network. The exact transaction cost specified is always debited from the sender and is completely separate from the fee calculations for any type of payment.</p>
|
||||
<h3 id="with-partial-payments">With Partial Payments</h3>
|
||||
<p>When sending a Payment that has the Partial Payment flag enabled, the <code>Amount</code> field of the transaction specifies a maximum amount to deliver. Partial payments can succeed at sending <em>some</em> of the intended value despite limitations including fees, lack of liquidity, insufficient space in the receiving account's trust lines, or other reasons.</p>
|
||||
<p>The optional <code>DeliverMin</code> field specifies a minimum amount to deliver. The <code>SendMax</code> field functions the same as with non-partial payments. The partial payment transaction is successful if it delivers any amount equal or greater than the <code>DeliverMin</code> field without exceeding the <code>SendMax</code> amount. If the <code>DeliverMin</code> field is not specified, a partial payment can succeed by delivering any positive amount.</p>
|
||||
<p>In other words:</p>
|
||||
<pre><code>Amount ≥ (Delivered Amount) = SendMax - (Fees) ≥ DeliverMin > 0
|
||||
</code></pre>
|
||||
<h3 id="partial-payment-limitations">Partial Payment Limitations</h3>
|
||||
<p>Partial Payments have the following limitations:</p>
|
||||
<ul>
|
||||
<li>A partial payment cannot provide the XRP to fund an address; this case returns the <a href="reference-transaction-format.html#transaction-results">result code</a> <code>telNO_DST_PARTIAL</code>.</li>
|
||||
<li>Direct XRP-to-XRP payments cannot be partial payments; this case returns the <a href="reference-transaction-format.html#transaction-results">result code</a> <code>temBAD_SEND_XRP_PARTIAL</code>.<ul>
|
||||
<li>However, issuance-to-XRP payments or XRP-to-issuance payments <em>can</em> be partial payments.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 id="the-delivered-amount-field">The <code>delivered_amount</code> Field</h3>
|
||||
<p>To help understand how much a partial payment actually delivered, the metadata of a successful Payment transaction includes a <code>delivered_amount</code> field. This field describes the amount actually delivered, in the <a href="reference-rippled.html#specifying-currency-amounts">same format</a> as the <code>Amount</code> field.</p>
|
||||
<p>For non-partial payments, the <code>delivered_amount</code> field of the transaction metadata is equal to the <code>Amount</code> field of the transaction. When a payment delivers an issued currency, the <code>delivered_amount</code> may be slightly different than the <code>Amount</code> field due to rounding.</p>
|
||||
<p>The delivered amount is <strong>not available</strong> for transactions that meet <strong>both</strong> of the following criteria:</p>
|
||||
<ul>
|
||||
<li>Is a partial payment</li>
|
||||
<li>Is included in a validated ledger before 2014-01-20</li>
|
||||
</ul>
|
||||
<p>If both conditions are true, then <code>delivered_amount</code> contains the string value <code>unavailable</code> instead of an actual amount. If this happens, you can only determine the actual delivered amount by reading the AffectedNodes in the transaction's metadata. If the transaction delivered an issued currency and the <code>issuer</code> of the <code>Amount</code> is the same account as the <code>Destination</code> address, the delivered amount may be divided among multiple <code>AffectedNodes</code> members representing trust lines to different counterparties.</p>
|
||||
<h2 id="partial-payments-exploit">Partial Payments Exploit</h2>
|
||||
<p>If a financial institution's integration with the Ripple Consensus Ledger assumes that the <code>Amount</code> field of a Payment is always the full amount delivered, malicious actors may be able to exploit that assumption to steal money from the institution. This exploit can be used against gateways, exchanges, or merchants as long as those institutions' software does not process partial payments correctly.</p>
|
||||
<p>To exploit a vulnerable financial institution, a malicious actor does something like this:</p>
|
||||
<ol>
|
||||
<li>The malicious actor sends a Payment transaction to the institution. This transaction has a large <code>Amount</code> field and has the <strong>tfPartialPayment</strong> flag enabled.</li>
|
||||
<li>The partial payment succeeds (result code <code>tesSUCCESS</code>) but actually delivers a very small amount of the currency specified.</li>
|
||||
<li>The vulnerable institution reads the transaction's <code>Amount</code> field without looking at the <code>Flags</code> field or <code>delivered_amount</code> metadata field.</li>
|
||||
<li>The vulnerable institution credits the malicious actor in an external system, such as the institution's own ledger, for the full <code>Amount</code>, despite only receiving a much smaller <code>delivered_amount</code> in the Ripple Consensus Ledger.</li>
|
||||
<li>The malicious actor withdraws as much of the balance as possible to another system before the vulnerable institution notices the discrepancy.<ul>
|
||||
<li>Malicious actors usually prefer to convert the balance to another crypto-currency such as Bitcoin, because blockchain transactions are usually irreversible. With a withdrawal to a fiat currency system, the financial institution may be able to reverse or cancel the transaction several days after it initially executes.</li>
|
||||
<li>In the case of an exchange, the malicious actor can also withdraw an XRP balance directly back into the Ripple Consensus Ledger.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
<p>In the case of a merchant, the order of operations is slightly different, but the concept is the same:</p>
|
||||
<ol>
|
||||
<li>The malicious actor requests to buy a large amount of goods or services.</li>
|
||||
<li>The vulnerable merchant invoices the malicious actor for the price of those goods and services.</li>
|
||||
<li>The malicious actor sends a Payment transaction to the merchant. This transaction has a large <code>Amount</code> field and has the <strong>tfPartialPayment</strong> flag enabled.</li>
|
||||
<li>The partial payment succeeds (result code <code>tesSUCCESS</code>) but delivers only a very small amount of the currency specified.</li>
|
||||
<li>The vulnerable merchant reads the transaction's <code>Amount</code> field without looking at the <code>Flags</code> field or <code>delivered_amount</code> metadata field.</li>
|
||||
<li>The vulnerable merchant treats the invoice as paid and provides the goods or services to the malicious actor, despite only receiving a much smaller <code>delivered_amount</code> in the Ripple Consensus Ledger.</li>
|
||||
<li>The malicious actor uses, resells, or absconds with the goods and services before the merchant notices the discrepancy.</li>
|
||||
</ol>
|
||||
<h3 id="avoiding-the-exploit">Avoiding the Exploit</h3>
|
||||
<p>The simplest and most effective way to avoid partial payment exploits is to use the <code>delivered_amount</code> field of the transaction metadata, not the <code>Amount</code> field, when processing incoming transactions. This way, an institution is never mistaken about how much it <em>actually</em> received.</p>
|
||||
<p>Additional proactive business practices can also avoid or mitigate the likelihood of this and similar exploits. For example:</p>
|
||||
<ul>
|
||||
<li>Add additional sanity checks to your business logic for processing withdrawals. Never process a withdrawal if the total balance you hold in the Ripple Consensus Ledger does not match your expected assets and obligations.</li>
|
||||
<li>Follow "Know Your Customer" guidelines and strictly verify your customers' identities. You may be able to recognize and block malicious users in advance, or pursue legal action against a malicious actor who exploits your system.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="content-info" role="contentinfo">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<section class="col-sm-3 widget nav_menu-3 widget_nav_menu">
|
||||
<h4>Resources<hr></h4>
|
||||
<ul id="menu-resources" class="menu">
|
||||
<li class="menu-insights"><a href="https://ripple.com/insights/">Insights</a></li>
|
||||
<li class="menu-events"><a href="https://ripple.com/events/">Events</a></li>
|
||||
<li class="menu-collateral"><a href="https://ripple.com/collateral/">Collateral</a></li>
|
||||
<li class="menu-press-center"><a href="https://ripple.com/press-center/">Press Center</a></li>
|
||||
<li class="menu-media-kit"><a href="https://ripple.com/media-kit/">Media Kit</a></li>
|
||||
<li class="menu-xrp-portal"><a href="https://ripple.com/xrp-portal/">XRP Portal</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="col-sm-3 widget nav_menu-5 widget_nav_menu">
|
||||
<h4>Regulators<hr></h4>
|
||||
<ul id="menu-compliance-regulatory-relations" class="menu">
|
||||
<li class="menu-compliance"><a href="https://ripple.com/compliance/">Compliance</a></li>
|
||||
<li class="menu-policy-framework"><a href="https://ripple.com/policy-framework/">Policy Framework</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="col-sm-3 widget nav_menu-4 widget_nav_menu">
|
||||
<h4>Support<hr></h4>
|
||||
<ul id="menu-dev-footer-menu" class="menu">
|
||||
<li class="menu-contact-us"><a href="https://ripple.com/contact/">Contact Us</a></li>
|
||||
<li class="active menu-developer-center"><a href="https://ripple.com/build/">Developer Center</a></li>
|
||||
<li class="menu-knowledge-center"><a href="https://ripple.com/learn/">Knowledge Center</a></li>
|
||||
<li class="menu-ripple-forum"><a target="_blank" href="https://forum.ripple.com/">Ripple Forum</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="col-sm-3 widget nav_menu-2 widget_nav_menu">
|
||||
<h4>About<hr></h4>
|
||||
<ul id="menu-company-footer" class="menu">
|
||||
<li class="menu-our-company"><a href="https://ripple.com/company/">Our Company</a></li>
|
||||
<li class="menu-careers"><a href="https://ripple.com/company/careers/">Careers</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="col-sm-12 absolute_bottom_footer">
|
||||
<div class="col-sm-8">
|
||||
<span>© 2013 - 2016 Ripple Labs, Inc. All Rights Reserved.</span>
|
||||
<span><a href="/terms-of-use/">Terms</a></span>
|
||||
<span><a href="/privacy-policy/">Privacy</a></span>
|
||||
</div>
|
||||
</div><!-- /.absolute_bottom_footer -->
|
||||
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.container -->
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -132,6 +133,7 @@
|
||||
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
|
||||
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
90
content/concept-partial-payments.md
Normal file
90
content/concept-partial-payments.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Partial Payments
|
||||
|
||||
In the default case, the `Amount` field of a [Payment transaction][] in the Ripple Consensus Ledger specifies the exact amount to deliver, after charging for exchange rates and [transfer fees](concept-transfer-fees.html). The "Partial Payment" flag ([**tfPartialPayment**](reference-transaction-format.html#payment-flags)) allows a payment to succeed by reducing the amount received instead of increasing the amount sent. Partial payments are useful for [returning payments](tutorial-gateway-guide.html#bouncing-payments) without incurring additional costs to oneself.
|
||||
|
||||
The amount of XRP used for the [transaction cost](concept-transaction-cost.html) is always deducted from the sender’s account, regardless of the type of transaction.
|
||||
|
||||
Partial payments can be used to exploit naive integrations with the Ripple Consensus Ledger to steal money from exchanges and gateways. The [Partial Payments Exploit](#partial-payments-exploit) section of this document describes how this exploit works and how you can avoid it.
|
||||
|
||||
## Semantics
|
||||
|
||||
### Without Partial Payments
|
||||
|
||||
When sending a Payment that does not use the Partial Payment flag, the `Amount` field of the transaction specifies the exact amount to deliver, and the `SendMax` field specifies the maximum amount and currency to send. If a payment cannot deliver the full `Amount` without exceeding the `SendMax` parameter, or the full amount cannot be delivered for any other reason, the transaction fails. If the `SendMax` field is omitted from the transaction instructions, it is considered to be equal to the `Amount`. In this case, the payment can only succeed if the total amount of fees is 0.
|
||||
|
||||
In other words:
|
||||
|
||||
Amount + (fees) = (sent amount) ≤ SendMax
|
||||
|
||||
In this formula, "fees" refers to [transfer fees](concept-transfer-fees.html) and currency exchange rates. The "sent amount" and the delivered amount (`Amount`) may be denominated in different currencies and converted by consuming Offers in the Ripple Consensus Ledger's decentralized exchange.
|
||||
|
||||
**Note:** The `Fee` field of the transaction refers to the XRP [transaction cost](concept-transaction-cost.html), which is destroyed to relay the transaction to the network. The exact transaction cost specified is always debited from the sender and is completely separate from the fee calculations for any type of payment.
|
||||
|
||||
### With Partial Payments
|
||||
|
||||
When sending a Payment that has the Partial Payment flag enabled, the `Amount` field of the transaction specifies a maximum amount to deliver. Partial payments can succeed at sending _some_ of the intended value despite limitations including fees, lack of liquidity, insufficient space in the receiving account's trust lines, or other reasons.
|
||||
|
||||
The optional `DeliverMin` field specifies a minimum amount to deliver. The `SendMax` field functions the same as with non-partial payments. The partial payment transaction is successful if it delivers any amount equal or greater than the `DeliverMin` field without exceeding the `SendMax` amount. If the `DeliverMin` field is not specified, a partial payment can succeed by delivering any positive amount.
|
||||
|
||||
In other words:
|
||||
|
||||
Amount ≥ (Delivered Amount) = SendMax - (Fees) ≥ DeliverMin > 0
|
||||
|
||||
### Partial Payment Limitations
|
||||
|
||||
Partial Payments have the following limitations:
|
||||
|
||||
- A partial payment cannot provide the XRP to fund an address; this case returns the [result code][] `telNO_DST_PARTIAL`.
|
||||
- Direct XRP-to-XRP payments cannot be partial payments; this case returns the [result code][] `temBAD_SEND_XRP_PARTIAL`.
|
||||
- However, issuance-to-XRP payments or XRP-to-issuance payments _can_ be partial payments.
|
||||
|
||||
[result code]: reference-transaction-format.html#transaction-results
|
||||
|
||||
### The `delivered_amount` Field
|
||||
|
||||
To help understand how much a partial payment actually delivered, the metadata of a successful Payment transaction includes a `delivered_amount` field. This field describes the amount actually delivered, in the [same format](reference-rippled.html#specifying-currency-amounts) as the `Amount` field.
|
||||
|
||||
For non-partial payments, the `delivered_amount` field of the transaction metadata is equal to the `Amount` field of the transaction. When a payment delivers an issued currency, the `delivered_amount` may be slightly different than the `Amount` field due to rounding.
|
||||
|
||||
The delivered amount is **not available** for transactions that meet **both** of the following criteria:
|
||||
|
||||
- Is a partial payment
|
||||
- Is included in a validated ledger before 2014-01-20
|
||||
|
||||
If both conditions are true, then `delivered_amount` contains the string value `unavailable` instead of an actual amount. If this happens, you can only determine the actual delivered amount by reading the AffectedNodes in the transaction's metadata. If the transaction delivered an issued currency and the `issuer` of the `Amount` is the same account as the `Destination` address, the delivered amount may be divided among multiple `AffectedNodes` members representing trust lines to different counterparties.
|
||||
|
||||
|
||||
## Partial Payments Exploit
|
||||
|
||||
If a financial institution's integration with the Ripple Consensus Ledger assumes that the `Amount` field of a Payment is always the full amount delivered, malicious actors may be able to exploit that assumption to steal money from the institution. This exploit can be used against gateways, exchanges, or merchants as long as those institutions' software does not process partial payments correctly.
|
||||
|
||||
To exploit a vulnerable financial institution, a malicious actor does something like this:
|
||||
|
||||
1. The malicious actor sends a Payment transaction to the institution. This transaction has a large `Amount` field and has the **tfPartialPayment** flag enabled.
|
||||
2. The partial payment succeeds (result code `tesSUCCESS`) but actually delivers a very small amount of the currency specified.
|
||||
3. The vulnerable institution reads the transaction's `Amount` field without looking at the `Flags` field or `delivered_amount` metadata field.
|
||||
4. The vulnerable institution credits the malicious actor in an external system, such as the institution's own ledger, for the full `Amount`, despite only receiving a much smaller `delivered_amount` in the Ripple Consensus Ledger.
|
||||
5. The malicious actor withdraws as much of the balance as possible to another system before the vulnerable institution notices the discrepancy.
|
||||
- Malicious actors usually prefer to convert the balance to another crypto-currency such as Bitcoin, because blockchain transactions are usually irreversible. With a withdrawal to a fiat currency system, the financial institution may be able to reverse or cancel the transaction several days after it initially executes.
|
||||
- In the case of an exchange, the malicious actor can also withdraw an XRP balance directly back into the Ripple Consensus Ledger.
|
||||
|
||||
In the case of a merchant, the order of operations is slightly different, but the concept is the same:
|
||||
|
||||
1. The malicious actor requests to buy a large amount of goods or services.
|
||||
2. The vulnerable merchant invoices the malicious actor for the price of those goods and services.
|
||||
3. The malicious actor sends a Payment transaction to the merchant. This transaction has a large `Amount` field and has the **tfPartialPayment** flag enabled.
|
||||
4. The partial payment succeeds (result code `tesSUCCESS`) but delivers only a very small amount of the currency specified.
|
||||
5. The vulnerable merchant reads the transaction's `Amount` field without looking at the `Flags` field or `delivered_amount` metadata field.
|
||||
6. The vulnerable merchant treats the invoice as paid and provides the goods or services to the malicious actor, despite only receiving a much smaller `delivered_amount` in the Ripple Consensus Ledger.
|
||||
7. The malicious actor uses, resells, or absconds with the goods and services before the merchant notices the discrepancy.
|
||||
|
||||
### Avoiding the Exploit
|
||||
|
||||
The simplest and most effective way to avoid partial payment exploits is to use the `delivered_amount` field of the transaction metadata, not the `Amount` field, when processing incoming transactions. This way, an institution is never mistaken about how much it _actually_ received.
|
||||
|
||||
Additional proactive business practices can also avoid or mitigate the likelihood of this and similar exploits. For example:
|
||||
|
||||
- Add additional sanity checks to your business logic for processing withdrawals. Never process a withdrawal if the total balance you hold in the Ripple Consensus Ledger does not match your expected assets and obligations.
|
||||
- Follow "Know Your Customer" guidelines and strictly verify your customers' identities. You may be able to recognize and block malicious users in advance, or pursue legal action against a malicious actor who exploits your system.
|
||||
|
||||
{% include 'snippets/tx-type-links.md' %}
|
||||
@@ -814,21 +814,15 @@ Transactions of the Payment type support additional values in the [`Flags` field
|
||||
| tfPartialPayment | 0x00020000 | 131072 | If the specified `Amount` cannot be sent without spending more than `SendMax`, reduce the received amount instead of failing outright. See [Partial Payments](#partial-payments) for more details. |
|
||||
| tfLimitQuality | 0x00040000 | 262144 | Only take paths where all the conversions have an input:output ratio that is equal or better than the ratio of `Amount`:`SendMax`. See [Limit Quality](#limit-quality) for details. |
|
||||
|
||||
### Partial Payments ###
|
||||
### Partial Payments
|
||||
|
||||
A partial payment allows a payment to succeed by reducing the amount received, instead of increasing the `SendMax`. Partial payments are useful for [returning payments](tutorial-gateway-guide.html#bouncing-payments) without incurring additional costs to oneself.
|
||||
A partial payment allows a payment to succeed by reducing the amount received. Partial payments are useful for [returning payments](tutorial-gateway-guide.html#bouncing-payments) without incurring additional costs to oneself. However, partial payments can also be used to exploit integrations that naively assume the `Amount` field of a successful transaction always describes the exact amount delivered.
|
||||
|
||||
By default, the `Amount` field of a Payment transaction specifies the amount of currency that is *received* by the account that is the destination of the payment. Any additional amount needed for fees or currency exchange is deducted from the sending account's balances, up to the `SendMax` amount. (If `SendMax` is not specified, that is equivalent to setting the `SendMax` to the `Amount` field.) If the amount needed to make the payment exceeds the `SendMax` parameter, or the full amount cannot be delivered for any other reason, the transaction fails.
|
||||
A partial payment is any [Payment transaction][] with the **tfPartialPayment** flag enabled. A partial payment can be successful if it delivers any positive amount greater than or equal to its `DeliverMin` field (or any positive amount at all if `DeliverMin` is not specified) without sending more than the `SendMax` value.
|
||||
|
||||
The [*tfPartialPayment* flag](#payment-flags) allows you to make a "partial payment" instead. When this flag is enabled for a payment, it delivers as much as possible, up to the `Amount` value, without exceeding the `SendMax` value. Fees and currency exchange rates are calculated the same way, but the amount being sent automatically scales down until the total amount deducted from the sending account's balances is within `SendMax`. The transaction is considered successful as long as it delivers equal or more than the `DeliverMin` value; if DeliverMin is omitted, then any positive amount is considered a success. This means that partial payments can succeed at sending *some* of the intended value despite limitations including fees, lack of liquidity, insufficient space in the receiving account's trustlines, or other reasons.
|
||||
The [`delivered_amount`](#delivered-amount) field of a payment's metadata indicates the amount of currency actually received by the destination account.
|
||||
|
||||
A partial payment cannot provide the XRP to fund an address; this case returns the error code `telNO_DST_PARTIAL`. Direct XRP-to-XRP payments also cannot be partial payments `temBAD_SEND_XRP_PARTIAL`.
|
||||
|
||||
The amount of XRP used for the [transaction cost](#transaction-cost) is always deducted from the sender’s account, regardless of the *tfPartialPayment* flag.
|
||||
|
||||
#### Partial Payments Warning ####
|
||||
|
||||
When the [*tfPartialPayment* flag](#payment-flags) is enabled, the `Amount` field __*is not guaranteed to be the amount received*__. The [`delivered_amount`](#delivered-amount) field of a payment's metadata indicates the amount of currency actually received by the destination account. When receiving a payment, use `delivered_amount` instead of the `Amount` field to determine how much your account received instead.
|
||||
For more information, see the full article on [Partial Payments](concept-partial-payments.html).
|
||||
|
||||
|
||||
### Limit Quality ###
|
||||
@@ -1300,6 +1294,7 @@ The `delivered_amount` field of transaction metadata is included in all successf
|
||||
|
||||
If both conditions are true, then `delivered_amount` contains the string value `unavailable` instead of an actual amount. If this happens, you can only figure out the actual delivered amount by reading the AffectedNodes in the transaction's metadata.
|
||||
|
||||
See also: [Partial Payments](concept-partial-payments.html)
|
||||
|
||||
## Full Transaction Response List ##
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -167,6 +168,7 @@ Ripple’s distributed settlement network is built on open-source technology tha
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
@@ -1342,13 +1343,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="partial-payments">Partial Payments</h3>
|
||||
<p>A partial payment allows a payment to succeed by reducing the amount received, instead of increasing the <code>SendMax</code>. Partial payments are useful for <a href="tutorial-gateway-guide.html#bouncing-payments">returning payments</a> without incurring additional costs to oneself.</p>
|
||||
<p>By default, the <code>Amount</code> field of a Payment transaction specifies the amount of currency that is <em>received</em> by the account that is the destination of the payment. Any additional amount needed for fees or currency exchange is deducted from the sending account's balances, up to the <code>SendMax</code> amount. (If <code>SendMax</code> is not specified, that is equivalent to setting the <code>SendMax</code> to the <code>Amount</code> field.) If the amount needed to make the payment exceeds the <code>SendMax</code> parameter, or the full amount cannot be delivered for any other reason, the transaction fails.</p>
|
||||
<p>The <a href="#payment-flags"><em>tfPartialPayment</em> flag</a> allows you to make a "partial payment" instead. When this flag is enabled for a payment, it delivers as much as possible, up to the <code>Amount</code> value, without exceeding the <code>SendMax</code> value. Fees and currency exchange rates are calculated the same way, but the amount being sent automatically scales down until the total amount deducted from the sending account's balances is within <code>SendMax</code>. The transaction is considered successful as long as it delivers equal or more than the <code>DeliverMin</code> value; if DeliverMin is omitted, then any positive amount is considered a success. This means that partial payments can succeed at sending <em>some</em> of the intended value despite limitations including fees, lack of liquidity, insufficient space in the receiving account's trustlines, or other reasons.</p>
|
||||
<p>A partial payment cannot provide the XRP to fund an address; this case returns the error code <code>telNO_DST_PARTIAL</code>. Direct XRP-to-XRP payments also cannot be partial payments <code>temBAD_SEND_XRP_PARTIAL</code>.</p>
|
||||
<p>The amount of XRP used for the <a href="#transaction-cost">transaction cost</a> is always deducted from the sender’s account, regardless of the <em>tfPartialPayment</em> flag.</p>
|
||||
<h4 id="partial-payments-warning">Partial Payments Warning</h4>
|
||||
<p>When the <a href="#payment-flags"><em>tfPartialPayment</em> flag</a> is enabled, the <code>Amount</code> field <strong><em>is not guaranteed to be the amount received</em></strong>. The <a href="#delivered-amount"><code>delivered_amount</code></a> field of a payment's metadata indicates the amount of currency actually received by the destination account. When receiving a payment, use <code>delivered_amount</code> instead of the <code>Amount</code> field to determine how much your account received instead.</p>
|
||||
<p>A partial payment allows a payment to succeed by reducing the amount received. Partial payments are useful for <a href="tutorial-gateway-guide.html#bouncing-payments">returning payments</a> without incurring additional costs to oneself. However, partial payments can also be used to exploit integrations that naively assume the <code>Amount</code> field of a successful transaction always describes the exact amount delivered.</p>
|
||||
<p>A partial payment is any <a href="#payment">Payment transaction</a> with the <strong>tfPartialPayment</strong> flag enabled. A partial payment can be successful if it delivers any positive amount greater than or equal to its <code>DeliverMin</code> field (or any positive amount at all if <code>DeliverMin</code> is not specified) without sending more than the <code>SendMax</code> value.</p>
|
||||
<p>The <a href="#delivered-amount"><code>delivered_amount</code></a> field of a payment's metadata indicates the amount of currency actually received by the destination account.</p>
|
||||
<p>For more information, see the full article on <a href="concept-partial-payments.html">Partial Payments</a>.</p>
|
||||
<h3 id="limit-quality">Limit Quality</h3>
|
||||
<p>Ripple defines the "quality" of a currency exchange as the ratio of the numeric amount in to the numeric amount out. For example, if you spend $2 USD to receive £1 GBP, then the "quality" of that exchange is <code>0.5</code>.</p>
|
||||
<p>The <a href="#payment-flags"><em>tfLimitQuality</em> flag</a> allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination <code>Amount</code> divided by the <code>SendMax</code> amount (the numeric amounts only, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality.</p>
|
||||
@@ -2127,6 +2125,7 @@
|
||||
<li>Included in a validated ledger before 2014-01-20</li>
|
||||
</ul>
|
||||
<p>If both conditions are true, then <code>delivered_amount</code> contains the string value <code>unavailable</code> instead of an actual amount. If this happens, you can only figure out the actual delivered amount by reading the AffectedNodes in the transaction's metadata.</p>
|
||||
<p>See also: <a href="concept-partial-payments.html">Partial Payments</a></p>
|
||||
<h2 id="full-transaction-response-list">Full Transaction Response List</h2>
|
||||
<p><a href="https://github.com/ripple/rippled/blob/develop/src/ripple/protocol/TER.h" title="Source">[Source]<br/></a></p>
|
||||
<h3 id="tel-codes">tel Codes</h3>
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -252,6 +252,13 @@ pages:
|
||||
- local
|
||||
- ripple.com
|
||||
|
||||
- md: concept-partial-payments.md
|
||||
category: RCL Features
|
||||
html: concept-partial-payments.html
|
||||
targets:
|
||||
- local
|
||||
- ripple.com
|
||||
|
||||
- name: Paths
|
||||
category: RCL Features
|
||||
html: concept-paths.html
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
|
||||
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
|
||||
<li><a href="concept-freeze.html">Freeze</a></li>
|
||||
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
|
||||
<li><a href="concept-paths.html">Paths</a></li>
|
||||
<li><a href="concept-reserves.html">Reserves</a></li>
|
||||
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
|
||||
|
||||
Reference in New Issue
Block a user