Вебхуки
При каждом изменении заявки мы отправляем POST на ваш адрес. Тело — событие с тем же объектом заявки, что отдаёт GET /orders/{id}.
Как включить
- Откройте проект в кабинете → «Вебхук».
- Укажите адрес, только
https://. - Сохраните. Сайт создаст секрет для подписи и покажет его там же — скопируйте его на свой сервер.
Удалили адрес — секрет удаляется вместе с ним. Новый адрес получит новый секрет.
Событие
id- Номер события,
evt_…. Одно событие может прийти дважды — отбрасывайте повторы поid. typeorder.createdилиorder.updated.createdAt- Когда событие создано.
data.order- Объект заявки на момент события.
Заголовки
Content-Typeapplication/jsonUser-Agent666.exchange-webhooks/2X-666-Signaturet=<время в секундах Unix>,v1=<подпись>
{
"id": "evt_9a41c7e0d3b25f86e1a07c34",
"type": "order.updated",
"createdAt": "2026-10-25T13:06:41.208Z",
"data": {
"order": {
"id": "Q7M2-KD4X",
"state": "confirming",
"rate": "floating",
"from": {
"asset": "USDT",
"network": "TRON",
"amount": "250",
"received": "250"
},
"to": {
"asset": "BTC",
"network": "BITCOIN",
"amount": "0.00241318"
},
"deposit": {
"address": "TJ4w2XqvQ7m1pHk9sF3nRbL6cVyE8dZt5U",
"network": "TRON",
"trusted": true,
"expiresAt": "2026-10-25T14:00:00.000Z",
"confirmations": {
"seen": 4,
"required": 20
},
"txHash": "a3f09c1e…"
},
"payout": {
"address": "bc1q9h7garjxw5c3l8wmxq0y8wzg7l3f5n2t4u6v8x"
},
"reference": "inv_20931",
"pageUrl": "https://666.exchange/swap/Q7M2-KD4X",
"createdAt": "2026-10-25T13:00:00.000Z",
"updatedAt": "2026-10-25T13:06:40.000Z"
}
}
}Проверка подписи
v1 — HMAC-SHA256 в hex от строки t + "." + тело на вашем секрете. Считайте подпись по телу в том виде, в каком оно пришло, до разбора JSON. Запросы с t старше 5 минут отклоняйте.
import crypto from 'node:crypto';
// rawBody: the request body as received (Buffer), before JSON.parse
export function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const want = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const got = String(parts.v1 || '');
return got.length === want.length && crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want));
}Доставка и повторы
- Ответ
- Ждём до 10 секунд. Доставлено — любой код
2xx. - Повторы
- Нет ответа или другой код — ещё попытки через 2, 4, 8, 16 и 30 секунд. Всего шесть попыток.
- Порядок
- Не гарантирован. Сравнивайте
data.order.updatedAtили запроситеGET /orders/{id}.
Отвечайте 200 сразу, а обрабатывайте событие после ответа: долгая обработка внутри запроса превращается в повторы.
Если вебхуки не приходят
- Проект выключен или ключ отозван — для такого проекта события не отправляются.
- Адрес недоступен из интернета или отвечает не по HTTPS.
- Ваш сервер отвечает
401: подпись считается по разобранному и снова собранному JSON, а не по исходному телу.