Referência da API: webhooks
Os webhooks enviam eventos ao seu servidor depois que eles acontecem. Defina a URL de webhook (opcional) do seu app em Mais → API para comerciantes; a plataforma então faz POST de um corpo JSON assinado para cada evento que você assinou.
O envelope
{
"update_id": 123,
"update_type": "invoice_paid",
"request_date": "2026-08-11T12:00:00Z",
"payload": { … }
}
O update_id é estável entre as reentregas do mesmo evento — baseie sua
deduplicação nele. O request_date registra a data e a hora de cada tentativa de entrega. O
payload é o objeto completo daquele tipo de evento: o objeto de fatura nos
eventos de fatura, o objeto de cheque, de transferência ou de assinatura (os formatos
estão nas páginas de referência de cada um).
Tipos de evento
update_type | Quando dispara | Payload |
|---|---|---|
invoice_paid | uma fatura é paga — não exige ativação separada | objeto de fatura |
invoice_expired | uma fatura passa do prazo sem ser paga | objeto de fatura |
check_activated | um cheque ou a parte de um destinatário é resgatada | objeto de cheque; no resgate de uma lista de destinatários, inclui também activated_slot |
check_expired | um cheque com lista de destinatários expira e as partes não resgatadas voltam ao app | objeto de cheque com recipients e seus valores de claimed_at |
transfer_completed | uma transferência é concluída ou um pagamento on-chain é confirmado | objeto de transferência ou de saque |
transfer_returned | uma transferência pendente não recebida volta ao app, ou um pagamento on-chain falha e o valor reservado é devolvido | objeto de transferência ou de saque |
refund_completed | um reembolso é executado | objeto de fatura com os campos refunded_* |
subscription_activated | um usuário aprova um plano | objeto de assinatura |
subscription_charged | um período é cobrado — o charge.kind diz qual: initial, renewal ou resubscribe | objeto de assinatura + charge: {period_no, kind, asset, amount, fee, paid_at} |
subscription_cancelled | uma assinatura é cancelada por qualquer um dos lados | objeto de assinatura |
subscription_expired | o período de carência acaba sem pagamento | objeto de assinatura |
Pagamentos on-chain criados no app usam esses mesmos eventos de transferência.
O payload tem kind: "withdrawal", campos da blockchain como network, address
e txid, e status completed ou failed. Seu transfer_id pertence a uma
sequência de IDs separada; diferencie os payloads por kind antes de usá-lo.
A referência OpenAPI para download descreve as duas variantes.
Tudo, menos o invoice_paid, é opcional (uma extensão sobre o Crypto Bot —
um consumidor estritamente no formato do Crypto Bot nunca encontra um
update_type desconhecido, a não ser que você peça). Ative por app, em Eventos
extras de webhook, na seção Webhook do app. As opções usam os identificadores da tabela acima. Salve uma URL de webhook para receber os eventos.
Verificando a assinatura
Toda entrega traz o cabeçalho TgPayCrypto-API-Signature
(TgCryptoPay-API-Signature e Crypto-Pay-API-Signature são aliases de
compatibilidade com o mesmo valor): o
HMAC-SHA256 em hexadecimal do corpo bruto da requisição, com chave igual ao
digest SHA-256 do token de API principal do seu app. É o esquema do Crypto
Bot, então o código de verificação existente funciona sem mudança:
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"])
Verifique sobre os bytes brutos recebidos — interpretar o JSON e serializá-lo novamente pode alterar os bytes e fazer a verificação falhar. Só o token principal assina; os tokens restritos nunca assinam. Rotacionar o token principal troca a chave da assinatura de webhook na hora, então atualize o segredo no seu servidor ao mesmo tempo.
Entrega e novas tentativas
- Uma entrega conta como bem-sucedida quando uma resposta 2xx chega antes do timeout. Responda rapidamente e processe tarefas demoradas separadamente.
- Um status de erro, timeout ou falha de conexão provoca novas tentativas com intervalos crescentes, até o limite de tentativas da plataforma. A entrega não é garantida; use
getInvoicespara conferir os pagamentos após uma indisponibilidade. - Depois da última tentativa, a entrega é descartada. A URL de webhook em si nunca é desativada automaticamente — um endpoint instável não cancela a inscrição do seu app em silêncio.
- Como as novas tentativas acontecem, seu handler precisa ser idempotente:
deduplique pelo
update_idantes de agir.
⚠️ Verifique antes de entregar
Qualquer um pode fazer POST na sua URL de webhook. Até a checagem de assinatura
passar, trate o corpo como entrada não confiável: não envie um pedido, não credite
um usuário, não marque nada como pago. A ordem segura é: verificar a assinatura →
deduplicar pelo update_id → agir.
Este artigo foi útil?
Obrigado pelo retorno.