Hosted Checkout
The fastest way to get paid: create a charge and redirect the customer to a branded ZaroPay payment page. No payment UI to build.
Flow
Your backend Customer ZaroPay
──────────── ──────── ───────
POST /v1/deposit-addresses ─────► opens checkout_url ─────► shows QR + live status
(amount, orderRef, pays USDT on TRON detects + confirms on-chain
successUrl, cancelUrl) │
▲ ▼
└──────────── deposit.confirmed webhook (verify!) ◄──────────┘
customer redirected to successUrl
1. Create the charge
POST /v1/deposit-addresses with an amount (and optionally orderRef, successUrl, cancelUrl).
The response includes a checkout_token and a ready-to-use
checkout_url (https://checkout.zaropay.com/c/<token>). See
Deposit Addresses.
2. Redirect the customer
Send them to data.checkout_url. The page is driven by the public, unauthenticated endpoint
GET /v1/checkout/:token — the unguessable token is the capability (no API key needed in the
browser). It returns a safe, whitelisted projection:
{
"state": "awaiting|confirming|paid|underpaid|overpaid|expired|error",
"merchant": { "name": "…", "logoUrl": "…", "accentColor": "#…" },
"order": { "ref": "INV-1042", "amount": "100", "payAmount": "100", "currency": "USDT",
"feeMode": "merchant", "successUrl": "…", "cancelUrl": "…",
"fiatCurrency": null, "fiatAmount": null, "quoteRate": null, "quoteExpiresAt": null },
"payment": { "address": "TXyz…", "chain": "tron", "expiresAt": "…" },
"status": { "depositStatus": "CONFIRMING", "confirmations": 5, "requiredConfirmations": 19,
"amountReceived": "100", "paymentState": "exact", "txHash": "0x…", "confirmedAt": null }
}
payAmount is the exact figure the payer must send. The page updates live (websocket + polling
fallback) as the payment is detected and confirmed.
USD-priced orders
If you created the charge with pricingCurrency: "USD",
the projection's order block carries the fiat denomination — fiatCurrency ("USD"), fiatAmount
(the dollar figure), quoteRate (the locked USDT-per-USD rate), and quoteExpiresAt (when the lock
ends). amount / payAmount stay the USDT the customer pays. The hosted page shows the USD
amount alongside the USDT total and a countdown to quoteExpiresAt; when the lock lapses it
auto-refreshes the quote via POST /v1/checkout/:token/requote (same token, no auth — only while the
order is still unpaid), so the displayed USDT amount always reflects a fresh rate.
3. Return redirect
On a terminal state the customer is redirected to your successUrl / cancelUrl with query params
appended:
?ref=<orderRef>&status=<paid|cancelled|expired>
The browser redirect is for UX only and is customer-controllable. Confirm fulfilment from the signed
deposit.confirmed webhook — never from the status query parameter.
Customizing the page
The checkout page shows your merchant name, logo, and accent color (merchant block above),
configured in the Merchant Dashboard. The orderRef you pass is shown
to the customer.