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

# Operaciones de devolución

> Maneja los casos límite de las devoluciones Pix vía BTG: devoluciones parciales distribuidas (devoluções) entre cuentas internas y desbloqueo de operaciones atascadas en PROCESSING.

El Plugin Pix Indirecto (BTG) procesa las devoluciones Pix (devoluções) mediante el endpoint [Devolver una transferencia Pix recibida](/es/reference/interfaces/pix-btg/refund-a-received-pix-transfer). Dos capacidades extienden ese flujo para escenarios de MED y de fraude:

* **Devoluciones parciales distribuidas**: retorna una devolución desde varias cuentas internas en una sola operación
* **Desbloqueo**: recupera una devolución o transferencia atascada en `PROCESSING`

# Devoluciones parciales distribuidas

***

Un Pix recibido puede dividirse internamente entre varias cuentas. Por ejemplo, el monto principal va a la cuenta del cliente y una comisión va a una cuenta de comisiones. Una devolución posterior por MED o por fraude puede entonces debitar parte del monto de cada cuenta.

El flujo de devolución estándar debita una cuenta. Para dividir el débito, envía un array `operations` opcional en el cuerpo de la solicitud. El array `operations` es la única señal. No hay un endpoint, una variable de entorno ni un feature flag nuevos.

## Solicitud

***

```json theme={null}
POST /v1/transfers/{transfer_id}/refunds
{
  "amount": "1000.82",
  "description": "MED Cappta",
  "operations": [
    { "accountAlias": "alias-conta-cliente", "amount": "0.82" },
    { "accountAlias": "alias-conta-fee", "amount": "1000.00" }
  ]
}
```

* Sin `operations` → se ejecuta sin cambios el flujo actual de una sola cuenta.
* Con `operations` → el plugin debita cada `accountAlias` por su `amount` en Midaz, y BTG recibe un único pacs.004 por el valor **total** de la devolución.

## Reglas de validación

***

| Regla                                                   | Error                                  |
| ------------------------------------------------------- | -------------------------------------- |
| `sum(operations[].amount)` debe ser igual a `amount`    | `400 PIX-0447` Operations Sum Mismatch |
| `accountAlias` no debe repetirse dentro de la solicitud | `400 PIX-0448` Duplicate Account Alias |
| cada `amount` debe ser mayor que `0`                    | `400 PIX-0004` Invalid Field Values    |
| cada `amount` debe tener como máximo 2 decimales        | `400 PIX-0004` Invalid Field Values    |
| la solicitud debe contener como máximo 50 operaciones   | `400 PIX-0013` Limit Exceeded          |
| el cash-in original debe existir                        | `404 PIX-0425` Cashin Not Found        |

<Note>
  El endpoint, el flujo de BTG (pacs.004 con el valor total), la idempotencia y la autenticación coinciden con los de la devolución estándar. Solo cambia la composición del débito interno en Midaz.
</Note>

## Ejemplo: Cappta

***

El plugin dividió un cash-in de R$ 50,000.00: R$ 49,000.00 a la cuenta del cliente y R$ 1,000.00 a una cuenta de comisiones. Tras el fraude, la devolución debe ser de R$ 1,000.82. Solo quedan R$ 0.82 en la cuenta del cliente. El array `operations` debita R$ 0.82 de la cuenta del cliente y R$ 1,000.00 de la cuenta de comisiones. BTG recibe una única devolución de R$ 1,000.82 sin consolidación manual en el ledger.

# Desbloquear operaciones atascadas

***

Una llamada de reversión a BTG puede agotar el timeout antes de que BTG la confirme. La devolución o la transferencia queda entonces atascada en `PROCESSING`, y Midaz sigue reteniendo los fondos. Dos endpoints vuelven a consultar a BTG y llevan la operación a su estado terminal.

