Clean REST API, real-time webhooks, and SDKs in every major language. Accept crypto payments with a few lines of code.
curl -X POST https://zateway.com/api/v1/payments \ -H "X-API-Key: zate_sk_..." \ -H "Content-Type: application/json" \ -d '{"amount":"<n>50.00</n>","currency":"USDT","chain":"polygon"}'A single, consistent REST API for creating payments, managing webhooks, and querying transaction data.
https://zateway.com/api/v1
API key via X-API-Key header
JSON request & response bodies
| Method | Endpoint | Description |
|---|---|---|
| POST | /payments | Create a new payment session |
| GET | /payments/:id | Retrieve payment details |
| POST | /payment-links | Create a reusable payment link |
| GET | /payment-links | List your payment links |
| GET | /currencies | List supported currencies & chains |
| POST | /refunds | Create a refund request |
| GET | /status | Check API and chain listener health |
From zero to live payments in under five minutes.
Sign up and grab your API key from the Dashboard under Settings → API Keys. Your key starts with zate_sk_.
Send a POST request to create a payment session. You'll receive a checkout URL to redirect your customer. Required fields: amount, currency, chain, and merchantWallet (your receiving wallet address).
curl -X POST https://zateway.com/api/v1/payments \ -H "X-API-Key: zate_sk_..." \ -H "Content-Type: application/json" \ -d '{"amount": "<n>50.00</n>", "currency": "USDT", "chain": "polygon", "merchantWallet": "0x..."}'Register a webhook URL in the Dashboard. We'll notify you when a payment is confirmed, failed, or expired.
{ "event": "payment.confirmed", "data": { "id": "pay_abc123", "amount": "<n>50.00</n>", "currency": "USDT", "chain": "polygon", "status": "confirmed", "txHash": "0xabc...def", "confirmedAt": "<n>2026</n>-<n>03</n>-25T12:<n>00</n>:00Z" }, "timestamp": "<n>2026</n>-<n>03</n>-25T12:<n>00</n>:05Z"}Subscribe to payment lifecycle events. Every webhook is signed with HMAC-SHA256 so you can verify authenticity.
| Event | Description |
|---|---|
| payment.confirmed | Payment has been confirmed on-chain |
| payment.failed | Payment failed or was rejected |
| payment.expired | Payment session expired without payment |
| payment.underpaid | Received amount is less than expected |
Every webhook includes three headers for verification: X-Zateway-Signature (format: sha256=<hmac>), X-Zateway-Timestamp (unix seconds), and X-Zateway-Nonce (unique string). The signature is computed as HMAC-SHA256(secret, timestamp.nonce.payload).
const crypto = require('crypto');function verifyWebhook(req, secret) { const signature = req.headers['x-zateway-signature']; const timestamp = req.headers['x-zateway-timestamp']; const nonce = req.headers['x-zateway-nonce']; const payload = JSON.stringify(req.body); // Check timestamp freshness (5 min window) const age = Math.abs(Date.now() / 1000 - parseInt(timestamp)); if (age > 300) return false; // Verify HMAC const message = `${timestamp}.${nonce}.${payload}`; const expected = crypto.createHmac('sha256', secret) .update(message).digest('hex'); const actual = signature.replace('sha256=', ''); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(actual) );}All errors return a JSON object with a single error string field.
| Code | Status | Description |
|---|---|---|
| 400 | Bad Request | Invalid parameters or missing required fields |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | API key lacks permission for this action |
| 404 | Not Found | Resource does not exist |
| 429 | Too Many Requests | Rate limit exceeded (varies by endpoint) |
| 500 | Internal Server Error | Something went wrong on our end |
Retry-After header.{ "error": "Amount must be a positive number"}Start building with Zateway today. Full API reference, guides, and support are just a click away.