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

# Webhooks

> Receba notificações em tempo real sobre eventos de pagamento

## Visão Geral

Webhooks permitem que você receba notificações HTTP automáticas quando eventos importantes acontecem na sua conta, como pagamentos confirmados, reembolsos processados ou saques concluídos.

## Eventos Disponíveis

| Evento | Descrição |
| - | - |
| `payment_completed` | Pagamento foi confirmado com sucesso |
| `payment_expired` | Pagamento expirou sem confirmação |
| `payment_failed` | Pagamento recebido mas recusado — depósito bloqueado por política da conta (ex.: pagador CNPJ) |
| `refund_completed` | Reembolso foi processado |
| `withdrawal_completed` | Saque foi processado com sucesso |
| `withdrawal_failed` | Saque foi rejeitado ou falhou |
| `withdrawal_reversed` | Saque foi estornado pelo PSP |
| `balance_block_created` | Bloqueio de saldo criado (MED/judicial/administrativo) |
| `balance_block_approved` | Bloqueio aprovado — valor devolvido ao pagador |
| `balance_block_rejected` | Bloqueio rejeitado — valor retorna ao lojista |

## Estrutura do Payload

Todos os webhooks seguem a mesma estrutura base:

```json theme={null}
{
  "event": "payment_completed",
  "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
  "timestamp": "2026-01-11T19:03:28.280Z",
  "subAccount": null,
  "data": {
    // Dados específicos do evento
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `event` | string | Tipo do evento |
| `eventId` | string | ID único do evento (geralmente o ID da transação) |
| `timestamp` | string | Data/hora do evento em formato ISO 8601 |
| `subAccount` | string ou null | `reference` da subconta que originou o evento; `null` quando o evento é da conta principal |
| `data` | object | Dados específicos do evento |

## Subcontas

Quando o evento pertence a uma [subconta](/#subcontas), o campo `subAccount` traz o `reference` dela:

```json theme={null}
{
  "event": "payment_completed",
  "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
  "timestamp": "2026-01-11T19:03:28.280Z",
  "subAccount": "loja-centro",
  "data": {
    "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "amount": 100.21,
    "status": "completed"
  }
}
```

<Warning>
  **Se a subconta não tiver um endpoint de webhook próprio cadastrado, os eventos dela são entregues nos endpoints da conta principal.** É por isso que o `subAccount` é essencial: é ele que diz de qual carteira é o evento.

  Sempre use esse campo para creditar o evento na carteira certa — nunca assuma que todo evento recebido no endpoint da conta principal pertence à conta principal.
</Warning>

## Headers Enviados

Cada requisição de webhook inclui os seguintes headers:

| Header | Descrição |
| - | - |
| `Content-Type` | `application/json` |
| `User-Agent` | `Pague-Webhook/1.0` |
| `X-Pague-Event` | Tipo do evento (ex.: `payment_completed`) |
| `X-Pague-Webhook-ID` | ID único desta entrega (UUID) |
| `X-Pague-Signature` | Assinatura do payload: `sha256=<HMAC-SHA256 em hex>` |
| `X-Pague-Timestamp` | Timestamp da entrega em milliseconds (Unix epoch) |

## Validando a Assinatura

Cada webhook é assinado com HMAC-SHA256 usando o **secret do seu endpoint**
(exibido uma única vez na criação). Siga estes passos para validar:

1. Calcule o **HMAC-SHA256** do body cru da requisição usando o seu secret como chave
2. Prefixe o resultado em hex com `sha256=`
3. Compare com o header `X-Pague-Signature` usando comparação em tempo constante

```typescript Node.js (crypto) theme={null}
import { createHmac, timingSafeEqual } from 'node:crypto';

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-pague-signature'] as string; // "sha256=<hex>"
  const rawBody = req.body; // raw string body

  // 1. HMAC-SHA256 do payload com o SEU secret (não hasheie o secret)
  // 2. Prefixar com "sha256="
  const expected = `sha256=${createHmac('sha256', 'seu_webhook_secret')
    .update(rawBody)
    .digest('hex')}`;

  // 3. Comparar em tempo constante
  const isValid =
    typeof signature === 'string' &&
    signature.length === expected.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(signature));

  if (!isValid) {
    return res.status(401).send('Assinatura inválida');
  }

  // Processar o evento...
  res.status(200).send('OK');
});
```

<Warning>
  Sempre use comparação em tempo constante (`timingSafeEqual`) para evitar ataques de timing.
  Nunca compare assinaturas com `===`.
</Warning>

## Exemplos de Payload

### payment\_completed

Enviado quando um pagamento PIX é confirmado.

```json theme={null}
{
  "event": "payment_completed",
  "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
  "timestamp": "2026-01-11T19:03:28.280Z",
  "data": {
    "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "sandbox",
    "amount": 100.21,
    "feeAmount": 0.5,
    "netAmount": 99.71,
    "split": [
      { "subAccount": "loja-sul", "amount": 20.00 }
    ],
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "completed",
    "completedAt": "2026-01-11T19:03:28.277Z",
    "externalReference": "pedido-12345",
    "e2eId": "E18189547202603160145ZYFfVx3jP8D",
    "counterpartName": "Maria Silva",
    "counterpartDocument": "12345678900",
    "metadata": {
      "orderId": "ORDER-12345",
      "customerId": "CUST-67890"
    }
  }
}
```

<Note>
  **O `split` do webhook é o que foi efetivamente distribuído**, não o que você pediu na criação da cobrança. Os dois divergem quando a taxa da conta muda entre a cobrança e o pagamento: o líquido encolhe e as pernas são reduzidas na ordem em que foram enviadas, em vez de a liquidação falhar.

  Para conciliar com o extrato da carteira, use sempre o valor que vem no webhook — nunca o que você mandou no request. O campo só aparece quando houve rateio; cobrança sem split não ganha a chave.
</Note>

| Campo | Tipo | Descrição |
| - | - | - |
| `transactionId` | string | ID único da transação |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor total do pagamento |
| `feeAmount` | number | Taxa cobrada |
| `netAmount` | number | Valor líquido (amount - feeAmount) |
| `split` | array | Rateio efetivado entre as carteiras, em reais; `subAccount` traz o `reference` de destino, ou `principal` para a conta principal (opcional — presente apenas quando houve [split](/#split-de-pagamento)) |
| `currency` | string | Moeda (BRL) |
| `paymentMethod` | string | Método de pagamento (pix) |
| `status` | string | Status do pagamento (completed) |
| `completedAt` | string | Data/hora da conclusão em ISO 8601 |
| `externalReference` | string | Sua referência externa (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente quando disponível) |
| `counterpartName` | string | Nome do pagador conforme retornado pelo PSP (opcional) |
| `counterpartDocument` | string | CPF/CNPJ do pagador conforme retornado pelo PSP (opcional, sem máscara) |
| `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) |

