Вебхуки
У аккаунта один URL вебхука, и все события уходят на него. Задайте его в Dashboard → API или через Настройку вебхука.События
Сегодня существует шесть событий.Конверт
У каждой доставки три одинаковых ключа верхнего уровня.timestamp — момент, когда мы собрали событие, ISO-8601 в UTC.
Response
order.updated
number
ID заказа.
string
energy или bandwidth.string
processing, filled, partial, failed, reclaimed или reclaim_failed. Это поле — источник истины, см. предупреждение ниже.string
Адрес, которому делегирован ресурс.
number
Заказанный объём — единицы энергии или пункты bandwidth.
number
То же, что
volume. Присутствует, чтобы сравнивать ожидаемое с доставленным, не выясняя, какое поле что означает.number
Сколько фактически делегировано на данный момент. Равно
volume, когда заказ filled; на processing и partial — сумма уже выданных частей; 0 при отказе.string
Цена заказа в TRX, десятичной строкой.
string | null
Транзакция, которой ресурс делегирован.
string | null
Транзакция, которой его забрали обратно по окончании аренды.
string | null
Когда ресурс запланировано отозвать, ISO-8601, либо
null для заказов без таймера отзыва.Response
subscription.transfer
number
Подписка Smart Mode, к которой относится перевод.
string
Отслеживаемый адрес, с которого ушёл перевод.
string | null
Метка, которую вы дали подписке.
string
Транзакция перевода в сети.
number
Сколько переводов покрыла эта делегация.
number
Сколько энергии под них делегировано.
string
Сколько списано за энергию, в TRX.
string | null
Сколько списано за bandwidth сверху, либо
null, если не списывалось.string
Баланс аккаунта после списания.
string
Когда перевод обработан. Обратите внимание: это поле внутри
data и отличается от timestamp самого конверта.Response
События Transfer Package
Четыре событияpackage.* уходят аккаунту, которому принадлежит пакет. У пакета, купленного по инвойсу без входа в аккаунт и без API-ключа, владельца нет, и событий по нему не будет. Не будет их и по отменённым инвойсам, отклонённым покупкам и покупкам на ручной проверке; пакет с проверки пришлёт package.activated, когда будет активирован.
Каждое событие package.* несёт в data эти поля:
number
ID пакета —
id в Списке пакетов.string
Адрес, который обслуживает пакет.
string
Статус пакета после события:
active или completed у package.transfer, completed у package.completed, active у package.activated, expired у package.expired.number
Сколько переводов было в пакете при покупке.
number
Сколько переводов осталось в пакете после изменения, о котором сообщает событие, — абсолютное число, а не разница.
remaining может уменьшиться и без события. Пакет на несколько переводов списывает один перевод в сутки как суточную подписку — первый при активации, поэтому пакет на 500 переводов начинается с remaining: 499, — и об этом списании событие не приходит. Два перевода с одного адреса в одном блоке могут прислать одинаковый remaining. Считайте remaining подсказкой, а источником правды — Список пакетов.(package_id, tx_hash) для package.transfer и (event, package_id) для остальных: повтор приходит с тем же телом, тем же timestamp и той же подписью.
package.transfer
Перевод с адреса оплачен из пакета. Отправляется по одному разу на каждый пакет, с которого списан перевод, — почти всегда одно событие на перевод; перевод, забравший последний перевод одного пакета и продолжившийся на следующем, даёт по событию на каждый.
string
Транзакция перевода в сети.
number
Сколько переводов списано с этого пакета за эту транзакцию. Перевод на адрес, где нет USDT, требует двойной энергии и считается за
2 — их можно разделить между двумя пакетами.status равен completed, если этот перевод исчерпал пакет.
Response
package.completed
Пакет перестал обслуживать переводы.
string
transfer — пакет исчерпан переводом; subscription — его исчерпало суточное списание; manual — пакет закрыла поддержка. После manual значение remaining может быть больше нуля, но эти переводы использовать уже нельзя.string | null
При
reason: "transfer" — перевод, закрывший пакет; иначе null.package.transfer: придёт только package.completed с tx_hash этого перевода.
Response
package.activated
Пакет стал активным, и с этого момента его переводы получают энергию. Отправляется при каждой активации — в том числе при покупке с баланса, хотя её ответ уже содержит active, и при оплате инвойса, которая активирует пакет вскоре после того, как платёж виден в сети.
string
Как оплачен пакет: ровно
balance, TRX или USDT.Response
package.expired
Инвойс на пакет не оплачен за отведённые 30 минут. Ничего не списано; чтобы получить новый инвойс, купите заново. Дополнительных полей нет; remaining равен quota_total и для использования недоступен.
Response
Доставка
- До 3 попыток, с паузами 1 секунда и затем 4 секунды между ними. После успеха и после последней попытки пауз нет.
- Таймаут 10 секунд на попытку.
- Мы ждём любой
2xx. Всё остальное считается неудачной попыткой. - Редиректы не следуются.
301/302— это неудачная попытка, а не переход. - Пропущенные события не досылаются. Если все три попытки не удались, событие потеряно; сверяйтесь через Получение заказа или Список пакетов, а не ждите повтора.
Проверка подписи
Каждый запрос несётX-Webhook-Signature: sha256=<hex> — HMAC-SHA256 по сырому телу запроса с вашим секретом вебхука.
Работоспособность вашей проверки решают две детали:
- Отрежьте префикс
sha256=перед сравнением. В заголовке не голый hex-дайджест. - Хешируйте полученные байты, а не пересобранный объект. Разбор JSON и повторная сериализация меняют порядок ключей и пробелы — подпись не сойдётся никогда.