Справочник API: вебхуки
Вебхуки доставляют события на ваш сервер после того, как они произошли. Задайте приложению Webhook URL (необязательно) в разделе Ещё → Merchant API — и платформа будет отправлять POST с подписанным JSON-телом на каждое событие, на которое вы подписаны.
Формат сообщения
{
"update_id": 123,
"update_type": "invoice_paid",
"request_date": "2026-08-11T12:00:00Z",
"payload": { … }
}
update_id не меняется между повторными доставками одного события —
стройте дедупликацию на нём. request_date проставляется при каждой
попытке доставки. payload — полный объект для типа события: объект
счёта для событий счетов, объект чека, перевода или подписки (их состав — на
страницах справочника).
Типы событий
update_type | Когда отправляется | Payload |
|---|---|---|
invoice_paid | счёт оплачен — не требует отдельного включения | объект счёта |
invoice_expired | срок счёта истёк без оплаты | объект счёта |
check_activated | активирован чек или получена доля из чека со списком | объект чека; для списка также activated_slot |
check_expired | истёк срок чека со списком, неполученные доли вернулись приложению | объект чека с recipients и значениями claimed_at |
transfer_completed | перевод завершён или выплата в блокчейне подтверждена | объект перевода или вывода |
transfer_returned | неполученный перевод вернулся приложению или выплата в блокчейне не состоялась и резерв вернулся на баланс | объект перевода или вывода |
refund_completed | выполнен возврат | объект счёта с полями refunded_* |
subscription_activated | пользователь подтвердил план | объект подписки |
subscription_charged | списана плата за период — какой именно, говорит charge.kind: initial, renewal или resubscribe | объект подписки + charge: {period_no, kind, asset, amount, fee, paid_at} |
subscription_cancelled | подписка отменена любой из сторон | объект подписки |
subscription_expired | льготный период истёк без оплаты | объект подписки |
Выплаты в блокчейне, созданные в приложении, используют те же события переводов.
В их payload есть kind: "withdrawal", поля network, address, txid
и статус completed или failed. Их transfer_id относится к отдельной
последовательности идентификаторов: прежде чем использовать его, определите
тип объекта по kind. Оба варианта payload описаны в скачиваемой спецификации OpenAPI.
Всё, кроме invoice_paid, включается по желанию (расширение над
Crypto Bot — обработчик, написанный строго под Crypto Bot, никогда не
встретит незнакомый update_type, если вы сами его не включили).
Включаются события на карточке приложения на экране Merchant API, в
блоке Дополнительные webhook-события раздела Webhook. Тумблеры
названы идентификаторами из таблицы выше. Для доставки событий сохраните
Webhook URL.
Проверка подписи
В каждой доставке есть заголовок TgPayCrypto-API-Signature
(прежнее TgCryptoPay-API-Signature и Crypto-Pay-API-Signature — псевдонимы для совместимости, значение то
же): hex-значение HMAC-SHA256 от сырого тела запроса с ключом —
SHA-256-дайджестом основного API-токена приложения. Это схема
Crypto Bot, так что существующий код проверки работает без изменений:
import hashlib, hmac
secret = hashlib.sha256(API_TOKEN.encode()).digest()
expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, headers["TgPayCrypto-API-Signature"])
Проверяйте по сырым полученным байтам — если разобрать JSON и сериализовать его заново, байты могут отличаться, и проверка не пройдёт. Подписывает только основной токен; ограниченные токены — никогда. Обновление основного токена мгновенно меняет ключ подписи — обновите секрет на своём сервере одновременно с ним.
Доставка и повторы
- Доставка считается успешной при ответе 2xx, полученном до таймаута попытки. Отвечайте быстро, а долгие задачи выполняйте отдельно.
- После ошибки, таймаута или обрыва соединения доставка повторяется с
растущими интервалами до установленного платформой числа попыток.
Доставка не гарантирована: после сбоя сверяйте платежи через
getInvoices. - После последней попытки доставка отбрасывается. Сам Webhook URL никогда не отключается автоматически — нестабильный сервер не отпишет ваше приложение от событий незаметно для вас.
- Поскольку доставки повторяются, обработчик
обязан быть идемпотентным: дедуплицируйте по
update_id, прежде чем действовать.
⚠️ Сначала проверка — потом выполнение
Отправить POST на ваш Webhook URL может кто угодно. Пока проверка
подписи не прошла, считайте тело запроса недоверенными данными: не
отгружайте заказ, ничего не начисляйте пользователю, ничего не помечайте
оплаченным.
Безопасный порядок: проверить подпись → дедуплицировать по update_id
→ действовать.
Была ли статья полезной?
Спасибо за отзыв.