Configurando webhooks
Toda confirmação de mudança de estado vem via webhook. Aqui você aprende a registrar sua URL, filtrar eventos, obter o secret de assinatura e validar o primeiro evento. A configuração detalhada de segurança vive em Webhooks · Configuração e segurança.
POST /webhook · GET /webhook · PATCH /webhook/{id}
Os endpoints de webhook ficam no serviço webhook-sender-manager (host próprio, ex.: https://webhook-sender-manager-production.iorq.com.br) e exigem o header Fund-Id além do Authorization.
1. Por que webhooks
O ciclo de uma operação envolve múltiplos atores fora do controle do integrador: validação de elegibilidade, geração de termo na administradora, coleta de assinaturas, desembolso bancário. Em vez de você ficar pollando estado, a IORQ te avisa quando algo muda.
- Latência baixa — eventos são entregues em segundos após a mudança
- Reentrega garantida — se sua URL falha, a IORQ retenta (ver Idempotência e reentrega)
- Um tipo de mensagem — hoje a IORQ envia o
message_typeLOAN_UPDATE; o que mudou vem nodata.statusdo payload
2. Pré-requisitos
- Endpoint HTTPS público com certificado válido (TLS 1.2+). HTTP e self-signed são rejeitados.
- Capacidade de responder rápido — após o timeout a IORQ considera falha e retenta.
- Token Bearer JWT válido + header
Fund-Idpara chamarPOST /webhook(ver Autenticação).
RecomendaçãoAntes de processar o evento, enfileire-o (SQS, RabbitMQ, etc.) e responda
200ao webhook. Processamento síncrono dentro do handler é frágil — uma lentidão downstream estoura o timeout de 10s.
3. Registrar uma URL de webhook
3.1 POST /webhook
POST /webhookPOST /webhook · application/json
Campos do payload
| Campo | Tipo | Descrição |
|---|---|---|
message_type | string | Tipo de mensagem assinada. Hoje: LOAN_UPDATE |
webhook_url | string (HTTPS) | URL pública que receberá os eventos. Obrigatoriamente https:// — URLs http:// são rejeitadas |
headers | object | Opcional. Headers custom ({ "Chave": "Valor" }) que a IORQ reenviará em cada entrega — camada adicional de autenticação |
O fundo é definido pelo header Fund-Id da requisição, não por um campo no corpo.
Exemplo:
curl -X POST 'https://webhook-sender-manager-production.iorq.com.br/webhook' \
-H 'Authorization: Bearer eyJhbGciOi...' \
-H 'Fund-Id: 374485cf-f6df-467c-b91d-9f14082c6f36' \
-H 'Content-Type: application/json' \
-d '{
"message_type": "LOAN_UPDATE",
"webhook_url": "https://api.meudominio.com/iorq-webhooks",
"headers": { "X-My-Auth": "meu-token" }
}'Resposta:
{
"webhook_id": "...",
"fund_id": "374485cf-f6df-467c-b91d-9f14082c6f36",
"user_id": "...",
"message_type": "LOAN_UPDATE",
"webhook_url": "https://api.meudominio.com/iorq-webhooks",
"status": "ACTIVE",
"headers": { "X-My-Auth": "meu-token" },
"max_attempts": 7,
"created_at": "2026-05-13T12:00:00Z",
"updated_at": "2026-05-13T12:00:00Z",
"signing_secret": "whsec_K8nP3qR7sT2vW9xY1zA4bC6dE0fG5hJ"
}
Guarde osigning_secretimediatamenteEle aparece apenas nesta resposta —
GET,PATCHe listagem não o retornam. É com ele que você valida a assinaturaX-IORQ-Signaturede cada entrega. Ver Configuração e segurança.
4. Formato dos eventos recebidos
Cada evento é enviado como POST JSON para a webhook_url, assinado com HMAC-SHA256:
Headers
| Header | Descrição |
|---|---|
Content-Type | Sempre application/json |
X-IORQ-Signature | t=<unix_ts>,v1=<hmac_sha256_hex> — digest sobre "{ts}.{corpo}" com o signing_secret |
X-IORQ-Timestamp | UNIX timestamp do envio (o mesmo t da assinatura) |
| (custom) | Os headers que você registrou em headers, reenviados como cadastrados |
Body
{
"event": "update",
"data": {
"entity_id": "OP-001",
"status": "approved",
"reason": null,
"nosso_numero": null,
"installment_code": null,
"entity_type": "ccb"
}
}O discriminador do que mudou é data.status. Veja o Catálogo de eventos para todos os valores possíveis.
5. Validar a configuração
Use o Fund-Id e o webhook_id retornado para conferir o registro:
curl 'https://webhook-sender-manager-production.iorq.com.br/webhook' \
-H 'Authorization: Bearer eyJhbGciOi...' \
-H 'Fund-Id: 374485cf-f6df-467c-b91d-9f14082c6f36'Para autenticar as entregas no seu endpoint, valide a assinatura HMAC com o signing_secret (comparação em tempo constante):
import hmac, hashlib, time
def verify(payload_bytes, signature_header, secret, tolerance=300):
parts = dict(p.split("=", 1) for p in signature_header.split(","))
ts, sig = parts["t"], parts["v1"]
if abs(time.time() - int(ts)) > tolerance:
return False
signed = f"{ts}.{payload_bytes.decode()}"
expected = hmac.new(secret.encode(), signed.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)Implementação em Node.js e detalhes de replay em Configuração e segurança.
6. Gerenciar webhooks existentes
| Operação | Endpoint |
|---|---|
| Listar webhooks do fundo | GET /webhook (header Fund-Id) |
| Detalhe de um webhook | GET /webhook/{webhook_id} |
| Atualizar URL / headers / status | PATCH /webhook/{webhook_id} |
| Pausar entrega | PATCH /webhook/{webhook_id} com {"status":"INACTIVE"} |
| Reativar | PATCH /webhook/{webhook_id} com {"status":"ACTIVE"} |
| Listar eventos de um webhook | GET /events/webhook/{webhook_id} |
| Reenviar (replay) um evento | POST /events/{event_id}/replay |
| Histórico de entregas de um evento | GET /attempts/event/{event_id} |
