Skip to main content
x402 proves a payment happened with a transaction hash, but it carries no receipt format, so verifying a settlement later means going back to the chain. algovoi-x402-receipt-adapter closes that gap. It turns an x402 payment into a settlement attestation: a small JSON object canonicalised under RFC 8785 (JCS) and content addressed with SHA-256, that any party recomputes and verifies offline with a JSON parser, JCS, and SHA-256 alone. No issuer call, no account, no service.

What it produces

PAYMENT-REQUIRED / PaymentRequirements   ->  maxAmountRequired, asset, payTo
PAYMENT-RESPONSE / SettleResponse        ->  transaction, network, payer, amount
                                 |
   x402_payment_ref = "sha256:" + SHA-256(JCS({txHash, networkId, payer,
                                               amount, currency, settled_at_ms}))
                                 |
   settlement_attestation_v1   (settlement_ref content addresses the receipt)
  • x402_payment_ref binds the settlement transaction to the requested amount and currency plus a timestamp, so a transaction hash can no longer be re-bound to a different amount.
  • settlement_ref is "sha256:" + SHA-256(JCS(attestation)), the content address of the whole receipt. Recompute it in any language and it matches byte for byte.

Three ways to capture

Every option produces the same settlement_ref for the same underlying payment.
OptionFunctionUse when
Facilitatorreceipt_from_settleyou run an x402 facilitator, and emit the receipt from your own SettleResponse at settle time
Origincapture_x402_settlementyou sit behind a managed gateway, and re-verify the transaction on chain (fail closed) before issuing
Directbuild_x402_settlement_attestationyou already hold both headers and trust them
Settlement fields follow the x402 Foundation SettleResponse model (transaction, network, payer); the legacy names txHash and networkId are accepted as aliases.
from algovoi_x402_receipt_adapter import receipt_from_settle

result = receipt_from_settle(
    payment_requirements,          # maxAmountRequired, asset, payTo
    settle_response,               # success, transaction, network, payer, amount
    settled_at_ms=1751472000000,
    provider_did="did:web:your-service.example",
)
result["settlement_ref"]     # "sha256:..."
result["confirmed_amount"]   # actual settled amount recorded

Bind it into the Keystone

The settlement binds into the Keystone accountability chain with the published algovoi-substrate binding primitive, introducing no new hashing. One call ties a payment to the verified agent action that authorised it, so an x402 payment becomes part of an offline-verifiable record that runs from identity through to settlement.
from algovoi_x402_receipt_adapter import to_keystone_binding

binding_ref = to_keystone_binding(
    result,
    action_ref="...",            # the verified agent action
    transition_hash="...",       # the committed lifecycle transition
    retention_chain_ref="sha256:...",
)
binding_ref = "sha256:" + SHA-256(JCS({action_ref, transition_hash,
                                       settlement_ref, retention_chain_ref}))
A worked example, the Keystone carried all the way through real settlements, is on the proven on-chain page.

Install

Apache License 2.0. manylinux wheels for Python 3.11 to 3.13, from the AlgoVoi index:
pip install --extra-index-url https://pip.algovoi.co.uk/simple/ algovoi-x402-receipt-adapter

Verify offline

from algovoi_x402_receipt_adapter import verify_settlement_ref

verify_settlement_ref(result["attestation"], result["settlement_ref"])  # True
The check is pure and deterministic: "sha256:" + SHA-256(JCS(attestation)). Recompute it with any RFC 8785 canonicaliser and a SHA-256 and the reference matches. No trust in AlgoVoi is required.

See also