tgpay cryptoAPI
crypto-payapiwebhookssignature

Справочник API: вебхуки

3 мин чтенияОбновлено 9 окт. 2026 г.

Вебхуки доставляют события на ваш сервер после того, как они произошли. Задайте приложению 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 → действовать.