Connect ZeroKYC Pay in 15 minutes
One REST call — and your customer gets a checkout with every coin. No KYC, no custody.
curl -X POST https://api.zerokyc-payments.com/v1/invoices \
-H "Authorization: Bearer pk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042" \
-d '{
"amount": "49.00",
"base_currency": "USD",
"payment_currency": "any",
"order_id": "order-1042",
"ttl_minutes": 360,
"success_url": "https://yourapp.com/paid",
"webhook_url": "https://yourapp.com/webhooks/zkp",
"metadata": { "customer_id": "cust_8821" }
}'Two ways to connect
Both start in the same console and share the same API — pick by how much control you want.
No code, ~5 minutes
Hosted checkout
Create an invoice from the console or with a single call, send the buyer to the checkout URL — QR codes, live status, localization are built in.
Start in the consoleFull control
API
Create invoices from your backend, build your own payment page, consume signed webhooks. The same endpoints your live traffic will use.
See the APIPrefer libraries? SDKs for Node.js, PHP and Python, plus a WooCommerce plugin.
SDKs & pluginFrom signup to your first confirmed webhook
Seven steps, working code, no marketing fog. Every snippet runs against the production API with a test key.
Create your account
Sign-up is email, password and 2FA — KYC is never requested. You start on the free plan (up to $500/mo) and connect your own wallets; buyers pay your wallet directly, the platform never holds funds.
Grab a test key
A pk_test key lives in the API keys section. The sandbox is the same production API (https://api.zerokyc-payments.com): identical contract, webhooks and signatures — payments are simulated and confirm instantly. You can fire a test payment right from an invoice page in the console.
Create an invoice
One POST covers every enabled coin: pass payment_currency "any" and the buyer picks at checkout. Send an Idempotency-Key so retries never duplicate an invoice; amounts are fiat (USD/EUR/RUB) or the coin itself; metadata comes back in every webhook.
curl -X POST https://api.zerokyc-payments.com/v1/invoices \ -H "Authorization: Bearer pk_test_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-1042" \ -d '{ "amount": "49.00", "base_currency": "USD", "payment_currency": "any", "order_id": "order-1042", "ttl_minutes": 360, "success_url": "https://yourapp.com/paid", "webhook_url": "https://yourapp.com/webhooks/zkp", "metadata": { "customer_id": "cust_8821" } }'The response carries one option per enabled asset and a hosted checkout URL:
{ "id": "inv_9f2k...", "status": "pending", "order_id": "order-1042", "amount": "49.00", "base_currency": "USD", "expires_at": "2026-09-06T18:20:11Z", "checkout_url": "https://app.zerokyc-payments.com/pay/inv_9f2k...", "options": [ { "asset": "USDT", "network": "tron", "amount_crypto": "49.00", "rate": "1.0", "status": "open" }, { "asset": "BTC", "network": "bitcoin", "amount_crypto": "0.000524", "rate": "93457.91", "status": "open" }, { "asset": "TON", "network": "ton", "amount_crypto": "9.81", "rate": "4.99", "status": "open" }, { "asset": "ETH", "network": "ethereum", "amount_crypto": "0.0101", "rate": "2970.29", "status": "open" }, { "asset": "BNB", "network": "bsc", "amount_crypto": "0.0815", "rate": "601.22", "status": "open" }, { "asset": "SOL", "network": "solana", "amount_crypto": "0.3267", "rate": "150.06", "status": "open" , { "asset": "XRP", "network": "ripple", "amount_crypto": "9.55", "rate": "2.19", "status": "open" , { "asset": "NEAR", "network": "near", "amount_crypto": "1.8182", "rate": "5.50", "status": "open" } ] }Send the buyer to checkout
Redirect to checkout_url: every coin with its amount and address, a QR code, a live TTL timer and 5-second status polling. EN/RU and white-label are built in. This is what your customer sees:
demo — cycles automatically
Interactive demoH#1042HostCare
VPS & VPN hosting
Amount due
$49.00
Expires in 29:47
Pay with
49.00 USDT TRC-20
TQn9Y2khES6uN9fgPqwPZLvWrRqXBqYm6B
Waiting for paymentThis is a static demo. The live checkout lives at /pay/[id] in the merchant console.
The buyer chooses; you settle on the same invoice.
USDT (TRON)TRXUSDC (Arbitrum)BTCLTCDOGEBCHSOLXRPNEARXMRTONETHBNB
Receive the webhook
payment.confirmed is the money event: invoice and order ids, the paid option, the transaction with hash, confirmations and an explorer link, plus your metadata. Answer 2xx within 10 seconds; deliveries are at-least-once with a 1m → 5m → 30m → 2h → 12h retry ladder — make your handler idempotent on evt.id.
{ "type": "payment.confirmed", "created_at": "2026-09-06T14:02:33Z", "data": { "invoice_id": "inv_9f2k...", "order_id": "order-1042", "amount": "49.00", "base_currency": "USD", "option": { "asset": "TON", "network": "ton", "amount_crypto": "9.81", "paid_amount": "9.81" }, "tx": { "hash": "9d24...", "confirmations": 1, "explorer_url": "https://tonviewer.com/transaction/9d24...", "output_index": 0 }, "metadata": { "customer_id": "cust_8821" } } }Verify the signature
Every webhook is signed. The X-ZKP-Signature header carries t= and v1=; the HMAC-SHA256 is computed over "{t}.{raw_body}" with a 5-minute window. If you skipped this check, you cannot trust the payload.
import { createHmac, timingSafeEqual } from "node:crypto"; // X-ZKP-Signature: t=1694007753,v1=ade537fa... const [t, v1] = Object.fromEntries( req.headers["x-zkp-signature"].split(",").map((p) => p.trim().split("=")), ); const expected = createHmac("sha256", WEBHOOK_SECRET) .update(`${t}.${req.rawBody}`) .digest("hex"); const ok = timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(v1, "hex")); if (!ok || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.status(400).end();Go live
Swap pk_test for pk_live — the code does not change. Before production, walk the checklist: HMAC verification on; idempotency by evt.id; underpaid/expired/canceled handled; Idempotency-Key on creation; rate limits accounted for.
Go-live checklist
- HMAC verification enabled on every webhook endpoint
- Idempotency by evt.id across retries
- underpaid, expired and canceled events handled
- Idempotency-Key sent on invoice creation
- Rate limits accounted for (30 invoices/min live)
Don't want to touch code? We'll integrate for you
A done-for-you integration by the team that built the platform.
- Your connected wallets (direct-only checkout)
- Checkout embedded into your site or service (button, redirect or API)
- Webhook receiver with HMAC verification on your stack
- A sandbox test payment and a control live payment
- A short operations checklist handed over to you
from $99·Usually 1–2 business days.
Integration FAQ
Is KYC required?
No. Sign-up is email, password and 2FA; KYC is not requested at any stage — not for the sandbox, not for live keys.
How long does integration take?
The hosted checkout takes about 5 minutes with no code. The API path usually takes about an hour including webhook verification. Done-for-you takes 1–2 business days.
Can I accept payments with zero code?
Yes: create an invoice in the console and send the buyer its checkout link or QR. The hosted page does the rest.
What do I need for live keys?
Connect a wallet for any of the 22 assets — the live key is issued in the console right after. The free plan covers up to $500/mo.
Which languages and frameworks are supported?
The API is plain REST over HTTPS with signed webhooks. Official SDKs cover Node.js, PHP and Python, and there is a WooCommerce plugin.
Can you build a custom integration for us?
Yes — that is the done-for-you service. Message us on Telegram and we will scope it.
Start accepting crypto today
A sandbox account is free and takes one email.