| Internet-Draft | x402-cancellation-receipt | May 2026 |
| Hopley | Expires 1 December 2026 | [Page] |
This document specifies a categorical mandate cancellation receipt format for agentic-payment flows. The format records that a recurring-payment mandate or other standing payer-to-payee authorisation has been cancelled, by whom, for what reason, and with what effective date.¶
The receipt format uses a closed four-element enumeration of categorical outcomes (USER_REQUESTED, MERCHANT_REQUESTED, COMPLIANCE_TERMINATED, EXPIRED). The four-state enumeration preserves the regulatorily-load-bearing distinction between payer-initiated revocation, payee-initiated termination, operator/compliance-forced termination, and time-based expiry. A collapse to a three-state or binary representation loses operational distinctions that drive PSD2 (Directive 2015/2366) Article 64 refund-window obligations, Article 72 contractual-termination record-keeping, and POCA/AML evidence-chain linkage on compliance-forced terminations.¶
The format records two distinct timestamps -- when the cancellation
was observed (cancellation_timestamp_ms) and when it takes legal
effect (effective_from_ms) -- to support PSD2 Article 64(3)(a)
direct-debit revocation timing, where the effective time is typically
end-of-business-day prior to the next scheduled execution.¶
The format composes with the AlgoVoi-authored compliance receipt (draft-hopley-x402-compliance-receipt), settlement attestation (draft-hopley-x402-settlement-attestation), and refund receipt (draft-hopley-x402-refund-receipt) formats under the same canonicalisation discipline (draft-hopley-x402-canonicalisation-jcs). A verifier walking the audit chain confirms the full mandate lifecycle from admission through recurring execution to cancellation, and (where owed) onward to refund of revoked settled debits, 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 categorical receipts across the mandate lifecycle. Where the compliance receipt format (draft-hopley-x402-compliance-receipt) admits a mandate and the settlement attestation format (draft-hopley-x402-settlement-attestation) records recurring executions, mandate termination is the corresponding end-state. Termination is not a degenerate refund; it is its own state transition with its own regulatory consequences.¶
The operational and regulatory distinctions are load-bearing across four genuinely-different states:¶
A receipt format that collapses these to a three-state enumeration (e.g. PARTY_REQUESTED + AUTO_TERMINATED) loses the payer-vs-payee distinction that drives the PSD2 Article 64 refund-window obligation. A collapse to two-state (CANCELLED / EXPIRED) loses both that distinction and the compliance-forced flag that anchors the AML/POCA evidence chain.¶
This document specifies a cancellation receipt format that preserves the four-state categorical outcome at the canonical-bytes level and records the two timestamps (event recording time and legal effective time) independently.¶
This document specifies:¶
This document does NOT specify:¶
mandate_ref of the form
sha256:<hex>. The mandate record MAY be a compliance receipt,
an Agent Payment Protocol (AP2) mandate object, a Merchant
Payment Protocol (MPP) subscription record, or any
operator-specific mandate format.¶
cancellation_reason) whether a refund obligation may apply.¶
This document normatively references:¶
This document is complementary to:¶
mandate_ref MAY
equal the content_hash of the compliance receipt that admitted
the mandate.¶
original_payment_ref MAY reference
a settlement attestation that became refundable as a result of a
USER_REQUESTED cancellation recorded 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.¶
cancellation receipt: 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 cancellation receipt object.¶
mandate_ref: a string of the form sha256:<lowercase-hex-64>
identifying the mandate record being cancelled by content hash. The
mandate record itself is out of scope of this document.¶
cancellation_reason: a string-valued field carrying one of four closed enumeration values. See Section 3.1.¶
canon_version: an in-band string identifying the canonicalisation
discipline. Fixed value jcs-rfc8785-v1 for this version.¶
A cancellation receipt is a JSON object with the following seven fields. All fields are REQUIRED. The receipt 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:¶
USER_REQUESTED -- the payer revoked the mandate. PSD2 Article 64
applies. UK Consumer Rights Act 2015 consumer-revocation
provisions apply. Triggers payer-side refund-window calculations
for direct debits already settled prior to the effective date.¶
MERCHANT_REQUESTED -- the payee terminated the recurring
billing arrangement. PSD2 Article 72 and contractual terms apply.
Does NOT trigger consumer-revocation refund-window obligations
on already-settled debits.¶
COMPLIANCE_TERMINATED -- the operator (gateway, facilitator,
bank, regulator) forced termination from a post-mandate
compliance trigger: sanctions hit on payer, KYC failure, AML
alert, court order, regulator directive. Triggers POCA s.330 and
AML 5+6 audit-chain linkage back to the originating compliance
event.¶
EXPIRED -- the mandate reached its agreed end-date or
maximum-execution count. No party-initiated decision; the
mandate's own terms terminated it. Standard record-keeping only.¶
The four-element enumeration is closed. Implementations MUST reject any other value at validation time before canonicalisation. Free-form "reason" strings, dispute codes, or operator-internal classification labels are not acceptable substitutes for the categorical outcome.¶
The regulatory distinction is load-bearing. The four-value enumeration is one wider than the three-value enums in sibling formats because the regulatorily-load-bearing distinctions in mandate termination are genuinely four-state: payer vs payee vs operator vs time.¶
A string-valued DID URI identifying the entity issuing the cancellation receipt (gateway, facilitator, payer-bank, operator).¶
An integer-valued field carrying the epoch-millisecond timestamp at which the cancellation event was observed and recorded by the issuing provider, 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.¶
An integer-valued field carrying the epoch-millisecond timestamp at which the cancellation takes legal effect, in UTC.¶
effective_from_ms MUST be greater than or equal to
cancellation_timestamp_ms. Implementations MUST reject receipts
where the effective time precedes the recording time, both at
validation time and at verification time.¶
For most cancellations the two timestamps are equal. The independent encoding supports PSD2 Article 64(3)(a) direct-debit revocation timing, where the agreed effective time is typically the end of the working day before the next scheduled execution -- distinct from the moment the revocation was recorded.¶
For COMPLIANCE_TERMINATED outcomes the effective time MAY be immediate (equal to the recording time) or scheduled (regulator-directed future effective date).¶
Substrate Rule 2 applies: integer-only, RFC 3339 string forms rejected.¶
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 cancellation 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 mandate
record being cancelled.¶
When the mandate was admitted under a compliance receipt (per
draft-hopley-x402-compliance-receipt), the mandate_ref MAY equal
the content_hash of that compliance receipt. This is the
conventional choice and enables the audit-chain composition
described in Section 5.¶
When the original mandate record is an operator-specific format
(AP2 mandate object, MPP subscription record, custom recurring
authorisation), the mandate_ref is the SHA-256 of that record's
JCS-canonical bytes.¶
Implementations MUST NOT strip the sha256: prefix during
canonicalisation or verification.¶
A string-valued in-band canonicalisation rule pin. For this version
of the receipt format the value MUST be jcs-rfc8785-v1.¶
The cancellation receipt 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 cancellation receipt MAY participate in an audit chain alongside compliance receipts, settlement attestations, 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 reused by the settlement attestation (draft-hopley-x402-settlement-attestation) and refund receipt (draft-hopley-x402-refund-receipt) formats. The row shape is:¶
{
"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 cancellation receipt references a compliance receipt via
mandate_ref, the audit-chain composition is:¶
chain row N chain row N+1 +------------+ +---------------+ | compliance |-->| cancellation | | receipt | | receipt | | (ALLOW) | | (USER_REQ) | +------------+ +---------------+¶
Row N anchors the compliance receipt admitting the mandate. Row N+1
anchors the cancellation receipt. The cancellation receipt's
mandate_ref equals row N's content_hash. Chain linkage via
prev_hash confirms ordering.¶
For mandates with intervening recurring executions, settlement attestations occupy rows between the compliance receipt and the cancellation receipt:¶
chain row N chain row N+1 chain row N+2 chain row N+3
+------------+ +-------------+ +-------------+ +---------------+
| compliance |-->| settlement |-->| settlement |->| cancellation |
| receipt | | attestation | | attestation | | receipt |
| (ALLOW) | | (SETTLED) | | (SETTLED) | | (USER_REQ) |
+------------+ +-------------+ +-------------+ +---------------+
row N row N+1 row N+2 row N+3
¶
A verifier walking the chain confirms the full mandate lifecycle under one canonicalisation pin.¶
When a USER_REQUESTED cancellation triggers a refund obligation under PSD2 Article 64 (refund of a recently-settled debit that predated the cancellation but post-dated the effective revocation window), a refund receipt MAY follow:¶
chain row N+3 chain row N+4 +---------------+ +------------+ | cancellation |--->| refund | | receipt | | receipt | | (USER_REQ) | | (FULL) | +---------------+ +------------+¶
The refund receipt's original_payment_ref references the
settlement attestation being refunded (not the cancellation
receipt). The cancellation receipt is the chain-evidence anchor
that establishes why the refund is owed.¶
The same six properties pinned by draft-hopley-x402-canonicalisation-jcs Section 5 apply to the cancellation receipt:¶
canon_version.¶
content_hash and chain prev_hash
linkage.¶
Plus one cancellation-specific property:¶
mandate_ref), (b) who
cancelled it (via the combination of cancellation_reason and
cancellation_provider_did), (c) when the cancellation was
recorded (cancellation_timestamp_ms), and (d) when it became
effective (effective_from_ms), without dependence on the
issuing operator's continued operation.¶
See Section 5.3. The conventional mandate_ref target for a
mandate admitted under a compliance receipt is the content_hash
of that compliance receipt.¶
See Section 5.4. Settlement attestations recording recurring
executions occupy chain rows between the admission and the
cancellation. The cancellation receipt does not reference
individual settlement attestations directly; chain linkage via
prev_hash establishes ordering.¶
See Section 5.5. A USER_REQUESTED cancellation MAY be followed in the chain by a refund receipt if PSD2 Article 64 refund obligations attach to a recently-settled debit.¶
This document does not encode:¶
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:cancellation-receipt-v1¶
This identifier MAY be used by composite-trust-query implementations
to refer to cancellation receipts as a class. Registration with
IANA is requested under the x402 URN namespace.¶
A cancellation receipt's content_hash is the SHA-256 of its
JCS-canonical bytes. Tampering with any field produces a different
hash; the tampered receipt fails verification against any
audit-chain row referencing the original content_hash.¶
The two-timestamp design (cancellation_timestamp_ms recording
event time, effective_from_ms recording legal effective time)
admits a class of attack where a malicious operator emits a
receipt at time T with effective_from_ms set to a past
timestamp T' < T, to retroactively void a debit that has already
settled.¶
Mitigation is verifier-side: a verifier MUST cross-check the
cancellation_timestamp_ms against operator-emission-time
evidence (TLS log, audit-chain prev_hash of the row recording
this receipt, external timestamping service) before accepting a
claimed effective time in the past.¶
The effective_from_ms >= cancellation_timestamp_ms invariant
required by Section 3.4 prevents the simpler attack of stamping
the recording time in the past, but does not by itself prevent
all backdating attacks.¶
A malicious operator could emit a MERCHANT_REQUESTED receipt for
what was actually a USER_REQUESTED cancellation, to avoid the
PSD2 Article 64 refund-window obligation. Detection requires
out-of-band evidence (payer complaint, payer-side log, regulator
inspection). The cancellation_provider_did identifies the
attesting party, supporting accountability.¶
A COMPLIANCE_TERMINATED receipt records that a compliance trigger fired against the payer. Such a receipt MAY contain indirectly-disclosing information: the existence of the cancellation under that reason, combined with public sanctions listing dates, MAY reveal that the payer was placed on a sanctions list.¶
Implementations SHOULD restrict access to COMPLIANCE_TERMINATED receipts to parties with a legitimate audit interest (regulator, auditor, court order). Public disclosure of such receipts is NOT in scope of this document.¶
If the original attesting operator becomes unavailable, the audit chain and its cancellation receipts 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",
"cancellation_provider_did": "did:web:api.algovoi.co.uk",
"cancellation_reason": "USER_REQUESTED",
"cancellation_timestamp_ms": 1716494400000,
"effective_from_ms": 1716537600000,
"jurisdiction_flags": ["UK", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
¶
Records a payer-initiated revocation under PSD2 Article 64 with effective time set to end-of-business-day prior to the next scheduled execution per Article 64(3)(a). If a debit already settled within the recoverable window prior to the effective date, a refund receipt MAY follow.¶
{
"canon_version": "jcs-rfc8785-v1",
"cancellation_provider_did": "did:web:api.algovoi.co.uk",
"cancellation_reason": "MERCHANT_REQUESTED",
"cancellation_timestamp_ms": 1716494400000,
"effective_from_ms": 1716537600000,
"jurisdiction_flags": ["UK", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
¶
Records payee-initiated termination of the recurring billing arrangement. Does not trigger the Article 64 refund-window obligation on already-settled debits.¶
{
"canon_version": "jcs-rfc8785-v1",
"cancellation_provider_did": "did:web:api.algovoi.co.uk",
"cancellation_reason": "COMPLIANCE_TERMINATED",
"cancellation_timestamp_ms": 1716494400000,
"effective_from_ms": 1716494400000,
"jurisdiction_flags": ["UK", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
¶
Records immediate operator-forced termination. Effective time equals recording time. Anchors POCA s.330 and AML 5+6 audit-chain linkage back to the originating compliance receipt (a separate record).¶
{
"canon_version": "jcs-rfc8785-v1",
"cancellation_provider_did": "did:web:api.algovoi.co.uk",
"cancellation_reason": "EXPIRED",
"cancellation_timestamp_ms": 1716494400000,
"effective_from_ms": 1716494400000,
"jurisdiction_flags": ["UK", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
¶
Records time-based expiry of the mandate. Standard record-keeping only; no further regulatory action attaches.¶
The following open-source implementations conform to this format:¶
algovoi-cancellation-receipt (Python) on PyPI:
target="https://pypi.org/project/algovoi-cancellation-receipt/"
Provides build_cancellation_receipt(). Depends on
algovoi-substrate for the JCS canonicalisation primitive.
Apache 2.0 licensed.¶
@algovoi/cancellation-receipt (TypeScript) on npm: target="https://www.npmjs.com/package/@algovoi/cancellation-receipt" 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/cancellation_receipt_v1¶
8 byte-level reference vectors + 7 pair invariants + 3 chain invariants pinning the closed four-element enumeration, jurisdiction-array-order, canon_version pin, effective-time-greater-equal-recording-time invariant, and audit-chain linkage properties.¶
The following downstream parties have published artefacts that anchor to the cancellation receipt format specified by this document, or to the canonicalisation discipline shared with this format. Inclusion in this list is informational and reflects public adoption only; it does not imply endorsement or normative authority from the listed party.¶
| Adopter | Surface | Anchor |
|---|---|---|
AlgoVoi (api.algovoi.co.uk) |
Production mandate-lifecycle issuer | All AlgoVoi-emitted cancellation receipts under canon_version: jcs-rfc8785-v1
|
Adopters publishing vector sets or receipt-format extensions that
anchor to this format are encouraged to publish them in
adopter-controlled repositories with canon_version recorded
in-band, so each adopter's authorship is unambiguous and their
artefact is independently citable.¶
This appendix is maintained as a record of observed adoption at the time of revision; absence from this list is not normative.¶
This document, the receipt format it specifies, and the conformance vectors derived from it are AlgoVoi work under 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 (draft-hopley-x402-compliance-receipt), per-execution settlement attestation (draft-hopley-x402-settlement-attestation), and post-cancellation refund receipt (draft-hopley-x402-refund-receipt) formats. The four formats share the same canonicalisation pin, audit-chain row shape, and integer-millisecond timestamp encoding, so that a verifier walking the full mandate 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.¶