Pular para o conteúdo

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:

RequisitoDescrição
HTTPSObrigatório. URLs HTTP não são aceitas.
Domínio públicoNão aceitamos localhost, IPs privados (10.x.x.x, 172.16-31.x.x, 192.168.x.x) ou 127.0.0.1
Resposta 2xxSeu endpoint deve retornar HTTP 200-299 para sucesso
TimeoutResponda em até 10 segundos
GzipAceite payloads com Content-Encoding: gzip
POSTDeve 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

  1. valid_url: Formato da URL é válido
  2. https: Protocolo é HTTPS
  3. gzip: Aceita requisições comprimidas
  4. timeout: Responde dentro do limite de tempo
  5. 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

Terminal window
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:

ValorDescrição
succeededCheck passou com sucesso
failedCheck falhou (veja message para detalhes)
skippedCheck 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

Terminal window
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 gzip
app.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 gzip
import json
from 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