Skip to content

docs(ap2): add Payment Lifecycle - AlgoVoi-authored cancellation and refund attestation envelopes (PSD2 Articles 64 and 89)#270

Open
chopmob-cloud wants to merge 7 commits into
google-agentic-commerce:mainfrom
chopmob-cloud:docs-ap2-payment-lifecycle
Open

docs(ap2): add Payment Lifecycle - AlgoVoi-authored cancellation and refund attestation envelopes (PSD2 Articles 64 and 89)#270
chopmob-cloud wants to merge 7 commits into
google-agentic-commerce:mainfrom
chopmob-cloud:docs-ap2-payment-lifecycle

Conversation

@chopmob-cloud
Copy link
Copy Markdown

@chopmob-cloud chopmob-cloud commented May 28, 2026

Summary

Adds the Payment Lifecycle specification to the AP2 documentation
set, documenting the two canonical AlgoVoi-authored attestation
envelopes for the post-settlement state transitions of a Payment
Mandate:

  • Cancellation Receipt - PSD2 Article 64. Closed four-element
    cancellation_reason enumeration:
    USER_REQUESTED / MERCHANT_REQUESTED / COMPLIANCE_TERMINATED / EXPIRED.
  • Refund Receipt - PSD2 Article 89. Closed three-element
    refund_result enumeration: FULL / PARTIAL / REJECTED.

Both formats are AlgoVoi-authored seven-field JSON objects canonicalised
under RFC 8785 (JCS) with SHA-256 binding to the original Payment Mandate.

AP2 references both formats; AP2 does not redefine them. The wire
formats match the canonical AlgoVoi specifications on IETF datatracker
(draft-hopley-x402-cancellation-receipt,
draft-hopley-x402-refund-receipt) and the live documentation at
docs.algovoi.co.uk/cancellation-receipt and /refund-receipt.

Single new file at docs/ap2/payment_lifecycle.md. No changes to
existing spec files. No code changes. No samples.

Why AP2 needs this

AP2 today specifies the Cart Mandate, Payment Mandate, and Agent
Authorization primitives covering the pre-settlement and settlement
phases of a transaction. It does not document the post-settlement
lifecycle: cancellation and refund.

PSD2 Article 64 (right to revoke a payment authorisation) and PSD2
Article 89 (refund obligations) impose regulatory requirements on real
payment systems that AP2 does not currently address. Without a
canonical attestation format, every party records these state
transitions in a bespoke shape, breaking the property that a Shopping
Agent or downstream relying party can confirm that a post-settlement
state transition occurred by hashing a fixed-shape JSON object.

This PR closes the gap by referencing the AlgoVoi-authored formats
(already in production, on IETF datatracker, with reference
implementations on PyPI and npm) and documenting how they compose with
AP2's Payment Mandate primitive.

Production reference

Both formats are emitted in production by the AlgoVoi platform:

  • Cancellation Receipts: emitted by the AlgoVoi recurring-payments
    service (recurr.algovoi.co.uk),
    live since May 2026.
  • Refund Receipts: emitted by the AlgoVoi Merchant Payment Processor
    facilitator (live API surface at
    api.algovoi.co.uk/openapi.json),
    live since May 2026.

This is not a theoretical proposal. Both formats have been emitting
receipts against live production traffic across eight chain families.

Authorship and substrate-author position

This PR is sole AlgoVoi authorship across the documented formats (both
receipt types), normative seven-field shapes, closed enumerations
(four-element cancellation_reason, three-element refund_result),
regulatory mappings, state machine, and the composition with the
AlgoVoi-authored canonicalisation pin
(urn:x402:canonicalisation:jcs-rfc8785-v1 per IETF I-D
draft-hopley-x402-canonicalisation-jcs-v1).

Companion IETF Internet-Drafts:

Reference implementations, AlgoVoi-authored, Apache 2.0:

The canonicalisation layer underneath both formats is byte-for-byte
cross-validated across eight independent implementations (Python,
TypeScript, Go, Rust, Java, PHP, .NET, Ruby) per the AlgoVoi 8-impl
matrix. Conformance corpus:
chopmob-cloud/algovoi-jcs-conformance-vectors.

