> ## 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

> Cómo configurar y gestionar webhooks para operaciones de Pix Indirecto a través de BTG.

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

En lugar de depender de respuestas síncronas, recibes **callbacks asíncronos basados en eventos** cada vez que ocurren cambios relevantes en las operaciones de Pix, como transferencias, reembolsos, reclamos de claves o eventos relacionados con MED.

Este modelo garantiza:

* Actualizaciones casi en tiempo real
* Integraciones desacopladas
* Conciliación confiable y trazabilidad operativa

<Warning>
  Los webhooks descritos en esta página actualmente aplican al **modelo de Pix Indirecto a través de BTG**.

  Los webhooks de Pix Directo pueden diferir según el modelo de conectividad y se documentan por separado.
</Warning>

# Requisitos previos

***

Antes de configurar los webhooks, asegúrate de tener:

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

# Por qué los webhooks son importantes en Pix

***

Pix es un sistema asíncrono y multiparte.

Incluso cuando una solicitud de API tiene éxito, el **estado final de una transacción solo se confirma más tarde**, después de la liquidación y del reconocimiento de la contraparte.

Los webhooks permiten que tu sistema:

* Haga seguimiento del **estado autoritativo de la transacción**
* Reaccione a **reembolsos, reversiones y eventos MED**
* Mantenga la **consistencia del libro mayor y 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 de clave Pix y reclamo de titularidad                               |
| DICT     | INFRACTION\_REPORT     | Reportes de infracción de MED (Mecanismo Especial de Devolução) y ciclo de vida de disputas |
| DICT     | REFUND                 | Eventos de solicitud de reembolso de MED                                                    |
| DICT     | FUNDS\_RECOVERY        | Cambios de estado de la entidad Funds Recovery de MED 2.0 (respaldados en base de datos)    |
| DICT     | FUNDS\_RECOVERY\_EVENT | Eventos del ciclo de vida de Funds Recovery de MED 2.0 (pass-through)                       |
| TRANSFER | CASHIN                 | Actualizaciones de estado de pagos Pix entrantes                                            |
| TRANSFER | CASHOUT                | Actualizaciones de estado de pagos Pix salientes                                            |
| REFUND   | CASHIN                 | Actualizaciones de estado de reembolsos Pix entrantes                                       |
| REFUND   | CASHOUT                | Actualizaciones de estado de reembolsos Pix salientes                                       |

Cada evento refleja una **transición de estado** en el ecosistema de Pix y debe tratarse como la fuente de verdad.

<Note>
  Las dos entidades de **MED 2.0** se comportan de forma diferente: `FUNDS_RECOVERY` se emite después de que el plugin actualiza su registro local, mientras que `FUNDS_RECOVERY_EVENT` es un pass-through de los eventos del ciclo de vida de BTG sin actualización en base de datos. Consulta [MED 2.0 — Funds Recovery](/es/midaz/plugins/pix/indirect/indirect-pix-med-2-funds-recovery) para ver el flujo completo.
</Note>

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

# Configuración de webhooks

***

Habilitas los webhooks configurando **URLs de destino** y seleccionando qué tipos de eventos debe recibir tu sistema.

## Variables de entorno

***

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

| Flujo    | Entidad            | Variable de URL a 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 a nivel de flujo** que aplica a todas sus entidades cuando no se configura una URL a nivel de entidad: `WEBHOOK_DICT_URL`, `WEBHOOK_TRANSFER_URL` y `WEBHOOK_REFUND_URL`.

## Prioridad de resolución de URL

***

Cuando se configuran múltiples URLs, el sistema las resuelve en el siguiente orden:

1. **URL a nivel de entidad**

   Ejemplo: `WEBHOOK_DICT_CLAIM_URL`

2. **URL a nivel de flujo**

   Ejemplo: `WEBHOOK_DICT_URL`

3. **URL por defecto**

   `WEBHOOK_DEFAULT_URL`

Esto te da un control de enrutamiento granular sin duplicar infraestructura.

# Formato de la solicitud

***

## Encabezados

***

Cada solicitud de webhook incluye encabezados estandarizados para trazabilidad y seguridad.

| Encabezado        | Descripción                                       |
| ----------------- | ------------------------------------------------- |
| `Content-Type`    | `application/json`                                |
| `X-Request-ID`    | Identificador único de la solicitud               |
| `X-Entity-Type`   | Entidad del evento (p. ej. `INFRACTION_REPORT`)   |
| `X-Flow-Type`     | Dominio de origen (p. ej. `DICT`)                 |
| `Idempotency-Key` | Identificador único del evento para 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 reintentos

***

## Respuesta esperada

***

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

| Respuesta | Resultado                   |
| --------- | --------------------------- |
| 2xx       | Entregado con éxito         |
| No-2xx    | Reintentado automáticamente |

## Estrategia de reintentos

***

Las entregas fallidas se reintentan automáticamente usando **backoff exponencial**:

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

**Valores por defecto**

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

Después de que todos los reintentos fallan, el evento se mueve a una **cola de fallos** para seguimiento operativo.

### Configuración personalizada de reintentos

Los reintentos y los tiempos de espera pueden personalizarse por evento:

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

## Protección con circuit breaker

***

Para prevenir fallos en cascada, la entrega de webhooks está protegida por un **circuit breaker**.

Cuando el Plugin de Pix detecta **fallos repetidos de entrega** (normalmente respuestas `5xx` consecutivas o tiempos de espera agotados), **pausa temporalmente las llamadas de webhook** al endpoint afectado.

