Pular para o conteúdo principal

Visão Geral de Webhooks

A A55 envia webhooks via HTTP POST para o seu servidor quando os status de cobrança, assinatura e pagamento mudam. Webhooks permitem reações em tempo real sem polling.


Por que webhooks

AbordagemLatênciaConfiabilidadeCarga na A55
Webhooks (push)SegundosAt-least-once com retentativasMínima
Polling (pull)Depende do intervaloNunca perde (compensa atrasos)Maior

Use webhooks como canal primário de notificação e polling como fallback de reconciliação.


Configuração

Defina webhook_url na requisição de cobrança, ou configure uma URL padrão no dashboard da A55.

ParâmetroEscopoDescrição
webhook_url na cobrançaPor cobrançaRecebe eventos apenas daquela cobrança
URL padrão no dashboardToda a contaUsada quando webhook_url é omitida

Detalhes de entrega

PropriedadeValor
MétodoPOST
Content-Typeapplication/json
Timeout30 segundos
TLSSomente HTTPS (HTTP é rejeitado)

Verificação de assinatura HMAC

A A55 assina todo webhook com HMAC-SHA256. Sempre verifique antes de processar.

HeaderConteúdo
X-Webhook-Signaturesha256={hex_signature}
X-Webhook-TimestampTimestamp Unix (segundos)

Etapas de verificação

  1. Extraia os headers X-Webhook-Signature e X-Webhook-Timestamp
  2. Rejeite se o timestamp for mais antigo que 5 minutos (proteção contra replay)
  3. Construa o payload assinado: {timestamp}.{raw_body}
  4. Compute HMAC-SHA256 com seu webhook secret
  5. Compare usando comparação timing-safe
  6. Processe o evento somente se a assinatura corresponder
import hmac, hashlib, time

def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
signed_payload = f"{timestamp}.".encode() + payload
expected = hmac.new(secret.encode(), signed_payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature.removeprefix("sha256="))
Segurança

Nunca processe um webhook sem verificar a assinatura HMAC. Webhooks não verificados podem ser forjados por atacantes.


Política de retentativas

Entregas com falha são retentadas com backoff exponencial ao longo de 24 horas:

TentativaAtrasoAcumulado
1ImediataT+0
21 minutoT+1m
35 minutosT+6m
430 minutosT+36m
52 horasT+2h 36m
66 horasT+8h 36m
724 horasT+32h 36m

Após 7 tentativas falhadas, o evento é marcado como falha no dashboard.

O que dispara uma retentativa

RespostaRetenta?Motivo
200–299NãoEntregue com sucesso
400–499NãoErro do cliente — retentar não ajudará
500–599SimErro do servidor — transiente
Timeout (>30s)SimEndpoint muito lento
Conexão recusadaSimEndpoint indisponível

Idempotência

Webhooks usam entrega at-least-once. O mesmo evento pode chegar mais de uma vez. Seu handler deve ser idempotente.

def handle_webhook(event):
event_id = event["id"]
if db.webhook_events.find_one({"event_id": event_id, "status": "completed"}):
return Response(status=200)
db.webhook_events.upsert({"event_id": event_id, "status": "processing"})
process_event(event)
db.webhook_events.update({"event_id": event_id, "status": "completed"})
return Response(status=200)
Resposta rápida

Retorne HTTP 200 imediatamente após receber o evento. Processe lógica pesada em um job de background para que o handler não estoure o timeout.


Tipos de evento

DomínioEventos
Cobrançascharge.authorized, charge.captured, charge.failed, charge.refunded, charge.cancelled, charge.chargeback
PIXpix.received, pix.expired, pix.refunded
Boletoboleto.paid, boleto.expired, boleto.cancelled
Assinaturassubscription.created, subscription.renewed, subscription.failed, subscription.cancelled

Veja Webhook de cobrança para detalhes do payload.


Testes

FerramentaMelhor para
webhook.siteInspecionar payloads visualmente
ngrokEncaminhar para localhost
A55 sandboxEventos de teste similares a produção