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

# Webhooks

> Configura y consume los webhooks del Plugin Pix Indirecto vía BTG: tipos de evento de reclamación DICT, infracción, devolución, transferencia y MED 2.0 con firma HMAC.

Los webhooks son el mecanismo principal que usa el **Plugin Pix Indirecto (BTG)** para notificarte sobre eventos relacionados con Pix en tiempo real.

Recibes **callbacks asíncronos y orientados a eventos** cuando ocurren cambios en las operaciones Pix: transferencias, devoluciones, reclamaciones de claves o eventos de MED.

<Warning>
  Estos webhooks aplican solo al **modelo Pix Indirecto vía BTG**.

  Los webhooks de Pix Directo pueden variar según el modelo de conectividad. Una página aparte los documenta.
</Warning>

# Requisitos previos

***

Antes de configurar los webhooks, confirma que tienes:

* El Plugin Pix Indirecto configurado y en ejecución (consulta [Cómo funciona la participación indirecta](/es/interfaces/pix/pix-overview))
* Un endpoint HTTPS listo para recibir solicitudes de webhook
* Conocimiento básico del ciclo de vida de los eventos Pix y de los flujos de transacciones

# Qué te dan los webhooks

***

Los webhooks **no son opcionales** en las operaciones de Pix Indirecto.

Pix es un sistema asíncrono y multipartito.

Una solicitud de API puede tener éxito antes de que la transacción llegue a su **estado final**. El sistema confirma ese estado después, tras la liquidación y la confirmación de la contraparte.

Los webhooks permiten que tu sistema:

* Siga el **estado autoritativo de las transacciones**
* Reaccione a **devoluciones, reversiones y eventos de MED**
* Mantenga la **consistencia del ledger y la operativa**
* Reduzca el polling y la carga operativa

# Tipos de eventos

***

Recibes eventos agrupados por **flujo** y **entidad**, alineados con los dominios de BACEN (Banco Central do Brasil).

| Flujo    | Entidad                | Descripción                                                                                        |
| -------- | ---------------------- | -------------------------------------------------------------------------------------------------- |
| DICT     | CLAIM                  | Eventos de portabilidad y de reclamación de titularidad de claves Pix                              |
| DICT     | INFRACTION\_REPORT     | Informes de infracción de MED (Mecanismo Especial de Devolução) y ciclo de vida de las disputas    |
| DICT     | REFUND                 | Eventos de solicitud de devolución de MED                                                          |
| DICT     | FUNDS\_RECOVERY        | Cambios de estado de la entidad de recuperación de fondos de MED 2.0 (respaldada en base de datos) |
| DICT     | FUNDS\_RECOVERY\_EVENT | Eventos de ciclo de vida de la recuperación de fondos de MED 2.0 (de paso)                         |
| TRANSFER | CASHIN                 | Actualizaciones de estado de los pagos Pix entrantes                                               |
| TRANSFER | CASHOUT                | Actualizaciones de estado de los pagos Pix salientes                                               |
| REFUND   | CASHIN                 | Actualizaciones de estado de las devoluciones Pix entrantes                                        |
| REFUND   | CASHOUT                | Actualizaciones de estado de las devoluciones Pix salientes                                        |

Cada evento refleja una **transición de estado** en el ecosistema Pix. Trata cada evento como la fuente de verdad.

<Note>
  Las dos entidades de **MED 2.0** se comportan de forma distinta. El plugin emite `FUNDS_RECOVERY` después de actualizar su registro local. `FUNDS_RECOVERY_EVENT` es de paso: lleva los eventos de ciclo de vida de BTG sin actualización en la base de datos. Consulta [MED 2.0 — Recuperación de fondos](/es/interfaces/pix-btg/indirect-pix-med-2-funds-recovery) para el flujo completo.
</Note>

<Note>
  **DICT** (Diretório de Identificadores de Contas Transacionais) es el directorio de BACEN que gestiona las claves Pix y las operaciones relacionadas, como reclamaciones, infracciones y devoluciones.