Both enumerations are closed by design and may be amended only by
a normative successor specification authored by AlgoVoi or with
explicit AlgoVoi co-authorship. Re-publication of either format under
a different attribution does not constitute substrate authorship of
the elements defined here.

No coalition acknowledgements. This specification does not absorb
from, depend on, or share authorship with any other party's work.

Orthogonality

This specification defines the verdict formats at the post-settlement
payment-lifecycle
layer. It is orthogonal to the admission-time
compliance verdict format (covered by the sibling AlgoVoi-authored
Compliance Receipt PR), counterparty-risk evidence formats,
settlement-attestation formats, and behavioural reputation,
trust-scoring, or composable trust evidence formats proposed elsewhere.
The cancellation and refund receipts make no claims about, and depend
on no fields from, any of the above.

Scope

Single new file at docs/ap2/payment_lifecycle.md. No changes to
existing spec files. No code changes. No samples. The .cspell/custom-words.txt
addition is project-specific cspell vocabulary for British orthography
matching the IETF I-Ds.

-- AlgoVoi (chopmob-cloud)
https://docs.algovoi.co.uk/acquisition

…refund attestation envelopes (PSD2 Articles 64 and 89)

Documents the two canonical AlgoVoi-authored attestation envelopes for
the post-settlement state transitions of a Payment Mandate:

- Cancellation Receipt (closed four-element cancellation_reason enum:
  USER_REQUESTED / MERCHANT_REQUESTED / COMPLIANCE_TERMINATED / EXPIRED)
  per PSD2 Article 64.
- Refund Receipt (closed three-element refund_result enum: FULL /
  PARTIAL / REJECTED) per PSD2 Article 89.

Both formats are AlgoVoi-authored seven-field JSON objects canonicalised
under RFC 8785 (JCS) with SHA-256 binding to the original Payment
Mandate. AP2 references both formats; AP2 does not redefine them. Wire
formats match draft-hopley-x402-cancellation-receipt and
draft-hopley-x402-refund-receipt on IETF datatracker.

Adds project-specific words to .cspell/custom-words.txt for British
orthography matching the IETF I-Ds.

Single new file at docs/ap2/payment_lifecycle.md. No changes to existing
spec files. No code changes. No samples.
@chopmob-cloud chopmob-cloud requested a review from a team as a code owner May 28, 2026 12:05
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new documentation file, docs/ap2/payment_lifecycle.md, which specifies the post-settlement state transitions of a Payment Mandate (Cancellation Receipt and Refund Receipt) under RFC 8785 (JCS) canonicalisation. It also updates .cspell/custom-words.txt with several new custom words. The review feedback points out that the JSON example and field table for the Cancellation Receipt are not sorted lexicographically, which contradicts the text and is inconsistent with other tables. Additionally, several newly added custom words in .cspell/custom-words.txt are out of order relative to the file's casing convention.

