
A resposta curta: quase sempre é uma de cinco coisas: o endereço não é HTTPS na porta 443, é um endereço privado, o seu servidor demora mais de 5 segundos a responder, a assinatura é conferida sobre o corpo errado, ou a mensagem foi criada antes de o webhook ser gravado. Comece sempre por POST /v1/sms/webhook/test: ele mostra o que o seu servidor respondeu.
A lista de verificação
| Sintoma | Causa provável | O que fazer |
| O webhook não grava | Endereço sem HTTPS, noutra porta, ou interno | Use https:// na porta 443, num endereço público. |
| O teste devolve erro ou tempo esgotado | O servidor não respondeu com um código 2xx em 5 segundos | Responda logo com 200 e faça o trabalho depois, numa fila sua. |
| O seu código recusa todos os avisos | A assinatura é calculada sobre o corpo já convertido, ou com o segredo antigo | Use o corpo bruto, tal como chegou, e o segredo actual. |
| Recusa só alguns avisos | Relógio do servidor atrasado, e a hora t parece antiga | Acerte a hora do servidor e dê uma tolerância razoável. |
| Uma mensagem não deu aviso | Foi criada antes de o webhook ser gravado | Consulte-a com GET /v1/sms/messages/{id}. |
| O mesmo aviso chegou duas vezes | O seu servidor não respondeu a tempo e tentámos de novo | Trate o aviso pelo id da mensagem e pelo acontecimento; ignore o repetido. |
Conferir a assinatura
O cabeçalho X-Webhook-Signature tem a forma t=<hora unix>,v1=<hex>. O v1 é o HMAC-SHA256 de t + "." + corpo com o seu segredo. Em PHP:
$corpo = file_get_contents('php://input'); // o corpo tal como chegou
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''), $a);
$esperado = hash_hmac('sha256', ($a['t'] ?? '') . '.' . $corpo, $segredo);
$recente = abs(time() - (int) ($a['t'] ?? 0)) < 300; // tolerância à sua escolha
if (!$recente || !hash_equals($esperado, $a['v1'] ?? '')) { http_response_code(401); exit; }
http_response_code(200); // responda já; trate o aviso depois
Mais pormenores, e o mesmo noutras linguagens, em receber um webhook em PHP e conferir a assinatura.
As novas tentativas
Se o seu servidor não responder com 2xx em 5 segundos, tentamos de novo 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas depois. Por isso um servidor parado algumas horas não perde avisos, mas pode recebê-los atrasados e, se respondeu tarde, repetidos.
| Não faça o trabalho pesado antes de responder. Enviar um e-mail, gerar um PDF ou chamar outro serviço dentro do pedido é a causa mais comum dos 5 segundos. Grave o aviso, responda 200 e trate-o a seguir. |
| Mudou o segredo? Pedir um novo com rotate_secret invalida o antigo para os avisos seguintes. Actualize o seu servidor no mesmo momento, senão passa a recusar tudo. |
|
Ainda sem avisos no seu endereço? Veja a página da API ou fale connosco com o correlation_id do pedido. Ver a página da API |
PRODUTO RECOMENDADO Hospedagem de sites com cPanel Domínio e SSL incluídos, cópias diárias e o painel que já conhece. desde 396,00 MT/mês (plano de 3 anos, com cupão) Ver planos |