</Note>

# Configuración de webhooks

***

Para habilitar los webhooks, configura las **URLs de destino** y selecciona qué tipos de evento recibe tu sistema.

## Variables de entorno

***

Puedes configurar los endpoints de webhook en el nivel de **entidad**, de **flujo** o **global**.

| Flujo    | Entidad            | Variable de URL en el nivel de entidad |
| -------- | ------------------ | -------------------------------------- |
| DICT     | CLAIM              | `WEBHOOK_DICT_CLAIM_URL`               |
| DICT     | INFRACTION\_REPORT | `WEBHOOK_DICT_INFRACTION_REPORT_URL`   |
| DICT     | REFUND             | `WEBHOOK_DICT_REFUND_URL`              |
| TRANSFER | CASHIN             | `WEBHOOK_TRANSFER_CASHIN_URL`          |
| TRANSFER | CASHOUT            | `WEBHOOK_TRANSFER_CASHOUT_URL`         |
| REFUND   | CASHIN             | `WEBHOOK_REFUND_CASHIN_URL`            |
| REFUND   | CASHOUT            | `WEBHOOK_REFUND_CASHOUT_URL`           |

Cada flujo también tiene una **URL en el nivel de flujo** para todas sus entidades. El plugin la usa cuando no existe una URL en el nivel de entidad: `WEBHOOK_DICT_URL`, `WEBHOOK_TRANSFER_URL` y `WEBHOOK_REFUND_URL`.

## Prioridad de resolución de URL

***

Cuando configuras varias URLs, el plugin las resuelve en este orden:

1. **URL en el nivel de entidad**

   Ejemplo: `WEBHOOK_DICT_CLAIM_URL`

2. **URL en el nivel de flujo**

   Ejemplo: `WEBHOOK_DICT_URL`

3. **URL predeterminada**

   `WEBHOOK_DEFAULT_URL`

# Formato de la solicitud

***

## Headers

***

Cada solicitud de webhook incluye headers estandarizados para la trazabilidad y la seguridad.

| Header            | Descripción                                           |
| ----------------- | ----------------------------------------------------- |
| `Content-Type`    | `application/json`                                    |
| `X-Request-ID`    | Identificador único de la solicitud                   |
| `X-Entity-Type`   | Entidad del evento (por ejemplo, `INFRACTION_REPORT`) |
| `X-Flow-Type`     | Dominio de origen (por ejemplo, `DICT`)               |
| `Idempotency-Key` | Identificador único del evento para la deduplicación  |

## Estructura del cuerpo

***

```json theme={null}
{
  "entityType": "INFRACTION_REPORT",
  "flowType": "DICT",
  "payload": {
    ...
  }
}
```

| Campo        | Descripción                  |
| ------------ | ---------------------------- |
| `entityType` | Entidad del evento           |
| `flowType`   | Dominio de Pix               |
| `payload`    | Datos específicos del evento |

El esquema del payload varía según el tipo de evento, pero siempre representa un **cambio de estado**.

# Respuestas y comportamiento de reintento

***

## Respuesta esperada

***

Tu endpoint debe devolver un estado **HTTP 2xx** para confirmar la entrega exitosa.

| Respuesta       | Resultado                    |
| --------------- | ---------------------------- |
| 2xx             | Entregado con éxito          |
| Distinto de 2xx | Se reintenta automáticamente |

## Estrategia de reintentos

***

El plugin reintenta automáticamente las entregas fallidas con **backoff exponencial**:

| Intento | Retraso    |
| ------- | ---------- |
| 1       | 1 segundo  |
| 2       | 2 segundos |
| 3       | 4 segundos |

**Valores predeterminados**

* Máximo de reintentos: 3
* Timeout por solicitud: 30 segundos

Después de que fallan todos los reintentos, el plugin mueve el evento a una **dead-letter queue** para el seguimiento operativo.

### Configuración de reintentos personalizada

