Payment flows¶
One-time charge¶
sequenceDiagram
participant B as Buyer
participant S as Seller middleware
participant F as Facilitator
participant X as XRPL
participant A as Seller app
B->>S: Request + Accept-Payment
S-->>B: 402 + charge challenge
B->>B: Validate terms, bind InvoiceID, sign
B->>S: One retry + Payment credential
S->>F: POST /charge (gateway bearer auth)
alt transaction blob
F->>F: Decode and validate exact transaction
F->>X: Submit and await validation
else transaction hash
F->>X: Resolve submitted transaction
F->>F: Validate exact transaction
end
F-->>S: Successful receipt
S->>A: Request + request.state.mpp_payment
A-->>S: 2xx response
S-->>B: 2xx + Payment-Receipt
The signer uses a challenge-provided invoiceId, or derives a deterministic
64-hex InvoiceID from the challenge ID. The credential source is the payer's
XRPL DID. Challenge-provided destination/source tags and memos are copied into
the transaction and verified. Access is granted only for a matching successful
validated transaction; an accepted submission is not settlement.
PaymentChannel session¶
sequenceDiagram
participant B as Buyer
participant S as Seller middleware
participant F as Facilitator
participant X as XRPL
B->>S: Request accepting xrpl/session
S-->>B: 402 + open challenge
B->>S: PaymentChannelCreate blob + signed claim
S->>F: POST /session (action=open)
F->>X: Validate/submit channel creation
F-->>S: receipt with channelId
S-->>B: 2xx + Payment-Receipt
B->>S: Later request with channel ID/high-water hints
S-->>B: 402 + higher cumulative amount
B->>S: Signed cumulative voucher
S->>F: POST /session (action=voucher)
F->>F: Atomically advance high-water mark
F-->>S: receipt with cumulative amount
S-->>B: 2xx + Payment-Receipt
The seller challenges for a cumulative channel amount. A buyer proves the new total with an XRPL PaymentChannel claim signature. The server charges only the delta from the accepted high-water mark and rejects non-advancing claims.
close is an explicit final voucher. Its receipt can record the final
channelId, cumulative, and redemption reference, but the MPP action itself
is not an XRPL channel close or refund. When the facilitator has the optional
recipient seed, it can submit the retained cumulative claim and await validated
redemption. That recipient-side PaymentChannelClaim does not set tfClose;
only the funder can initiate the on-ledger close that eventually returns unused
XRP. Without a recipient signer, the session is durably finalized while its
final voucher remains off-ledger and must be redeemed separately.
Channel creation and funding can also happen outside the MPP exchange. A
matching existing channel is imported from validated ledger state on the first
voucher/close. PaymentChannelFund is submitted directly to XRPL, and a later
voucher causes the facilitator to adopt the validated increased funding.
Error boundary¶
- Missing payment produces
402plus a fresh challenge. - Malformed, expired, mismatched, replayed, or failed evidence does not reach the protected application.
- A facilitator verification failure is returned as a payment problem, not a receipt.
- If a charge hash, pull submission, or channel-open transaction may have
reached XRPL but validation is not yet observable, the facilitator returns a
non-cacheable
503 settlement-pendingproblem withRetry-Afterand the locally derived transaction hash. The buyer must reconcile that hash and retry the same proof; it must not create a fresh payment or channel. - If the application returns an error after verification, middleware must not
attach
Payment-Receiptto that error response.