Agentic Settlement Protocol: An Application Profile for Refundable, Delayed-Fulfilment Agent Commerce on Stablecoin Rails
Analyze & explore related research in Conceptio
Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.
arXiv:2609.02208v1 [cs.CR] 2 Sep 2026
Agentic Settlement Protocol: An Application Profile for Refundable, Delayed-Fulfilment Agent Commerce on Stablecoin Rails Behnam (Beny) Mohammadkhani — XDC AI — beny@xinfin.org — X: @zerobeny Atul Khekade — XDC AI — atul@xinfin.org — X: @atulkhekade Ritesh Kakkad — XDC AI — rik@xinfin.org — X: @riteshkakkad Draft v0.6 — 31 August 2026 Abstract Autonomous agents can already pay per request: HTTP-native protocols such as x402 let an agent sign a stablecoin authorization and receive a resource in the same round trip. That model is atomic, instant and final, which is what metered access needs and what commerce cannot tolerate. A purchase made on a person’s behalf — a service appointment, a physical order, a freelance deliverable, a flight, a hotel night, an invoice — is large, is frequently cancelled, and should not become the seller’s money until the seller has actually delivered. We present the Agentic Settlement Protocol (ASP), an application profile that specifies how a buyer agent, a seller, an operator and an on-chain authorize-and-capture escrow coordinate a quote, a timebounded hold, fulfilment, capture and refund for any online business whose booking, order, scheduling or invoicing system can expose, or be adapted to expose, a hold, a commit, a cancel and a refund computation. ASP treats all such systems uniformly as fulfilment engines, and defines the lifecycle once against a registry of fulfilment classes rather than per vertical. ASP does not introduce a new escrow primitive; it builds on the auth-capture escrow pattern already standardised by the Commerce Payments Protocol and adopted by x402 refund extensions. Its contributions are a three-deadline hold model — an issuance deadline, an escrow expiry and the engine’s own inventory expiry, separated by an explicit submission-inclusion-finality margin — under which no inventory is ever issued against funds the buyer can reclaim; a fulfilment-verification ladder that states explicitly which party is trusted to trigger capture, what its assertion does and does not prove, and what challenge window applies; fare-ruledriven partial refunds with a specified refund-liquidity order and per-seller exposure controls that bound the operator’s credit risk; distributor revenue share taken atomically at capture with a condition under which self-dealing is provably unprofitable; a single-currency-per-charge invariant that removes swaps, oracles and slippage from the settlement path; a fulfilment-class registry with worked mappings for order-management, service-scheduling, invoicing and travel systems that leaves the seller’s core engine unchanged and integrates through a connector; and a normative interface specification (x402 scheme, vault interface, operator and connector APIs, registries, conformance levels) intended to let independent implementations interoperate. The design originated in a review of how travel agencies could join agentic settlement layers, and travel remains the running example because it forces every part of the design to exist; nothing in the protocol is specific to it. We state the trust model candidly, including where the operator is trusted, give informal arguments for five safety properties, and describe an instantiation on the XDC Network. ASP is presented as a design and specification together with a narrow reference-implementation scope and a fault-injection evaluation plan; measured results are left to follow-up work.
1
1
Introduction
A payment standard already exists for AI agents, and it solves the wrong half of commerce. x402 revived the HTTP 402 status code so that an agent can request a resource, receive a machinereadable price, sign a stablecoin authorization and receive the response in a single exchange [Reppel et al., 2025]. The protocol has since moved to the Linux Foundation, gained multiple settlement schemes, and reports hundreds of millions of payments [Linux Foundation, 2026, x402 Foundation, 2026]. It is the right design for data, tools and inference: one-shot, instant, irreversible, and small. The moment an agent tries to buy something real, that shape breaks. A plumber’s appointment, a physical order from an online store, a design deliverable from a freelancer, a seat on a flight or a night in a hotel all share three properties that a metered API call does not. The amount is large relative to the buyer’s per-call budget. The purchase is refundable, and in many service businesses cancellation is routine rather than exceptional. And, critically, the money should not become the seller’s until the seller has delivered: the technician turned up, the parcel shipped, the file was accepted, the ticket issued. A single atomic transfer has no room to hold funds, wait for fulfilment, and then either settle or return them. The traditional answer is the card network’s authorize–capture–refund lifecycle executed by a processor. That lifecycle is the correct abstraction, but its implementation is custodial, fiat-bound and closed to any seller without a processor relationship. In 2025 Coinbase and Shopify brought the same lifecycle on-chain in the Commerce Payments Protocol (CPP), a non-custodial escrow contract with authorize, capture, charge, void, reclaim and refund operations, pluggable token collectors, and time-bounded holds that the buyer can unilaterally reclaim on expiry [Coinbase and Shopify, 2025, Shopify Engineering, 2025]. Refund extensions to x402 now wire that escrow into the 402 handshake [x402r, 2026]. The on-chain primitive therefore exists and is audited. What does not exist is a specification of how that primitive should be driven when fulfilment is decided by an off-chain system that has its own clock, its own hold semantics and its own refund rules. Every online business already runs one: an order-management system with a fulfilment deadline, a scheduling system with an appointment slot that lapses if unconfirmed, an invoicing system with a due date, a booking engine with a ticketing time limit. If the escrow hold and the business’s own hold are not coordinated, one of two failures occurs: money is held after the slot or stock has been released, or the slot is held after the money has gone back to the buyer. Neither CPP nor the x402 schemes say anything about this, because they are payment-layer specifications and the problem sits one layer up. This paper specifies that layer. The Agentic Settlement Protocol (ASP) is an application profile over an auth-capture escrow for purchases from any online business whose fulfilment system can expose, or be adapted to expose, the four operations below; that covers most businesses that sell online, but it is an interface requirement, not a universal claim. We abstract the business’s system as a fulfilment engine exposing a hold, a commit, a cancel and a refund computation, define the settlement lifecycle once against that abstraction, and instantiate it per business type through a registry of fulfilment classes. Travel is the running example throughout, for two reasons. The first is historical: this work began as a review of how travel agencies could participate in agentic AI settlement layers, and the design was worked out against their booking engines, ticketing time limits and fare rules before it became clear that nothing in it was specific to travel. The second is that travel is the hardest instance — the holds are short, refunds are rule-driven and partial, and the engines are decades old — so a design that survives it survives easier verticals. A reader should substitute their own business type at every occurrence. We make the following contributions. 2
1. A three-deadline hold model (Section 4.5) that separates the issuance deadline the connector enforces, the escrow expiry, and the engine’s inventory expiry by an explicit margin covering transaction submission, inclusion and finality, together with a proposition that no inventory is issued against funds the buyer can reclaim. The model does not assume that two independent systems cancel each other atomically. 2. An explicit fulfilment-verification ladder (Section 4.7) that names, for each class of good, which party’s assertion triggers capture, what evidence it carries, and what challenge window applies. This replaces the phrase “on fulfilment” that most agent-payment designs leave undefined. 3. A refund and exposure model (Section 4.6) in which the off-chain engine’s fare or rate rules are authoritative for the refundable amount, with a specified refund-liquidity order, a refund window, and per-seller exposure controls (rolling reserve, settlement delay, outstandingrefundable caps) that make the operator’s refund backstop a bounded credit exposure rather than an open-ended guarantee. 4. Revenue share at capture (Section 4.8), with a proposition giving the condition under which a distributor cannot profit by generating its own referred volume. 5. A single-currency invariant (Section 4.9), a fulfilment-class registry with worked mappings for order-management, service-scheduling, invoicing and travel systems (Section 6) that leaves the seller’s core engine unchanged, and a deliberately narrow reference-implementation scope with a fault-injection evaluation plan (Sections 7 and 9). 6. A normative interface specification (Section 4.11 and Appendices C–F): the x402 asp scheme, the vault’s Solidity interface with events and errors, the operator and connector APIs, the registry and webhook schemas, and conformance levels. The intent is that two independent implementations built from the appendices interoperate. We state the trust model in Section 3 without euphemism: the operator is trusted for the capture decision to the extent set by the verification rung, and the “instant reserve” settlement mode is custodial by construction. Section 5 gives informal arguments for five safety properties. Section 7 describes the instantiation on the XDC Network. Section 8 situates ASP against both industry protocols and the recent academic literature on agent payments, and Section 9 lists limitations and open questions. ASP is a design contribution; we have not yet measured a deployed vault, and we say so, but Section 9 specifies exactly what will be measured.
2
Background
2.1
Metered agent payments: x402
x402 defines an HTTP handshake in which a server answers an unpaid request with 402 Payment Required and a list of acceptable payment requirements; the client signs a payment payload and retries; a facilitator verifies the payload and submits settlement on the server’s behalf [Reppel et al., 2025]. Version 2 moved the payload into standard headers, adopted CAIP chain identifiers and made networks and facilitators pluggable [Linux Foundation, 2026]. Three schemes are specified: exact, where the buyer authorises the advertised amount; upto, where the buyer authorises a maximum and the seller charges actual usage; and batch-settlement, where the buyer deposits into an onchain escrow once, signs an off-chain voucher per request, and the seller redeems many vouchers in one transaction [x402 Foundation, 2026]. Cloudflare has separately proposed a deferred scheme that decouples the cryptographic handshake from settlement entirely [Cloudflare, 2025]. All three shipped schemes share one property: the seller’s entitlement to funds is decided by the 3
buyer’s signature and the seller’s own accounting. There is no notion of a hold that lapses if the seller fails to deliver, and exact is a push payment that cannot be reversed after execution [Linux Foundation, 2026]. Refunds, where they exist, are a separate remittance.
2.2
On-chain authorize-and-capture escrow: CPP and x402r
The Commerce Payments Protocol places a non-custodial escrow contract between payer and receiver and drives it through an operator address. Six operations are defined: authorize (funds move from payer to escrow under a time-bounded hold), capture (escrow pays the receiver, less a fee within a pre-declared range), charge (authorize and capture in one call), void (operator cancels an authorization), reclaim (payer unilaterally recovers an expired authorization) and refund (funds return to payer after capture, sourced from a refund collector that may draw on the receiver, another merchant address, or the operator) [Coinbase and Shopify, 2025, Shopify Engineering, 2025]. Token collection is modular over ERC-3009, Permit2, allowances and spend permissions [Lecoq and Fischer, 2020, Uniswap Labs, 2022, Lecoq, 2020]. Refunds must occur before a refund expiry after which the capture is final. x402r packages this escrow as a commerce scheme inside the x402 handshake, with dispute resolution pluggable per arbiter [x402r, 2026]. CPP is the primitive ASP builds on. Where this paper says “the escrow”, a CPP-compatible contract satisfies every requirement; where ASP names its own vault, it is to fix a minimal interface (Section 4.2) and the XDC deployment (Section 7), not to claim a new mechanism.
2.3
Agent authorization and checkout: AP2 and ACP
Google’s Agent Payments Protocol (AP2) standardises the consent chain: a signed intent mandate records the user’s goal and spend cap, a cart mandate records the agent’s specific selection, and a payment mandate records the charge [Parikh and Surapaneni, 2025]. Lan et al. show that AP2 implementations are exposed to replay and context-binding failures unless mandates are bound to the runtime context that produced them [Lan et al., 2026]. The Agentic Commerce Protocol (ACP) from Stripe and OpenAI standardises the checkout messages between an agent and a merchant, with a processor performing authorization, capture and refund off-chain [Stripe and OpenAI, 2025]. Neither protocol specifies on-chain settlement; both are the layers ASP expects to sit beneath.
2.4
Fulfilment lifecycles in online businesses
Almost every system that sells online already implements a hold-then-commit lifecycle, whether or not it calls it that. An order-management system (Shopify, WooCommerce, Salesforce Commerce, a custom OMS) creates an order, reserves stock, and moves to fulfilled when a shipment or pickup is confirmed; unreserved stock is released after a timeout and refunds follow a returns policy. A service-scheduling system (Calendly-style, field-service platforms, marketplaces for trades and professionals) tentatively holds a slot, confirms it, and marks the job complete; cancellation fees follow a notice-period rule. An invoicing or procurement system issues an invoice with a due date and marks it paid or disputed. A freelance or gig marketplace opens a task, accepts a deliverable, and releases payment on acceptance. In travel, a global distribution system creates a passenger name record with a ticketing time limit after which the seat is released; IATA’s NDC standard has OrderCreate with an order time limit and OrderChange for modification and refund [IATA, 2024]; hotels expose an option with an option date, then a confirmed reservation, then cancellation under rate rules.
4
The common shape is: a hold with a time limit, a commit that produces a reference the buyer can later check, a cancel that releases the hold, and a refund computation the engine owns. ASP calls any such system a fulfilment engine and requires exactly those four operations of it (Section 4). Refund amounts are computed by the engine from its own rules and are rarely a flat window, in every one of these verticals.
3
System and Trust Model
3.1
Parties
• Principal. The human or organisation on whose behalf the purchase is made. Establishes the agent’s spend cap (an AP2 intent mandate or equivalent). • Buyer agent. Software that selects the offer and signs the authorization. Holds funds in a smart-contract wallet with an on-chain spending limit (Section 7). • Seller. Owns the inventory and operates, or subscribes to, a booking or order engine. Receives capture proceeds to a payout vault. • Operator. Runs the protocol: publishes offers, relays signed authorizations to the escrow, observes fulfilment evidence, and calls capture or void. In the reference deployment the operator is XDC AI. • Distributor (optional). A party that referred the buyer agent and earns a configured share of the fee. • Escrow. An on-chain contract holding each charge’s funds between authorization and capture. • Fulfilment engine. The seller’s order-management, scheduling, invoicing, marketplace or booking system, exposed through an API the connector can drive. Authoritative for whether fulfilment occurred and for the refundable amount. • Arbiter (optional). A party or contract that can resolve a challenge during a challenge window (Section 4.7).
3.2
Assumptions
• A1 (Timing). Three delays are distinguished. 𝑇𝑠 bounds the operator’s time from deciding to capture to broadcasting the transaction (relayer, nonce management, RPC availability); 𝑇𝑖 bounds the time from broadcast to inclusion in a block (congestion, fee policy); 𝑇𝑓 bounds the time from inclusion to deterministic finality. Block timestamps drift from wall-clock time by at most 𝛿. Only 𝑇𝑓 is a property of the chain; 𝑇𝑠 and 𝑇𝑖 are operational bounds the operator chooses and is responsible for. Define the capture margin 𝑀 = 𝑇𝑠 + 𝑇𝑖 + 𝑇𝑓 + 𝛿. • A2 (Stablecoin). The settlement token is a fiat-referenced stablecoin supporting at least one gasless authorization method (ERC-3009, EIP-2612 or Permit2). Depeg risk is handled by a pause (Section 4.10), not by the protocol. • A3 (Signatures). EIP-712 typed signatures are unforgeable; the buyer agent’s key is under the principal’s spend policy [Bloemen et al., 2017]. • A4 (Operator liveness). The operator eventually submits transactions; if it does not, the buyer’s recovery path does not depend on it (Property P1). • A5 (Engine honesty). The fulfilment engine reports issuance, cancellation and refundable amounts correctly to the connector. ASP treats the engine as an oracle for its own inventory. • A6 (Operator honesty, bounded). The operator may be malicious with respect to timing (delaying capture or void) but is trusted not to fabricate fulfilment evidence at the verification 5
rung in force for the charge. Section 4.7 sets out how this trust is reduced.
3.3
What is and is not trust-minimised
Two claims in earlier descriptions of this design need qualifying. “Non-custodial” holds in the sense that funds in flight sit in a contract with deterministic rules and cannot be moved by the operator to an arbitrary address; it does not mean the operator has no discretion. The operator decides when to capture, and if it captures without fulfilment the buyer’s remedy is the refund path and the challenge window, not the escrow itself. This is the same trust position as CPP’s operator [Shopify Engineering, 2025]. Second, the instant reserve settlement mode (Section 4.10), in which the seller is paid at authorization and refunds are drawn from a rolling reserve, is custodial by construction: the reserve is operator-controlled. It is offered as a vetted-seller option, not as the default, and is labelled as such.
3.4
Threats considered
Double-charging a booking on retry; stranded funds when a hold is never captured; capture without fulfilment; refund default when a seller’s vault is empty; a compromised buyer agent draining the principal; a seller hook redirecting settlement funds; a distributor generating its own referred volume to farm revenue share; and a stablecoin depeg mid-hold. Threats not in scope: compromise of the fulfilment engine itself, chain-level censorship beyond 𝑇𝑓 , and privacy of on-chain charge metadata (Section 9).
4
Protocol
4.1
Objects
An Offer is a priced, signed quotation with a short expiry. It is the document that fixes every settlement term the safety rules depend on, so those terms are fields of the Offer rather than operator-side configuration: Offer { sellerId, description, amount, currency, fulfilmentClass, // registry entry, Section 6.1 engineRef, // handle to the provisional engine hold engineExpiry, // t_e as reported by the engine (or policy default) issueDeadline, // t_issue, Section 4.5 holdExpiresAt, // t_h, Section 4.5 verificationRung, // D | C | A | S (Section 4.7) challengeWindow, // W_c refundWindow, // W_r refundPolicyRef, // pointer to the engine's refund rules expiresAt, // offer validity signer, signerAuthority, signature // Section 4.3 } offerId = keccak256(EIP-712 encoding of Offer) Because offerId is the hash of the whole Offer, a buyer authorization that names offerId commits the buyer to all of these terms, and no party can alter 𝑡issue , 𝑡ℎ , the rung or the windows after
6
authorization without producing a different offerId that the escrow will not match. A Charge is the payment intent and its lifecycle record: Charge { chargeId, offerId, buyer, sellerVault, distributor, amount, currency, // one currency, no swap feeBps, feeAmount, distributorShareBps, status, // Section 4.2 issueDeadline, holdExpiresAt, // on-chain, copied from the Offer idempotencyKey, // = chargeId capturedAmount, refundedAmount, // refundedAmount <= capturedAmount captureEvidence, refundRecords[] } A FulfilmentAttestation is the evidence that moves a charge from authorized to captured. It is a connector-signed normalised receipt whose hash is committed on-chain: FulfilmentReceipt { chargeId, supplierId, orderId, fulfilmentRef, subjectHash, issuedAt, rung } FulfilmentAttestation { chargeId, receiptHash, issuedAt, attestor, attestorSig }
// signed off-chain by the connector // engine order / booking / job / invoice id // ticket no., tracking no., completion id... // keccak(normalised buyer/recipient data)
// passed to capture() // keccak(FulfilmentReceipt)
The receipt gives unambiguous attribution: the connector, operated by the operator, asserts that the engine reported issuance with these references. It does not prove that the supplier issued anything; Section 4.7 is explicit about that. chargeId is the EIP-712 hash of the buyer’s authorization struct, so it doubles as the idempotency key at every layer.
4.2
State machine and escrow interface
deposit capture created ------------> authorized -------------> captured <--+ refund(partial): | | | | refundedAmount +=, | expire/reject | void | expire | +-- stays captured v v | refund with cumulative cancelled reclaimed | == capturedAmount v refunded Transitions and who may trigger them: From
To
Trigger
Caller
created
authorized
deposit(auth)
operator (relays buyer sig) 7
From
To
Trigger
Caller
created authorized
cancelled captured
anyone operator
authorized authorized captured
reclaimed reclaimed captured
captured
refunded
offer expired / buyer declines capture(chargeId, attestation) void(chargeId) reclaim(chargeId) after expiry refund(chargeId, amount), cumulative < captured refund(chargeId, amount), cumulative = captured
operator buyer, or anyone on behalf operator, within refund window operator, within refund window
The escrow interface ASP requires is a strict subset of CPP: deposit (CPP authorize), capture, void, reclaim and refund. Every call is keyed by chargeId and is idempotent: a repeated deposit with the same key is a no-op, a repeated capture returns the existing settlement, and refund accumulates refundedAmount, which cannot exceed capturedAmount; the charge remains captured while further refund is possible and becomes refunded only when the two are equal. On-chain, deposit also records issueDeadline from the authorization, and capture reverts if the attestation’s issuedAt exceeds it, so rule H3 (Section 4.5) is enforced by the vault rather than by operator discipline. Terminology note. An earlier draft used release for the return of funds to the buyer. Because release conventionally means paying the seller, this draft uses void (operator-initiated) and reclaim (buyer-initiated after expiry) throughout.
4.3
Who signs the Offer
An Offer binds the seller commercially, so its signer matters. Three models are defined, recorded in the Offer’s signerAuthority field: • Direct. The seller’s own key signs each Offer. Appropriate for direct integrations with low quote volume. • Delegated. The seller registers a connector key with a scope (fulfilment classes, maximum amount, validity period) in the operator’s seller registry, and the connector signs Offers under that key. The seller can revoke the delegation at any time; Offers signed after revocation are invalid. This is the model for platform connectors, where thousands of sellers on one commerce or scheduling platform cannot sign machine-generated quotes individually. • Operator-signed under mandate. The seller signs a standing mandate authorising the operator to issue Offers within stated limits; the operator signs Offers and includes the mandate reference. Functionally similar to delegated, but the key is the operator’s and the trust boundary is correspondingly wider. In the delegated and mandate models the party holding the signing key can bind the seller to prices and terms within scope. That is a real trust grant, and the scope limits are what bound it; the registry makes the grant and its limits inspectable. ASP-Lite uses the delegated model.
4.4
Message flow
The sequencing question every implementation must answer is when the engine’s hold is created, because 𝑡𝑒 has to be known before 𝑡ℎ and 𝑡issue can be derived, and those have to be in the Offer 8
before the buyer signs. ASP therefore places the engine hold before the Offer: 1. Provisional hold and quote. The buyer agent requests a price. The connector asks the fulfilment engine for a provisional hold (reserve stock, tentatively hold the slot, create an unticketed PNR); the engine returns engineRef and its expiry 𝑡𝑒 . The connector derives 𝑡issue and 𝑡ℎ from 𝑡𝑒 under rule H1 and the operator, or the delegated signer, issues the signed Offer with a short expiresAt. Price and every timing term are locked before the buyer commits. 2. Authorize. The buyer agent signs an EIP-712 ChargeAuthorization over (offerId, buyer, token, amount, issueDeadline, holdExpiresAt, nonce) (Appendix A) using the token’s gasless method. The operator relays it; the escrow verifies that the authorization’s timing fields match the Offer’s (it recomputes offerId from the terms the operator supplies alongside), pulls funds, and records issueDeadline and holdExpiresAt. The charge is authorized; the buyer has paid nothing yet. 3. Decline or lapse. If the buyer does not authorize before expiresAt, or the deposit fails, the connector releases the provisional engine hold. Provisional holds are therefore short-lived and their cost is bounded by expiresAt. 4. Commit. Before 𝑡issue , the connector instructs the engine to commit against engineRef (ship the order, confirm the appointment, accept the deliverable, issue the ticket). The engine returns its record; the connector produces a FulfilmentAttestation. 5. Capture. The operator calls capture with the attestation. The escrow checks issuedAt ≤ issueDeadline, pays feeAmount to the fee splitter (Section 4.8) and amount - feeAmount to the seller’s vault, in the same token. The charge is captured. 6. Void or reclaim. If the engine cannot commit, the operator calls void. If the operator does neither by holdExpiresAt, the buyer (or any relayer) calls reclaim. Either way the full amount returns to the buyer. 7. Refund. After capture, a cancellation or return is submitted to the engine; the engine computes the refundable amount under its own rules; the operator calls refund for exactly that amount, sourced per Section 4.6. Engines that cannot hold before payment. Some systems only create a reservation once a payment is authorized. For a fulfilment class flagged holdBeforeAuth = false in the registry, the connector uses a conservative policy expiry 𝑡∗𝑒 recorded in the registry for that class (for example, the platform’s documented minimum reservation lifetime) in place of the engine’s reported value at step 1, and creates the engine hold immediately after step 2. When the engine then returns its actual 𝑡𝑒 , the connector checks H1 against it. If 𝑡𝑒 ≥ 𝑡ℎ + 𝛿 the charge proceeds; if not, the connector calls void at once, the funds return to the buyer, and the offer is re-quoted with the now-known 𝑡𝑒 . A charge is never allowed to continue under a violated H1. The cost of this path is one wasted deposit-void round trip on the rare shortfall, which the evaluation plan measures.
4.5
Hold coordination
The escrow and the fulfilment engine are two independent distributed systems with independent clocks. No rule can make them expire atomically, so ASP does not try. Instead it introduces a third deadline, enforced by the connector, that sits strictly before both. Let 𝑡𝑒 be the engine’s hold time limit (stock reservation timeout, slot hold expiry, invoice due date, ticketing time limit) in wall-clock time; 𝑡ℎ the escrow’s holdExpiresAt in chain time; and 𝑡issue the issuance deadline, the latest time at which the connector will instruct the engine to issue against
9
this charge. Rule H1 (ordering). 𝑡issue + 𝑀 < 𝑡ℎ ≤ 𝑡𝑒 − 𝛿, with 𝑀 = 𝑇𝑠 + 𝑇𝑖 + 𝑇𝑓 + 𝛿 from A1. Rule H2 (issuance gate). The connector instructs issuance only if the current time is before 𝑡issue and the charge is authorized. After 𝑡issue the connector refuses to issue even if the engine’s reservation is still alive. Rule H3 (capture gate). capture succeeds only for an attestation with issuedAt ≤ 𝑡issue ; the vault enforces this against the issueDeadline recorded at deposit. The operator submits within 𝑇𝑠 of receiving the attestation. Rule H4 (cleanup). When 𝑡ℎ passes without capture, the connector cancels the engine reservation promptly; when the engine cancels first, the connector calls void promptly. Promptness here is a liveness goal, not a safety requirement. Proposition 1 (no issuance against reclaimable funds). Under A1 and H1–H3, no inventory is issued against a charge whose funds are, or will become before capture lands, reclaimable by the buyer. Argument. Issuance occurs only before 𝑡issue (H2), and a capture whose attestation post-dates 𝑡issue reverts on-chain (H3). Any capture that lands therefore has issuedAt ≤ 𝑡issue , was broadcast within 𝑇𝑠 , included within a further 𝑇𝑖 , and final within a further 𝑇𝑓 . Allowing 𝛿 for clock drift, the capture is final by 𝑡issue + 𝑀 , which by H1 is strictly before 𝑡ℎ . Hence at the moment funds become reclaimable (𝑡ℎ ), either the charge is already captured, or no issuance occurred. □ What Proposition 1 does not say is also important. Between 𝑡ℎ and 𝑡𝑒 the engine reservation may still be technically alive while the funds are reclaimable. That window is harmless because H2 forbids issuance in it; the reservation is inventory held, not inventory sold, and H4 releases it. Earlier drafts claimed there was no such window; there is, and the design tolerates it rather than pretending it away. Residual risk (late capture). If the operator violates its own 𝑇𝑠 + 𝑇𝑖 bound — a relayer outage, a nonce stall, sustained congestion — a capture broadcast before 𝑡ℎ may be included after it and revert, while the ticket was already issued. The buyer is made whole by reclaim; the seller has issued and is unpaid. Because the operator sets 𝑀 and operates the relayer, ASP assigns this protocol-level loss to the operator: the operator pays the seller from its own pool (Section 4.6), the liability is counted in the operator’s aggregate exposure (Proposition 3), and the event is reported as a late-capture loss in the evaluation metrics (Section 9). The seller’s remaining risk is counterparty risk against the operator’s pool, which is what the exposure ceiling exists to bound. The correct mitigation is a generous 𝑀 , not a shorter one; the reference deployment uses 𝑇𝑠 = 60 s, 𝑇𝑖 = 120 s, 𝑇𝑓 per Section 7 and 𝛿 = 30 s, giving 𝑀 under five minutes against engine hold limits that are typically minutes for a scheduling slot, hours for a stock reservation, and hours or days for travel. Fulfilment classes whose engine hold is shorter than 𝑀 cannot be served in escrow mode and must use charge (authorize and capture in one call, rung D or C only); the registry records this per class.
4.6
Refunds
Pre-capture. Void and reclaim return the full amount; there is no partial pre-capture refund because nothing has been charged.
10
Post-capture. The refundable amount is whatever the fulfilment engine computes under its own rules: a returns policy for an order, a notice-period schedule for a service appointment, a dispute outcome for an invoice, fare or rate rules for travel. ASP does not impose a flat window on top of the engine; it executes the engine’s number. This choice follows from A5 and keeps the seller’s back office authoritative. Refund window. A captured charge carries a refund window 𝑊𝑟 (default: the longer of the engine’s cancellation horizon and 30 days) after which the capture is final and the escrow will reject refund. This mirrors CPP’s refund expiry [Shopify Engineering, 2025] and bounds the seller’s contingent liability at the protocol layer. Settlement becomes final under ASP after 𝑊𝑟 ; this does not extinguish any refund, warranty or consumer-protection obligation that exists outside the protocol under the law that governs the sale, and a seller or operator that owes such a refund after 𝑊𝑟 must pay it off-protocol. ASP bounds what the escrow will do, not what the parties owe. Refund liquidity order. A refund is sourced, in order, from (i) the seller’s payout vault, (ii) the seller’s rolling reserve, (iii) the seller’s settlement-delayed proceeds not yet released, (iv) the operator’s refund pool. The operator’s pool is funded from fees and is the last-resort backstop; the operator recovers advances from the seller’s future captures and reserve. Seller exposure controls. A backstop that is unbounded is a credit line, and a seller with large refundable volume who withdraws proceeds and becomes insolvent would convert it into the operator’s loss. ASP therefore requires the operator to enforce, per seller 𝑠, a set of controls that bound its exposure before any charge is captured: • Outstanding refundable exposure. 𝑅(𝑠) = ∑ captured amounts within their refund window not yet refunded. This is the quantity every other control is sized against. • Rolling reserve 𝜌(𝑠) ∈ [0, 1]: a fraction of each capture retained in a reserve vault and released after the refund window closes. • Settlement delay 𝐷(𝑠): captured proceeds beyond the reserve are released to the seller’s withdrawable balance only after 𝐷(𝑠), so that for young or high-cancellation sellers most refundable volume is still in escrow-adjacent custody when a refund is requested. • Exposure cap 𝐸max (𝑠): new captures are refused (and new offers are not issued) when 𝑅(𝑠) − reserve(𝑠) − delayed(𝑠) > 𝐸max (𝑠). The uncovered exposure is the only amount the operator’s pool can be asked to absorb. • Capture limits: per-charge and per-day maximums by risk tier. • Risk tier: a small number of tiers (new, verified, accredited) that set default values of 𝜌, 𝐷, 𝐸max and capture limits, adjusted by observed cancellation and refund rates. • Exposure reservation. Checks against a cap are useless if a hundred concurrent quotes can each pass them before any is recorded. Exposure is therefore reserved at Offer issuance, not measured at capture. For seller 𝑠 define 𝐴(𝑠) = 𝐸max (𝑠) − [𝑅(𝑠) + authorized(𝑠) + committedNotCaptured(𝑠) + reservedOffers(𝑠)], the available exposure. An Offer for amount 𝑎 MAY be issued only if 𝑎 ≤ 𝐴(𝑠), and issuing it atomically adds 𝑎 to reservedOffers. The amount moves to authorized on deposit, to committedNotCaptured on commit, to 𝑅(𝑠) on capture, and is released on Offer expiry, void or reclaim. The reservation update MUST be atomic in the risk engine (a compare-and-set or a serialisable transaction); the on-chain vault maintains the authorized, committedNotCaptured and 𝑅 terms itself, and the operator adds reservedOffers. Without reservation, a seller at USD 90k of a USD 100k cap could be quoted a hundred USD 1k Offers simultaneously and end at USD 190k of potential liability. 11
• Operator aggregate liability: the operator’s pool backstops more than refunds. Define 𝐿 = ∑ max(0, 𝑅(𝑠) − reserve(𝑠) − delayed(𝑠)) + 𝐶𝑀 + 𝐺, 𝑠
where 𝐶𝑀 is the late-capture exposure, the value of charges committed but not yet captured (bounded by the volume committed in any window of length 𝑀 , Section 4.5), and 𝐺 is any other settlement guarantee the operator has extended (for example advances under instantreserve mode). The operator exposure ceiling requires 𝐿 ≤ 𝜆 ⋅ pool for a fixed 𝜆 < 1; new offers are not issued while it is breached. Proposition 3 (bounded operator exposure). If every seller’s reserved-inclusive exposure is within its cap, the aggregate ceiling holds, and reservation updates are atomic, the operator’s maximum loss from the simultaneous default of all sellers together with the failure of every in-flight capture is at most 𝜆 ⋅ pool. Argument. Refund claims beyond a seller’s own reserve and delayed proceeds are limited to that seller’s uncovered exposure, which is a term of 𝐿; late-capture claims are limited to 𝐶𝑀 ; other guarantees are 𝐺. The ceiling bounds their sum. Bounding each term separately would not suffice, since all three are claims on the same pool; that is why the ceiling is on 𝐿. Atomic reservation is needed because otherwise concurrent Offers could each be admitted against the same headroom and the bound would hold only for exposure already recorded, not for exposure already promised. □ The controls are enforced off-chain by the operator except the reserve and settlement delay, which are enforced by the vault’s fee splitter at capture. They are parameters of the deployment, not of the protocol; the protocol requires only that they exist and that 𝑅(𝑠) is computable from on-chain state.
4.7
Fulfilment verification ladder
The phrase “capture on fulfilment” is only meaningful once one says who asserts fulfilment. ASP assigns each offer a rung:
Rung Name
Challenge window
Capture trigger
D
DeterministicOn-chain verifiable outcome
none
C
Data commitment
short (e.g. 24 h)
A
Attested
Connector-signed normalised receipt (Section 4.1) whose hash is committed on-chain; the buyer can audit the receipt against the engine record Seller-signed attestation without independently checkable record
S
Subjective
Buyer acknowledgement or arbiter ruling
until ruling
12
medium (e.g. 72 h)
Typical goods on-chain assets, some digital shipped orders, confirmed appointments, travel on-site services, custom orders, invoices freelance deliverables, quality-dependent services
At rungs C and A, capture is optimistic: the escrow pays the seller at capture, but the charge remains challengeable for the window, during which the buyer may present evidence (an engine record that does not match the committed hash, a cancellation confirmation) to the arbiter, who may direct a refund from the liquidity order above. At rung S, capture is deferred until acknowledgement or ruling. The rung is part of the Offer, so the buyer agent knows the trust position before signing. Rung C must be described carefully, because it is the rung most physical-goods and travel purchases live on. Committing a hash of (orderId, fulfilmentRef) on-chain does not prove that the carrier shipped the parcel, the technician completed the visit, or the airline issued the ticket. It proves that the connector, whose signature is attributable, asserted at a specific time that the engine reported issuance with those references, and it fixes that assertion so it cannot later be altered. Rung C is therefore an auditable data-commitment model, not cryptographically verified fulfilment: the buyer, an arbiter or an auditor can retrieve the e-ticket or confirmation from the supplier and check it against the committed receipt. Cryptographic verification of fulfilment would require the supplier or carrier itself to sign, which is rung D and which almost no order-management, scheduling or booking system offers today. This is nonetheless where A6 is reduced in practice. At rung C an operator that captures without issuance has signed a receipt for a record that does not exist; the mismatch is demonstrable within the challenge window and the refund is sourced from the operator’s own pool. The operator’s discretion is bounded by its own attributable liability rather than by the buyer’s goodwill.
4.8
Fees and revenue share
Capture is the single point at which a fee is taken. The fee is a basis-point rate 𝑓 on the charge amount, tiered by the seller’s trailing volume and capped in absolute terms per charge, and it is split between the operator and, if present, the distributor at share 𝑠 of the fee. For a USD 512.40 charge at 𝑓 = 150 bps and 𝑠 = 60%: fee USD 7.69, distributor USD 4.61, operator USD 3.08, seller USD 504.71. Rounding is to the token’s smallest unit, with the remainder allocated to the operator so that the three parts sum exactly to the fee. Proposition 2 (self-dealing is unprofitable). Suppose a distributor can act as, or collude with, a buyer whose spend it refers. If 𝑠 < 1 and the distributor bears the full charge amount with no subsidy from any party, then each referred charge yields the distributor a net loss of 𝑓 ⋅ amount ⋅ (1 − 𝑠) > 0. Argument. The distributor pays amount, receives amount - fee back as seller (or the seller does, in which case the distributor’s loss is larger), and earns 𝑠 ⋅ fee. Net: −fee + 𝑠 ⋅ fee < 0 whenever 𝑠 < 1. □ The condition matters. If a third party subsidises volume (a launch incentive paid per referred charge, for instance), the inequality can flip; such incentives must be sized below 𝑓(1 − 𝑠) per charge or the guarantee lapses.
4.9
Multi-stablecoin, single-currency charges
ASP is currency-agnostic in the sense that USDC is the first entry in a currency registry, and adding another stablecoin is a registry entry plus, where needed, a deposit adapter for the token’s authorization method. It is single-currency in the sense that a given charge is denominated, escrowed, captured and refunded in one token. The protocol never converts. 13
Invariant I1. For every charge, currency is constant across deposit, capture and refund. The consequence is that there is no DEX, no price oracle, no slippage and no swap-failure state anywhere in the settlement path. If a buyer and seller share no currency, the buyer agent funds one they both accept before quoting; that is a wallet-layer concern, not a settlement one. The cost is that liquidity is fragmented per token and a seller must maintain a vault per accepted currency.
4.10
Settlement modes and pause
• Escrow mode (default). Funds are held until capture. Safest for the buyer; the seller waits for fulfilment to be paid. • Instant-reserve mode (vetted sellers). The seller is paid at authorization; refunds are drawn from a rolling reserve funded by a percentage of the seller’s captures, with clawback rights. As noted in Section 3, this mode is custodial and requires business verification. A pause role can halt deposit and capture for a token (depeg), a seller (dispute or misbehaving hook) or the whole vault. reclaim is never pausable, so a pause can never strand buyer funds. The pause role is held by a time-locked multisig in the reference deployment (Section 7).
4.11
Interface specification, orchestration and conformance
Sections 4.1–4.10 define the protocol; Appendices C–F define the interfaces precisely enough to implement it. The key words MUST, MUST NOT, SHOULD and MAY in the appendices are to be interpreted as in RFC 2119 [Bradner, 1997]. Four interfaces are normative: • the x402 asp scheme (Appendix C): how an Offer is advertised in a 402 response and how a ChargeAuthorization is returned; • the vault interface (Appendix D): the on-chain functions, structs, events, errors, access control and revocation semantics every ASP escrow MUST expose; • the operator and connector APIs (Appendix E): the HTTP surface a buyer agent talks to, the adapter surface a fulfilment-engine connector implements including its timeout rule, the registry and webhook schemas, and the clock and relayer requirements; • conformance levels (Appendix F): what an implementation MUST support to call itself ASP-Lite, ASP-Core or ASP-Full, demonstrated by an executable suite. Three design rules govern the appendices. Every message that affects settlement is either an on-chain call or a signed off-chain object whose hash is on-chain (Offer, ChargeAuthorization, FulfilmentReceipt); nothing that only lives in an HTTP body can change who gets paid. Every off-chain call is idempotent on chargeId. And every timing field is an integer of UTC unix seconds in chain time, with the connector responsible for converting engine-local time under the 𝛿 bound. Orchestration. The on-chain state machine (Section 4.2) is deliberately small. An operator implementation needs a richer off-chain one — in particular an AUTHORIZED_PENDING_ENGINE_HOLD state that blocks commit until the holdBeforeAuth H1 check has passed, and a COMMIT_UNKNOWN state entered when the engine call times out, from which the only exit is a getHold query rather than a retry. Because the chain is authoritative for payment state and the engine for fulfilment state, the operator MUST run reconciliation over every non-terminal charge and resolve disagreements toward the authoritative source: engine committed and chain authorized → capture; engine cancelled and chain authorized → void; chain reclaimed and engine hold alive → release the hold; capture transaction status unknown → read the chain before resubmitting. The full off-chain state machine,
14
reconciliation matrix, risk-engine algorithm and relayer design are specified in the companion ASPLite Implementation Specification, which is the document an engineering team builds from; this paper fixes only what two implementations must agree on to interoperate.
5
Security Properties
We state five properties and argue each informally. A mechanised check of P1 and P2 against a TLA+ model of the state machine is planned [Lamport, 2002]. P1 (No stranded funds). Every deposited amount is eventually either captured to the seller or returned to the buyer, without depending on operator liveness. Argument. From authorized, either the operator captures or voids, or holdExpiresAt passes and reclaim becomes callable by anyone (A4). Pause does not block reclaim. From captured, funds are the seller’s by construction. No other state holds funds. P2 (No double charge). A buyer authorization is debited at most once. Argument. chargeId is the hash of the authorization struct including a nonce; the escrow rejects a second deposit with the same key, and the token-level authorization (ERC-3009 nonce or Permit2 nonce) is single-use. P3 (Bounded buyer exposure). A buyer’s loss from a malicious operator is bounded by the sum of charges captured without fulfilment within one challenge window, minus what the operator’s refund pool covers, and by the smart wallet’s spend cap. Argument. The operator cannot move escrowed funds anywhere but the seller’s registered vault and the fee splitter; capture without fulfilment at rung C is challengeable and refunded from the liquidity order; the wallet cap (Section 7) bounds total authorizations irrespective of operator behaviour. P3’ (Late-capture loss assignment). Protocol-level loss from a capture that fails to land before 𝑡ℎ is assigned to the operator (Section 4.5, residual risk) and counted in the operator’s aggregate liability 𝐿. The seller is not exposed to chain timing; it is exposed to the operator’s solvency, which Proposition 3 bounds. Argument. Commit before 𝑡issue is the only path to a seller-committed, buyer-reclaimed charge; the operator has undertaken to pay such charges from its pool; and 𝐶𝑀 in 𝐿 reserves for them. P4 (Seller payment finality). Once captured, the seller’s net amount cannot be reduced except by a refund within 𝑊𝑟 that the seller’s own engine rules authorise or an arbiter directs. Argument. The escrow only accepts refund before the window closes and only for amounts up to the captured total; there is no other reducing operation. P5 (Hook isolation). No seller-supplied code path can move, hold or redirect funds. Argument. Off-chain hooks are webhooks with no on-chain authority. On-chain hooks, where enabled, are called by the vault with a read-only view of the charge and can only return an observe/annotate/veto result; the vault, not the hook, executes any transfer, and veto rights are granted per hook by the operator after review.
6
Integration with Fulfilment Engines
ASP does not replace a seller’s system and does not require changes to it. It sits in front of one, as the agent-facing payment layer, and maps its states onto the engine’s own lifecycle through a connector that the operator runs. The claim is deliberately scoped: the seller’s core engine is unchanged; the seller’s operations are not (Section 6.4). 15
6.1
Fulfilment-class registry
The protocol defines one lifecycle. Business types differ only in how the four engine operations are named, what the hold time limit is, which verification rung applies, and how refunds are computed. ASP captures those differences in a registry of fulfilment classes; an Offer names its class, and the connector for that class implements the mapping. Adding a business type is a registry row and a connector, not a protocol change. Registry field
Meaning
classId
e.g. order.shipped, service.appointment, invoice.b2b, deliverable.accepted, travel.air, travel.hotel the engine calls the connector maps ASP transitions onto
holdOp, commitOp, cancelOp, refundQuoteOp holdLimitSource minHold holdBeforeAuth, policyExpiry defaultRung fulfilmentRefKind refundRuleSource challengeWindow, refundWindow
6.2
where 𝑡𝑒 is read from (a field, a policy default, an invoice due date) whether the class can run in escrow mode or must use charge (Section 4.5) whether the engine can hold before payment authorization; if not, the conservative 𝑡∗𝑒 used at quote time (Section 4.4) verification rung (Section 4.7) what the receipt’s fulfilmentRef is (tracking number, completion id, ticket number) who computes the refundable amount (engine, policy table, arbiter) class defaults for 𝑊𝑐 and 𝑊𝑟
Worked mappings
The table below gives the mapping for five representative classes. Travel is included because it has the tightest holds and the most complex refund rules; the other columns are what most online service businesses will use. ASP engine hold (step 1) 𝑡𝑒 source
E-commerce order (OMS)
Service appointment
reserve stock
tentative slot hold
invoice issued
stock reservation timeout shipment confirmed
slot hold expiry
due date
appointment confirmed or completed release slot
goods/services deliverable accepted accepted
ticket issued
invoice cancelled
cancel PNR before ticketing
commit / capture void/reclaim cancel order, release stock
B2B invoice
16
Freelance deliverable
Air travel (GDS / NDC)
task opened, milestone funded delivery deadline
create PNR / OrderCreate
task cancelled
ticketing / order time limit
ASP refund
E-commerce order (OMS)
Service appointment
per returns policy
per notice-period schedule completion / visit id C (confirmed) / A (completed)
fulfilmentRef tracking number default C rung
B2B invoice
Freelance deliverable
Air travel (GDS / NDC)
per credit note / dispute acceptance reference A
per arbiter or partial acceptance acceptance hash S
per fare rules / OrderChange e-ticket number C
In every column the engine hold is created at quote time (step 1 of Section 4.4) so that 𝑡𝑒 is known before the Offer is signed; where a platform cannot hold before payment, the holdBeforeAuth path applies. Two mappings deserve comment. A service appointment has two candidate commit points: confirmation (the slot is booked) and completion (the work was done). The class chooses one; confirmation is rung C and captures earlier, completion is rung A and protects the buyer more, and a class may use two charges (deposit at confirmation, balance at completion) to get both. A B2B invoice inverts the usual timing: fulfilment often precedes payment, so deposit and capture may be close together and the escrow mainly provides the dispute window before capture. The connector’s hard requirements are: obtain 𝑡𝑒 before quoting (or apply the holdBeforeAuth path), derive 𝑡ℎ and 𝑡issue under H1 and place them in the Offer, release provisional holds on decline, and gate commit on 𝑡issue (H2). H3 is enforced by the vault. H4 is a liveness goal it should also meet.
6.3
Extensibility
Sellers often want their own logic at settlement points: issue loyalty points, sync a back office, gate on live inventory. Two tiers are offered. Off-chain hooks are webhooks emitted at each state transition; they run on the seller’s infrastructure, cannot affect settlement, and need no review. On-chain hooks are contracts the vault calls at capture and refund for logic that must be atomic with settlement; they are inert until audited and whitelisted, and are constrained by P5. The reference deployment ships off-chain hooks only.
6.4
Onboarding paths
Path
Change to core booking engine
Indicative time to live
Platform connector (Shopify, Square, a scheduling SaaS, a GDS/NDC gateway) Gateway-wrap the seller’s own API Direct integration
none
days
none
days to two weeks
optional, for control
two to four weeks
Platform connectors are the route to scale: one connector for a commerce or scheduling platform onboards every seller on it. “No change to the core engine” is not “no work”. Every path requires engine or API access and credentials, a one-time field mapping, cancellation and refund permissions 17
for the connector, a payout vault, business verification, and, for some classes, sector accreditation (travel being the obvious case). The last two are usually the long pole. A fixed sandbox certification (Appendix B) must pass before a seller goes live. Buyer agents require no seller-specific integration. ASP is advertised as an additional scheme in the x402 402 response, so support is implemented once at the x402 client, wallet or facilitator layer (parsing the Offer, constructing the ChargeAuthorization, and tracking the charge’s state), after which every ASP seller is reachable without further work.
7
Instantiation on the XDC Network
The reference deployment targets the XDC Network, an EVM-compatible chain with deterministic finality under XDPoS 2.0 [XDC Network, 2023], which supplies the bounded 𝑇𝑓 that A1 and Proposition 1 rely on. The settlement token is USDC on XDC, which supports ERC-3009, so the default deposit adapter is transferWithAuthorization and the buyer agent never pays gas. Gas for deposit, capture, void and refund is paid by the operator’s relayer, which is the same sponsored-gas facilitator infrastructure XDC AI runs for x402 settlement. Buyer agents hold funds in an ERC-4337 smart account [Buterin et al., 2021] with a session-key policy that enforces a per-charge and rolling spend cap on-chain, so that a compromised agent has a bounded blast radius (P3). Sellers receive proceeds in a counterfactually deployed smart account so that onboarding does not require the seller to hold a key before first capture. Agent and seller identities are registered under ERC-8004 [ERC-8004 Authors, 2025], which supplies the identity and reputation registries the distributor and verification-rung logic reference; we note the empirical caveats about ERC-8004 ecosystem maturity raised by Xiong et al. [Xiong et al., 2026]. The pause role is a two-of-three multisig behind a 24-hour timelock, except for the token-level depeg pause, which is immediate and affects deposit only. The vault is intended to be bytecodecompatible with CPP’s escrow so that audits of the upstream contract carry over; deviations, if any, will be listed in the deployment notes.
7.1
Reference implementation scope: ASP-Lite
The full profile above is more than a first implementation should attempt. The reference implementation, ASP-Lite, is deliberately narrow so that the safety model can be validated before any of the optional machinery is added: • USDC on XDC only; one currency-registry entry. • One seller, one fulfilment class and one connector (the first is expected to be an e-commerce or service-scheduling platform, with a travel NDC connector second), rung C only. • Escrow mode only; no instant-reserve mode, no rolling reserve beyond what the exposure controls require. • The seven operations quote, authorize, fulfil, capture, void, reclaim, refund; no partial capture. • Fee to a single operator address; no distributor split. • Off-chain hooks only; no on-chain hooks. • No ERC-8004 registration; identities are operator-issued. Multi-stablecoin support, distributor revenue share, instant-reserve mode, rung A and S arbitration, on-chain hooks and ERC-8004 integration are each added only after ASP-Lite has passed the evaluation in Section 9 on the narrow case. 18
8
Related Work
Industry protocols. x402 and its schemes [Reppel et al., 2025, x402 Foundation, 2026], CPP [Coinbase and Shopify, 2025], x402r [x402r, 2026], Cloudflare’s deferred scheme [Cloudflare, 2025], AP2 [Parikh and Surapaneni, 2025] and ACP [Stripe and OpenAI, 2025] are discussed in Section 2. Table 5 summarises the positioning. x402 (exact)
CPP / x402r
AP2
ACP
ASP
Rail
metered access stablecoin
escrow operations stablecoin
consent chain any
fulfilment-coupled settlement stablecoin
Hold / capture
no
yes
n/a
Hold tied to inventory Who asserts fulfilment Refund amount source Revenue share
n/a
no
n/a
n/a
operator, unspecified operatorspecified fee range only
n/a
checkout messages cards / processor via processor processorspecific merchant
n/a
merchant
n/a
none
Layer Standardises
n/a n/a
yes (CPP-compatible) yes (H1–H3, issuance deadline) per-rung, specified engine’s fare / rate rules at capture, with Prop. 2
Academic literature. Zhang et al. systematise blockchain agent-to-agent payments around discovery, authorisation, execution and accounting, and note the absence of reversibility in shipped designs [Zhang et al., 2026]. Mao et al. survey the security of LLM agents in agentic commerce and catalogue attacks on the payment step in particular [Mao et al., 2026]. A402 binds a cryptocurrency payment to verifiable service execution through an atomic service channel, which is the rung-D case of our ladder [Li et al., 2026]. The systematic analysis of x402 free-riding shows how a seller can be induced to serve without payment or a buyer to pay without service under the exact scheme, which is the failure mode escrow removes [Anonymous, 2026]. See and Tan integrate programmable compliance into a stablecoin rail and use an escrow tranche for pending compliance conditions; their compliance hooks are complementary to ASP’s settlement hooks [See and Tan, 2026]. Lan et al.’s analysis of AP2 replay is the reason ASP binds the authorization struct to offerId, holdExpiresAt and a nonce [Lan et al., 2026]. Vaziry et al. combine A2A with x402 micropayments and ledger-anchored identities [Vaziry et al., 2025]; AESP proposes privacy-preserving settlement for agents [Wang, 2026]; Alqithami surveys execution models and trust boundaries for on-chain agents [Alqithami, 2026]. The earliest agent-mediated payment protocols predate blockchains by two decades [Pang et al., 2002] and already identified the need to separate authorization from settlement. To our knowledge no prior work specifies the coupling between an on-chain hold and an off-chain fulfilment engine’s hold, or states the fulfilment-verification trust position per class of good or service.
19
9
Limitations and Open Questions • No deployed measurement. Gas per operation, latency to finality on XDC, and behaviour under expiry races are unmeasured. The evaluation plan below is the most important followup, and this paper should be read as the specification that plan tests. • Operator trust at rungs A and S. The challenge window bounds but does not eliminate operator discretion. Multi-operator or arbiter-set designs are future work. • Partial capture. Multi-leg itineraries and split deliveries need partial capture, which CPP supports and this profile does not yet specify. • Privacy. Charge amounts, seller vaults and timing are public on-chain. Mitigations (amount blinding, batched capture) are out of scope here. • Regulatory posture. Sector accreditation where it applies (IATA for air), consumerprotection rules on refunds and cancellations that vary by class and jurisdiction, stablecoin regimes (MiCA in the EU, VARA in the UAE) and the classification of the operator’s refund pool are unresolved and jurisdiction-dependent. • Pricing model. Whether ASP is priced as a thin rail or as a distribution channel sets the fee ceiling and is a commercial decision outside the protocol. • Name. “Agentic Settlement Protocol” was chosen to avoid collision with “Agentic Commerce Protocol”; it remains a working name.
9.1
Evaluation plan
ASP-Lite will be exercised on XDC testnet, then mainnet, against a simulated fulfilment engine that implements the generic hold / commit / cancel / refund-quote lifecycle with a configurable hold time limit (so that short-hold scheduling classes and long-hold travel classes are both covered), and against one real connector. Each run executes a booking lifecycle end to end; fault injection is applied per run from the following catalogue: engine timeout before issuance; engine commit after 𝑡issue (must be refused by H2); operator crash between attestation and capture; duplicate engine callbacks; duplicate capture and duplicate refund submissions; RPC outage of configurable duration during the capture window; capture broadcast within 𝑇𝑠 of 𝑡issue ; reclaim submitted at 𝑡ℎ ± one block; refund request when the seller vault is empty; refund request at the refund-window boundary; token pause during an open hold. Metrics recorded per run: time from attestation to capture inclusion and to finality; time from refund request to refund finality; captures that reverted and why; late-capture losses (issued, then reclaimed); reclaim frequency and cause; H2 refusals; H3 reverts; holdBeforeAuth void-and-requote events; refund source used (vault, reserve, delayed, pool); gas per operation by role; and, across runs, the empirical distribution of 𝑇𝑠 + 𝑇𝑖 against the configured margin. The target is on the order of thousands of lifecycles, with a fault injected in a stated fraction of them, so that Proposition 1 and the exposure controls are tested against measured rather than assumed delays. The Appendix B cases are packaged as an executable conformance suite (asp-conformance) that any vault or connector implementation can run and that reports the number of cases passed at the claimed level; passing it is the onboarding gate for sellers and connectors. A second, independently written ASPLite implementation exercising the same suite against the first’s vault will test the interoperability claim of Appendix F. Results will be reported in a revised version of this paper.
20
10 Conclusion Metered agent payments are solved; agent purchases are not, because a purchase needs a hold that lapses with the inventory, a fulfilment assertion someone is accountable for, and a refund computed by whoever owns the fare rules. The escrow primitive that makes this possible on-chain already exists. ASP specifies how to drive it: an issuance deadline that keeps the two holds apart by a margin the operator is accountable for, a verification ladder that says who is trusted, what their assertion proves and for how long, a refund model that defers to the engine and bounds the operator’s exposure, and revenue share that cannot be farmed. Travel forces every one of these to exist, which is why it is the running example; but the protocol is defined against an abstract fulfilment engine, and physical orders, service appointments, invoices, freelance deliverables and subscriptions are each a row in the fulfilment-class registry over the same machine.
A
Authorization struct
struct Offer { // signed by seller, delegate or operator (Section 4.3) bytes32 sellerId; bytes32 fulfilmentClass; bytes32 engineRef; address token; uint256 amount; uint64 engineExpiry; // t_e uint64 issueDeadline; // t_issue uint64 holdExpiresAt; // t_h uint8 verificationRung; uint32 challengeWindow; // seconds uint32 refundWindow; // seconds bytes32 refundPolicyRef; uint64 expiresAt; address signer; bytes32 signerAuthority; // direct | delegation id | mandate id uint32 delegationVersion; // seller's delegationVersion at signing (0 if direct) } // offerId = keccak256(EIP-712 encoding of Offer); binds every term above. struct ChargeAuthorization { // signed by the buyer agent bytes32 offerId; address buyer; address token; uint256 amount; uint64 issueDeadline; // must equal Offer.issueDeadline uint64 holdExpiresAt; // must equal Offer.holdExpiresAt bytes32 nonce; } // EIP-712 domain: name "ASP", version "1", chainId, verifyingContract = vault // chargeId = keccak256(abi.encode(TYPEHASH, ...fields)) // deposit() receives the Offer terms alongside, recomputes offerId, and reverts
21
// on mismatch; it stores issueDeadline and holdExpiresAt for capture()/reclaim().
B
Sandbox certification cases
1. Happy path: quote, deposit, fulfil, capture; seller receives amount - fee; splitter receives fee in correct shares. 2. Void: deposit, engine fails to issue, void; buyer receives full amount. 3. Expiry: deposit, operator silent, reclaim by third party after holdExpiresAt; buyer receives full amount; capture afterwards reverts. 4. Refund: capture, engine returns partial refundable amount, refund for exactly that amount; refund beyond window reverts; cumulative refund cannot exceed capture. 5. Idempotency: duplicate deposit, duplicate capture, duplicate refund are no-ops with identical results. 6. H2 gate: issuance request after 𝑡issue is refused by the connector even though the engine reservation is alive. 7. H3 gate: a capture whose attestation has issuedAt > 𝑡issue reverts in the vault; the operator’s pre-check also refuses to submit it. 8. H4 (engine first): engine hold lapses, connector voids promptly. 9. H4 (escrow first): escrow hold lapses, connector cancels engine hold; no issuance possible. 10. Exposure cap: a capture that would push a seller’s uncovered exposure above 𝐸max is refused before deposit. 11. Pause: token pause blocks deposit and capture, does not block reclaim. 12. Offer binding: a deposit whose authorization timing fields differ from the Offer’s reverts; an Offer signed by a revoked delegate is rejected. 13. Decline: buyer never authorizes; provisional engine hold is released at expiresAt. 14. holdBeforeAuth = false shortfall: engine returns 𝑡𝑒 < 𝑡ℎ + 𝛿 after deposit; connector voids immediately and re-quotes. 15. Partial refund: two refunds summing to less than capture leave the charge captured; a third bringing the cumulative total to the captured amount moves it to refunded; any further refund reverts. 16. Commit timeout: the engine accepts the commit but the response is lost; the operator observes COMMIT_UNKNOWN, calls getHold, finds committed, and captures exactly once with no second engine call. 17. Exposure reservation: with headroom for one Offer, two concurrent quote requests result in exactly one Offer issued and one EXPOSURE_CAP refusal; the reservation is released when the issued Offer expires unauthorized.
C
Appendix C: The x402 asp scheme
C.1 Advertising. A seller endpoint that supports ASP MUST include, in the accepts array of its x402 402 response, an entry with scheme: "asp". The entry carries the signed Offer and enough context for the client to construct a ChargeAuthorization. Networks are identified by CAIP-2 [Chain Agnostic Standards Alliance, 2019]. { "x402Version": 2, "accepts": [{
22
"scheme": "asp", "network": "eip155:50", "asset": "0x<usdc-on-xdc>", "amount": "512400000", "payTo": "0x<vault>", "maxTimeoutSeconds": 900, "extra": { "aspVersion": "1", "offer": { "...Offer fields, Appendix A..." }, "offerId": "0x<keccak256 of EIP-712 Offer>", "offerSignature": "0x<65 bytes>", "depositMethod": "eip3009", "eip712Domain": { "name": "ASP", "version": "1", "chainId": 50, "verifyingContract": "0x<vault>" }, "operatorApi": "https://<operator>/asp/v1", "statusUrl": "https://<operator>/asp/v1/charges/{chargeId}" } }] } Rules: amount MUST equal offer.amount; payTo MUST be the vault; maxTimeoutSeconds MUST be at most offer.expiresAt - now. A client MUST recompute offerId from offer and MUST reject the entry if it differs from the advertised value or if offerSignature does not recover to offer.signer. A client SHOULD verify signerAuthority against the operator’s seller registry (Appendix E.3) before signing. C.2 Payment payload. The client retries with the standard x402 payment header whose payload is: { "scheme": "asp", "network": "eip155:50", "payload": { "authorization": { "...ChargeAuthorization fields, Appendix A..." }, "authorizationSignature": "0x<65 bytes>", "depositMethod": "eip3009", "depositProof": "0x<ERC-3009 / EIP-2612 / Permit2 signature>" } } authorization.offerId MUST equal the advertised offerId, and issueDeadline and holdExpiresAt MUST equal the Offer’s. The facilitator (the operator’s relayer) verifies the payload, calls deposit, and responds with the x402 settlement header containing chargeId, the deposit transaction hash and statusUrl. Unlike exact, a successful settlement response means funds are held, not paid; the resource is delivered when the charge reaches captured, and the client MUST poll statusUrl or subscribe to webhooks to learn that. C.3 Failure codes. In addition to x402’s own errors, the facilitator returns one of: OFFER_EXPIRED, OFFER_ID_MISMATCH, OFFER_SIGNER_UNAUTHORISED, TIMING_MISMATCH (authorization timing fields differ from Offer), H1_VIOLATION (only on the holdBeforeAuth path, 23
after void), EXPOSURE_CAP (seller or operator ceiling breached), TOKEN_PAUSED.
D
Vault interface
Every ASP escrow MUST implement the following interface. Amounts are in the token’s smallest unit; times are unix seconds. interface IASPVault { enum Status { None, Authorized, Captured, Refunded, Reclaimed } struct Offer { /* Appendix A */ } struct ChargeAuthorization { /* Appendix A */ } struct Attestation { bytes32 chargeId; bytes32 receiptHash; uint64 issuedAt; address attestor; bytes attestorSig; } struct Charge { Status status; address buyer; address token; uint256 amount; uint256 capturedAmount; uint256 refundedAmount; uint64 issueDeadline; uint64 holdExpiresAt; uint64 refundWindowEnd; bytes32 offerId; bytes32 receiptHash; } struct Delegation { // seller -> connector signing key bytes32 sellerId; address signer; uint32 version; uint64 validUntil; uint256 maxAmount; bytes32[] classes; } struct AttestorGrant { // seller/class -> connector attestor key bytes32 sellerId; bytes32 classId; address attestor; uint64 validFrom; uint64 validUntil; } // --- registry (operator role; seller may revoke) --function setDelegation(Delegation calldata d, bytes calldata sellerSig) external; function revokeDelegations(bytes32 sellerId) external; // bumps delegationVersion function delegationVersion(bytes32 sellerId) external view returns (uint32); function setAttestor(AttestorGrant calldata g) external; function revokeAttestor(bytes32 sellerId, bytes32 classId, address attestor) external; // --- lifecycle --function deposit(Offer calldata offer, bytes calldata offerSig, ChargeAuthorization calldata auth, bytes calldata authSig, bytes calldata depositProof) external returns (bytes32 chargeId); function capture(bytes32 chargeId, Attestation calldata att) external; function void(bytes32 chargeId) external; function reclaim(bytes32 chargeId) external; // anyone, after holdExpiresAt function refund(bytes32 chargeId, uint256 amount, uint8 source) external;
24
// --- views --function charges(bytes32 chargeId) external view returns (Charge memory); function offerId(Offer calldata offer) external view returns (bytes32); function chargeId(ChargeAuthorization calldata auth) external view returns (bytes32); // --- events --event Authorized(bytes32 indexed chargeId, bytes32 indexed offerId, address indexed buyer, address token, uint256 amount, uint64 issueDeadline, uint64 holdExpiresAt); event DelegationSet(bytes32 indexed sellerId, address signer, uint32 version); event DelegationsRevoked(bytes32 indexed sellerId, uint32 newVersion); event AttestorSet(bytes32 indexed sellerId, bytes32 indexed classId, address attestor, uint64 validFrom, uint64 validUntil); event Captured(bytes32 indexed chargeId, bytes32 receiptHash, uint256 toSeller, uint256 fee, uint256 reserve); event Voided(bytes32 indexed chargeId); event Reclaimed(bytes32 indexed chargeId, address caller); event Refunded(bytes32 indexed chargeId, uint256 amount, uint256 cumulative, uint8 source); event Paused(bytes32 scope, bool paused); // token | seller | vault // --- errors --error OfferExpired(); error OfferIdMismatch(); error InvalidOfferSignature(); error InvalidDelegate(uint32 offerVersion, uint32 currentVersion); error TimingMismatch(); error AuthorizationUsed(); error WrongStatus(Status have); error IssueDeadlinePassed(uint64 issuedAt, uint64 deadline); error InvalidAttestor(address attestor, uint64 issuedAt); error HoldExpired(); error HoldNotExpired(); error RefundWindowClosed(); error RefundExceeded(uint256 cumulative, uint256 captured); error ExposureCap(); error PausedScope(bytes32 scope); error NotOperator(); } Normative behaviour: • deposit MUST recompute offerId from offer, verify offerSig recovers to offer.signer, verify that signer is the seller’s direct key or holds a Delegation whose version == delegationVersion(sellerId), whose validUntil has not passed, whose maxAmount >= offer.amount and whose classes include offer.fulfilmentClass (else InvalidDelegate), verify authSig, and revert with TimingMismatch unless auth.issueDeadline == offer.issueDeadline and auth.holdExpiresAt == offer.holdExpiresAt. It MUST revert with HoldExpired if block.timestamp >= offer.holdExpiresAt - M_min (a vault constant, default 300 s). It MUST be a no-op returning the existing chargeId on a duplicate, and MUST consume the token-level authorization nonce so a second deposit with a different chargeId but the same buyer nonce reverts with AuthorizationUsed. • Revocation semantics. revokeDelegations(sellerId) increments the seller’s delegationVersion. An Offer carries the version under which it was signed (Appendix A, delegationVersion); an Offer whose version is lower than the current one is invalid at deposit immediately, even if expiresAt has not passed. Charges already Authorized under the old version are unaffected. This choice favours the seller (a compromised key 25
is neutralised at once) at the cost of buyers who hold not-yet-deposited Offers, which are short-lived by construction. • capture MUST revert with IssueDeadlinePassed if att.issuedAt > issueDeadline, MUST verify att.attestorSig recovers to an attestor with an AttestorGrant for (sellerId, fulfilmentClass) whose [validFrom, validUntil] contains att.issuedAt (else InvalidAttestor; an attestation signed before a key’s revocation but submitted after it remains valid, since validity is judged at issuedAt), and MUST pay amount - fee reserve to the seller vault, fee to the splitter and reserve to the reserve vault in the same transaction. It MUST set refundWindowEnd = block.timestamp + offer.refundWindow. • reclaim MUST NOT be restricted by caller or by any pause, and MUST succeed whenever status == Authorized && block.timestamp >= holdExpiresAt. • refund MUST revert if block.timestamp > refundWindowEnd or refundedAmount + amount > capturedAmount (RefundExceeded); it MUST transition to Refunded exactly when the cumulative equals capturedAmount. Atomic sourcing. The vault MUST keep, per seller and token, three internal balances — available, reserve and delayed (with release schedule) — plus one operator pool balance, and a single refund call MUST draw the amount from them in that order within one transaction. The source argument is advisory and the Refunded event reports the tier actually reached; if the pool is also insufficient the call reverts and no partial refund is made. Sequential refunds from separate wallets are non-conformant because they create partial-failure states. • Only the operator role MAY call deposit, capture, void and refund. The pause role MAY pause deposit and capture per scope; it MUST NOT be able to pause reclaim. • Fee, reserve and settlement-delay parameters MUST be read from the seller’s registry entry at capture time, not supplied by the caller. • capture MUST decrement the seller’s committed-not-captured exposure and increment refundable exposure in the same transaction as the transfer (Section 4.6, reservation model), so that the on-chain view of exposure is never stale relative to funds.
E
Off-chain interfaces
E.1 Operator API (base path /asp/v1; JSON; all responses carry aspVersion). Requests that create or change state MUST carry an Idempotency-Key header equal to chargeId where one exists. Method Path
Caller
Purpose
POST
/quotes
buyer agent
POST
/charges
GET
/charges/{chargeId}
buyer agent / facilitator any
Body: { sellerId, fulfilmentClass, items, buyer }. Creates the provisional engine hold, derives deadlines, returns the signed Offer as in Appendix C.1. Body: the C.2 payload. Relays deposit; returns { chargeId, txHash, status }. Returns the Charge view plus off-chain fields: engineRef, receipt (after capture), refunds[], challenge (if any).
26
Method Path
Caller
Purpose
POST
/charges/{chargeId}/cancelbuyer agent
POST
/charges/{chargeId}/refundbuyer agent
GET
/charges/{chargeId}/receipt buyer, arbiter, auditor
GET
/charges/{chargeId}/refunds buyer, arbiter, auditor
POST
/charges/{chargeId}/challenge buyer agent
GET GET
/registry/classes any /registry/sellers/{sellerId} any
POST
/webhooks
seller / buyer agent
Pre-capture: requests void. Post-capture: submits cancellation to the engine, returns { refundableAmount, refundPolicyRef, expiresAt } as a quote. Accepts a refund quote; operator executes refund for exactly refundableAmount. Returns the normalised FulfilmentReceipt, the connector signature, receiptHash, and engine references. MUST be retained for at least 𝑊𝑐 + 𝑊𝑟 and SHOULD be retained for the operator’s audit period. Returns each refund’s engine quote, refundable amount, reason, refundPolicyRef, connector response and timestamp: the off-chain evidence for an on-chain refund. Within 𝑊𝑐 : body { claim, evidence[] }. Opens a case with the arbiter (E.5). Fulfilment-class registry (E.4). Public part of the seller registry (E.3): delegations, tier, accepted tokens, vault. Subscribe to E.6 events for a sellerId or buyer.
Errors use RFC 7807 problem details with type set to one of the C.3 codes or ENGINE_UNAVAILABLE, CHALLENGE_WINDOW_CLOSED, REFUND_QUOTE_EXPIRED. A machine-readable OpenAPI 3.1 description [OpenAPI Initiative, 2021] of this surface accompanies the reference implementation. E.2 Connector interface. A fulfilment-engine connector is a component the operator loads per fulfilment class. It MUST implement: interface Ctx { sellerId: string; offerId?: string; chargeId?: string; engineRef?: string; idempotencyKey: string; }
interface FulfilmentConnector { classId: string; createHold(ctx: Ctx, req: HoldRequest): Promise<{ engineRef: string; engineExpiry: number | null; price: bigint; currency: string }>; getHold(ctx: Ctx): Promise<{ state: "held" | "committed" | "cancelled" | "expired" | "unknown engineExpiry: number | null; record?: EngineRecord }>; // reconciliation releaseHold(ctx: Ctx): Promise<void>; // decline / lapse / H4 commit(ctx: Ctx): Promise<FulfilmentReceipt>; // before t_issue cancel(ctx: Ctx): Promise<{ refundableAmount: bigint; refundPolicyRef: string; quoteExpiresAt: number; engineResponse: unknown }>; // refund quote } 27
Every call carries a Ctx with the identifiers above so the connector can make the engine call idempotent on (engineRef, chargeId, idempotencyKey). createHold MUST return engineExpiry when the engine can hold before authorization and null otherwise, in which case the operator applies the class’s policyExpiry and the holdBeforeAuth path (Section 4.4). commit MUST refuse, without calling the engine, if the current time is at or past the charge’s issueDeadline. Timeout rule. If commit times out or returns an indeterminate error, the operator MUST NOT retry it; it MUST call getHold and act on the engine’s reported state (committed → produce the receipt and capture; held → retry commit if still before issueDeadline; cancelled/expired → void; unknown → keep polling until 𝑡issue , then void). A retried commit without a preceding getHold risks duplicate orders, double bookings or double ticket issuance and is non-conformant. The connector holds the attestor key for its class; the operator MUST register that key on-chain via setAttestor for the sellers the connector serves. E.3 Seller registry entry (fields marked pub are served by /registry/sellers): { "sellerId": "0x<bytes32>", // pub "payoutVault": "0x<address>", // pub "reserveVault": "0x<address>", "acceptedTokens": ["0x<usdc>"], // pub "classes": ["order.shipped", "travel.air"], // pub "delegations": [{ "signer": "0x<connector key>", "scope": { "classes": ["*"], "maxAmount": "5000000000", "validUntil": 1790000000 }, "revoked": false }], "attestors": ["0x<connector attestor key>"], // pub "riskTier": "verified", // pub "feeBps": 150, "distributorShareBps": 6000, "reserveBps": 500, "settlementDelaySeconds": 604800, "exposureCap": "250000000000", "perChargeCap": "5000000000", "dailyCap": "100000000000", "settlementMode": "escrow"
// pub
} The on-chain vault MUST hold, at minimum, payoutVault, reserveVault, the delegation set, the attestor set, feeBps, reserveBps and settlementDelaySeconds; the rest MAY be off-chain. E.4 Fulfilment-class registry entry: { "classId": "service.appointment", "engineOps": { "hold": "slot.tentative", "commit": "slot.confirm", "cancel": "slot.cancel", "refundQuote": "policy.noticePeriod" }, "holdLimitSource": "engine", // engine | policy | invoiceDueDate "holdBeforeAuth": true, "policyExpirySeconds": null, "minHoldSeconds": 900, "escrowMode": true, // false => charge() only "defaultRung": "C", "fulfilmentRefKind": "completionId", "refundRuleSource": "engine", 28
"challengeWindowSeconds": 86400, "refundWindowSeconds": 2592000 } E.5 Arbiter interface. An arbiter MUST expose open(case), submitEvidence(caseId, party, evidence) and rule(caseId) -> { outcome: "uphold" | "refund", amount }. A refund ruling is executed by the operator through the liquidity order and recorded with source on-chain. The arbiter MAY be a contract (rung D/S with on-chain evidence) or an off-chain service whose rulings are signed; the Offer’s verificationRung determines which is acceptable. E.6 Webhook payloads. Delivered as POST with an HMAC signature header over the body, retried with backoff for 24 h, and MUST be idempotent on eventId. { "eventId": "uuid", "aspVersion": "1", "type": "charge.captured", "chargeId": "0x…", "sellerId": "0x…", "occurredAt": 1790000000, "txHash": "0x…", "data": { "receiptHash": "0x…", "toSeller": "504710000", "fee": "7690000", "reserve": "0" } } Event types: charge.authorized, charge.captured, charge.voided, charge.reclaimed, charge.refunded (with cumulative and final: bool), charge.challenged, challenge.ruled, charge.late_capture_loss (operator-internal), hold.released. E.7 Time and identity conventions. All timestamps are unix seconds UTC. Chain identifiers are CAIP-2. sellerId, chargeId, offerId and receiptHash are bytes32 rendered as 0x-prefixed hex. Amounts are decimal strings in the token’s smallest unit. The connector MUST convert engine-local time to UTC unix seconds and MUST apply the class’s 𝛿 when doing so. Clock health. The operator MUST monitor its clock against the chain’s latest block timestamp and at least one trusted time source, and MUST stop issuing Offers while observed drift exceeds the configured 𝛿. Clock drift is a safety input to H1 and is treated as infrastructure health, like RPC availability. E.8 Relayer requirements. The relayer is part of the safety-critical path because 𝑇𝑠 and 𝑇𝑖 are its properties. It MUST record, per transaction, submittedAt, includedAt, finalizedAt, nonce, RPC endpoint, retries, replacements and fee parameters; MUST use at least two independent RPC endpoints; MUST implement nonce management and fee-bump replacement; and MUST alert when observed 𝑇𝑠 + 𝑇𝑖 over a rolling window exceeds a configured fraction of 𝑀 . The evaluation plan (Section 9) reports the empirical 𝑇𝑠 + 𝑇𝑖 distribution from these records. E.9 Authority of record. Three stores hold state and the specification fixes which is authoritative for what: the chain for payment state; the fulfilment engine for fulfilment state; the operator database for orchestration and derived state only. Any disagreement is resolved by reconciliation toward the authoritative source, never by editing it. The operator MUST run reconciliation over every non-terminal charge (the reconciliation matrix is given in the ASP-Lite Implementation Specification and summarised in Section 4.11).
F
Conformance levels and versioning
An implementation MAY claim one of three levels.
29
Level
MUST support
ASPLite
One token; escrow mode; rung C; Appendix D vault; Appendix C scheme; E.1 routes /quotes, /charges, /charges/{id}, /charges/{id}/receipt, /charges/{id}/cancel, /charges/{id}/refund; one connector with the E.2 timeout rule; delegated Offer signing with version-based revocation; a single attestor grant; exposure reservation (Section 4.6); E.7 clock health and E.8 relayer records; Appendix B cases 1–17. ASP-Lite plus: multiple tokens under Invariant I1; distributor share (Proposition 2); all four rungs with an E.5 arbiter; the holdBeforeAuth path; E.6 webhooks; exposure controls with the Proposition 3 ceiling. ASP-Core plus: instant-reserve mode; on-chain hooks under P5; ERC-8004 identity; partial capture.
ASPCore ASPFull
Versioning: aspVersion is a single integer carried in every message. Additive changes (new optional fields, event types, error codes) do not bump it; any change to the EIP-712 struct layouts, the vault interface, or the meaning of an existing field MUST bump it, and a vault MUST reject authorizations whose EIP-712 domain version it does not implement. Fulfilment-class registries and connectors are versioned independently of the protocol. Conformance is demonstrated by running the executable suite that accompanies the reference implementation (asp-conformance, Section 9), which reports the number of Appendix B cases passed at the claimed level. Interoperability claim: two implementations at the same level that each pass Appendix B, expose Appendix D, and speak Appendix C SHOULD be able to exchange a buyer agent, a seller, or a connector without modification. Demonstrating this with two independent ASP-Lite implementations is part of the evaluation plan (Section 9).
References Saad Alqithami. Autonomous agents on blockchains: Standards, execution models, and trust boundaries. arXiv preprint arXiv:2601.04583, 2026. Anonymous. Free-riding the agentic web: A systematic security analysis of x402 payments. arXiv preprint arXiv:2605.30998, 2026. Author list to be verified against the arXiv record. Remco Bloemen, Leonid Logvinov, and Jacob Evans. Eip-712: Typed structured data hashing and signing. Ethereum Improvement Proposals, 2017. URL https://eips.ethereum.org/EIPS/eip-712. Scott Bradner. Key words for use in RFCs to indicate requirement levels. RFC 2119, IETF, 1997. URL https://www.rfc-editor.org/rfc/rfc2119. Vitalik Buterin, Yoav Weiss, Dror Tirosh, Shahaf Nacson, Alex Forshtat, Kristof Gazso, and Tjaden Hess. Erc-4337: Account abstraction using alt mempool. Ethereum Improvement Proposals, 2021. URL https://eips.ethereum.org/EIPS/eip-4337. Chain Agnostic Standards Alliance. Caip-2: Blockchain id specification, 2019. URL https://gith ub.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md.
30
Cloudflare. Launching the x402 foundation with coinbase, and support for x402 transactions. Cloudflare Blog, September 2025. URL https://blog.cloudflare.com/x402/. Coinbase and Shopify. Commerce payments protocol: Onchain authorization and capture for trust-minimized commerce. GitHub repository base/commerce-payments, 2025. URL https: //github.com/base/commerce-payments. ERC-8004 Authors. Erc-8004: Trustless agents. Ethereum Improvement Proposals, 2025. URL https://eips.ethereum.org/EIPS/eip-8004. IATA. New distribution capability (ndc) standard. International Air Transport Association, 2024. URL https://www.iata.org/en/programs/airline-distribution/retailing/ndc/. Leslie Lamport. Specifying systems: The TLA+ language and tools for hardware and software engineers, 2002. Qianlong Lan, Anuj Kaul, Shaun Jones, and Stephanie Westrum. Zero-trust runtime verification for agentic payment protocols: Mitigating replay and context-binding failures in AP2. arXiv preprint arXiv:2602.06345, 2026. Peter Lecoq. Eip-2612: Permit extension for eip-20 signed approvals. Ethereum Improvement Proposals, 2020. URL https://eips.ethereum.org/EIPS/eip-2612. Peter Lecoq and Yoav Fischer. Eip-3009: Transfer with authorization. Ethereum Improvement Proposals, 2020. URL https://eips.ethereum.org/EIPS/eip-3009. Yue Li, Lei Wang, Kaixuan Wang, Zhiqiang Yang, Ke Wang, Zhi Guan, and Jianbo Gao. A402: Binding cryptocurrency payments to service execution for agentic commerce. arXiv preprint arXiv:2603.01179, 2026. Linux Foundation. x402 transfers to the linux foundation, July 2026. https://xenospectrum.com/en/linux-foundation-x402-agent-payments/.
Press coverage:
Qian’ang Mao, Jiaxin Wang, Ya Liu, Li Zhu, Cong Ma, and Jiaqi Yan. SoK: Security of autonomous LLM agents in agentic commerce. arXiv preprint arXiv:2604.15367, 2026. OpenAPI Initiative. Openapi specification v3.1, 2021. URL https://spec.openapis.org/oas/v3.1.0. Xiaolin Pang, Kian-Lee Tan, Yong Wang, and Jian Ren. A secure agent-mediated payment protocol. In Information and Communications Security (ICICS), pages 422–433. Springer, 2002. Stavan Parikh and Rao Surapaneni. Powering ai commerce with the new agent payments protocol (ap2). Google Cloud Blog, 2025. URL https://cloud.google.com/blog/products/ai-machinelearning/announcing-agents-to-payments-ap2-protocol. Erik Reppel, Nemil Dalal, and Dan Kim. Introducing x402: a new standard for internet-native payments. Coinbase Developer Platform, 2025. URL https://www.coinbase.com/developerplatform/discover/launches/x402. Kenneth See and Xue Wen Tan. Compliance-aware agentic payments on stablecoin rails. arXiv preprint arXiv:2605.00071, 2026. Shopify Engineering. Engineering the commerce payments protocol, June 2025. URL https://shop ify.engineering/commerce-payments-protocol. Stripe and OpenAI. Agentic commerce protocol, 2025. URL https://www.agenticcommerce.dev/. 31
Uniswap Labs. Permit2. GitHub repository Uniswap/permit2, 2022. URL https://github.com/U niswap/permit2. Awid Vaziry, Sandro Rodriguez Garzon, and Axel Küpper. Towards multi-agent economies: Enhancing the A2A protocol with ledger-anchored identities and x402 micropayments for AI agents. arXiv preprint arXiv:2507.19550, 2025. J. S. Wang. AESP: A human-sovereign economic protocol for AI agents with privacy-preserving settlement. arXiv preprint arXiv:2603.00318, 2026. x402 Foundation. Payment schemes: exact, upto, and batch-settlement. x402 documentation, 2026. URL https://docs.x402.org/schemes/overview. x402r. x402r refund protocol: Escrow-backed refunds for x402 payments, 2026. URL https: //www.x402r.org/. XDC Network. Xdpos 2.0: Deterministic finality for the xdc network. XDC Network documentation, 2023. URL https://docs.xdc.network/. Xiaofan Xiong, Zhuo Li, Wenjie Wei, Qin Wang, William Knottenbelt, and Zhipeng Wang. Can trustless agents be trusted? an empirical study of the ERC-8004 decentralized AI agent ecosystem. arXiv preprint arXiv:2606.26028, 2026. Yuanzhe Zhang et al. SoK: Blockchain agent-to-agent payments. arXiv preprint arXiv:2604.03733, 2026. Author list to be verified against the arXiv record.
32
Related documents
- Agentic Settlement Protocol: An Application Profile for Refundable, Delayed-Fulfilment Agent Commerce on Stablecoin Rails#822601
- Augmented Backpressure for Decentralized Management of Agentic Networks#423905
- Fair Stable Matching: A Nash Social Welfare Approach#632893
- Agentic Transaction: Towards ACID-Compliant Agent Systems#458358
- Analysis of the effectiveness of the procurement and receipt process of goods in supporting retail store operations#459201
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive