Testar webhooks localmente
Como expor sua aplicação local em uma URL HTTPS pública para receber webhooks da Allya Payments.
A Allya envia webhooks outbound para URLs HTTPS públicas. Em desenvolvimento, http://localhost:3000/webhooks/allya, IPs privados, hosts .local e nomes internos não são aceitos. Para receber eventos na sua máquina, exponha a rota da sua aplicação com um túnel HTTPS e cadastre a URL pública no painel.
Este guia cobre o cenário do cliente da API: sua aplicação local recebendo webhooks da Allya hospedada. A chamada para criar pagamentos continua indo para https://payments-api.allyasolutions.com; o túnel serve apenas para a Allya alcançar seu endpoint local.
Fluxo
sua aplicação local
<- túnel HTTPS público
<- webhook outbound da Allya
<- evento normalizado do gatewayUse este fluxo para validar handlers de payment.* e subscription.* antes de publicar o endpoint definitivo.
1. Suba seu endpoint local
Sua aplicação precisa ter uma rota HTTP que receba o webhook da Allya. Exemplo:
POST http://localhost:3000/webhooks/allyaO handler deve ler o body cru e validar X-Allya-Signature. Veja o exemplo completo em Webhooks.
2. Instale e autentique o ngrok
# macOS (Homebrew)
brew install ngrok
# Linux (apt)
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update && sudo apt install ngrokCrie uma conta em ngrok.com, copie o authtoken do dashboard e configure:
ngrok config add-authtoken SEU_TOKEN_AQUI3. Abra o túnel para sua aplicação
Aponte o túnel para a porta onde a sua aplicação está rodando:
ngrok http 3000A saída mostra uma URL HTTPS pública:
Forwarding https://abcd-1234.ngrok-free.app -> http://localhost:3000Monte a URL final do webhook com o caminho da sua rota:
https://abcd-1234.ngrok-free.app/webhooks/allyaNo plano gratuito do ngrok, essa URL muda a cada reinício.
4. Cadastre no painel da Allya
No painel:
- Entre no projeto.
- Selecione o ambiente Sandbox.
- Acesse Webhooks.
- Clique em Novo endpoint.
- Cadastre a URL pública do túnel, por exemplo:
https://abcd-1234.ngrok-free.app/webhooks/allyaCopie o secret exibido na criação e use-o no seu handler local para validar X-Allya-Signature.
5. Dispare um pagamento em sandbox
Crie o pagamento chamando a API hospedada da Allya, não a URL do túnel:
curl -X POST https://payments-api.allyasolutions.com/v1/payments \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 1990,
"currency": "BRL",
"method": "pix",
"externalId": "pedido_teste_local_1",
"customer": {
"name": "Cliente Teste",
"email": "cliente@example.com",
"document": "00000000000"
}
}'Quando o gateway confirmar o pagamento em sandbox, a Allya atualiza o status e envia o webhook outbound para a URL do túnel. No painel, confira Webhooks → Histórico de entregas para ver HTTP status, tentativa e timestamp.
Cloudflare Tunnel
Cloudflare Tunnel é uma alternativa ao ngrok. O quick tunnel cria uma URL temporária:
# macOS
brew install cloudflared
# Linux: siga o instalador da distribuição em developers.cloudflare.comcloudflared tunnel --url http://localhost:3000A saída mostra uma URL pública:
https://random-words-1234.trycloudflare.comCadastre no painel da Allya usando o caminho do seu webhook:
https://random-words-1234.trycloudflare.com/webhooks/allyaPara URL fixa, use um túnel nomeado com domínio próprio:
cloudflared tunnel login
cloudflared tunnel create allya-webhooks-local
cloudflared tunnel route dns allya-webhooks-local webhooks.suaempresa.com
cloudflared tunnel run --url http://localhost:3000 allya-webhooks-localTroubleshooting
O endpoint foi rejeitado como URL inválida
A Allya bloqueia URLs que não sejam HTTPS públicas:
http://...: não usa HTTPS.https://localhost:3000e IPs privados (10.x,172.16-31.x,192.168.x).*.local,*.internale link-local (169.254.x).- Hosts sem DNS público, como
https://meu-servidor.
Use a URL HTTPS retornada pelo ngrok ou cloudflared. Se ainda falhar, teste a URL em outra rede com curl: se a conexão não abrir fora da sua máquina, a URL não está pública.
A entrega aparece como FAILED
- A aplicação local não está rodando na porta apontada pelo túnel.
- A rota cadastrada não existe ou não aceita
POST. - O handler demorou mais de 8 segundos para responder.
- A aplicação respondeu
4xxou5xx. - O endpoint foi cadastrado em outro ambiente. Uma API key
sk_test_...gera evento no sandbox; confira se o endpoint também está no sandbox.
Depois de corrigir, use Webhooks → Histórico de entregas → Reenviar no painel.
Recebi o webhook, mas a assinatura não bate
As causas mais comuns são:
- O handler usa
req.json()antes de calcular o HMAC. Use body cru. - O HMAC foi calculado só com o body, sem o prefixo
{timestamp}.. - O secret usado no handler é de outro endpoint ou foi rotacionado.
- Algum middleware reserializou o JSON antes da validação.
Compare com o exemplo em Webhooks.
A URL do túnel mudou
No ngrok gratuito e no quick tunnel do Cloudflare, a URL muda ao reiniciar. Atualize o endpoint em Webhooks ou use domínio reservado/túnel nomeado.
Inspecionar payload com mitmproxy
Se você usa cloudflared ou quer registrar/reproduzir payloads localmente, coloque o mitmproxy entre o túnel e a aplicação:
brew install mitmproxy
# Linux: apt install mitmproxy
mitmweb --listen-port 8080 --mode reverse:http://localhost:3000Depois aponte o túnel para o mitmproxy:
ngrok http 8080
# ou
cloudflared tunnel --url http://localhost:8080Cadastre a URL pública do túnel no painel da Allya. A requisição aparece na interface do mitmweb e segue para sua aplicação local.
Cuidados
- Não cadastre túnel de desenvolvimento no ambiente de produção.
- Apague ou desative o endpoint temporário quando terminar o teste.
- Se um secret usado localmente vazar em logs, rotacione o endpoint no painel.
- Não trate
processingcomo sucesso: esperepayment.paidou rodePOST /v1/payments/:id/sync.
Veja também
- Webhooks: formato e validação dos eventos.
- Troubleshooting: cenários comuns durante testes.
- Quickstart: uso do túnel no fluxo inicial.