Documentation Index
Fetch the complete documentation index at: https://docs.algovoi.co.uk/llms.txt
Use this file to discover all available pages before exploring further.
The Payment Evidence Frame (PEF) is a transport-agnostic envelope that wraps any AlgoVoi payment-lifecycle receipt into a single, verifiable artefact. Each frame carries a byte-deterministic frame_id (SHA-256 of the JCS-canonical preimage) and an optional detached RFC 9421 signature field.
It is AlgoVoi-authored, specified in IETF Internet-Draft draft-hopley-x402-payment-evidence-frame-00 (published 2026-05-30, Independent Submission), and published as a standalone reference implementation:
Both packages depend on algovoi-substrate / @algovoi/substrate for the JCS canonicalisation primitive. Apache 2.0.
Lifecycle position
PEF is the outermost envelope. It wraps every receipt type in the payment lifecycle stack:
compliance --> settlement --> cancellation --> refund
receipt attestation receipt receipt
| | | |
+------------------+---------------+--------------+
|
payment_evidence_frame
(frame_id, claim_type,
receipt_hash, signature)
All five wrapped formats anchor to the same canonicalisation discipline (urn:x402:canonicalisation:jcs-rfc8785-v1). A verifier holding a PEF can independently re-derive frame_id from the enclosed receipt without trusting the issuer’s assertion.
Downstream consumers of payment evidence — auditors, regulators, acquiring counterparties — receive receipts from multiple sources in multiple formats. PEF answers three problems:
- Canonical identity:
frame_id is a SHA-256 of the JCS-canonical preimage. Any party can recompute it offline. There is no proprietary identifier or opaque token to trust.
- Uniform verification surface: a single verifier handles all five receipt types without format-specific parsing logic. The
claim_type field is the sole discriminator.
- Optional signature binding: RFC 9421 HTTP Message Signatures attach a detached signature to the frame bytes, binding the issuer’s keypair to the canonical
frame_id. The frame is fully verifiable without the signature; the signature narrows the trust surface for regulated contexts.
Frame shape
A PEF frame is a six-field JSON object canonicalised under RFC 8785 (JCS):
{
"canon_version": "urn:x402:canonicalisation:jcs-rfc8785-v1",
"claim_type": "payment_admission",
"frame_id": "sha256:09929082c83d5006f61f06bb12eb58cc2c21acebd70a31bca3cb26169c11b6bf",
"frame_provider_did": "did:web:api.algovoi.co.uk",
"frame_timestamp_ms": 1748534600000,
"receipt_hash": "sha256:abc123..."
}
| Field | Type | Description |
|---|
canon_version | string | In-band canonicalisation pin. Fixed urn:x402:canonicalisation:jcs-rfc8785-v1. |
claim_type | string (closed enum) | Receipt type discriminator. See table below. |
frame_id | string | sha256:{hex} — SHA-256 of the JCS-canonical preimage bytes. Self-describing. |
frame_provider_did | string | DID URI of the party asserting the frame. |
frame_timestamp_ms | integer | Epoch milliseconds. Substrate Rule 2. |
receipt_hash | string | sha256:{hex} — SHA-256 of the JCS-canonical receipt bytes. |
The optional signature field carries a detached RFC 9421 / RFC 9530 Content-Digest over the canonical frame bytes. Its presence is indicated by the sig key; its absence does not invalidate the frame.
Claim types
Five claim types, each mapping to an IETF I-D-anchored receipt format:
claim_type | Receipt format | IETF I-D |
|---|
payment_admission | Compliance receipt (ALLOW / DENY) | draft-hopley-x402-compliance-receipt |
payment_settlement | Settlement attestation (SETTLED / PENDING_FINALITY / REVERSED) | draft-hopley-x402-settlement-attestation |
payment_cancellation | Cancellation receipt (USER_REQUESTED / MERCHANT_REQUESTED / COMPLIANCE_TERMINATED / EXPIRED) | draft-hopley-x402-cancellation-receipt |
payment_refund | Refund receipt (FULL / PARTIAL / REJECTED) | draft-hopley-x402-refund-receipt |
composite_verdict | Composite trust-query response (ALLOW / DENY / INDETERMINATE) | draft-hopley-x402-composite-trust-query |
frame_id derivation
preimage = JCS(
canon_version,
claim_type,
frame_provider_did,
frame_timestamp_ms,
receipt_hash
)
frame_id = "sha256:" + hex(SHA-256(preimage))
frame_id is excluded from the JCS preimage — standard JCS self-describing identifier pattern. Any verifier with the receipt bytes can recompute receipt_hash, recompute preimage, and independently verify frame_id without trusting the issuer.
Cross-implementation validation
frame_id derivation has been independently validated across eight JCS implementations in eight programming languages — 64/64 byte-for-byte agreements across all five claim types (both receipt_hash and frame_id layers per vector):
| Language | JCS library |
|---|
| Python | rfc8785 0.1.4 (Trail of Bits) |
| JavaScript | canonicalize 1.0.8 (Samuel Erdtman) |
| Ruby | json-canonicalization 1.0.0 |
| PHP | inline pure-stdlib JCS (AlgoVoi) |
| Go | gowebpki/jcs v1.0.1 (Web PKI Working Group) |
| Rust | serde_jcs 0.2.0 |
| Java | erdtman/java-json-canonicalization 1.1 (Anders Rundgren + Samuel Erdtman) |
| .NET | Baqhub.Packages.JsonCanonicalization 1.0.1 |
Full attestation record: _attestations/2026-05-30-8-impl-pef-v1.md in chopmob-cloud/algovoi-jcs-conformance-vectors.
The cumulative cross-validation corpus now stands at 576/576 byte-for-byte agreements across eight vector sets covering the full AlgoVoi agentic-payment receipt stack.
Quick start
Python
from algovoi_pef import build_pef, verify_pef
frame = build_pef(
claim_type="payment_admission",
receipt={
"canon_version": "urn:x402:canonicalisation:jcs-rfc8785-v1",
"jurisdiction_flags": ["EU", "UK"],
"payer_ref": "sha256:abc123...",
"prev_hash": None,
"screen_provider_did": "did:web:api.algovoi.co.uk",
"screen_result": "ALLOW",
"screen_timestamp_ms": 1748534600000,
},
frame_provider_did="did:web:api.algovoi.co.uk",
frame_timestamp_ms=1748534600000,
)
result = verify_pef(frame)
assert result["valid"]
print(frame["frame_id"])
# sha256:09929082c83d5006f61f06bb12eb58cc2c21acebd70a31bca3cb26169c11b6bf
TypeScript
import { buildPef, verifyPef } from "@algovoi/pef";
const frame = buildPef({
claim_type: "payment_settlement",
receipt: {
canon_version: "urn:x402:canonicalisation:jcs-rfc8785-v1",
settled_payment_ref: "sha256:abc123...",
settlement_chain: "ethereum:84532",
settlement_provider_did: "did:web:api.algovoi.co.uk",
settlement_result: "SETTLED",
settlement_timestamp_ms: 1748534700000,
},
frame_provider_did: "did:web:api.algovoi.co.uk",
frame_timestamp_ms: 1748534700000,
});
const result = verifyPef(frame);
console.log(result.valid); // true
console.log(frame.frame_id); // sha256:...
The platform wraps receipts automatically via pef_or_none() — returns None if algovoi-pef is not installed, so existing API responses are unaffected during a rolling deploy:
from shared.utils.pef_wrapper import wrap_compliance_receipt
pef_frame = wrap_compliance_receipt(
compliance_receipt_dict,
screen_timestamp_ms=screen_ts,
)
What this is NOT
- Not a receipt format itself. PEF is a wrapper. The enclosed receipt retains its own canonical identity (
receipt_hash) and IETF I-D normative status.
- Not a cryptographic settlement proof. PEF records the operator’s categorical claim. Cryptographic proofs of payment conditions are orthogonal and compose on top.
- Not a transport protocol. PEF is a JSON envelope. How it is transmitted (HTTP response header, webhook payload, audit-log row) is out of scope.
Companion IETF Internet-Draft
draft-hopley-x402-payment-evidence-frame-00 (Independent Submission, published 2026-05-30). AlgoVoi-authored, sole authorship. Normatively references draft-hopley-x402-canonicalisation-jcs-v1 and all five receipt-format I-Ds.
See also