draft-hopley-x402-cancellation-receipt (POSTED on IETF datatracker 2026-05-25, Independent Submission, Informational), and published as a standalone reference implementation:
- Python:
algovoi-cancellation-receipt(live on PyPI, v0.1.1)
algovoi-substrate / @algovoi/substrate for the JCS canonicalisation primitive. Apache 2.0.
Lifecycle position
urn:x402:canonicalisation:jcs-rfc8785-v1). A verifier walking the audit chain confirms admission → recurring execution → termination → (optional) refund under one byte-deterministic pin.
Why a four-state enumeration
Mandate termination is genuinely four-state. The regulatorily-load-bearing distinctions are:- Payer revocation under PSD2 (Directive 2015/2366) Article 64 + UK Consumer Rights Act 2015 — MAY trigger refund obligations on debits already settled prior to the effective date.
- Payee termination under PSD2 Article 72 + contractual terms — does NOT trigger consumer-revocation refund-window obligations on already-settled debits.
- Operator/compliance-forced termination (sanctions, KYC, AML, court order) — anchors POCA s.330 / AML 5+6 evidence chain back to the originating compliance event.
- Time-based expiry — mandate’s own terms terminated it. Standard record-keeping only.
PARTY_REQUESTED + AUTO_TERMINATED) loses the payer-vs-payee distinction that drives the PSD2 Article 64 refund-window obligation.
Receipt shape
A cancellation receipt is a seven-field JSON object canonicalised under RFC 8785 (JCS). Field names are sorted lexicographically by JCS during canonicalisation.The closed enumeration: cancellation_reason
Each value produces a byte-distinct
content_hash. Free-form “reason” strings or operator-internal codes are not acceptable substitutes.
Two timestamps
The cancellation receipt records two epoch-millisecond integer timestamps independently:cancellation_timestamp_ms— when the cancellation event was observed and recorded by the issuing provider.effective_from_ms— when the cancellation takes legal effect.
effective_from_ms >= cancellation_timestamp_ms. Implementations MUST reject receipts where the effective time precedes the recording time.
Composition
A cancellation receiptmandate_ref MAY reference a compliance receipt content_hash (the receipt that admitted the mandate). A USER_REQUESTED cancellation may chain forward to a refund receipt if PSD2 Article 64 refund is owed on a recently-settled debit:
Conformance vectors
8 byte-level reference vectors + 7 pair invariants + 3 chain invariants atvectors/cancellation_receipt_v1/.
The vector set pins:
- Closed four-element
cancellation_reasonenumeration — four byte-distinctcontent_hashvalues. jurisdiction_flagsarray order (RFC 8785 §3.2.3).canon_versionin-band pin.effective_from_ms >= cancellation_timestamp_msinvariant.mandate_refcontent-addressing (sha256:prefix retained in canonical bytes).- Audit chain row linkage via
prev_hash.
Quick start
TypeScript
What this is NOT
- Not a refund receipt. Cancellation records the termination of a mandate; refund records the reversal of a settled payment. When a USER_REQUESTED cancellation triggers a refund, both receipts are emitted and chained via the audit-chain.
- Not a dispute receipt. Disputes are state machines over multiple parties; cancellation is a single state transition.
- Not an attestation of mandate validity. The receipt records the termination of a previously-valid mandate; the mandate itself is specified elsewhere.
Companion IETF Internet-Draft
draft-hopley-x402-cancellation-receipt (Independent Submission, Informational). AlgoVoi-authored. Normatively references draft-hopley-x402-canonicalisation-jcs-v1. Welcomes downstream-adopter contributions per the established Appendix C “Known Adopters” pattern.
See also
- Canonicalisation substrate — the JCS discipline
- Settlement attestation — recurring-execution counterpart
- Refund receipt — post-cancellation refund counterpart
- Conformance vectors — full vector corpus
- Substrate authorship and provenance — citable AlgoVoi authorship record