> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zipdin.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Receba notificações em tempo real sobre eventos nas propostas

Webhooks são a forma recomendada de acompanhar o ciclo de vida de uma proposta sem ficar consultando a
API repetidamente (*polling*). Em vez de perguntar "e agora?", sua aplicação registra uma URL e a Zipdin
a notifica por HTTP assim que cada evento acontece — da criação da proposta ao pagamento liberado.

Esta página cobre o fluxo de entrega e reenvio, o catálogo de eventos por etapa, o formato do payload,
como validar a autenticidade das notificações e as boas práticas para um endpoint confiável.

## Como Funciona

```mermaid theme={null}
sequenceDiagram
    participant Z as Zipdin
    participant S as Seu Servidor
    Z->>S: POST /seu-webhook (evento)
    S->>Z: 200 OK
    Note over Z,S: Se falhar, Zipdin reenvia até 3x
```

1. Você registra uma URL de callback
2. Quando um evento ocorre, enviamos um POST para sua URL
3. Você responde com HTTP 200 para confirmar recebimento
4. Se não recebemos 200, reenviamos até **3 tentativas** com backoff

## Eventos Disponíveis

| Evento                   | Descrição                      | Etapa        |
| ------------------------ | ------------------------------ | ------------ |
| `proposta.criada`        | Nova proposta criada           | Proposta     |
| `proposta.pre_aprovada`  | Análise de crédito aprovada    | Proposta     |
| `proposta.aprovada`      | Proposta aprovada              | Proposta     |
| `proposta.negada`        | Proposta negada                | Proposta     |
| `proposta.cancelada`     | Proposta cancelada             | Proposta     |
| `averbacao.solicitada`   | Averbação enviada à conveniada | Averbação    |
| `averbacao.aprovada`     | Margem reservada com sucesso   | Averbação    |
| `averbacao.negada`       | Conveniada negou averbação     | Averbação    |
| `formalizacao.iniciada`  | Link de assinatura enviado     | Formalização |
| `formalizacao.concluida` | Documentos assinados           | Formalização |
| `efetivacao.concluida`   | Contrato registrado            | Efetivação   |
| `pagamento.realizado`    | Valor liberado ao cliente      | Pagamento    |
| `pagamento.falha`        | Falha no pagamento             | Pagamento    |

## Payload do Webhook

```json theme={null}
{
  "evento": "proposta.aprovada",
  "timestamp": "2026-08-06T14:30:00-03:00",
  "dados": {
    "nu_proposta": 789456,
    "nu_cpf": "12345678901",
    "st_proposta": "aprovada",
    "vl_emprestimo": 10000.00,
    "no_conveniada": "Empresa ABC"
  },
  "metadata": {
    "tentativa": 1,
    "webhook_id": "wh_abc123"
  }
}
```

## Validando a Autenticidade

Cada webhook inclui um header `X-Zipdin-Signature` com HMAC-SHA256 do body:

```python theme={null}
import hmac
import hashlib

def validar_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)
```

## Configuração

Registre sua URL de webhook via API ou painel:

```bash theme={null}
curl -X POST https://api.zipdin.com.br/api/v1/webhooks \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seuapp.com/webhooks/zipdin",
    "eventos": ["proposta.aprovada", "pagamento.realizado"],
    "secret": "seu_secret_para_validacao"
  }'
```

## Boas Práticas

<CardGroup cols={2}>
  <Card title="Responda rápido" icon="bolt">
    Retorne 200 em menos de 5 segundos. Processe o evento de forma assíncrona.
  </Card>

  <Card title="Idempotência" icon="rotate">
    Webhooks podem ser reenviados. Use o `webhook_id` para deduplicar.
  </Card>

  <Card title="Valide a assinatura" icon="shield">
    Sempre verifique o `X-Zipdin-Signature` antes de processar.
  </Card>

  <Card title="Trate falhas" icon="triangle-exclamation">
    Se sua URL falhar 3x seguidas, o webhook será desativado automaticamente.
  </Card>
</CardGroup>
