Skip to main content
Qualquer pessoa que descubra a URL do seu webhook pode simular uma entrega. Por isso a SocialSell assina cada requisição com HMAC-SHA256 usando o secret da assinatura — e você deve validar antes de processar qualquer payload.

Os headers de cada entrega

O que é assinado

A assinatura não é do corpo sozinho. É do timestamp e do corpo, unidos por um ponto:
O valor do header vem prefixado por sha256=. Incluir o timestamp é o que permite recusar uma entrega capturada e reenviada horas depois.
Use sempre o corpo bruto (bytes), nunca o JSON já parseado: reserializar reordena chaves e muda espaçamento, e a assinatura deixa de bater.

Como validar

Testando sua validação

Chame POST /v1/webhooks/{id}/test (ou o botão Testar no painel) para receber uma entrega real assinada com o seu secret. O evento chega com type: "webhook.test" e é entregue na hora, sem retentativa — a resposta da chamada traz o status HTTP e o tempo do seu endpoint.
webhook.test não é um evento assinável — ele não aparece na referência de eventos e não precisa (nem pode) ser incluído em events ao criar a assinatura. Ele chega apenas quando você aciona o teste. Trate-o como um caso à parte no seu roteador de eventos.
O teste só funciona em assinatura ativa. Endpoint pausado devolve 409 WEBHOOK_PAUSED — um teste verde num webhook pausado seria o resultado mais enganoso possível.

Erros comuns de validação

Rotação de secret

Se o secret vazou, gere um novo sem recriar a assinatura nem perder o histórico:
A rotação vale na hora: a próxima entrega já vai assinada com o secret novo. Atualize o seu backend antes de rotacionar, ou aceite uma janela curta de entregas rejeitadas — elas serão reentregues pelo mecanismo de retentativa.

Como o secret é guardado

Do nosso lado, o secret fica cifrado em repouso (AES-256-GCM) e nunca é devolvido por nenhum endpoint de leitura — só na criação e na rotação. Nem a listagem nem o detalhe da assinatura trazem o valor. Do seu lado, trate-o como credencial: variável de ambiente, fora do repositório, e rotacione se houver qualquer suspeita.

Boas práticas

  • Valide antes de processar. Nunca confie no payload sem conferir a assinatura.
  • Use comparação em tempo constante. hmac.compare_digest, crypto.timingSafeEqual, hash_equals, hmac.Equal.
  • Rejeite entregas velhas. Uma janela de 5 minutos sobre o X-Webhook-Timestamp mata replay.
  • Responda 401, não 200. Responder sucesso a payload inválido confunde seu próprio monitoramento.
  • Guarde o secret como variável de ambiente. Nunca no código nem no repositório.
  • A URL precisa ser HTTPS pública. Endereços de rede privada, localhost e faixas reservadas são recusados no cadastro e novamente no momento da entrega. Redirects não são seguidos.