### payment\_expired

Enviado quando um pagamento PIX expira sem confirmação.

```json theme={null}
{
  "event": "payment_expired",
  "eventId": "payment_expired_d5e6f7a8-1234-5678-9abc-def012345678",
  "timestamp": "2026-01-11T19:30:00.000Z",
  "data": {
    "transactionId": "d5e6f7a8-1234-5678-9abc-def012345678",
    "environment": "sandbox",
    "amount": 75.50,
    "feeAmount": 0,
    "netAmount": 0,
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "expired",
    "expiredAt": "2026-01-11T19:30:00.000Z",
    "externalReference": "pedido-12345",
    "metadata": {
      "orderId": "ORDER-12345",
      "customerId": "CUST-67890"
    }
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `transactionId` | string | ID único da transação |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor do pagamento |
| `feeAmount` | number | Taxa cobrada (sempre 0 para pagamentos expirados) |
| `netAmount` | number | Valor líquido (sempre 0 para pagamentos expirados) |
| `currency` | string | Moeda (BRL) |
| `paymentMethod` | string | Método de pagamento (pix) |
| `status` | string | Status do pagamento (expired) |
| `expiredAt` | string | Data/hora da expiração em ISO 8601 |
| `externalReference` | string | Sua referência externa (opcional) |
| `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) |

