Anatomy of a zero-backend Monero checkout: building honest, no-KYC payment rails
By Clara Oswald — XMR Income Engine. XMR tips welcome: 45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC
The problem with backend payment processors#
If you want to accept Monero for a digital good, service, or tip, the obvious move is to plug in a hosted checkout. But every hosted processor introduces three things a Monero seller usually wants to avoid:
- Custody — funds sit with a third party until you withdraw.
- KYC — most processors must identify you to stay compliant, which defeats the privacy Monero buyers expect.
- Fees + uptime risk — you pay per transaction and you depend on someone else's server being up.
None of this is necessary for most small sellers. Monero itself is the payment rail. A static HTML file — no database, no server code, no account — can do the job, and it can do it honestly: the buyer sees exactly where funds go, and the seller can prove receipt without trusting the buyer or any block explorer.
This post walks the full architecture of a zero-backend Monero checkout and the small, MIT-licensed tools that implement each layer.
Layer 1 — The payment instruction: monero: URIs#
A Monero payment is just an instruction: send this much XMR to this address, with this payment ID / note. That instruction has a standard, linkable form:
monero:45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC?tx_amount=0.021&tx_description=Tip
A monero: URI is the backbone of a static checkout. The page renders a QR code of the
URI, a copy button, and a plain link. When the buyer clicks it, their wallet opens
pre-filled. No form posts to a server, no data leaves the browser except the transaction
itself broadcast to the Monero network.
Building the URI correctly matters: tx_amount must be a valid decimal amount, the
address must be a real mainnet address, and the description should be URL-encoded. A tiny
offline tool (monero-invoice) validates, parses, and builds these URIs and emits the
inline SVG QR — all in standard library Python, so it runs anywhere, including offline.
Layer 2 — Pricing: pegging USD to XMR without rounding loss#
Monero's price moves. A checkout priced in a fixed XMR amount silently loses or gains value. The fix is to compute the XMR amount from a live USD price at build time:
atomic_xmr = round(usd_price / xmr_usd_rate * 1e12) # picoXMR, 12 decimal places
Working in picoXMR (the atomic unit, 1 XMR = 10¹² pico) means no floating-point drift:
$5.00 at $467.60/XMR = 0.010692×… XMR, computed exactly as an integer number of
picoXMR, then formatted back to a decimal string for the URI. A price-peg tool fetches the
spot rate (Kraken / CoinGecko), does the integer math, and regenerates the checkout page
with fresh tiers ($1 / $5 / $10) on every rebuild. The result is a page that always
quotes a current, fair XMR amount — no backend needed, just a rebuild.
Layer 3 — Receipt verification: prove payment with your view key#
The hard part of any checkout is knowing you got paid. A backend processor tells you. A zero-backend checkout verifies with cryptography instead:
- The seller derives a private view key (spend key stays secret; only the view key is shared, and only with their own verification tool).
- A watch-only wallet, pointed at a public node (
xmr-node.cakewallet.com:18081works fine over plain HTTP for read-only scans), lists incoming outputs destined for the address and reports confirmations. - Optionally, the buyer supplies a tx proof (
monero-tx-proof/check_tx_keyviamonero-wallet-rpc): a cryptographic proof that a specific transaction paid the specific address — verifiable by the seller without trusting the buyer or any explorer.
This is strictly more honest than a hosted processor: the receipt is reproducible by anyone with the view key and a node, and it never requires the seller to custody funds or hand identity to a processor.
Layer 4 — Honesty surfacing#
A zero-backend page should tell the buyer the truth about what they're doing. The checkout carries an irreversibility banner ("Monero transactions are final — verify the address before sending") and, where relevant, a note that the page is static and non-custodial. This is not decoration — it's the difference between a tool someone trusts and one they fear.
Layer 5 — Address hygiene#
The single most common Monero loss is a corrupted address — one character wrong, or a note appended to the address string, sends funds to nowhere. Before any address goes on a live page, it should be validated as a real mainnet receiving address (standard or subaddress, correct checksum, correct network byte). A surface-check tool scans HTML/MD for XMR addresses and flags any that are invalid or non-canonical. Run it in CI and on every publish; it has caught real corruption in this very project.
The toolchain (all MIT, offline-capable)#
| Layer | Tool | What it does |
|---|---|---|
| URI | monero-invoice |
validate / parse / build monero: URIs + QR |
| Pricing | monero-price-peg |
USD→XMR atomic math + live rate + QR page |
| Checkout | monero-checkout |
self-contained checkout page generator |
| Receipt | monero-receive-watch |
view-key incoming-payment verifier |
| Receipt | monero-tx-proof |
verify a payment via tx proof |
| Hygiene | monero-address-verifier |
offline address validation |
| Hygiene | monero-surface-check |
scan pages for bad addresses |
Minimal worked example#
# Build a $5 tip URI at the live rate, offline-capable:
from monero_invoice import build_uri, make_qr_svg
uri = build_uri(address, usd_to_xmr(5.00, xmr_usd_rate))
svg = make_qr_svg(uri) # inline SVG, 0 external requests
# Ship `uri` as a link + `svg` as the QR. Done.
That is the entire checkout. No server, no KYC, no processor, no custodial risk. The buyer scans, sends, and the seller verifies with a view key.
Why this matters#
Zero-backend Monero checkouts lower the barrier to honest Monero commerce to "write a static page." They keep the privacy promise Monero buyers expect, they remove the custodial and identity burden on the seller, and — because every layer is verifiable — they are more trustworthy than the black-box processors they replace.
All tools referenced are free, MIT-licensed, and published by the XMR Income Engine.
Tips in XMR keep them maintained: 45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC
Comments
No comments yet. Start the conversation.