Authentication
Create an API key in your dashboard under API Keys and send it as a Bearer token with every request. Keep it on your server, never in the browser.
Authorization: Bearer izpk_live_YOUR_KEY
Every response has the form {"success": true, "data": {…}}, or {"success": false, "error": {…}} with a 4xx status.
Create a payment
POST /payments
Creates a payment and returns a unique deposit address. Show the address and the amount to your customer, as text or as a QR code.
| Field | Required | Description |
|---|---|---|
price_amount | Yes | Amount to collect in USD, for example 100.00. |
pay_currency | Yes | What the customer pays with. See Coins. |
order_id | No | Your order reference. It comes back in webhooks. |
order_description | No | Free text description. |
ipn_callback_url | No | Webhook URL for this payment only, overrides the one in your dashboard. |
sandbox | No | true with a test key to create a test payment. |
# cURL
curl -X POST https://gate.izipay.me/api/v1/payments \
-H "Authorization: Bearer izpk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"price_amount": 100.00, "pay_currency": "usdttrc20", "order_id": "order-1042"}'
// Node.js
const res = await fetch("https://gate.izipay.me/api/v1/payments", {
method: "POST",
headers: { "Authorization": "Bearer " + process.env.IZIGATE_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ price_amount: 100, pay_currency: "usdttrc20", order_id: "order-1042" })
});
const { data } = await res.json();
console.log(data.pay_address, data.pay_amount);
# Python
import requests
r = requests.post("https://gate.izipay.me/api/v1/payments",
headers={"Authorization": "Bearer izpk_live_YOUR_KEY"},
json={"price_amount": 100, "pay_currency": "usdttrc20", "order_id": "order-1042"})
data = r.json()["data"]
Response:
{
"success": true,
"data": {
"payment_id": "7cc73692-b5d3-402d-9c15-6495bcc7a3d7",
"status": "waiting",
"pay_address": "TY7vA68AS2s6tN7Fe7xqEdusCfpPBcJBc8",
"pay_amount": 100,
"pay_currency": "usdt",
"network": "trc20",
"price_amount": 100,
"expires_at": "2026-09-19 08:38:43",
"qr_data": "TY7vA68AS2s6tN7Fe7xqEdusCfpPBcJBc8"
}
}
Get a payment
GET /payments/{payment_id} GET /payments?limit=50&status=confirmed
Poll a single payment or list your payments. Most integrations just wait for the webhook.
Statuses
| Status | Meaning |
|---|---|
waiting | The address is open, nothing confirmed yet. |
confirmed | The payment is confirmed on chain and credited to your balance. |
partially_paid | Less than the amount arrived. |
expired | Nothing arrived before expires_at. |
failed | The payment could not be processed. |
Webhooks
Set your endpoint in the dashboard under Webhooks. It must be a public https:// URL. Each event is a JSON POST with an X-Signature header: HMAC-SHA256 of the raw body with your signing secret (whsec_…).
Events: payment.confirmed, payment.partial, payment.failed, payout.pending, payout.completed, payout.failed.
{
"id": "evt_f360f9685e79bf88b60050fe",
"type": "payment.confirmed",
"created": 1789656000,
"data": {
"payment_id": "7cc73692-b5d3-402d-9c15-6495bcc7a3d7",
"order_id": "order-1042",
"status": "confirmed",
"pay_currency": "USDT",
"network": "trc20",
"amount_paid": 100,
"amount_usd": 100,
"fee_usd": 1,
"credited_usd": 99,
"balance_usd": 99
}
}
// PHP: verify the signature
$raw = file_get_contents("php://input");
$expected = hash_hmac("sha256", $raw, "whsec_YOUR_SIGNING_SECRET");
if (!hash_equals($expected, $_SERVER["HTTP_X_SIGNATURE"] ?? "")) { http_response_code(400); exit; }
$event = json_decode($raw, true);
if ($event["type"] === "payment.confirmed") { /* mark the order as paid */ }
http_response_code(200);
// Node.js (raw body)
const sig = crypto.createHmac("sha256", process.env.IZIGATE_WHSEC).update(req.rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.get("X-Signature") || ""))) return res.sendStatus(400);
Balance
GET /gateway/balance
Your balance (confirmed payments minus fees and payouts) and the latest ledger entries.
Payouts
POST /payouts { "amount_usd": 250, "network": "trc20", "currency": "usdt", "address": "TYourWallet…" } GET /payouts
Withdraws your balance to your own wallet. The minimum is $10. The amount is reserved immediately and a flat network fee is deducted from it, so your wallet receives amount_usd minus the fee. The response shows both network_fee and net_amount. USDT payouts on Tron up to $200 are sent automatically within minutes, larger ones are sent after a manual check.
Auto settlement
Turn on auto settlement in Settings and add a Tron USDT address. Each confirmed USDT payment on Tron is then forwarded straight to your wallet, minus the 1% fee and the Tron network fee, without going through your balance.
Coins
| Network | Coins | pay_currency |
|---|---|---|
| Tron (TRC20) | USDT, USDC, TRX | usdttrc20, usdctrc20, trx |
| BNB Smart Chain | USDT, BNB | usdtbsc, bnb |
| Polygon | USDT | usdtpolygon |
| Ethereum (ERC20) | USDT, ETH | usdterc20, eth |
| Solana | USDT, SOL | usdtsol, sol |
| Bitcoin | BTC | btc |
Fees
No monthly fee. We deduct 1% from each confirmed payment before it is credited. Payouts have a flat network fee:
| Network | Fee per payout |
|---|---|
| Tron (TRC20) | $3.00 |
| BNB Smart Chain | $0.50 |
| Polygon | $0.20 |
| Ethereum (ERC20) | $3.00 |
| Solana | $0.20 |
| Bitcoin | $2.00 |
Sandbox
Ask support@izipay.me for a test key (prefix izpk_test_). Create a payment with "sandbox": true, then confirm it without real crypto:
curl -X POST https://gate.izipay.me/api/v1/sandbox/confirm \
-H "Authorization: Bearer izpk_test_YOUR_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{"payment_id": "PAYMENT_ID_FROM_CREATE"}'
You receive the same webhook as in production. Sandbox payments never change your real balance, and test keys cannot request payouts.
Questions? Write to support@izipay.me.