### payment\_failed

Enviado quando um pagamento PIX foi **recebido mas não pôde ser creditado** — hoje, quando a conta bloqueia depósitos de pagadores pessoa jurídica (CNPJ). O valor não entra no seu saldo, não gera taxa e é devolvido ao pagador automaticamente. `blockedDeposit.refund` informa o andamento da devolução.

```json theme={null}
{
  "event": "payment_failed",
  "eventId": "payment_failed_13e3ffd1-55d9-4863-9cc1-8955475cdf64",
  "timestamp": "2026-09-09T20:50:17.612Z",
  "data": {
    "transactionId": "13e3ffd1-55d9-4863-9cc1-8955475cdf64",
    "environment": "production",
    "amount": 5000.00,
    "feeAmount": 0,
    "netAmount": 5000.00,
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "failed",
    "failureReason": "Bloqueio de depósito: pagador CNPJ não permitido",
    "failedAt": "2026-09-09T20:50:17.610Z",
    "createdAt": "2026-09-09T20:49:41.506Z",
    "e2eId": "E71328769202609092049JcZwvkhgNGJ",
    "counterpartName": "EMPRESA PAGADORA LTDA",
    "counterpartDocument": "60937487000165",
    "blockedDeposit": {
      "reason": "cnpj_payer_not_allowed",
      "refund": {
        "status": "confirmed",
        "e2eId": null,
        "settledAt": "2026-09-09T20:50:14.900Z"
      }
    },
    "externalReference": "pedido-12345",
    "metadata": {
      "orderId": "ORDER-12345"
    }
  }
}
```

<Note>
  A devolução é feita pela instituição de pagamento logo após o bloqueio. O `refund.status` do webhook é o estado no momento do envio; o E2E da devolução (`refund.e2eId`) costuma chegar segundos depois — consulte `GET /transactions/{id}` para o dado final e para responder ao pagador.
</Note>

