Um webhook é um pedido que outro serviço lhe faz quando algo acontece. Num ficheiro PHP do seu site recebe-o em quatro passos: ler o corpo em bruto, verificar a assinatura, responder depressa e tratar depois. O passo da assinatura é o que impede que qualquer pessoa que descubra o endereço lhe envie dados falsos.
O esqueleto, em quatro passos
| 1 |
Leia o corpo em bruto com file_get_contents('php://input'). Não use ainda o json_decode: a assinatura calcula-se sobre o texto exactamente como chegou.
|
|
| 2 |
Calcule a assinatura esperada com hash_hmac('sha256', $corpo, $segredo), em que o segredo é o que combinou com o serviço. Leia a assinatura enviada no cabeçalho que o serviço indica, por exemplo $_SERVER['HTTP_X_ASSINATURA']. O nome do cabeçalho muda de serviço para serviço.
|
|
| 3 |
Compare com hash_equals, e não com ==. Se forem diferentes, responda 401 e pare.
|
|
| 4 |
Responda 200 depressa. Muitos serviços desistem e repetem o envio se não houver resposta em poucos segundos. Grave o evento num ficheiro ou numa tabela e deixe uma tarefa cron tratá-lo. Veja correr um script PHP a partir de uma tarefa cron.
|
|
Provar que funciona, sem esperar pelo serviço
| 1 |
Calcule uma assinatura de teste no terminal: echo -n '{"teste":1}' | openssl dgst -sha256 -hmac "SEGREDO".
|
|
| 3 |
Repita com um corpo ligeiramente diferente. Tem de receber 401. Se receber 200, a verificação não está a funcionar.
|
|
Quando o webhook não chega ou é recusado
| Sintoma |
Causa provável |
| A assinatura nunca bate |
Segredo diferente, ou o corpo foi alterado antes de calcular (analisado e reescrito). |
| O serviço fala em formato diferente |
Alguns juntam um prefixo ao valor, como o nome do algoritmo. Siga a documentação do serviço. |
| O pedido chega como GET, sem corpo |
Um redireccionamento de http para https, ou de www para sem www, transforma o POST em GET. Use o endereço final. |
| 403 antes de chegar ao PHP |
Uma regra de segurança ou um bloqueio por IP. Veja erros do site explicados. |
| O mesmo evento duas vezes |
Os serviços repetem quando não recebem 200. Guarde o identificador do evento e ignore repetidos. |
Um segredo no código é um segredo à vista. Guarde-o num ficheiro fora de public_html, e não o ponha num repositório. Veja manter senhas fora do código PHP. E nunca confie nos dados de um webhook sem assinatura como se fossem seus.
|
|
Registe cada pedido recebido (hora, resultado da verificação, tamanho do corpo), sem gravar os dados sensíveis. Quando o serviço jura que enviou e você não vê nada, o registo diz de que lado está o problema.
|
|
Quer um plano com PHP para receber os seus webhooks? Veja os planos de hospedagem.
Ver os planos
|
Onde ver na sua conta
As versões de PHP que pode usar e o tempo que um script pode correr dependem da sua conta, por isso leia-os no cPanel. Em Selecionar versão do PHP (Select PHP Version) ou no MultiPHP Manager vê as versões disponíveis, e o separador Options do Select PHP Version mostra valores como max_execution_time e memory_limit, que também aí pode alterar. Seja como for, um receptor de webhook deve responder em poucos segundos, como diz o artigo: guarde o evento e deixe o trabalho lento para uma tarefa cron, e assim o tempo de execução quase não conta. Se o receptor for recusado ou parado nas horas de maior movimento, o Uso de recursos (Resource Usage) mostra se a conta bateu num limite nesse momento.
PRODUTO RECOMENDADO Alojamento de sites com cPanel Domínio e SSL incluídos, cópias diárias e o painel que já conhece. desde 5.940,00 Kz/mês (plano de 3 anos, com cupão) Ver planos |