Webhooks

Como o IndicaSaaS recebe os eventos de venda do seu gateway com segurança: assinatura verificada, idempotência, resposta rápida e processamento assíncrono com retentativa.

Você não chama estes endpoints — o gateway chama. Esta página é referência para depurar a entrega. A configuração de cada webhook está na página do seu gateway.

Endpoints

Dois formatos, conforme o tipo de conexão:

ConexãoEndpointGateways
OAuthPOST /webhooks/<gateway>Stripe, Mercado Pago — endpoint único; o merchant vem no próprio evento
API-keyPOST /webhooks/<gateway>/<token>Asaas, AbacatePay — o token na URL identifica o seu SaaS

Verificação de assinatura

Todo evento é verificado antes de qualquer processamento (HMAC-SHA256 via Web Crypto, comparação em tempo constante). Assinatura inválida → 400.

GatewayHeaderComoSecret
Stripestripe-signatureHMAC sobre timestamp.corpo; tolerância 10 min (anti-replay)plataforma
Mercado Pagox-signature + x-request-idHMAC sobre o manifesto id;request-id;ts; tolerância 5 minplataforma
Asaasasaas-access-tokentoken estático comparado em tempo constantepor merchant (gerado no connect)
AbacatePayx-webhook-signatureHMAC sobre o corpopor merchant (gerado no connect)

Idempotência

Cada evento é gravado com uma chave única (gateway, id_do_evento). Reentregas do mesmo evento respondem 200 e são descartadas — pode reenviar à vontade sem duplicar comissão.

Resposta rápida + fila

O handler verifica, deduplica e enfileira o evento, respondendo 200 em milissegundos. O trabalho pesado (cálculo de comissão, hidratação, chamadas à API do gateway) roda assíncrono num consumidor de fila — seu gateway nunca espera por isso.

Retentativa & DLQ

Se o processamento falhar, a mensagem é retentada (até ). Esgotadas as tentativas, vai para uma dead-letter queue para inspeção. Como o pipeline é idempotente, retentar é seguro.

Respostas HTTP (para depurar)

StatusCorpoSignificado
200{ ok: true }aceito e enfileirado
200{ duplicate: true }evento já visto (idempotente)
200{ ignored: true }tipo de evento não rastreado
200{ unresolved: true }merchant não encontrado — gravado p/ inspeção, sem disparar retry
400missing_tokenendpoint API-key sem token na URL
400invalid_signatureassinatura não confere
404unknown_merchanttoken não corresponde a nenhuma conexão
500missing_platform_secretsecret de plataforma ausente (Stripe/MP)