tgpay cryptoAPI
crypto-payapiwebhookssignature

Referência da API: webhooks

3 min de leituraAtualizado em 11 de ago. de 2026

Os webhooks empurram eventos para o seu servidor no momento em que eles acontecem. Defina a URL de webhook 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 é carimbado a 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 ou o objeto de assinatura (os formatos estão nas páginas de referência de cada um).

Tipos de evento

update_typeQuando disparaPayload
invoice_paiduma fatura é paga — sempre entregueobjeto de fatura
invoice_expireduma fatura passa do prazo sem ser pagaobjeto de fatura
check_activatedum dos seus cheques é resgatadoobjeto de cheque
refund_completedum reembolso é executadoobjeto de fatura com os campos refunded_*
subscription_activatedum usuário aprova um planoobjeto de assinatura
subscription_chargedum período é cobrado — o charge.kind diz qual: initial, renewal ou resubscribeobjeto de assinatura + charge: {period_no, kind, asset, amount, fee, paid_at}
subscription_cancelleduma assinatura é cancelada por qualquer um dos ladosobjeto de assinatura
subscription_expiredo período de carência acaba sem pagamentoobjeto de assinatura

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 tela API para comerciantes — as chaves aparecem quando uma URL de webhook é definida, e são identificadas pelos identificadores brutos da tabela acima.

Verificando a assinatura

Toda entrega traz o cabeçalho TgCryptoPay-API-Signature (Crypto-Pay-API-Signature é um alias 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["TgCryptoPay-API-Signature"])

Verifique sobre os bytes brutos recebidos — um parse reserializado pode diferir byte a byte e reprovar na checagem. 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 no mesmo movimento.

Entrega e novas tentativas

  • Uma entrega conta como bem-sucedida com qualquer resposta 2xx em até 10 segundos.
  • Qualquer outra coisa — um status de erro, um timeout, uma falha de conexão — é repetida com backoff exponencial: a primeira nova tentativa depois de cerca de 10 segundos, com o intervalo dobrando até 8 horas, em até 17 tentativas espalhadas por mais ou menos 3 dias.
  • 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_id antes 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.