Configurar Webhook URL
A Webhook URL é o endpoint onde você receberá todos os eventos processados pela plataforma. Configurá-la corretamente é essencial para o funcionamento da integração.
Requisitos da URL
Antes de configurar, certifique-se de que seu endpoint atende a todos os requisitos:
| Requisito | Descrição |
|---|---|
| HTTPS | Obrigatório. URLs HTTP não são aceitas. |
| Domínio público | Não aceitamos localhost, IPs privados (10.x.x.x, 172.16-31.x.x, 192.168.x.x) ou 127.0.0.1 |
| Resposta 2xx | Seu endpoint deve retornar HTTP 200-299 para sucesso |
| Timeout | Responda em até 10 segundos |
| Gzip | Aceite payloads com Content-Encoding: gzip |
| POST | Deve aceitar requisições HTTP POST |
Validação Automática
Quando você configura uma URL, a API realiza uma série de validações automaticamente:
Checklist de Validação
- valid_url: Formato da URL é válido
- https: Protocolo é HTTPS
- gzip: Aceita requisições comprimidas
- timeout: Responde dentro do limite de tempo
- post_success: Retorna HTTP 2xx para POST de teste
Exemplo de Teste
A API envia um POST de teste com o seguinte payload:
{ "id": null, "installation_id": null, "integration_driver_slug": null, "name": "webhook_url.test", "created_at": 1705319100, "payload": {}, "superseded": false, "superseded_by": null, "webhook_dispatched_at": 1705319100}Configurar Webhook URL
PUT /me/tenant/webhook_url
curl -X PUT https://api.integracoesinteligentes.com/me/tenant/webhook_url \ -H "Authorization: Bearer <seu-token>" \ -H "Content-Type: application/json" \ -d '{ "webhook_url": "https://api.suaempresa.com/webhooks/integracoes" }'Resposta de Sucesso (200):
{ "valid": true, "checks": { "valid_url": { "result": "succeeded", "message": null }, "https": { "result": "succeeded", "message": null }, "gzip": { "result": "succeeded", "message": null }, "timeout": { "result": "succeeded", "message": null }, "post_success": { "result": "succeeded", "message": null } }}Resposta de Erro (422):
{ "valid": false, "checks": { "valid_url": { "result": "succeeded", "message": null }, "https": { "result": "succeeded", "message": null }, "gzip": { "result": "succeeded", "message": null }, "timeout": { "result": "failed", "message": "O webhook não respondeu dentro do tempo limite." }, "post_success": { "result": "failed", "message": "O servidor retornou código HTTP 500." } }}Valores possíveis para result:
| Valor | Descrição |
|---|---|
succeeded | Check passou com sucesso |
failed | Check falhou (veja message para detalhes) |
skipped | Check foi pulado (ex: se URL é inválida, checks subsequentes são pulados) |
Remover Webhook URL
Para desativar o recebimento de eventos:
DELETE /me/tenant/webhook_url
curl -X DELETE https://api.integracoesinteligentes.com/me/tenant/webhook_url \ -H "Authorization: Bearer <seu-token>"Resposta (204 No Content):
Sem corpo na resposta.
Atenção:
Se você remover a webhook_url, todos os eventos serão rejeitados até que uma nova URL válida seja configurada.
Exemplo de Implementação
Node.js (Express)
const express = require("express");const zlib = require("zlib");
const app = express();
// Middleware para descomprimir gzipapp.use((req, res, next) => { if (req.headers["content-encoding"] === "gzip") { const chunks = []; req.on("data", (chunk) => chunks.push(chunk)); req.on("end", () => { const buffer = Buffer.concat(chunks); zlib.gunzip(buffer, (err, result) => { if (err) { return res.status(400).send("Erro ao descomprimir"); } req.body = JSON.parse(result.toString()); next(); }); }); } else { next(); }});
app.post("/webhooks/integracoes", (req, res) => { // Responda rapidamente para evitar timeout res.status(200).send("OK");
// Processar o evento assincronamente const event = req.body; console.log("Evento recebido:", event.name);
// Implemente sua lógica aqui...});
app.listen(3000);PHP (Laravel)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;use Illuminate\Http\Response;
class WebhookController extends Controller{ public function handle(Request $request) { // O Laravel descomprime gzip automaticamente $event = $request->all();
// Responda imediatamente return response()->json(['status' => 'received'], Response::HTTP_OK);
// Processe assincronamente (dispatch job) }}Python (Flask)
import gzipimport jsonfrom flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks/integracoes', methods=['POST'])def handle_webhook(): # Descomprimir se necessário if request.headers.get('Content-Encoding') == 'gzip': data = gzip.decompress(request.data) event = json.loads(data) else: event = request.get_json()
# Responder rapidamente return {'status': 'received'}, 200
# Processar evento...
if __name__ == '__main__': app.run(host='0.0.0.0', port=3000)Boas Práticas
1. Responda Rapidamente
O webhook deve retornar HTTP 2xx em menos de 10 segundos. Processe o evento de forma assíncrona.
2. Implemente Idempotência
Eventos podem ser entregues múltiplas vezes. Use o campo id do evento para deduplicar:
const processedEvents = new Set(); // ou Redis, DB, etc.
app.post("/webhooks/integracoes", (req, res) => { const eventId = req.body.id;
if (processedEvents.has(eventId)) { return res.status(200).send("OK"); // Já processado }
processedEvents.add(eventId); res.status(200).send("OK");
// Processar evento...});3. Verifique Sequência de Eventos
O campo superseded indica que um evento chegou fora da ordem esperada. Por exemplo, se recebermos order.paid antes de order.waiting_payment para a mesma order:
if (event.superseded) { // Este evento chegou após um evento que deveria vir depois dele // A plataforma detectou a inconsistência na sequência console.log( `Evento ${event.id} chegou fora de ordem (já recebemos ${event.superseded_by.event_name})`, );}Troubleshooting
Erro: “URL inválida”
- Verifique se está usando HTTPS
- Certifique-se de que não é localhost ou IP privado
- A URL deve ser acessível da internet
Erro: “Timeout”
- Seu servidor demorou mais de 10 segundos para responder
- Otimise o processamento ou responda mais rápido
- Use processamento assíncrono
Erro: “Gzip não suportado”
- Implemente descompressão gzip no seu endpoint
- A maioria dos frameworks modernos faz isso automaticamente
Erro: “POST falhou”
- Seu endpoint não está aceitando POST
- Verifique se não há firewall ou WAF bloqueando
- Certifique-se de retornar HTTP 200-299
Próximos Passos
- Configurar Integração - Criar sua primeira instalação
- Receber Eventos - Processar eventos corretamente
- Estrutura dos Eventos - Conheça todos os tipos de eventos