Después de un período de enfriamiento configurable, el sistema realiza **intentos de reintento controlados** para verificar si el endpoint se ha recuperado.

Una vez que se detectan respuestas exitosas, la entrega normal se reanuda automáticamente.

Este mecanismo garantiza:

* Protección contra endpoints sobrecargados o inestables
* Recuperación elegante sin intervención manual
* Mayor estabilidad general del sistema en entornos de producción

<Note>
  El comportamiento del circuit breaker funciona junto con los reintentos y el backoff exponencial, agregando una capa de seguridad adicional para la entrega de webhooks.
</Note>

## Errores de transporte y eventos huérfanos

***

Un intento de entrega puede fallar en la capa de transporte (conexión rechazada, fallo de DNS, error de handshake TLS) antes de que se devuelva cualquier estado HTTP. Estos fallos se **persisten como eventos huérfanos** en lugar de perderse, de modo que permanecen visibles para seguimiento operativo y reprocesamiento en lugar de desaparecer silenciosamente.

Al gestionar eventos de reembolso, ten en cuenta que las búsquedas de transferencias para cash-in y cash-out de `REFUND` se ampliaron para resolverse correctamente en ambas direcciones: asegúrate de que tu consumidor indexe los reembolsos por `originalEndToEndId` en lugar de asumir una única ruta de búsqueda.

# Reportes de transacciones internas (intra-PSP)

***

Las transferencias intra-PSP (P2P) se liquidan internamente y nunca llegan a BTG para su liquidación, pero aún se reportan a BACEN a través de la abstracción **TRCK002**. BTG confirma el estado del reporte mediante un webhook **CAMT025** que lleva la entidad `PixInternalTransactionsReport`.

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

El plugin actualiza el estado del reporte y, al completarse o fallar, emite los eventos salientes estándar intra-PSP (`cashout.completed`/`cashout.failed`, `cashin.completed` y los equivalentes de reembolso). Para ver el flujo interno completo, consulta [Transferencias intra-PSP](/es/midaz/plugins/pix/indirect/indirect-pix-intra-psp).

# Buenas prácticas

***

| Práctica                       | Por qué es importante                                                                                            |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **Ignora campos desconocidos** | Mantente compatible hacia adelante a medida que se agregan nuevos campos                                         |
| **Procesamiento idempotente**  | Usa `Idempotency-Key` para evitar procesar duplicados                                                            |
| **Reconocimiento rápido**      | Devuelve `202 Accepted` y procesa de forma asíncrona                                                             |
| **Procesamiento asíncrono**    | Evita bloquear el hilo del webhook                                                                               |
| **Gestiona la compresión**     | Los payloads >1KB se comprimen con gzip. Verifica el encabezado `Content-Encoding` y descomprime en consecuencia |

# Ejemplos de eventos

***

A continuación se muestran ejemplos representativos de los payloads de webhook que recibes del Plugin de Pix Indirecto. Expande cada entrada para ver su payload.

<AccordionGroup>
  <Accordion title="Reclamo DICT">
    Eventos del ciclo de vida de titularidad o portabilidad. Úsalos para hacer seguimiento de las disputas de clave 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="Reporte de infracción DICT (MED)">
    Eventos de señalización de disputas y 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="Reembolso DICT (MED)">
    Solicitudes y decisiones de reembolso relacionadas con 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="Funds recovery DICT (MED 2.0)">
    Cambios de estado de la entidad Funds Recovery. 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 del ciclo de vida llegan como `entityType: FUNDS_RECOVERY_EVENT` (pass-through, sin actualización en base de datos), 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 reembolso">
    Eventos de liquidación de reembolso para transacciones Pix.

    **Cash-in de reembolso (recibir un reembolso):**

    ```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 reembolso (enviar un reembolso):**

    ```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>

# Conclusión clave

***

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

Son el **canal autoritativo** para el estado de las transacciones, los reembolsos y la gestión de disputas.

Una implementación correcta de webhooks garantiza:

* Conciliación precisa
* Cumplimiento normativo
* Resiliencia operativa
* Experiencia del cliente predecible

Para entornos de producción, diseña siempre los consumidores de webhooks como **sistemas idempotentes, asíncronos y observables**.

# Próximos pasos

***

Ahora que entiendes cómo funcionan los webhooks en Pix Indirecto, explora estos temas relacionados:

* [Dominios principales de Pix: transferencias](/es/midaz/plugins/pix/main-domains-transactions) - Análisis detallado de las operaciones de transferencia
* [Dominios principales de Pix: DICT](/es/midaz/plugins/pix/main-domains-dict) - Comprensión de las operaciones de DICT y la gestión de claves
* [Dominios principales de Pix: MED](/es/midaz/plugins/pix/main-domains-med) - Gestión de disputas y reembolsos de MED
* [MED 2.0 — Funds Recovery](/es/midaz/plugins/pix/indirect/indirect-pix-med-2-funds-recovery) - Recuperación de fondos por fraude entre cuentas y sus webhooks
* [Transferencias intra-PSP](/es/midaz/plugins/pix/indirect/indirect-pix-intra-psp) - Liquidación P2P interna y reportes TRCK002
* [Referencia de API](/es/reference/midaz/plugins/indirect-pix/create-entry) — Documentación completa de la API para operaciones de DICT, Reclamos, Transacciones, Códigos QR y MED
