Verify a crypto payment receipt

A receipt/1 receipt records one on-chain transfer — tx hash, chain, amount, sender, recipient, block, time — and signs it with Ed25519. This page checks the signature and the canonical bytes. It does not ask the chain anything: the block is public, so the transfer is re-checkable by anyone from the tx hash.

What each verdict means

VerdictMeaning
okThe signature verifies against the public key in the receipt, and the signed fields are unchanged.
tamperedThe signature does not verify: at least one signed field was changed after signing.
wrong_keyThe receipt is internally consistent but signed by a key you did not name. Compare the fingerprint.
unsignedThere is no signature at all. Nothing was attested.
malformedNot a receipt/1 object, or a field has the wrong type. Nothing was checked.

Reproduce it without this page

The signed bytes are the canonical JSON (RFC 8785) of the receipt without signature and public_key. Verify with the module itself — no network, no server:

python3 -m attest.payment_receipt verify receipt.json --key <issuer-public-key-b64>

What a receipt proves, and what it does not

ProvesDoes not prove
A transfer of that amount, asset and recipient existed in that block.That goods or services were delivered.
The issuer signed those exact facts at issuance.That the issuer is solvent, honest or still in business.
Any change to the facts breaks the signature.That the transfer was for the stated subject: the subject is the requester's declaration, signed as a declaration.
The receipt records the facts the issuer read from the chain at issuance.That the payer owned the funds lawfully.

A receipt costs $0.50. Issue one: POST /api/receipt/issue with {"tx_hash": "0x…", "chain": "base", "subject": "what was paid for"}.