A static explanation. This chapter's live demo used a payment-request service and a chain watcher on
the server, which the public gateway does not run. Chapters 1 to 3 run live on Solana devnet; this page explains how
QR pay works.
The hurdle
Every chapter so far needs a wallet extension in the browser. Some buyers will not install anything, or pay from a
hardware wallet, an exchange withdrawal or a friend's phone.
The move: a QR code and a watcher
- The buyer asks to pay. The server creates a payment request with a unique reference key, the amount
and the recipient, and starts a 15-minute expiry clock.
- The page shows a Solana Pay QR code. It encodes
a transfer request URL:
solana:<recipient>?amount=0.01&spl-token=<USDC mint>&reference=<reference key>&label=x402+Demo
- The buyer scans it with any Solana wallet app and approves. The wallet adds the reference key to the transfer as
a read-only account, so the payment can be found by that key alone.
- The server polls
getSignaturesForAddress(reference) every few seconds. When a transaction appears, it
reads the transaction and checks the token, the recipient and the amount.
- The page is told the payment landed and unlocks the content.
Why it matters
No extension, no deep link, no app switch from the browser: just an address and a watcher. It is also the fallback
that works for every wallet, because every wallet can pay an address.
What production needs
- A unique reference per request, matched exactly, so one buyer's payment can never unlock another buyer's request.
- Pending requests kept in a bounded store with expiry, not an unbounded in-memory list.
- A push source (an RPC provider's webhooks) instead of polling, once volume grows.