| Internet-Draft | x402-settlement-attestation | May 2026 |
| Hopley | Expires 1 December 2026 | [Page] |
This document specifies a categorical settlement attestation format for agentic-payment flows. The format records that a payment has reached a particular settlement state on a particular chain, at a particular instant, under the attesting party's risk model.¶
The receipt format uses a closed enumeration of categorical outcomes (SETTLED, PENDING_FINALITY, REVERSED). The categorical outcome is load-bearing for downstream regulatory obligations: SETTLED triggers settlement-finality record-keeping obligations under EU Markets in Crypto-Assets Regulation Article 80 and Anti-Money Laundering Regulation Article 56; the PSD2 (Directive 2015/2366) Article 89 unauthorised-payment refund-window clock begins at SETTLED. PENDING_FINALITY records an inclusion-without-finality state where the refund-window has not yet started. REVERSED records chain-reorganisation, fraud-reversal, or operator-initiated reversal events for chain-of-custody audit.¶
The format is multi-chain: a single settlement_chain string field
identifies the chain on which settlement occurred, using a flat
identifier convention (<chain_family> for default mainnets,
<chain_family>:<network> for non-default networks). The receipt
does not encode chain-specific finality semantics; those are applied
at verification time by a verifier that knows the chain.¶
The format composes with the AlgoVoi-authored compliance receipt format (draft-hopley-x402-compliance-receipt) and refund receipt format (draft-hopley-x402-refund-receipt) under the same canonicalisation discipline (draft-hopley-x402-canonicalisation-jcs). A verifier walking the audit chain confirms the full payment lifecycle from admission through settlement to refund (or non-refund) under one byte-deterministic canonicalisation pin.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 1 December 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Agentic-payment flows generate three classes of categorical receipt across the payment lifecycle:¶
Settlement is the state transition at which a broadcast payment is considered final by the attesting party's risk model. The operational and regulatory significance is load-bearing:¶
A receipt format that collapses these distinctions to a binary "settled / not settled" or to a continuous "confirmation depth" representation loses the load-bearing operational distinction.¶
This document specifies a settlement attestation format that preserves the categorical outcome at the canonical-bytes level and records the settlement chain explicitly, enabling multi-chain operator audit trails under one canonicalisation discipline.¶
This document specifies:¶
This document does NOT specify:¶
settlement_chain; verifiers apply chain-specific
finality semantics (Algorand's deterministic instant finality,
Ethereum's probabilistic depth-based finality, Stellar's SCP,
etc.) at verification time.¶
settled_payment_ref or
via a separate audit-chain row.¶
settlement_amount.asset_id MAY differ from
the original payment asset) but the bridge mechanism is out of
scope.¶
This document normatively references:¶
This document is complementary to:¶
settled_payment_ref MAY equal the content_hash of a compliance
receipt.¶
original_payment_ref MAY equal the
content_hash of a settlement attestation under this document.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
settlement attestation: a JSON object of the shape specified in Section 3, canonicalised under the discipline of draft-hopley-x402-canonicalisation-jcs.¶
content_hash: SHA-256, lowercase hex, of the JCS-canonical bytes of the attestation object.¶
settled_payment_ref: a string of the form
sha256:<lowercase-hex-64> identifying the payment record being
settled by content hash. The original record MAY be a compliance
receipt, an operator-specific payment authorisation record, or a
cryptographic settlement proof.¶
settlement_chain: a string identifier for the chain on which settlement occurred. See Section 3.5.¶
settlement_amount: a two-field object {amount_minor, asset_id}
representing the settled value.¶
canon_version: an in-band string identifying the canonicalisation
discipline. Fixed value jcs-rfc8785-v1 for this version.¶
A settlement attestation is a JSON object with the following eight fields. All fields are REQUIRED. The attestation is canonicalised under draft-hopley-x402-canonicalisation-jcs per Section 4. Field names are sorted lexicographically by JCS during canonicalisation; the object itself uses arbitrary authoring order.¶
A string-valued field. The value MUST be one of:¶
SETTLED -- payment confirmed on-chain with sufficient finality
for the operator's risk model. Funds transferred and irreversible
under normal chain operation.¶
PENDING_FINALITY -- payment broadcast and included in a block,
awaiting the operator's required confirmation depth. Operator
has visibility of inclusion but does not yet assert finality.¶
REVERSED -- payment previously SETTLED is now considered
reversed (chain reorganisation, fraud reversal, double-spend
resolution, operator-initiated under regulatory directive).¶
The three-element enumeration is closed. Implementations MUST reject any other value at validation time before canonicalisation. Score, depth, or confirmation-count representations are not acceptable substitutes for the categorical outcome.¶
The regulatory distinction is load-bearing. Under MiCA Article 80, settlement-finality records must be retained and re-verifiable; SETTLED is the operational state that triggers this obligation. Under PSD2 Article 89, refund-window timing is tied to settled state. Under AML Directives 5 and 6, reversed transactions require documented evidence chains independent of the original settlement.¶
An ordered array of string-valued ISO-3166-1 alpha-2 country codes or alpha-3 region codes identifying the applicable regulatory frameworks for the settlement event.¶
Authoring convention: primary jurisdiction first (where the operating entity is licensed), secondary jurisdictions in order of regulatory precedence.¶
Array element ORDER is SIGNIFICANT and load-bearing per draft-hopley-x402-canonicalisation-jcs Section 4.3.¶
A string-valued field of the form sha256:<lowercase-hex-64>. The
hex digest is SHA-256 of the JCS-canonical bytes of the payment
record being settled.¶
When settling a payment that was admitted under a compliance
receipt (per draft-hopley-x402-compliance-receipt), the
settled_payment_ref MAY equal the content_hash of the
compliance receipt itself. This is the conventional choice and
enables the audit-chain composition described in Section 5.¶
When the original payment record is an operator-specific format
(payment authorisation, mandate, settlement proof, etc.), the
settled_payment_ref is the SHA-256 of that record's
JCS-canonical bytes.¶
Implementations MUST NOT strip the sha256: prefix during
canonicalisation or verification.¶
A sub-object with exactly two fields:¶
amount_minor -- a string of decimal digits representing the
settled value in the asset's minor unit. String typing avoids
float-precision loss and JavaScript-integer-overflow concerns for
large values.¶
asset_id -- a string identifying the asset and its decimal
precision. Convention: <symbol>.<decimals> for chain-native
assets (e.g. USDC.6, ALGO.6, ETH.18); <chain>:<asset_id>.<decimals>
for ASA-style assets (e.g. algo:31566704.6).¶
The sub-object's keys are sorted lexicographically by RFC 8785
during canonicalisation: amount_minor then asset_id.¶
Cross-asset substitution is permitted. When settlement is in a
different asset than the original payment (e.g. paid USDC on Base,
settled USDC on Solana via a bridge), settlement_amount.asset_id
reflects the SETTLED asset, not the original. The equivalence-of-value
claim across the substitution is operator-layer and out of scope.¶
A string-valued field identifying the chain on which settlement occurred. The string is in one of two forms:¶
Default mainnet of a chain family: <chain_family>. Examples:¶
Non-default network of a chain family: <chain_family>:<network>.
Examples:¶
The string is case-sensitive at the JCS layer. Implementations
SHOULD canonicalise to lowercase before emission. Verifiers MUST
treat Ethereum:8453 and ethereum:8453 as distinct canonical
bytes per RFC 8785.¶
The receipt does not decompose the chain identifier into a sub-object. Operators requiring richer chain metadata (block height, confirmation count, validator quorum at settlement time) MUST emit those as separate operator-layer audit records, not as nested fields in this receipt.¶
A string-valued DID URI identifying the entity attesting settlement (gateway, facilitator, oracle, or operator).¶
An integer-valued field carrying the epoch-millisecond timestamp of the settlement event in UTC.¶
This field MUST be an integer. RFC 3339 string forms (e.g.
"2026-05-30T12:00:00Z") MUST be rejected at the validation layer
before canonicalisation. This is Substrate Rule 2, normatively
specified in draft-hopley-x402-canonicalisation-jcs Section 4.1.¶
A string-valued in-band canonicalisation rule pin. For this version
of the receipt format the value MUST be jcs-rfc8785-v1.¶
The settlement attestation MUST be canonicalised under the discipline pinned by draft-hopley-x402-canonicalisation-jcs and identified by the URN:¶
urn:x402:canonicalisation:jcs-rfc8785-v1¶
The full normative specification of the discipline (JCS RFC 8785 plus the schema-normalisation requirements including Substrate Rule 2) is in that document. This document does not redefine the discipline inline.¶
A settlement attestation MAY participate in an audit chain alongside compliance receipts, refund receipts, and other receipt classes that pin the same canonicalisation discipline.¶
The audit chain row shape used by this document is identical to that specified in draft-hopley-x402-compliance-receipt Section 5.1 and draft-hopley-x402-refund-receipt Section 5.1:¶
{
"row_number": 1,
"content_hash": "<hex64>",
"prev_hash": "<hex64>",
"row_content_hash": "<hex64>"
}
¶
Row 1's prev_hash MUST be 64 zero hex characters. Row N's
prev_hash MUST equal row N-1's row_content_hash.¶
Per draft-hopley-x402-compliance-receipt Section 5.2: a verifier
reading a chain segment recomputes each row's row_content_hash
from its first three fields and confirms forward linkage via
prev_hash. Any mismatch indicates tampering or chain integrity
loss.¶
When a settlement attestation references a compliance receipt via
settled_payment_ref, the audit-chain composition is:¶
chain row N chain row N+1 +------------+ +-------------+ | compliance |-->| settlement | | receipt | | attestation | | (ALLOW) | | (SETTLED) | +------------+ +-------------+¶
Row N anchors the compliance receipt. Row N+1 anchors the
settlement attestation. The settlement attestation's
settled_payment_ref equals row N's content_hash. Chain
linkage via prev_hash confirms ordering.¶
When a settled payment is subsequently refunded, the refund
receipt's original_payment_ref MAY equal the content_hash of
the settlement attestation. The chain extends:¶
chain row N+1 chain row N+2 +-------------+ +------------+ | settlement |->| refund | | attestation | | receipt | | (SETTLED) | | (FULL) | +-------------+ +------------+¶
A verifier walking the full chain confirms admission -> settlement -> refund under one canonicalisation pin.¶
The same six properties pinned by draft-hopley-x402-canonicalisation-jcs Section 5 apply to the settlement attestation:¶
canon_version.¶
content_hash and chain prev_hash
linkage.¶
Plus one settlement-specific property:¶
settlement_chain string identifies which chain's finality
model applies. A verifier years after the event can apply the
correct chain-specific finality semantics to re-evaluate the
original SETTLED claim against retained chain state (block
height, confirmation depth, etc.).¶
See Section 5.3. The conventional settled_payment_ref target for
an admission-then-settlement flow is the content_hash of the
compliance receipt that admitted the original payment.¶
See Section 5.4. A refund receipt's original_payment_ref MAY
equal a settlement attestation content_hash rather than the
underlying compliance receipt, producing a precise
"the settled payment was reversed" audit trail.¶
Cryptographically-strong settlement proofs (post-quantum proofs of payment conditions, validator signatures, STARK proofs of inclusion, etc.) are orthogonal to the categorical settlement attestation specified by this document. The two layers compose:¶
Both MAY be retained alongside one another, or chained via
settled_payment_ref references, depending on operator
requirements.¶
This document references the URN
urn:x402:canonicalisation:jcs-rfc8785-v1 registered by
draft-hopley-x402-canonicalisation-jcs Section 10.1. No additional
URN namespace registration is required by this document.¶
This document defines the receipt format identifier:¶
urn:x402:receipt:settlement-attestation-v1¶
This identifier MAY be used by composite-trust-query implementations
to refer to settlement attestations as a class. Registration with
IANA is requested under the x402 URN namespace.¶
A settlement attestation's content_hash is the SHA-256 of its
JCS-canonical bytes. Tampering with any field produces a different
hash; the tampered attestation fails verification against any
audit-chain row referencing the original content_hash.¶
A SETTLED attestation may later become incorrect if the underlying chain reorganises and the settled transaction is no longer canonical. The REVERSED outcome records this event. Operators SHOULD emit a REVERSED attestation when a previously SETTLED state is invalidated; the audit chain extends rather than overwrites.¶
A malicious operator could emit a SETTLED attestation for a payment that never reaches chain-finality, then fail to emit the corresponding REVERSED. Detection is verifier-side: a verifier SHOULD periodically re-check chain state against retained SETTLED attestations and flag discrepancies.¶
The settlement_chain field is operator-asserted. A verifier MUST
NOT trust the chain identifier alone; verification against actual
chain state (via the verifier's own chain client) is required to
confirm settlement.¶
When settlement_amount.asset_id differs from the original payment
asset, the equivalence-of-value claim is operator-asserted. A
verifier cannot determine equivalence from the receipt alone;
external evidence (price oracle attestations at settlement time,
bridge proofs) is required and out of scope of this document.¶
If the original attesting operator becomes unavailable, the audit chain and its attestations MUST remain independently verifiable from retained bytes plus the reference implementations cited in draft-hopley-x402-canonicalisation-jcs Section 7.¶
{
"canon_version": "jcs-rfc8785-v1",
"jurisdiction_flags": ["UK", "EU"],
"settled_payment_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f",
"settlement_amount": {"amount_minor": "100000", "asset_id": "USDC.6"},
"settlement_chain": "ethereum:8453",
"settlement_provider_did": "did:web:api.algovoi.co.uk",
"settlement_result": "SETTLED",
"settlement_timestamp_ms": 1716494400000
}
¶
Records that 0.1 USDC was settled on Base mainnet (chainId 8453)
under joint UK + EU jurisdiction. The PSD2 Article 89 refund-window
clock begins at settlement_timestamp_ms. MiCA Article 80 record-
keeping obligations apply to retention of this attestation.¶
{
"canon_version": "jcs-rfc8785-v1",
"jurisdiction_flags": ["UK"],
"settled_payment_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f",
"settlement_amount": {"amount_minor": "100000", "asset_id": "USDC.6"},
"settlement_chain": "algo",
"settlement_provider_did": "did:web:api.algovoi.co.uk",
"settlement_result": "PENDING_FINALITY",
"settlement_timestamp_ms": 1716494400000
}
¶
Records broadcast-and-inclusion on Algorand mainnet without yet asserting operator-required confirmation depth.¶
{
"canon_version": "jcs-rfc8785-v1",
"jurisdiction_flags": ["UK", "EU"],
"settled_payment_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f",
"settlement_amount": {"amount_minor": "100000", "asset_id": "USDC.6"},
"settlement_chain": "ethereum:1",
"settlement_provider_did": "did:web:api.algovoi.co.uk",
"settlement_result": "REVERSED",
"settlement_timestamp_ms": 1716494400000
}
¶
Records that a previously SETTLED payment on Ethereum mainnet is now considered reversed. The audit chain extends with this row; the prior SETTLED row remains as historical record.¶
The following open-source implementations conform to this format:¶
algovoi-settlement-attestation (Python) on PyPI:
target="https://pypi.org/project/algovoi-settlement-attestation/"
Provides build_settlement_attestation(). Depends on
algovoi-substrate for the JCS canonicalisation primitive.
Apache 2.0 licensed.¶
@algovoi/settlement-attestation (TypeScript) on npm: target="https://www.npmjs.com/package/@algovoi/settlement-attestation" Byte-for-byte parity with the Python sibling. Depends on @algovoi/substrate for the JCS canonicalisation primitive. Apache 2.0 licensed.¶
Conformance vectors:¶
https://github.com/chopmob-cloud/algovoi-jcs-conformance-vectors/tree/main/vectors/settlement_attestation_v1¶
8 byte-level reference vectors + 5 pair invariants + 3 chain invariants pinning the closed-enumeration, jurisdiction-array-order, canon_version pin, and audit-chain linkage properties.¶
This document, the receipt format it specifies, and the conformance vectors derived from it are AlgoVoi work under sole AlgoVoi authorship. Substrate authorship history is catalogued at target="https://docs.algovoi.co.uk/substrate-authorship-provenance".¶
The canonicalisation discipline pinned by Section 4 is normatively specified in draft-hopley-x402-canonicalisation-jcs under the same authorship.¶
This document closes the lifecycle gap between the admission-time compliance receipt format (draft-hopley-x402-compliance-receipt) and the post-settlement refund receipt format (draft-hopley-x402-refund-receipt). The three formats share the same canonicalisation pin, audit-chain row shape, and integer- millisecond timestamp encoding so that a verifier walking the full payment lifecycle requires only one implementation of the canonicalisation discipline.¶
The author acknowledges Anders Rundgren as the editor of RFC 8785, the JSON Canonicalization Scheme on which the discipline builds.¶