| Campo | Tipo | Descrição |
| - | - | - |
| `transactionId` | string | ID único da transação |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor pago pelo pagador |
| `feeAmount` | number | Taxa cobrada (sempre 0 — nada foi creditado) |
| `netAmount` | number | Igual a `amount` (referência; nada foi creditado) |
| `currency` | string | Moeda (BRL) |
| `paymentMethod` | string | Método de pagamento (pix) |
| `status` | string | Status do pagamento (failed) |
| `failureReason` | string | Motivo, em texto |
| `failedAt` | string | Data/hora da recusa em ISO 8601 |
| `createdAt` | string | Data/hora da criação da cobrança em ISO 8601 |
| `e2eId` | string | ID fim-a-fim do PIX recebido (opcional) |
| `counterpartName` | string | Nome do pagador conforme retornado pelo PSP (opcional) |
| `counterpartDocument` | string | CNPJ do pagador, sem máscara |
| `blockedDeposit.reason` | string | Motivo do bloqueio: `cnpj_payer_not_allowed` |
| `blockedDeposit.refund.status` | string | Devolução ao pagador: `pending` (aceita, sem confirmação), `confirmed` (liquidada) ou `failed` (em tratamento manual) |
| `blockedDeposit.refund.e2eId` | string | ID fim-a-fim da devolução (`D…`), quando já conhecido |
| `blockedDeposit.refund.settledAt` | string | Data/hora da liquidação da devolução em ISO 8601, quando confirmada |
| `externalReference` | string | Sua referência externa (opcional) |
| `customer` | object | Dados do cliente informados na criação da cobrança (opcional) |
| `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) |

### refund\_completed

Enviado quando um reembolso é processado.

```json theme={null}
{
  "event": "refund_completed",
  "eventId": "c92d45e6-8b33-4f12-a789-2e56f8901def",
  "timestamp": "2026-01-11T19:22:15.456Z",
  "data": {
    "refundTransactionId": "c92d45e6-8b33-4f12-a789-2e56f8901def",
    "originalTransactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "sandbox",
    "amount": 50.00,
    "feeAmount": 0.25,
    "netAmount": 50.00,
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "completed",
    "refundedAt": "2026-01-11T19:22:15.400Z",
    "externalReference": "pedido-12345",
    "metadata": {
      "orderId": "ORDER-12345",
      "customerId": "CUST-67890"
    }
  }
}
```

<Note>
  **Convenção do `netAmount` em refund**: representa o que o destinatário do evento (o cliente final) efetivamente recebe — ou seja, o valor cheio do reembolso. A taxa de reembolso é debitada separadamente do saldo do lojista. O custo total do refund para o lojista é `amount + feeAmount`.
</Note>

| Campo | Tipo | Descrição |
| - | - | - |
| `refundTransactionId` | string | ID único da transação de reembolso |
| `originalTransactionId` | string | ID da transação original que foi reembolsada |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor do reembolso |
| `feeAmount` | number | Taxa do reembolso cobrada do lojista |
| `netAmount` | number | Valor líquido recebido pelo cliente final (igual a `amount`) |
| `currency` | string | Moeda (BRL) |
| `paymentMethod` | string | Método de pagamento da transação original |
| `status` | string | Status do reembolso (completed) |
| `refundedAt` | string | Data/hora do reembolso em ISO 8601 |
| `externalReference` | string | Sua referência externa do pagamento original (opcional) |
| `metadata` | object | Metadados customizados do pagamento original (opcional) |

### withdrawal\_completed

Enviado quando um saque é processado com sucesso.

```json theme={null}
{
  "event": "withdrawal_completed",
  "eventId": "e73775b5-70ee-4bad-be4c-4acff9890e27",
  "timestamp": "2026-01-11T19:08:21.953Z",
  "data": {
    "withdrawalId": "e73775b5-70ee-4bad-be4c-4acff9890e27",
    "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "environment": "sandbox",
    "amount": 500.00,
    "feeAmount": 2.50,
    "netAmount": 497.50,
    "currency": "BRL",
    "status": "completed",
    "completedAt": "2026-01-11T19:08:21.939Z",
    "externalReference": "saque-empresa-001",
    "e2eId": "E18189547202603160145ZYFfVx3jP8D",
    "counterpartName": "João da Silva",
    "counterpartDocument": "12345678900",
    "metadata": {
      "batchId": "BATCH-001"
    }
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `withdrawalId` | string | ID único do saque |
| `projectId` | string | ID do projeto do saque (null quando não informado na criação e a conta tem 2+ projetos) |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor do saque |
| `feeAmount` | number | Taxa do saque |
| `netAmount` | number | Valor líquido transferido |
| `currency` | string | Moeda (BRL) |
| `status` | string | Status do saque (completed) |
| `completedAt` | string | Data/hora da conclusão em ISO 8601 |
| `externalReference` | string | Sua referência externa enviada na criação do saque (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente após confirmação do PSP) |
| `counterpartName` | string | Nome do destinatário no banco de destino (opcional) |
| `counterpartDocument` | string | CPF/CNPJ do destinatário (opcional, sem máscara) |
| `metadata` | object | Metadados customizados do saque (opcional) |

### withdrawal\_failed

Enviado quando um saque é rejeitado ou falha.

```json theme={null}
{
  "event": "withdrawal_failed",
  "eventId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc",
  "timestamp": "2026-01-11T19:15:42.123Z",
  "data": {
    "withdrawalId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc",
    "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "environment": "sandbox",
    "amount": 1000.00,
    "feeAmount": 5.00,
    "netAmount": 995.00,
    "currency": "BRL",
    "status": "failed",
    "failedAt": "2026-01-11T19:15:42.100Z",
    "failureReason": "insufficient_funds",
    "externalReference": "saque-empresa-001",
    "e2eId": "E18189547202603160145ZYFfVx3jP8D",
    "counterpartName": "João da Silva",
    "counterpartDocument": "12345678900",
    "metadata": {
      "batchId": "BATCH-001"
    }
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `withdrawalId` | string | ID único do saque |
| `projectId` | string | ID do projeto do saque (null quando não informado na criação e a conta tem 2+ projetos) |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor do saque |
| `feeAmount` | number | Taxa do saque |
| `netAmount` | number | Valor líquido que seria transferido |
| `currency` | string | Moeda (BRL) |
| `status` | string | Status do saque (failed) |
| `failedAt` | string | Data/hora da falha em ISO 8601 |
| `failureReason` | string | Motivo da falha (insufficient\_funds, invalid\_account, etc.) |
| `externalReference` | string | Sua referência externa enviada na criação do saque (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente apenas se o saque chegou a ser processado pelo PSP) |
| `counterpartName` | string | Nome do destinatário no banco de destino (opcional) |
| `counterpartDocument` | string | CPF/CNPJ do destinatário (opcional, sem máscara) |
| `metadata` | object | Metadados customizados do saque (opcional) |

### withdrawal\_reversed

Enviado quando um saque é estornado pelo PSP.

```json theme={null}
{
  "event": "withdrawal_reversed",
  "eventId": "f12a34b5-6c78-9d01-ef23-456789abcdef",
  "timestamp": "2026-01-11T20:00:00.000Z",
  "data": {
    "reversalTransactionId": "f12a34b5-6c78-9d01-ef23-456789abcdef",
    "originalTransactionId": "e73775b5-70ee-4bad-be4c-4acff9890e27",
    "environment": "sandbox",
    "amount": 500.00,
    "feeAmount": 0,
    "netAmount": 500.00,
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "completed",
    "reversedAt": "2026-01-11T20:00:00.000Z",
    "metadata": {
      "batchId": "BATCH-001"
    }
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `reversalTransactionId` | string | ID único da transação de estorno |
| `originalTransactionId` | string | ID do saque original que foi estornado |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor do estorno |
| `feeAmount` | number | Taxa do estorno |
| `netAmount` | number | Valor líquido do estorno |
| `currency` | string | Moeda (BRL) |
| `paymentMethod` | string | Método de pagamento (pix) |
| `status` | string | Status do estorno (completed) |
| `reversedAt` | string | Data/hora do estorno em ISO 8601 |
| `externalReference` | string | Sua referência externa do saque original (opcional) |
| `metadata` | object | Metadados customizados do saque original (opcional) |

### balance\_block\_created

Enviado quando um bloqueio de saldo é criado (MED, judicial ou administrativo).

```json theme={null}
{
  "event": "balance_block_created",
  "eventId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef",
  "timestamp": "2026-01-11T19:30:00.000Z",
  "data": {
    "blockId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef",
    "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "production",
    "amount": 1500.00,
    "currency": "BRL",
    "blockType": "med",
    "referenceNumber": "MED-2026-001234",
    "reason": "Notificação de infração Pix recebida",
    "status": "awaiting_response",
    "createdAt": "2026-01-11T19:30:00.000Z",
    "externalReference": "pedido-12345",
    "e2eId": "E18189547202603160145ZYFfVx3jP8D"
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `blockId` | string | ID único do bloqueio |
| `transactionId` | string | ID da transação original bloqueada |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor bloqueado em reais |
| `currency` | string | Moeda (BRL) |
| `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) |
| `referenceNumber` | string | Número de referência do bloqueio |
| `reason` | string | Motivo do bloqueio |
| `status` | string | Status inicial (`awaiting_response`) |
| `createdAt` | string | Data/hora da criação em ISO 8601 |
| `externalReference` | string | Referência externa da transação original (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) |

### balance\_block\_approved

Enviado quando um bloqueio de saldo é aprovado e o valor é devolvido ao pagador original.

```json theme={null}
{
  "event": "balance_block_approved",
  "eventId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef",
  "timestamp": "2026-01-12T14:00:00.000Z",
  "data": {
    "blockId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef",
    "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "production",
    "amount": 1500.00,
    "currency": "BRL",
    "blockType": "med",
    "referenceNumber": "MED-2026-001234",
    "reason": "Notificação de infração Pix recebida",
    "resolutionReason": "Devolução confirmada pelo BACEN",
    "status": "approved",
    "createdAt": "2026-01-11T19:30:00.000Z",
    "resolvedAt": "2026-01-12T14:00:00.000Z",
    "externalReference": "pedido-12345",
    "e2eId": "E18189547202603160145ZYFfVx3jP8D"
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `blockId` | string | ID único do bloqueio |
| `transactionId` | string | ID da transação original bloqueada |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor bloqueado em reais |
| `currency` | string | Moeda (BRL) |
| `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) |
| `referenceNumber` | string | Número de referência do bloqueio |
| `reason` | string | Motivo original do bloqueio |
| `resolutionReason` | string | Motivo da resolução (opcional) |
| `status` | string | Status do bloqueio (`approved`) |
| `createdAt` | string | Data/hora da criação em ISO 8601 |
| `resolvedAt` | string | Data/hora da resolução em ISO 8601 |
| `externalReference` | string | Referência externa da transação original (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) |

### balance\_block\_rejected

Enviado quando um bloqueio de saldo é rejeitado e o valor retorna ao saldo disponível do lojista.

```json theme={null}
{
  "event": "balance_block_rejected",
  "eventId": "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef",
  "timestamp": "2026-01-12T14:00:00.000Z",
  "data": {
    "blockId": "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef",
    "transactionId": "b1c89f20-d8e5-5f6a-99ee-4f47eafeb923",
    "environment": "production",
    "amount": 250.00,
    "currency": "BRL",
    "blockType": "med",
    "referenceNumber": "MED-2026-005678",
    "reason": "Notificação de infração Pix recebida",
    "resolutionReason": "Defesa aceita - transação legítima comprovada",
    "status": "rejected",
    "createdAt": "2026-01-11T19:30:00.000Z",
    "resolvedAt": "2026-01-12T14:00:00.000Z",
    "externalReference": "pedido-67890",
    "e2eId": "E4071059520260316020613919677838"
  }
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `blockId` | string | ID único do bloqueio |
| `transactionId` | string | ID da transação original bloqueada |
| `environment` | string | Ambiente (`production` ou `sandbox`) |
| `amount` | number | Valor bloqueado em reais |
| `currency` | string | Moeda (BRL) |
| `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) |
| `referenceNumber` | string | Número de referência do bloqueio |
| `reason` | string | Motivo original do bloqueio |
| `resolutionReason` | string | Motivo da resolução (opcional) |
| `status` | string | Status do bloqueio (`rejected`) |
| `createdAt` | string | Data/hora da criação em ISO 8601 |
| `resolvedAt` | string | Data/hora da resolução em ISO 8601 |
| `externalReference` | string | Referência externa da transação original (opcional) |
| `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) |

## Boas Práticas

<AccordionGroup>
  <Accordion title="Responda rapidamente">
    Retorne um status `200 OK` o mais rápido possível. Processe o webhook de forma assíncrona se necessário.
  </Accordion>

  <Accordion title="Implemente idempotência">
    Use o `eventId` para evitar processar o mesmo evento duas vezes. Webhooks podem ser reenviados em caso de falha.
  </Accordion>

  <Accordion title="Use HTTPS">
    Configure seu endpoint apenas com HTTPS para garantir a segurança dos dados.
  </Accordion>
</AccordionGroup>

## Retentativas

Se o seu endpoint não responder com status `2xx`, tentaremos reenviar o webhook:

* **5 tentativas** com backoff exponencial
* Intervalo inicial: 2 segundos
* Intervalo máximo: \~30 segundos entre tentativas

Após 5 tentativas sem sucesso, o webhook é marcado como falho.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.