Comment on lines +45 to +53
{
"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": ["GB", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The JSON example for the Cancellation Receipt is not sorted lexicographically by keys, which contradicts the statement on line 41: "Field names are sorted lexicographically by JCS during canonicalisation." Specifically, "cancellation_provider_did", "cancellation_reason", and "cancellation_timestamp_ms" should precede "canon_version" because 'c' comes before 'o'.

Suggested change
{
"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": ["GB", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}
{
"cancellation_provider_did": "did:web:api.algovoi.co.uk",
"cancellation_reason": "USER_REQUESTED",
"cancellation_timestamp_ms": 1716494400000,
"canon_version": "jcs-rfc8785-v1",
"effective_from_ms": 1716537600000,
"jurisdiction_flags": ["GB", "EU"],
"mandate_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f"
}

Comment thread docs/ap2/payment_lifecycle.md Outdated
Comment on lines +58 to +64
| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1`. |
| `cancellation_provider_did` | string | DID URI of the issuing party. |
| `cancellation_reason` | string (closed enum) | `USER_REQUESTED` / `MERCHANT_REQUESTED` / `COMPLIANCE_TERMINATED` / `EXPIRED`. |
| `cancellation_timestamp_ms` | integer | Epoch milliseconds when the cancellation event was recorded. MUST be integer. |
| `effective_from_ms` | integer | Epoch milliseconds when the cancellation takes legal effect. MUST be `>= cancellation_timestamp_ms`. |
| `jurisdiction_flags` | ordered array of string | ISO-3166-1 alpha-2 codes; primary jurisdiction first. Array order significant under RFC 8785 §3.2.3. |
| `mandate_ref` | string | `sha256:{hex}` reference to the JCS-canonical Payment Mandate this cancellation terminates. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fields in the Cancellation Receipt table are not sorted lexicographically, which is inconsistent with the Refund Receipt table (lines 104-110) and the lexicographical sorting requirement of JCS. Sorting the table lexicographically makes it easier to read and compare with the JSON example.

Suggested change
| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1`. |
| `cancellation_provider_did` | string | DID URI of the issuing party. |
| `cancellation_reason` | string (closed enum) | `USER_REQUESTED` / `MERCHANT_REQUESTED` / `COMPLIANCE_TERMINATED` / `EXPIRED`. |
| `cancellation_timestamp_ms` | integer | Epoch milliseconds when the cancellation event was recorded. MUST be integer. |
| `effective_from_ms` | integer | Epoch milliseconds when the cancellation takes legal effect. MUST be `>= cancellation_timestamp_ms`. |
| `jurisdiction_flags` | ordered array of string | ISO-3166-1 alpha-2 codes; primary jurisdiction first. Array order significant under RFC 8785 §3.2.3. |
| `mandate_ref` | string | `sha256:{hex}` reference to the JCS-canonical Payment Mandate this cancellation terminates. |
| `cancellation_provider_did` | string | DID URI of the issuing party. |
| `cancellation_reason` | string (closed enum) | `USER_REQUESTED` / `MERCHANT_REQUESTED` / `COMPLIANCE_TERMINATED` / `EXPIRED`. |
| `cancellation_timestamp_ms` | integer | Epoch milliseconds when the cancellation event was recorded. MUST be integer. |
| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1`. |
| `effective_from_ms` | integer | Epoch milliseconds when the cancellation takes legal effect. MUST be `>= cancellation_timestamp_ms`. |
| `jurisdiction_flags` | ordered array of string | ISO-3166-1 alpha-2 codes; primary jurisdiction first. Array order significant under RFC 8785 §3.2.3. |
| `mandate_ref` | string | `sha256:{hex}` reference to the JCS-canonical Payment Mandate this cancellation terminates. |

Comment thread .cspell/custom-words.txt Outdated
Comment on lines +10 to +11
algovoi
AlgoVoi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

The custom words file follows a convention where uppercase words precede lowercase words (e.g., Dcql before dcql, Disclosable before disclosable). The addition of algovoi and AlgoVoi is out of order.

AlgoVoi
algovoi

Comment thread .cspell/custom-words.txt Outdated
Comment on lines +16 to +17
authorisation
Authorisation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

The addition of authorisation and Authorisation is out of order. Uppercase should precede lowercase to match the file's sorting convention.

Authorisation
authorisation

Comment thread .cspell/custom-words.txt Outdated
Comment on lines +19 to +20
behavioural
Behavioural
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

The addition of behavioural and Behavioural is out of order. Uppercase should precede lowercase to match the file's sorting convention.

Behavioural
behavioural

Comment thread .cspell/custom-words.txt Outdated
Comment on lines +26 to +27
canonicalise
Canonicalise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

The addition of canonicalise and Canonicalise is out of order. Uppercase should precede lowercase to match the file's sorting convention.

Canonicalise
canonicalise

POCA is the regulatory acronym cited in the COMPLIANCE_TERMINATED
cancellation_reason mapping. recurr is the AlgoVoi recurring-payments
service hostname (recurr.algovoi.co.uk) cited in the production
reference section.
- 'ISO-3166-1' -> 'ISO 3166-1' (correct standard designation, 2 occurrences)
@chopmob-cloud chopmob-cloud changed the title docs(ap2): add Payment Lifecycle — AlgoVoi-authored cancellation and refund attestation envelopes (PSD2 Articles 64 and 89) docs(ap2): add Payment Lifecycle - AlgoVoi-authored cancellation and refund attestation envelopes (PSD2 Articles 64 and 89) May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant