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

# Operações de devolução

> Trate os casos de borda da devolução Pix via BTG: devoluções parciais distribuídas (refunds) entre contas internas e desbloqueio de operações travadas em PROCESSING.

O Plugin Pix Indireto (BTG) processa devoluções Pix (refunds) pelo endpoint [Devolver uma transferência Pix recebida](/pt/reference/interfaces/pix-btg/refund-a-received-pix-transfer). Dois recursos estendem esse fluxo para cenários de MED e de fraude:

* **Devoluções parciais distribuídas**: devolva um valor a partir de várias contas internas em uma única operação
* **Desbloqueio**: recupere uma devolução ou transferência travada em `PROCESSING`

# Devoluções parciais distribuídas

***

Um Pix recebido pode ser dividido internamente entre várias contas. Por exemplo, o valor principal vai para a conta do cliente e uma tarifa vai para uma conta de tarifas. Uma devolução posterior de MED ou de fraude pode então debitar parte do valor de cada conta.

O fluxo padrão de devolução debita uma conta. Para dividir o débito, envie um array `operations` opcional no corpo da requisição. O array `operations` é o único sinal. Não há novo endpoint, variável de ambiente nem feature flag.

## Requisição

***

```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" }
  ]
}
```

* Sem `operations` → o fluxo atual de conta única roda sem mudança.
* Com `operations` → o plugin debita cada `accountAlias` pelo seu `amount` no Midaz, e o BTG recebe um único pacs.004 com o valor **total** da devolução.

## Regras de validação

***

| Regra                                                   | Erro                                   |
| ------------------------------------------------------- | -------------------------------------- |
| `sum(operations[].amount)` deve ser igual a `amount`    | `400 PIX-0447` Operations Sum Mismatch |
| `accountAlias` não deve se repetir dentro da requisição | `400 PIX-0448` Duplicate Account Alias |
| cada `amount` deve ser maior que `0`                    | `400 PIX-0004` Invalid Field Values    |
| cada `amount` deve ter no máximo 2 casas decimais       | `400 PIX-0004` Invalid Field Values    |
| a requisição deve conter no máximo 50 operações         | `400 PIX-0013` Limit Exceeded          |
| o cash-in original deve existir                         | `404 PIX-0425` Cashin Not Found        |

<Note>
  O endpoint, o fluxo no BTG (pacs.004 com o valor total), a idempotência e a autenticação são iguais aos da devolução padrão. Apenas a composição do débito interno no Midaz muda.
</Note>

## Exemplo: Cappta

***

O plugin dividiu um cash-in de R$ 50.000,00: R$ 49.000,00 para a conta do cliente e R$ 1.000,00 para uma conta de tarifas. Depois da fraude, a devolução deve ser de R$ 1.000,82. Restam apenas R$ 0,82 na conta do cliente. O array `operations` debita R$ 0,82 da conta do cliente e R$ 1.000,00 da conta de tarifas. O BTG recebe uma única devolução de R$ 1.000,82, sem consolidação manual no ledger.

# Desbloqueio de operações travadas

***

Uma chamada de estorno ao BTG pode dar timeout antes de o BTG confirmá-la. A devolução ou a transferência fica então travada em `PROCESSING`, e o Midaz continua retendo os fundos. Dois endpoints reconsultam o BTG e levam a operação ao seu estado terminal.

| Método | Endpoint                                                                                         | Desbloqueia                                         |
| ------ | ------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| `POST` | [`/v1/refunds/{refund_id}/unblock`](/pt/reference/interfaces/pix-btg/unblock-a-pix-refund)       | Uma devolução travada em `PROCESSING`               |
| `POST` | [`/v1/transfers/{transfer_id}/unblock`](/pt/reference/interfaces/pix-btg/unblock-a-pix-transfer) | Uma transferência travada em `PENDING`/`PROCESSING` |

Os dois exigem o header `X-Account-Id`.

## Como o desbloqueio funciona

***

O plugin reconsulta o status do estorno ou da transferência no BTG e:

* Se o BTG informar `CONFIRMED` ou `ERROR` → dispara a liquidação correspondente e move a operação para o estado terminal.
* Se o BTG ainda informar `INITIATED`/`PROCESSING` → retorna **HTTP 200** sem ação. Tente de novo mais tarde.

Uma trava de consistência aborta a operação se `entity`, `returnIdentification` ou `originalEndToEndId` do BTG divergirem do registro local. Isso evita a liquidação contra a transação errada.

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

A resposta inclui o `refund` atualizado, uma `message` e o `btgStatus`.

## Como tratar um 404 do BTG

***

O BTG pode retornar `404` quando não tem mais o estorno ou a transferência. O resultado depende então do tipo da operação e da flag de adesão explícita `allowNotFoundUnblock` no corpo da requisição.

| Operação                                                                                                    | Padrão (estrito)                                 | Com `allowNotFoundUnblock: true`                                                                                                                                                                |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Transferência** ([`/v1/transfers/{id}/unblock`](/pt/reference/interfaces/pix-btg/unblock-a-pix-transfer)) | Retorna um erro                                  | Reverte a retenção no Midaz (melhor esforço, idempotente), marca o cash-out como `FAILED` com `BTG_NOT_FOUND`, emite um webhook de saída `CASHOUT` e retorna `200` com `btgStatus: "NOT_FOUND"` |
| **Devolução** ([`/v1/refunds/{id}/unblock`](/pt/reference/interfaces/pix-btg/unblock-a-pix-refund))         | Retorna `PIX-1012` (`ErrProviderRefundNotFound`) | Reverte a retenção e leva a devolução ao seu estado terminal                                                                                                                                    |

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

<Warning>
  `allowNotFoundUnblock` tem `false` como padrão. Um corpo vazio ou ausente, ou `false`, preserva o comportamento estrito. Um 404 do BTG retorna então um erro e nunca reverte a retenção. Adira apenas quando você tiver confirmado que a operação deve ser liberada.
</Warning>

<Note>
  A recuperação de 404 por adesão explícita se aplica apenas a operações `CASHOUT` em `PENDING`/`PROCESSING` com um `endToEndId` não vazio. Cash-ins e status terminais nunca entram nesse ramo.
</Note>

## Limitação intra-PSP

***

O fluxo de desbloqueio de transferência resolve o estado consultando o BTG. Ele não se aplica a transferências intra-PSP (internas), que não têm transação no BTG. Veja [Transferências intra-PSP](/pt/interfaces/pix-btg/indirect-pix-intra-psp).

# Próximos passos

***

* [Transferências intra-PSP](/pt/interfaces/pix-btg/indirect-pix-intra-psp): Transferências e devoluções P2P internas
* [MED 2.0 — Recuperação de Fundos](/pt/interfaces/pix-btg/indirect-pix-med-2-funds-recovery): Recuperação de fraude entre contas
* [Webhooks](/pt/interfaces/pix-btg/indirect-pix-webhooks): Tratamento de eventos de devolução e transferência
* [Referência da API](/pt/reference/interfaces/pix-btg/create-entry): Documentação completa da API
