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.
Endpoints
Dois formatos, conforme o tipo de conexão:
| Conexão | Endpoint | Gateways |
|---|---|---|
| OAuth | POST /webhooks/<gateway> | Stripe, Mercado Pago — endpoint único; o merchant vem no próprio evento |
| API-key | POST /webhooks/<gateway>/<token> | Pagar.me, Asaas, AbacatePay — o token na URL identifica o seu SaaS |
Autenticação dos eventos
Todo evento é autenticado antes de entrar na fila, pelo mecanismo do gateway. Segredos são comparados em tempo constante; no Pagar.me, o evento também é consultado pela API autenticada antes de gerar comissão. Autenticação inválida → 400.
| Gateway | Header | Como | Secret |
|---|---|---|---|
| Stripe | stripe-signature | HMAC sobre timestamp.corpo; tolerância 10 min (anti-replay) | plataforma |
| Mercado Pago | x-signature + x-request-id | HMAC sobre o manifesto id;request-id;ts; tolerância 5 min | plataforma |
| Pagar.me | webhookSecret na query | segredo por conexão + consulta autenticada do evento na API v5 | por merchant (gerado no connect) |
| Asaas | asaas-access-token | token estático comparado em tempo constante | por merchant (gerado no connect) |
| AbacatePay | x-webhook-signature | HMAC do corpo em base64 com chave pública fixa; exige também webhookSecret na query | query por merchant (gerado no connect) |
Idempotência
Cada evento é gravado com uma chave única (conexão, id_do_evento). Reentregas preservam a idempotência; cobranças e aliases de invoice também são únicos por conexão para impedir comissão duplicada.
Resposta rápida + fila
O handler verifica, deduplica e enfileira o evento antes de confirmar o recebimento. Cálculo de comissão e hidratação rodam na fila; o HTTP de aceite não comprova atribuição nem comissão.
Retentativa & DLQ
Se o processamento falhar, a mensagem é retentada (até 5×). Esgotadas as tentativas, vai para uma dead-letter queue para inspeção. Como o pipeline é idempotente, retentar é seguro.
Respostas HTTP (para depurar)
| Status | Corpo | Significado |
|---|---|---|
| 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 |
| 400 | missing_token | endpoint API-key sem token na URL |
| 400 | invalid_signature | assinatura não confere |
| 404 | unknown_merchant | token não corresponde a nenhuma conexão |
| 500 | missing_platform_secret | secret de plataforma ausente (Stripe/MP) |
Diagnóstico do anunciante
GET /api/v1/advertiser/diagnostics, com a sessão e a organização ativa, mostra as conexões e os resultados dos eventos dos últimos sete dias. processed significa processamento encerrado; confira também outcome e reason para distinguir comissão criada, venda inelegível, falta de atribuição ou evento ignorado.