| Método | Endpoint                                                                                         | Desbloquea                                           |
| ------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
| `POST` | [`/v1/refunds/{refund_id}/unblock`](/es/reference/interfaces/pix-btg/unblock-a-pix-refund)       | Una devolución atascada en `PROCESSING`              |
| `POST` | [`/v1/transfers/{transfer_id}/unblock`](/es/reference/interfaces/pix-btg/unblock-a-pix-transfer) | Una transferencia atascada en `PENDING`/`PROCESSING` |

Ambos requieren el header `X-Account-Id`.

## Cómo funciona el desbloqueo

***

El plugin vuelve a consultar el estado de la reversión o de la transferencia en BTG y:

* Si BTG informa `CONFIRMED` o `ERROR` → despacha la liquidación correspondiente y lleva la operación a su estado terminal.
* Si BTG sigue informando `INITIATED`/`PROCESSING` → devuelve **HTTP 200** sin acción. Reintenta más tarde.

Una protección de consistencia aborta la operación si el `entity`, el `returnIdentification` o el `originalEndToEndId` de BTG difieren del registro local. Esto evita liquidar contra la transacción equivocada.

```json theme={null}
POST /v1/refunds/{refund_id}/unblock
X-Account-Id: <account-id>
```

La respuesta incluye el `refund` actualizado, un `message` y el `btgStatus`.

## Manejo de un 404 de BTG

***

BTG puede devolver `404` cuando ya no tiene la reversión o la transferencia. El resultado depende entonces del tipo de operación y del flag de activación explícita `allowNotFoundUnblock` en el cuerpo de la solicitud.

| Operación                                                                                                   | Predeterminado (estricto)                         | Con `allowNotFoundUnblock: true`                                                                                                                                                                       |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Transferencia** ([`/v1/transfers/{id}/unblock`](/es/reference/interfaces/pix-btg/unblock-a-pix-transfer)) | Devuelve un error                                 | Revierte la retención en Midaz (de mejor esfuerzo, idempotente), marca el cashout como `FAILED` con `BTG_NOT_FOUND`, emite un webhook saliente `CASHOUT` y devuelve `200` con `btgStatus: "NOT_FOUND"` |
| **Devolución** ([`/v1/refunds/{id}/unblock`](/es/reference/interfaces/pix-btg/unblock-a-pix-refund))        | Devuelve `PIX-1012` (`ErrProviderRefundNotFound`) | Revierte la retención y lleva la devolución a su estado terminal                                                                                                                                       |

```json theme={null}
POST /v1/transfers/{transfer_id}/unblock
{
  "allowNotFoundUnblock": true
}
```

<Warning>
  `allowNotFoundUnblock` tiene `false` como valor predeterminado. Un cuerpo vacío o ausente, o `false`, conserva el comportamiento estricto. Un 404 de BTG devuelve entonces un error y nunca revierte la retención. Actívalo solo cuando hayas confirmado que la operación debe liberarse.
</Warning>

<Note>
  La recuperación de 404 por activación explícita aplica solo a operaciones `CASHOUT` en `PENDING`/`PROCESSING` con un `endToEndId` no vacío. Los cash-ins y los estados terminales nunca entran en esta rama.
</Note>

## Limitación intra-PSP

***

El flujo de desbloqueo de transferencias resuelve el estado consultando a BTG. No aplica a las transferencias intra-PSP (internas), que no tienen transacción en BTG. Consulta [Transferencias intra-PSP](/es/interfaces/pix-btg/indirect-pix-intra-psp).

# Próximos pasos

***

* [Transferencias intra-PSP](/es/interfaces/pix-btg/indirect-pix-intra-psp): Transferencias y devoluciones P2P internas
* [MED 2.0 — Recuperación de fondos](/es/interfaces/pix-btg/indirect-pix-med-2-funds-recovery): Recuperación de fraude entre cuentas
* [Webhooks](/es/interfaces/pix-btg/indirect-pix-webhooks): Manejo de eventos de devolución y de transferencia
* [Referencia de API](/es/reference/interfaces/pix-btg/create-entry): Documentación completa de la API
