XRPL Exact Scheme

Detailed specification for the XRPL presigned payment scheme used by x402.

Overview

The XRPL Exact scheme uses presigned Payment transactions to enable trustless, atomic payments between clients and resource servers.

Payment authorization: the payer signs a standard XRPL Payment transaction
Settlement: the facilitator submits the signed transaction to XRPL
Fee payer: the payer pays the XRPL transaction fee (included in the signed tx)

Network Identifiers (CAIP-2)

x402 uses CAIP-2 network identifiers. For XRPL, the format is xrpl:{network_id}

Mainnet

xrpl:0

Testnet

xrpl:1

Devnet

xrpl:2

x402 v2 HTTP Headers

DirectionHeaderDescription
Server → ClientPAYMENT-REQUIREDPayment challenge (base64 JSON)
Client → ServerPAYMENT-SIGNATURESigned payment payload (base64 JSON)
Server → ClientPAYMENT-RESPONSESettlement result (base64 JSON)

Payment Payload Format

The PAYMENT-SIGNATURE header contains a base64-encoded JSON payload.

Example: XRP Payment

PAYMENT-SIGNATURE (decoded)
{
  "x402Version": 2,
  "accepted": {
    "scheme": "exact",
    "network": "xrpl:1",
    "asset": "XRP",
    "payTo": "rDestinationAddress...",
    "amount": "1000000",
    "maxTimeoutSeconds": 600,
    "extra": {
      "invoiceId": "INV-abc123"
    }
  },
  "payload": {
    "signedTxBlob": "1200002280000000..."
  }
}

Example: IOU Payment (e.g., RLUSD)

PAYMENT-SIGNATURE (decoded)
{
  "x402Version": 2,
  "accepted": {
    "scheme": "exact",
    "network": "xrpl:1",
    "asset": "524C555344000000000000000000000000000000",
    "payTo": "rDestinationAddress...",
    "amount": "0.01",
    "maxTimeoutSeconds": 600,
    "extra": {
      "issuer": "rIssuerAddress...",
      "invoiceId": "INV-abc123"
    }
  },
  "payload": {
    "signedTxBlob": "1200002280000000..."
  }
}

For IOUs, the asset must be a 3-character code (e.g., "USD") or a 160-bit hex currency code. The issuer is required in extra.

Asset Types

AssetAmount FormatExampleExtra Fields
"XRP"Drops (string integer)"1000000" = 1 XRPNone
"USD" or hexDecimal string"0.01"issuer (required)

Note: 1 XRP = 1,000,000 drops. When pricing in XRP, always specify the amount in drops as a string.

Payment Requirements Fields

The PAYMENT-REQUIRED header advertises these fields in the accepts array:

FieldRequiredDescription
schemeYesAlways "exact"
networkYesCAIP-2 identifier (e.g., "xrpl:1")
assetYes"XRP" or currency code
payToYesXRPL classic address to receive payment
amountYesAmount (drops for XRP, decimal for IOU)
maxTimeoutSecondsYesMax validity window for payment
extra.invoiceIdYesUnique invoice identifier
extra.issuerIOU onlyIssuer address for IOUs
extra.destinationTagOptionalDestination tag if required

Invoice Binding (Security)

To prevent replay attacks, the signed transaction MUST commit to the invoice. The facilitator accepts two binding methods:

Method A: Memos

Include a memo where MemoData equals the invoice ID (hex-encoded UTF-8).

MemoData = HEX(UTF-8(invoiceId))

Method B: InvoiceID

Set the transaction's InvoiceID field to SHA-256 of the invoice ID.

InvoiceID = SHA256(invoiceId)

Important: Without invoice binding, a single valid payment could be replayed against multiple invoices. The facilitator rejects transactions missing valid binding.

Verification Process

The facilitator performs these checks before accepting a payment:

1

Envelope checks

x402Version = 2, scheme = "exact", network supported

2

Decode transaction

Decode signedTxBlob from hex, parse XRPL binary format

3

Transaction type

Must be a Payment transaction

4

Destination

tx.Destination must match payTo address

5

Network binding

NetworkID field must match CAIP-2 network rules

6

Amount matching

DeliverMax/Amount must match required amount

7

Expiry check

LastLedgerSequence must be present and within limits

8

Invoice binding

Memos or InvoiceID must bind to invoiceId

9

Policy checks

Fee limits, no partial payments, no cross-currency

Settlement Response

On successful settlement, the PAYMENT-RESPONSE header contains:

PAYMENT-RESPONSE (decoded)
{
  "success": true,
  "transaction": "ABC123...txhash",
  "network": "xrpl:1",
  "payer": "rPayerAddress..."
}

Common Error Codes

invalid_x402_version
unsupported_scheme
invalid_network
payment_requirements_mismatch
invalid_tx_blob
not_payment_tx
destination_mismatch
amount_mismatch
invoice_binding_missing
invoice_binding_mismatch
missing_last_ledger_sequence
settle_failed_onchain

Security Considerations

  • Invoice replay: Always enforce invoice binding to prevent cross-resource reuse
  • Network replay: Bind to intended network via CAIP-2 and NetworkID rules
  • Expiry: Require LastLedgerSequence and cap maximum horizon
  • Idempotency: Consume invoices once settlement succeeds