Guides
Hosted checkout
The payment page your buyer sees. Send them to one link and it handles the choice of method, the address and the confirmations, with no JavaScript and no account.
Send the buyer
Every transaction has its own checkout at /checkout/{transaction_id}, using the transaction_id that Create a transaction returns. Redirect the buyer there or show it as a link. It works on both addresses:
- Clearnet
https://anonpay.org/checkout/{transaction_id}- Onion service
http://anonpay666ie3ah4nl55ssimvacwrdkbbji6h4a4snvry26lnemfaxid.onion/checkout/{transaction_id}
from flask import Flask, redirect
from shop.anonpay import create_transaction
from shop.orders import Order
app = Flask(__name__)
CHECKOUT = "https://anonpay.org/checkout/"
@app.post("/orders/<int:order_id>/pay")
def pay(order_id):
order = Order.get(order_id)
created = create_transaction(order)
order.save_payment(created["transaction_id"], created["private_key"])
return redirect(CHECKOUT + created["transaction_id"], code=303)import express from "express";
import { createTransaction } from "./anonpay.js";
import { Order } from "./orders.js";
const app = express();
const CHECKOUT = "https://anonpay.org/checkout/";
app.post("/orders/:id/pay", async (req, res) => {
const order = await Order.find(req.params.id);
const created = await createTransaction(order);
await order.savePayment(created.transaction_id, created.private_key);
res.redirect(303, CHECKOUT + created.transaction_id);
});$order = Order::find((int) $_POST["order_id"]);
$created = createTransaction($order);
$order->savePayment($created["transaction_id"], $created["private_key"]);
header("Location: https://anonpay.org/checkout/" . $created["transaction_id"], true, 303);
exit;
- Answer the POST that created the order with a
303redirect, so reloading your page cannot create a second transaction. - The link carries no secret. The buyer can bookmark it and come back until the transaction ends.
- Keep the
private_keyon your server. The checkout never needs it. - Create a new transaction for every order. A checkout belongs to one transaction and ends with it.
What the buyer sees
Choose a method
The methods on offer, each with its name and icon, and the network for tokens.
Pay
The exact amount, the receiving address and a QR code, or the PayPal account to pay.
Done
The payment shows as complete, and you receive the
completedwebhook.
| Transaction | The checkout shows |
|---|---|
pendingno method yet | The methods on offer. |
pendingmethod chosen | The amount, the address and a QR code. |
pendingpartly paid | What is still owed, with a QR code for exactly that. |
pendingconfirming | The confirmations so far. |
| completed | The payment is complete. |
| expired | Expired, as soon as expires passes, even before the status changes. |
| cancelled | Cancelled. Nothing more can be paid. |
Which methods are offered
A method is offered when all three hold: it is enabled on your account, it is in the transaction's allowed_payment_methods if you set any, and the platform has it available right now. Methods appear in the platform's order. Payment methods lists every code.
With exactly one method on offer, the buyer gets a single button for it. If the platform refuses a choice, for example because the amount is outside the method's limits or the method was paused a moment ago, the buyer is told why and the method leaves the list.
Choosing a method fixes the rate and creates the receiving address, and it cannot be undone. To let a buyer switch, cancel the transaction with its private_key and send them a new one.
Paying
For crypto the page shows the exact amount, rounded up to the coin's precision so you are never short, the receiving address, and a QR code. The QR code includes the amount for coins whose wallet links have a standard amount field, such as Bitcoin and Monero. A token's QR code carries the address alone, because a correct token link needs the token's contract address; the buyer types the amount.
For a token, the network is part of the method. Tether on Tron and Tether on Ethereum are different methods, the page names the network, and coins sent on another network do not arrive.
If less arrives than asked, the page asks for the rest until the transaction expires. Your completion threshold decides how far short still counts as paid. If more arrives, the transaction still completes, and until it does the page shows the extra.
For PayPal the page shows your PayPal email, the amount, the currency to send it in, and the payment type your account accepts: Friends and Family, Goods and Services, or either. A deposit accepts any amount, so the page asks for none.
While the buyer waits
The buyer never has to keep the page open. The transaction completes once the payment confirms, and your webhook tells you.
To see confirmations arrive, the buyer refreshes the page. Each load reads the payment again.
Your store on the page
The checkout shows your store name, your logo and your theme colour, set in the dashboard under Settings, Store and Settings, Checkout. A deposit shows none of it, because it tops up your own balance.
Styling with link parameters
These parameters arrive with the redesigned checkout. Until then the checkout ignores them, so a link that already carries them works today and takes on the style when the redesign ships.
Add parameters to a checkout link to change how that link looks and behaves. Only the values listed are accepted. Anything else is ignored and the default is used, so a typo can never stop a buyer paying.
https://anonpay.org/checkout/9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c?theme=dark&list=grid
Appearance
themedefault autoLight or dark page.
auto- Follows the buyer's device setting. Tor Browser always reports light.
light- White page, grey panels, black text.
dark- The ANONPAY dark palette.
layoutdefault splitWhere the order summary sits relative to the payment.
split- The summary in a column beside the payment. Stacks on phones.
card- One centred card with the summary as its header.
plain- No panels. One column on the page.
listdefault autoHow the payment methods are offered.
auto- Rows for up to 6 methods, tiles up to 15, a search box beyond.
list- One row per method.
grid- Tiles, several per row.
search- A search box over the full list. Typing suggests names.
chips- Compact pills that wrap.
select- A dropdown and a Continue button.
groups- A collapsible section per network.
tabs- One tab per network.
densitydefault cozyHow much room everything gets.
cozy- Standard spacing.
compact- About a quarter tighter, for long lists and small windows.
shapedefault roundThe corner radius of panels, rows and controls.
round- Rounded corners.
square- No rounding anywhere.
pill- Fully rounded buttons, rows and fields.
fontdefault brandThe font every text uses.
brand- Roboto, the ANONPAY typeface.
system- The device's own font. Nothing to download, so the fastest over Tor.
mono- Monospace throughout.
Content
qrdefault showHow the payment QR code is shown.
show- Beside the amount.
fold- Behind a Show QR code button.
big- Large and first, for scanning with a phone.
off- No QR code. Amount and address only.
addrdefault groupHow the receiving address is printed.
group- In blocks of four, easier to compare with the wallet. Copying gives the address without spaces.
plain- One unbroken string.
stepsdefault onThe Method, Payment, Done indicator.
on- Shown above the content.
off- Hidden.
summarydefault fullWhat the order summary shows.
full- Store, total, reference, expiry and your store's links.
min- Store and total only.
helpdefault offCommon questions under the payment details.
off- Hidden.
on- Shown, folded.
badgedefault fullThe footer that says who processes the payment.
full- The ANONPAY logo.
min- One line of text.
Behaviour
confirmdefault onWhether choosing a method takes one click or two.
on- The buyer picks a method, then presses Continue. The choice cannot be undone, so it takes two clicks.
off- One click on a method commits to it.
refreshdefault 30How often a page waiting for payment reloads itself.
30- Every 30 seconds.
60- Every minute.
off- Never. The buyer uses Check now.
embeddefault 0For ANONPAY's own dashboard, which frames the checkout on its deposit page.
0- A normal page.
1- No summary, steps or footer, on a transparent background. Other sites still cannot frame the checkout.
topup to 3 codesPuts these methods first, or in a Suggested group when the list is grouped. Codes the transaction does not offer are dropped. Example:
top=xmr,btc.qtext, 40 charactersThe search text for
list=search. The search box sets it; a link never needs to, and it is not carried into other links.
Presets
- Default. No parameters at all.
- Night market. Dark page, methods as tiles.
?theme=dark&list=grid - Quick card. One card and one click per method, for stores that sell one thing.
?layout=card&qr=big& steps=off& summary=min& confirm=off - Big catalogue. Every method behind a search box, with Monero and Bitcoin first.
?list=search&top=xmr,btc - Terminal. Monospace, square and compact.
?theme=dark&list=chips& density=compact& shape=square& font=mono
What a link cannot change
- The amount, the currency or the methods on offer.
toponly reorders methods the transaction already allows. - Any text on the page, including your store's name. A parameter that could set text could put a phishing message on a real ANONPAY page.
- Where the buyer goes next. There is no redirect parameter.
- How often the page asks for updates, except to slow it down.
Embedding
Other sites cannot show the checkout in a frame. It sends X-Frame-Options: SAMEORIGIN and frame-ancestors 'self', which stops a page from tricking a buyer into pressing a payment button they cannot see. Redirect or link to the checkout instead.
Privacy
- No JavaScript. The page is HTML and CSS, so it works in Tor Browser at the Safest setting.
- No third parties. Every font, icon and image comes from ANONPAY, and the QR code is drawn on the server.
- No referrer. A link on the checkout does not tell the next site which transaction the buyer came from.
- No caching. Pages are sent with
Cache-Control: no-store, so a shared computer keeps no copy of the address or amount.