Puedes personalizar los reintentos y los timeouts por evento:

```bash theme={null}
WEBHOOK_DICT_INFRACTION_REPORT_MAX_RETRIES=5
WEBHOOK_DICT_INFRACTION_REPORT_REQUEST_TIMEOUT=60s
```

## Protección con circuit breaker

***

Un **circuit breaker** protege la entrega de webhooks y evita fallas en cascada.

Cuando el Plugin Pix detecta **fallas repetidas de entrega** (por lo general respuestas `5xx` consecutivas o timeouts), **pausa temporalmente las llamadas de webhook** al endpoint afectado.

Después de un período de espera configurable, el sistema reintenta el endpoint para verificar si se recuperó.

Cuando el endpoint devuelve respuestas exitosas, el plugin reanuda la entrega normal automáticamente.

<Note>
  El circuit breaker funciona junto con los reintentos y el backoff exponencial.
</Note>

## Errores de transporte y eventos huérfanos

***

Cuando el plugin recibe un webhook de devolución, busca la transferencia original a lo largo de la cadena cash-in → cash-out. Si ninguna fuente local coincide, el plugin persiste la devolución como un **registro huérfano** para la auditabilidad ante BACEN. No descarta la devolución, por lo que el registro queda visible para la conciliación y el seguimiento. Si una consulta de fuente falla en la capa de transporte, el plugin omite esa fuente y continúa. Cuando ninguna fuente se resuelve (por una ausencia limpia o por un error de transporte silenciado), el plugin registra la devolución como huérfana. El plugin aborta solo si no configuras el puente de consulta de transferencias.

`originalEndToEndId` es la clave canónica para todas las consultas de devoluciones. El plugin resuelve las devoluciones con este campo en ambos sentidos, cash-in → devolución y cash-out → devolución. Indexa siempre las devoluciones por `originalEndToEndId` (el ID end-to-end de la transferencia original), no por una única ruta de consulta específica de un sentido.

# Informes de transacciones internas (intra-PSP)

***

El plugin liquida internamente las transferencias intra-PSP (P2P). Nunca llegan a BTG para su liquidación, pero el plugin igual las informa a BACEN mediante la abstracción **TRCK002**. BTG confirma el estado del informe mediante un webhook **CAMT025** que lleva la entidad `PixInternalTransactionsReport`.

| Campo                            | Descripción                                                    |
| -------------------------------- | -------------------------------------------------------------- |
| `pactualId`                      | Identificador del informe asignado por BTG                     |
| `clientRequestId`                | Tu clave de idempotencia, enviada durante el envío del informe |
| `entity`                         | Siempre `PixInternalTransactionsReport`                        |
| `status`                         | `PROCESSING`, `CONFIRMED` o `ERROR`                            |
| `errorCode` / `errorDescription` | Se completan cuando `status = ERROR`                           |

El plugin actualiza el estado del informe cuando el webhook de informe CAMT025 confirma o falla. Los webhooks salientes se disparan antes, cuando la transferencia intra-PSP se liquida: `cashin.completed` para el tramo de cash-in y `cashout.completed` o `cashout.failed` para el tramo de cash-out. Para el flujo interno completo, consulta [Transferencias intra-PSP](/es/interfaces/pix-btg/indirect-pix-intra-psp).

# Mejores prácticas

***

| Práctica                           | Por qué importa                                                                                                       |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Ignora los campos desconocidos** | Mantén la compatibilidad con versiones futuras a medida que se agregan campos nuevos                                  |
| **Procesamiento idempotente**      | Usa `Idempotency-Key` para evitar procesar duplicados                                                                 |
| **Confirmación rápida**            | Devuelve `202 Accepted` y procesa de forma asíncrona                                                                  |
| **Procesamiento asíncrono**        | Evita bloquear el hilo del webhook                                                                                    |
| **Maneja la compresión**           | Los payloads de más de 1KB se comprimen con gzip. Revisa el header `Content-Encoding` y descomprime según corresponda |

