Payment Request
Status: partly available, last checked 2026-11-02. Level 1 uses existing wallet standards. Level 2 is conceptual. Level 3 is an EVM prototype that only handles ETH, so don’t use it for stablecoins.
A payment request is the smallest useful thing you can build here. It needs a destination, an amount and an optional note.
{
"destination": "0xRecipient",
"network": "base",
"asset": "USDC",
"amount": "25.00",
"notes": "Logo design, October"
}This shows the idea and isn’t a wire format. You can share it at three levels, depending on what you need to prove.
| Level | What the payer gets | What it adds | Limit |
|---|---|---|---|
| 1. Plain QR | A standard wallet payment URI | Works today, no contract, no Dial software | Unsigned, and can’t be matched to a request reliably |
| 2. Signed request | A link or QR that resolves to a signed object | Proof of who asked, and the note travels with it | Still pays a shared address |
| 3. Payable hash | An address derived from the request’s parameters | Every request has its own address, so a payment identifies its request | Needs activation to move funds onward |
Level 1: Plain QR
Encode the request as a payment URI and show it as a QR code. Most of the work is already done by existing standards, although wallet support varies.
| Network | Standard | Example |
|---|---|---|
| Ethereum and EVM, native asset | ERC-681Â | ethereum:0xRecipient@8453?value=1e16 |
| Ethereum and EVM, ERC-20 token | ERC-681Â | ethereum:0xToken@8453/transfer?address=0xRecipient&uint256=25000000 |
| Cardano, ADA | CIP-13Â | web+cardano:addr1...?amount=25 |
For an ERC-20 token the URI targets the token contract, and the amount is in the token’s smallest unit. That’s 25,000,000 for 25 USDC with its 6 decimals. Getting either wrong is an easy way to send the wrong amount, so test with your target wallets.
The note isn’t part of these URIs. The payer sees only the address and amount, so nothing here proves who asked. Anyone who swaps the QR code for their own gets paid instead.
Level 2: Signed request
Sign the request as a SPORE. The request now has a content hash, which identifies it. Share that hash as a QR code or link, or send it directly over the network as a message. The planned message types are a PaymentRequest object and a REQUEST command, and the planned link is dial.work/s/{reference}.
The recipient resolves the hash, verifies the signature, and sees the signed destination, amount and note before paying.
A content hash identifies a request, but it can’t receive funds. You can’t pay it directly. The hash is what you look up and verify, and payment still goes to the destination inside.
Level 3: Payable hash
Some networks can derive an address by hashing a program’s parameters. That address is a hash you can actually pay, and it’s known before anything is deployed.
| Network | How the address is derived |
|---|---|
| EVM | CREATE2: a hash of the factory, salt and init code, with the destination and fee inside the init code |
| Cardano | Script address: a hash of the compiled validator with its parameters applied |
The QR code then points at that derived address, and anyone can recompute it from the parameters. You can try the EVM calculation yourself. Because each request has its own address, a transfer there tells you which request it was for, even from a wallet that knows nothing about Dial.
Three things to keep in mind:
- Paying isn’t executing. Funds sit at the address until something activates the program and moves them. See SPAWN.
- The address doesn’t enforce the amount. A wallet can send any amount, or the wrong asset, so the program needs a rule for underpayment, overpayment and repeat payment. The Cardano prototype and the EVM forwarders behave differently.
- Add something unique. Two identical requests would otherwise derive the same address and mix their funds. Include a nonce in the parameters.
Where the note goes
Keep notes off the chain, since chain data is public and permanent. That applies to init code and to validator parameters once they’re revealed.
Put the note in the signed object and commit to it by hash. If you publish the object to public storage such as IPFS, its contents are public too, so encrypt anything private. Add a random value before hashing a short note, because otherwise someone could guess it and check their guess against the hash. A QR code should carry a reference to the note rather than the note itself, which also keeps the code small enough to scan.
Safety checklist
- Show the payer the exact network, asset, amount and address, and warn when a request isn’t signed.
- Treat a QR code as a pointer that carries no authority of its own. See payment links and phishing.
- Reject expired or revoked requests before paying.
- Confirm payment from network evidence, since a webhook or a screenshot is only a signal.
Next steps
Add an issuer, terms and a receipt, and a payment request becomes an invoice. See all use cases.
Explore invoicing: Programmable Invoicing