ERC-5570: Digital Receipt NFTs
ERC-5570 standardises a structured metadata schema for digital receipts as NFTs: each NFT represents a single purchase / transaction and carries a machine-readable JSON receipt with merchant, items, totals, currency, taxes, and signatures. Replaces emailed PDF receipts, paper receipts, and per-merchant proprietary loyalty cards with a portable, queryable, on-chain artefact.
Use cases:
- Retail receipts — POS terminals mint a receipt NFT to the shopper's wallet on each purchase. Combined returns / warranties.
- B2B invoices — supplier mints invoice NFT to buyer's contract; used as accounting input.
- Subscription receipts — recurring services mint a renewal receipt per period.
- Restaurant / hospitality — itemised bills as NFTs for splitting, tipping, expense reporting.
The standard is JSON-schema heavy (the on-chain footprint is just NEP- 11 + URI to off-chain JSON), so this mirror documents the shape and the on-chain wrapper.
Required Receipt Fields
{
"merchantId": "...",
"merchantName": "...",
"transactionId": "...",
"timestamp": 1735689600,
"currency": "USD",
"items": [
{ "name": "Espresso", "qty": 1, "unitPrice": 4.50, "tax": 0.36 },
{ "name": "Croissant", "qty": 2, "unitPrice": 3.25, "tax": 0.52 }
],
"subtotal": 11.00,
"taxTotal": 0.88,
"total": 11.88,
"paymentMethod": "card_visa_4242",
"merchantSignature": "0x..."
}The merchantSignature proves the receipt was issued by the merchant (prevents fraudulent receipt forgery). The signature scheme is free-form per the spec; ERC-1271 + EIP-712 typed-data is the recommended pattern.
Neo Equivalent: NEP-11 + Receipt Metadata Schema
NEP-11's Properties(tokenId) returns a Map; the receipt fields drop in directly. The receipt JSON typically lives off-chain (IPFS / HTTPS), with the on-chain Properties returning a URI plus the merchant signature for verification.
public static Map<string, object> Properties(ByteString tokenId)
{
var props = base.Properties(tokenId);
var receipt = (Map<string, object>)StdLib.Deserialize(
(ByteString)Storage.Get(Storage.CurrentContext, ReceiptKey(tokenId)));
if (receipt is not null)
{
props["receipt"] = receipt;
props["merchantSignature"] = Storage.Get(Storage.CurrentContext, SigKey(tokenId));
}
return props;
}
public static void MintReceipt(
UInt160 to, ByteString tokenId, Map<string, object> receipt,
ECPoint merchantPubKey, ByteString merchantSig)
{
if (!Runtime.CheckWitness(GetMerchant())) throw new Exception("RECEIPT:NotMerchant");
var receiptBytes = StdLib.Serialize(receipt);
if (!(bool)CryptoLib.VerifyWithECDsa(receiptBytes, merchantPubKey, merchantSig, NamedCurveHash.secp256r1SHA256))
throw new Exception("RECEIPT:InvalidSignature");
Storage.Put(Storage.CurrentContext, ReceiptKey(tokenId), receiptBytes);
Storage.Put(Storage.CurrentContext, SigKey(tokenId), merchantSig);
Mint(tokenId, new TokenState { Owner = to }); // NEP-11 base: Mint(tokenId, TokenState)
}| ERC-5570 (Ethereum) | Neo Equivalent | Notes |
|---|---|---|
| Receipt JSON metadata | Map<string, object> stored serialised + URI | Same schema |
| Merchant signature (EIP-712 / ERC-1271) | secp256r1 signature verified at mint | On-chain verification |
tokenURI(tokenId) returns receipt JSON | NEP-11 Properties(tokenId)["receipt"] | Direct port |
| Merchant identity | Stored merchant pubKey or contract hash | Verifiable provenance |
Composition
- ERC-2981 — royalties. Merchants don't typically resell receipts, but if they do, royalties to the receipt issuer.
- ERC-2135 — consumable. Receipt redemption (e.g. a warranty claim) marks the receipt as consumed without burning.
- ERC-7066 — lockable. Lock receipts during a return-window dispute.
- ERC-3643 — T-REX. For receipts in regulated contexts (B2B invoices) requiring KYC.
Migration Notes
For POS / payment systems issuing ERC-5570 on Ethereum:
- Receipt schema stays the same (it's a JSON convention).
- Mint flow becomes a single Neo transaction: merchant signs the receipt JSON off-chain, calls
MintReceipt(to, tokenId, receipt, pubKey, sig). - Wallets render the receipt by reading
Properties(tokenId)and verifying the signature off-chain (or trusting the on-chain verification at mint time).
For accounting / tax software integrating receipt NFTs: the on-chain mint is the immutable record; off-chain processors read the standard schema for line-item + tax extraction.