# Ejemplos de eventos

***

Expande cada entrada para ver un payload de ejemplo de ese tipo de evento.

<AccordionGroup>
  <Accordion title="Reclamación DICT">
    Eventos de ciclo de vida de titularidad o portabilidad. Úsalos para seguir las disputas de claves Pix entre instituciones.

    ```json theme={null}
    {
      "entityType": "CLAIM",
      "flowType": "DICT",
      "payload": {
        "id": "claim-7f8a9b2c-1234-5678-abcd-ef0123456789",
        "key": "+5511999998888",
        "keyType": "PHONE",
        "claimType": "PORTABILITY",
        "claimer": {
          "ispb": "12345678",
          "name": "Banco Exemplo S.A."
        },
        "donor": {
          "ispb": "87654321",
          "name": "Outra Instituição S.A."
        },
        "status": "CONFIRMED",
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T14:45:00Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Informe de infracción DICT (MED)">
    Eventos de señalización de disputas y de fraude alineados con las reglas de MED de BACEN.

    ```json theme={null}
    {
      "entityType": "INFRACTION_REPORT",
      "flowType": "DICT",
      "payload": {
        "id": "infraction-3e4f5a6b-7890-1234-cdef-567890abcdef",
        "endToEndId": "E12345678202401151030abcdefghij12",
        "infractionType": "FRAUD",
        "reportedBy": {
          "ispb": "12345678",
          "name": "Banco Exemplo S.A."
        },
        "reportedAgainst": {
          "ispb": "87654321",
          "name": "Outra Instituição S.A."
        },
        "status": "OPEN",
        "analysisResult": null,
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Devolución DICT (MED)">
    Solicitudes de devolución y decisiones relacionadas con los casos de MED.

    ```json theme={null}
    {
      "entityType": "REFUND",
      "flowType": "DICT",
      "payload": {
        "id": "refund-9a8b7c6d-5432-1098-fedc-ba0987654321",
        "endToEndId": "E12345678202401151030abcdefghij12",
        "infractionId": "infraction-3e4f5a6b-7890-1234-cdef-567890abcdef",
        "refundAmount": 150.00,
        "refundReason": "FRAUD",
        "status": "REQUESTED",
        "requestedBy": {
          "ispb": "12345678",
          "name": "Banco Exemplo S.A."
        },
        "createdAt": "2024-01-16T09:00:00Z",
        "updatedAt": "2024-01-16T09:00:00Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Recuperación de fondos DICT (MED 2.0)">
    Cambios de estado de la entidad de recuperación de fondos. El plugin actualiza su registro local antes de reenviar la entidad completa.

    ```json theme={null}
    {
      "entityType": "FUNDS_RECOVERY",
      "flowType": "DICT",
      "payload": {
        "id": "91d65e98-97c0-4b0f-b577-73625da1f9fc",
        "externalId": "ca1b9c01-ff9e-4a58-90ab-d31512e15ce0",
        "accountId": "01989f9e-6508-79f8-9540-835be49fbd0d",
        "status": "CREATED",
        "rootTransactionId": "E9999901012341234123412345678900",
        "situationType": "SCAM",
        "reporterParticipant": "99999010",
        "contactInformation": {},
        "reportDetails": "Details to help receiving participants",
        "createdAt": "2020-01-17T10:00:00.000Z",
        "updatedAt": "2020-01-17T10:00:00.000Z"
      }
    }
    ```

    Los eventos de ciclo de vida llegan como `entityType: FUNDS_RECOVERY_EVENT` (de paso, sin actualización en la BD), con valores de `event` como `FUNDS_RECOVERY_ANALYSED` y `FUNDS_RECOVERY_COMPLETED`.
  </Accordion>

  <Accordion title="Cash-in y cash-out de transferencia">
    Eventos de transferencias Pix entrantes y salientes.

    **Cash-in (transferencia entrante):**

    ```json theme={null}
    {
      "entityType": "CASHIN",
      "flowType": "TRANSFER",
      "payload": {
        "id": "transfer-1a2b3c4d-5678-90ab-cdef-1234567890ab",
        "endToEndId": "E12345678202401151030abcdefghij12",
        "amount": 250.00,
        "payer": {
          "ispb": "87654321",
          "name": "João Silva",
          "cpfCnpj": "12345678901"
        },
        "payee": {
          "ispb": "12345678",
          "name": "Maria Santos",
          "cpfCnpj": "98765432100",
          "accountNumber": "12345-6"
        },
        "status": "SETTLED",
        "createdAt": "2024-01-15T10:30:00Z",
        "settledAt": "2024-01-15T10:30:05Z"
      }
    }
    ```

    **Cash-out (transferencia saliente):**

    ```json theme={null}
    {
      "entityType": "CASHOUT",
      "flowType": "TRANSFER",
      "payload": {
        "id": "transfer-2b3c4d5e-6789-01bc-def0-2345678901bc",
        "endToEndId": "E87654321202401151045zyxwvutsrqp98",
        "amount": 500.00,
        "payer": {
          "ispb": "12345678",
          "name": "Maria Santos",
          "cpfCnpj": "98765432100",
          "accountNumber": "12345-6"
        },
        "payee": {
          "ispb": "87654321",
          "name": "Empresa ABC Ltda",
          "cpfCnpj": "12345678000199"
        },
        "status": "SETTLED",
        "createdAt": "2024-01-15T10:45:00Z",
        "settledAt": "2024-01-15T10:45:03Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Cash-in y cash-out de devolución">
    Eventos de liquidación de devoluciones de transacciones Pix.

    **Cash-in de devolución (recibir una devolución):**

    ```json theme={null}
    {
      "entityType": "CASHIN",
      "flowType": "REFUND",
      "payload": {
        "id": "refund-4d5e6f7g-8901-23cd-ef01-4567890123cd",
        "originalEndToEndId": "E87654321202401151045zyxwvutsrqp98",
        "refundEndToEndId": "D12345678202401161000refund123456",
        "amount": 500.00,
        "reason": "CUSTOMER_REQUEST",
        "status": "SETTLED",
        "createdAt": "2024-01-16T10:00:00Z",
        "settledAt": "2024-01-16T10:00:02Z"
      }
    }
    ```

    **Cash-out de devolución (enviar una devolución):**

    ```json theme={null}
    {
      "entityType": "CASHOUT",
      "flowType": "REFUND",
      "payload": {
        "id": "refund-5e6f7g8h-9012-34de-f012-5678901234de",
        "originalEndToEndId": "E12345678202401151030abcdefghij12",
        "refundEndToEndId": "D87654321202401161015refund789012",
        "amount": 250.00,
        "reason": "OPERATIONAL_FLAW",
        "status": "SETTLED",
        "createdAt": "2024-01-16T10:15:00Z",
        "settledAt": "2024-01-16T10:15:04Z"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

# Próximos pasos

***

* [Dominios principales de Pix: transferencias](/es/interfaces/pix/main-domains-transactions): Las operaciones de transferencia en detalle
* [Dominios principales de Pix: DICT](/es/interfaces/pix/main-domains-dict): Entender las operaciones de DICT y la gestión de claves
* [Dominios principales de Pix: MED](/es/interfaces/pix/main-domains-med): Manejo de disputas y devoluciones de MED
* [MED 2.0 — Recuperación de fondos](/es/interfaces/pix-btg/indirect-pix-med-2-funds-recovery): Recuperación de fraude entre cuentas y sus webhooks
* [Transferencias intra-PSP](/es/interfaces/pix-btg/indirect-pix-intra-psp): Liquidación P2P interna e informes TRCK002
* [Referencia de API](/es/reference/interfaces/pix-btg/create-entry): Documentación completa de la API para las operaciones de DICT, reclamaciones, transacciones, códigos QR y MED
