|Docs
Open App ↗

XRPL Payments (Devnet) — Quick Start

Audience: Operators and developers running demos/verification Prerequisites: tflow-server / tflow-client running, Devnet environment

This document walks you through the end-to-end demo procedure on the /projects/:id/payment screen (ProjectPayment), step by step: creating a milestone → depositing → locking escrow → settlement. It also summarizes where to look when a screen is empty or stuck.


XRPL Payment Quick Start — Escrow demo on Devnet, from milestone to settlement

0. Pre-checks — Operator Checklist

ItemHow to checkHealthy state
Devnet activationcd tflow-xrpl-payment/server && node scripts/tus-ops.js balance <TFlow address>XRP > 10, TUS TrustLine exists
TUS Issuer flagQuery the Issuer address with the same commandallowTrustLineLocking: true
TFlow Wallet → Issuer TrustLineSame as aboveTUS entry shown

If inactive → run setup with tflow-xrpl-payment/server/scripts/tus-ops.js, or see the Phase 1 README.


1. Project-side Preparation

1-1. Register Buyer / Seller in ProjectShare

In the /projects/:id/share menu, add two users, each with a different actor_type:

  • User A → actor_type = 'buyer'
  • User B → actor_type = 'seller'

⚠️ If Buyer/Seller are not registered, the case is created with seller_user_id as NULL. The case itself is created, but during escrow the wallet address is empty, so lock-funds fails. You can still add milestones, but the actual payment flow is only possible after both roles are registered.

1-2. Activate each user's XRPL wallet (Devnet)

Each demonstrator, in a separate browser / incognito window:

  1. Install the Crossmark extension (crossmark.io)
  2. Create a new wallet → obtain the address (e.g., r9uEmgPLHMNZS8AHH62zm5whEVYXRn5vPJ)
  3. Activate with the Devnet faucet:
    curl -X POST https://faucet.devnet.rippletest.net/accounts \
      -H "Content-Type: application/json" \
      -d '{"destination":"<wallet address>"}'
    
    → 100 XRP deposited + account activated

1-3. Register the wallet in the host UI

Each demonstrator goes to /projects/:id/paymentVerification (Request) or Verification (Issue) tab → Connect Wallet button:

  • Approve sign-in in the Crossmark popup
  • The system automatically opens a TUS TrustLine setup popup → sign (one time)
  • "Wallet registered" toast

1-4. Issue TUS tokens to the Buyer (operator)

The operator runs a one-line command:

cd tflow-xrpl-payment/server
node scripts/tus-ops.js issue <Buyer address> 1000

→ Issues 1000 TUS to the Buyer wallet. Check the balance:

node scripts/tus-ops.js balance <Buyer address>

⚠️ Issuance must happen only after 1-3 (Buyer sets up the TrustLine) is complete. If it isn't finished, the issuance transaction is rejected with tecPATH_DRY or similar.


2. Payment Demo Flow

2-1. Create a milestone (case)

/projects/:id/paymentSettlement Dashboard tab:

  1. Click the "Add Milestone" button in the center of the empty screen
  2. Modal: enter milestone name (e.g., "Advance 30%"), amount (e.g., 100), ratio (30), date
  3. Create → first case registered, status = DRAFT

2-2. Buyer deposits (Deposit)

Verification (Issue) tab (automatic if you have Buyer permission) → "Deposit Tokens" action:

  1. Crossmark popup → sign the Payment transaction (Buyer → TFlow Escrow Agent)
  2. Server: calls the confirm-funding API → status DRAFTFUNDED
  3. Verify the transaction on devnet.xrpl.org (the TX hash is shown in the UI)

2-3. Automatic escrow lock (Lock)

The XrplEscrowJob worker runs every 30 seconds, finds FUNDED cases, and automatically runs EscrowCreate:

  • Within 30 seconds, status FUNDEDESCROW_OPEN
  • The TFlow Oracle wallet locks the IOU into escrow (Crypto-Condition security)
  • Stores escrow_sequence, escrow_condition, escrow_fulfillment in the DB

To lock immediately without waiting (optional):

curl -X POST http://localhost:3000/api/payment/cases/<case-uuid>/lock-funds \
  -H "Authorization: Bearer <token>"

2-4. Seller uploads documents + Buyer approves → Release

Verification (Request) tab (Seller) → upload documents → AI verification → "Request Approval"

Verification (Issue) tab (Buyer) → "Approve" → server runs EscrowFinish:

  • status ESCROW_OPENRELEASED
  • IOU deposited to the Seller wallet (check the balance: node scripts/tus-ops.js balance <Seller address>)

2-5. (Optional) Refund demo

By default cancelAfterSeconds = 7 days, so immediate refunds are not possible. For a demo:

# tflow-server/.env
XRPL_ESCROW_CANCEL_AFTER_SECONDS=60

After restarting, create a new case → after 60 seconds click the "Refund" button → EscrowCancel → funds recovered to TFlow → Payment to the Buyer.


3. Cleanup after the demo (operator)

The TUS held by each demonstrator is a temporary Devnet token, so it can safely be discarded. But if you want to reuse the same wallet for the next demo, you can recover it to the Issuer:

node scripts/tus-ops.js return <holder-seed> <amount>

→ The holder's TUS is sent to the Issuer and automatically burned.


4. Common Sticking Points — Troubleshooting

SymptomCauseResolution
Column 'seller_user_id' cannot be null when adding a milestoneMigration not appliedApply migration 20260507-01. Or register a seller in ProjectShare
tecPATH_DRY on DepositBuyer TrustLine not set up, or TUS balance is 0Redo in the order 1-3 then 1-4
tecNO_PERMISSION or temMALFORMED on EscrowCreateIssuer flag not setCheck allowTrustLineLocking with tus-ops.js balance <Issuer>
Seller balance unchanged after EscrowFinishSeller TrustLine missingRe-enter the host UI from the Seller wallet → triggers automatic TrustLine setup
Automatic lock doesn't happen even after waiting 30 secondsXrplEscrowJob worker not runningCheck for [AutoLock] Job started in the tflow-server logs. If absent, restart the worker process
Crossmark popup doesn't appearExtension disabled, or the session is held by another tabClick the Crossmark extension again → refresh the tab
Screen shows "T FLOW Network" / "Global Traders Ltd."You entered the mock demo screen (/demo/payment)Go to the /projects/:id/payment production screen

5. Mainnet Transition is Separate

This guide is for Devnet only. Mainnet RLUSD escrow becomes possible only after Ripple enables the asfAllowTrustLineLocking flag on the RLUSD issuer account (currently inactive). For preparation items, see 260506-xrpl-스타일링/README.md Phase 4.


  • Operations script: tflow-xrpl-payment/server/scripts/tus-ops.js
  • e2e dry-run: tflow-xrpl-payment/server/scripts/dry-run.js
  • Demo screens (mock): /demo/payment, /demo/pof (hidden routes)
  • Production screen: /projects/:id/payment