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

# Balance Overdraft

> Habilite o Balance Overdraft controlado no Midaz com divisão automática de operações, prioridade de pagamento do crédito e limites para BNPL ou contas de liquidação.

O Balance Overdraft permite debitar um saldo além dos fundos disponíveis. O saldo principal nunca fica negativo. O Midaz registra o déficit em **OverdraftUsed** e divide a operação entre o saldo principal e um saldo companheiro interno. Quando chegam créditos, o Midaz paga primeiro o overdraft. O que sobra vai para Available.

Esse mecanismo atende linhas de crédito, BNPL, contas de liquidação, antecipação salarial e qualquer produto que precise de posições negativas controladas.

## Direção do saldo

***

Os saldos têm um campo `direction` que define como débitos e créditos afetam o saldo:

| Direção | Comportamento | Uso típico |
| - | - | - |
| `credit` | Débito reduz, crédito aumenta | Contas correntes, carteiras, reservas |
| `debit` | Débito aumenta, crédito reduz | Empréstimos, controle de overdraft, contas a pagar |

Na criação, o Midaz usa um `direction` explícito quando ele é informado e, depois, o `defaultDirection` do tipo de conta. Se nenhum dos dois estiver definido, o saldo usa `credit`. As contas externas sempre usam `debit`.

> [!NOTE]
>
> Você define a direção no momento da criação. Ela é imutável. O saldo companheiro de overdraft (descrito abaixo) sempre usa `direction=debit`.

## Configurações do saldo

***

O objeto `settings` de um saldo controla o comportamento do overdraft:

| Campo | Tipo | Descrição |
| - | - | - |
| `allowOverdraft` | boolean | Habilita o overdraft neste saldo |
| `overdraftLimitEnabled` | boolean | Controla se um limite é aplicado |
| `overdraftLimit` | string (decimal) | Valor máximo de overdraft. Obrigatório quando `overdraftLimitEnabled` é `true`. Deve ser maior que `0`. |

> [!NOTE]
>
> O objeto `settings` também carrega `balanceScope`. Ele identifica um saldo transacional (o padrão) ou um saldo interno gerenciado pelo sistema, como o companheiro de overdraft. Você pode definir `balanceScope: "transactional"` ao criar ou atualizar um saldo público. Você não pode definir `balanceScope: "internal"` pela API pública.

## Modos de configuração

***

### Sem overdraft (padrão)

`allowOverdraft` é `false` por padrão. Um débito não pode levar um saldo com `direction: credit` abaixo de zero.

```json JSON theme={null}
{
  "key": "checking",
  "settings": {
    "allowOverdraft": false
  }
}
```

### Overdraft ilimitado

A posição derivada pode ficar negativa sem teto. O saldo `Available` persistido permanece em `0`, enquanto o Midaz registra o déficit em `OverdraftUsed`. Use isso em contas de liquidação ou contas pool, onde posições negativas são normais e você as concilia por fora.

```json JSON theme={null}
{
  "key": "settlement",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": false
  }
}
```

### Overdraft limitado

A posição derivada pode ficar negativa até um limite definido. O saldo `Available` persistido permanece em `0`, enquanto o Midaz registra o déficit em `OverdraftUsed`. Esse é o modo mais comum para produtos de crédito ao consumidor.

```json JSON theme={null}
{
  "key": "checking",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "5000.00"
  }
}
```

> [!WARNING]
>
> Quando `overdraftLimitEnabled` é `true`, você deve definir `overdraftLimit` como uma string decimal positiva. Se você omitir o campo ou defini-lo como `"0"`, o Midaz retorna o erro `0172`.

## Como o overdraft funciona

***

### Divisão da operação

Quando uma transação de débito excede os fundos disponíveis, o Midaz divide a operação automaticamente:

1. O débito consome todo o Available restante e o limita em **0**.
2. O Midaz acumula o excedente como **OverdraftUsed** no saldo principal.

**Exemplo:** o saldo tem Available = 300. Chega um débito de 500.

| Etapa | Available | OverdraftUsed | Descrição |
| - | - | - | - |
| Antes | 300 | 0 | Estado normal |
| Depois | 0 | 200 | 300 consumidos de Available, 200 acumulados como overdraft |

A transação é concluída como uma única operação atômica. Quem chama não precisa tratar a divisão. O Midaz faz isso automaticamente.

> [!NOTE]
>
> Se você configurar um limite, o Midaz compara o OverdraftUsed resultante com `overdraftLimit` antes de processar a transação. Se o resultado exceder o limite, o Midaz rejeita a transação com o erro `0167`.

### Pagamento automático (divisão de reembolso)

Quando chega um crédito e `OverdraftUsed > 0`, o Midaz prioriza o pagamento:

1. O Midaz aplica o crédito primeiro em **OverdraftUsed** e reduz a dívida.
2. Qualquer valor que sobrar depois que OverdraftUsed chega a 0 vai para **Available**.

**Exemplo:** OverdraftUsed = 200, Available = 0. Chega um crédito de 350.

| Etapa | Available | OverdraftUsed | Descrição |
| - | - | - | - |
| Antes | 0 | 200 | Overdraft ativo |
| Depois | 150 | 0 | 200 pagos, 150 vão para Available |

> [!TIP]
>
> O pagamento é automático. Você não pode contorná-lo. O Midaz reduz as posições de overdraft o mais cedo possível, o que mantém o saldo saudável.

### Transações pendentes e overdraft

Uma transação `PENDING` cria uma retenção. Ela não saca overdraft. Se uma retenção fosse exceder Available, o Midaz rejeita a transação com o erro `0018 - Insufficient Funds Error`. A retenção rejeitada não altera Available, OnHold nem `OverdraftUsed`.

Quando você cancela uma transação pendente, o Midaz libera a retenção dela. Uma transação pendente criada por uma versão anterior do Midaz pode já carregar overdraft. O Midaz ainda desfaz esse estado legado corretamente durante o cancelamento.

### Transações de bloqueio e overdraft

Uma transação de bloqueio nunca usa overdraft. Se um bloqueio exceder Available, o Midaz o rejeita com o erro `0018 - Insufficient Funds Error`, mesmo quando o saldo permite overdraft. Um desbloqueio paga primeiro o overdraft, como qualquer outro crédito.

## Posição

***

Toda resposta de saldo inclui um bloco `position` calculado. Ele dá uma visão em tempo real do estado do saldo:

| Campo | Descrição |
| - | - |
| `available` | O `position.available` derivado. Pode ficar negativo quando o saldo persistido tem `Available = 0` e `OverdraftUsed > 0`. |
| `onHold` | Espelha `Balance.OnHold` (fundos reservados por operações pendentes). |
| `overdraftLimitAvailable` | Margem de overdraft restante, nunca negativa. É `"0"` quando um limite configurado está totalmente usado e é omitido quando o overdraft é ilimitado. |

> [!WARNING]
>
> Não guarde o bloco `position` em cache para fins contábeis. O Midaz nunca o persiste. Ele calcula o bloco no momento da consulta, a partir do estado atual do saldo.

## Saldo companheiro

***

Quando você cria ou atualiza um saldo com `allowOverdraft` definido como `true` pela primeira vez, o Midaz provisiona automaticamente um **saldo companheiro** na mesma conta. O saldo companheiro registra o lado do passivo das partidas dobradas. O Midaz o cria uma vez por conta e o reutiliza em cada saque e pagamento de overdraft.

| Propriedade | Valor | Por quê |
| - | - | - |
| `key` | `"overdraft"` | Chave reservada do sistema |
| `direction` | `debit` | O companheiro registra um passivo: débitos o aumentam, créditos o reduzem |
| `scope` | `internal` | Bloqueia operações diretas do usuário |
| `allowSending` | `true` | Obrigatório para operações DEBIT no companheiro (saques de overdraft) |
| `allowReceiving` | `true` | Obrigatório para operações CREDIT no companheiro (pagamentos de overdraft) |

Esse saldo é totalmente gerenciado pelo sistema:

* Você não pode criá-lo, modificá-lo nem excluí-lo pela API pública.
* O Midaz reserva a chave `"overdraft"`. Uma requisição que cria um saldo com essa chave retorna o erro `0170`.
* Ele espelha o passivo como um registro correto de partidas dobradas, então o ledger continua equilibrado.

> [!NOTE]
>
> O valor `scope: "internal"` bloqueia operações diretas do usuário, seja qual for o valor das flags de permissão acima. O Midaz rejeita qualquer operação direta nesse saldo com o erro `0168`. O companheiro se move apenas pelo enriquecimento de overdraft conduzido pelo sistema.

## Estado do overdraft nas operações

***

Cada operação expõe o estado do overdraft nos blocos `balance` e `balanceAfter`. O campo `overdraftUsed` registra o overdraft consumido antes e depois da operação. Isso dá uma trilha de auditoria completa sem uma consulta de saldo separada.

As operações companheiras gerenciadas pelo sistema no saldo `"overdraft"` usam `type: "OVERDRAFT"` (em maiúsculas). O campo `direction` carrega o ciclo de vida: `"debit"` para um saque, `"credit"` para um pagamento.

```json Primary debit drawing overdraft theme={null}
{
  "type": "DEBIT",
  "direction": "debit",
  "amount": { "value": "300" },
  "accountAlias": "@user123",
  "balanceKey": "checking",
  "balance": {
    "available": "300",
    "onHold": "0",
    "version": 1,
    "overdraftUsed": "0"
  },
  "balanceAfter": {
    "available": "0",
    "onHold": "0",
    "version": 2,
    "overdraftUsed": "200"
  }
}
```

```json Companion overdraft draw theme={null}
{
  "type": "OVERDRAFT",
  "direction": "debit",
  "amount": { "value": "200" },
  "balanceKey": "overdraft",
  "balance": {
    "available": "0",
    "onHold": "0",
    "version": 1,
    "overdraftUsed": "0"
  },
  "balanceAfter": {
    "available": "200",
    "onHold": "0",
    "version": 2,
    "overdraftUsed": "200"
  }
}
```

A operação principal e a companheira compartilham o mesmo par antes/depois de `overdraftUsed`. Elas espelham a transição de overdraft do saldo principal, então o ciclo de vida fica visível por qualquer uma das linhas. A coluna interna `snapshot`, do tipo JSONB, na tabela `operations` guarda os mesmos valores para indexação e reconstrução histórica. Essa coluna não faz parte do JSON público. Em vez disso, os valores aparecem em `balance.overdraftUsed` e `balanceAfter.overdraftUsed`. O Midaz pode acrescentar ao snapshot contexto futuro gerado pelo sistema sem quebrar o contrato público.

> [!TIP]
>
> As operações companheiras herdam o `routeId` da operação principal. Para cada rota habilitada para overdraft, configure as rubricas `debit` e `credit` da entrada `overdraft`. O Midaz exige as duas. O Midaz resolve `routeCode` e `routeDescription` pela rubrica que corresponde à direção do companheiro.

## Eventos de overdraft

***

O Midaz publica cada evento de overdraft em dois canais:

* No tópico de streaming `lerian.streaming.ledger`, quando `STREAMING_ENABLED` é `true`.
* No RabbitMQ, no exchange definido em `RABBITMQ_OVERDRAFT_EVENTS_EXCHANGE`.

`RABBITMQ_OVERDRAFT_EVENTS_ENABLED` controla os dois canais. Sem valor, ela vale `true`. Com `false`, o Midaz não publica os eventos de overdraft em nenhum dos canais.

```bash Environment theme={null}
# Midaz publishes overdraft events unless this flag is false.
RABBITMQ_OVERDRAFT_EVENTS_ENABLED=true

# Optional: route the RabbitMQ messages to a dedicated exchange.
# When unset, the broker's default exchange is used.
RABBITMQ_OVERDRAFT_EVENTS_EXCHANGE=transaction.overdraft_events.exchange

# Midaz emits the streaming events only when streaming is enabled.
STREAMING_ENABLED=true
```

O Ledger emite os eventos ao mesmo tempo que os eventos de transação e não os ordena. Correlacione-os com a transação por `transactionId`.

### Tipos de evento

| Evento de streaming | Routing key do RabbitMQ | Descrição |
| - | - | - |
| `balance.overdraft_drawn` | `midaz.balance.overdraft.drawn` | O overdraft foi consumido (OverdraftUsed aumentou) |
| `balance.overdraft_repaid` | `midaz.balance.overdraft.repaid` | O overdraft foi parcialmente pago (OverdraftUsed diminuiu, mas continua > 0) |
| `balance.overdraft_cleared` | `midaz.balance.overdraft.cleared` | O overdraft foi totalmente pago (OverdraftUsed chegou a 0) |

### Exemplo de payload do evento

O payload do streaming é o campo `data` do evento. Consulte [Eventos do Midaz](https://docs.lerian.studio/pt/reference/events/midaz.md) para ver o esquema completo. A mensagem do RabbitMQ traz os campos do evento em `payload`.

```json Streaming expandable theme={null}
{
  "balanceId": "0198575f-a8f9-7924-a6d7-8122f2c77d01",
  "accountId": "0198575f-a8f9-7924-a6d7-8122f2c77ddd",
  "organizationId": "0198575d-f9fd-702b-bb15-fa4c980b32c7",
  "ledgerId": "0198575d-fa0b-7ac7-8b7d-9d3ab7dccafc",
  "assetCode": "BRL",
  "transactionId": "019b2c3d-4e5f-6789-0123-456789abcdef",
  "operationId": "019b2c3d-4e5f-6789-0123-456789abce02",
  "action": "drawn",
  "amount": "200",
  "overdraftBalance": "200",
  "occurredAt": "2026-04-28T14:30:00.000000Z"
}
```

```json RabbitMQ expandable theme={null}
{
  "source": "midaz",
  "eventType": "balance",
  "action": "overdraft.drawn",
  "timestamp": "2026-04-28T14:30:00.000000Z",
  "version": "v4.4.0",
  "organizationId": "0198575d-f9fd-702b-bb15-fa4c980b32c7",
  "ledgerId": "0198575d-fa0b-7ac7-8b7d-9d3ab7dccafc",
  "payload": {
    "accountId": "0198575f-a8f9-7924-a6d7-8122f2c77ddd",
    "transactionId": "019b2c3d-4e5f-6789-0123-456789abcdef",
    "amount": "200",
    "overdraftBalance": "200",
    "timestamp": "2026-04-28T14:30:00.000000Z"
  }
}
```

> [!TIP]
>
> Use os eventos de overdraft para disparar workflows downstream: acúmulo de juros, notificações ao cliente, alertas de risco ou processos automáticos de cobrança.

## Casos de uso

***

### Overdraft em conta corrente (cheque especial)

Crédito clássico ao consumidor. A posição derivada da conta corrente pode ficar negativa até um limite pré-aprovado. O saldo `Available` persistido permanece em `0` e o valor em aberto é registrado em `OverdraftUsed`.

```json JSON theme={null}
{
  "key": "checking",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "2000.00"
  }
}
```

### Buy Now, Pay Later (BNPL)

Um provedor de BNPL concede um crédito de compra contra o saldo do cliente. Isso cria uma posição de overdraft imediata que o cliente paga em parcelas.

```json JSON theme={null}
{
  "key": "bnpl",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "10000.00"
  }
}
```

### Earned Wage Access / Antecipação salarial

Os funcionários sacam contra ganhos futuros. Os créditos da folha de pagamento zeram a posição de overdraft quando chegam.

```json JSON theme={null}
{
  "key": "salary-advance",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "3000.00"
  }
}
```

### Antecipação de recebíveis de marketplace

Os vendedores recebem uma antecipação sobre recebíveis futuros. O Midaz paga o overdraft automaticamente conforme chegam as liquidações das vendas.

```json JSON theme={null}
{
  "key": "receivables",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "50000.00"
  }
}
```

### Contas de liquidação / contas pool (modo ilimitado)

Contas de liquidação e contas pool ficam negativas com frequência durante o processamento intradiário. O overdraft ilimitado evita rejeições artificiais enquanto você concilia a posição até o fim do dia.

```json JSON theme={null}
{
  "key": "settlement-pool",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": false
  }
}
```

### Linhas de crédito rotativo (B2B)

As empresas sacam e pagam a partir de uma linha de crédito rotativo. O limite de overdraft representa a linha de crédito total.

```json JSON theme={null}
{
  "key": "credit-line",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "500000.00"
  }
}
```

### Pré-financiamento de seguros

As seguradoras pré-financiam sinistros antes de os ciclos de cobrança de prêmios fecharem. O overdraft cobre a lacuna entre o pagamento e a cobrança.

```json JSON theme={null}
{
  "key": "claims-prefin",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "100000.00"
  }
}
```

### Programas de fidelidade (pontos antecipados)

Os clientes resgatam pontos antes de acumulá-los. O overdraft registra o déficit de pontos e zera conforme os clientes acumulam novos pontos.

```json JSON theme={null}
{
  "key": "loyalty-points",
  "settings": {
    "allowOverdraft": true,
    "overdraftLimitEnabled": true,
    "overdraftLimit": "10000"
  }
}
```

## Regras de proteção

***

O overdraft traz algumas restrições de imutabilidade e de acesso para manter a integridade do ledger:

* **A direção é imutável.** Depois que você define o `direction` de um saldo na criação, não pode mais alterá-lo.
* **Saldos internos bloqueiam escritas.** Você não pode criar, excluir nem atualizar o saldo companheiro `"overdraft"` pela API pública. Um PATCH retorna o erro `0175`.
* **Chaves reservadas.** O Midaz reserva a chave `"overdraft"` para o saldo companheiro gerenciado pelo sistema.
* **Desabilitar o overdraft preserva a dívida em aberto.** Você pode definir `allowOverdraft: false` enquanto `OverdraftUsed > 0` para bloquear saques futuros, e os créditos recebidos continuam pagando a dívida existente.
* **O limite não pode ficar abaixo do uso.** Se `OverdraftUsed = 200`, o Midaz rejeita `overdraftLimit: "100"` com o erro `0173`, então pague até ficar abaixo do novo teto antes ou defina um limite maior.

Para os códigos de erro 0167–0175, veja a [lista de erros do Midaz](https://docs.lerian.studio/pt/reference/products/midaz/error-list.md).

## Próximos passos

***

* Conheça os [Saldos](https://docs.lerian.studio/pt/products/midaz/balances.md), a base sobre a qual o overdraft é construído.
* Entenda as [Operações](https://docs.lerian.studio/pt/products/midaz/operations.md) para rastrear como as divisões de overdraft aparecem no ledger.
* Configure o [Event Publisher](https://docs.lerian.studio/pt/products/midaz/event-publisher.md) para consumir os eventos do ciclo de vida do overdraft.
* Explore as [Transações](https://docs.lerian.studio/pt/products/midaz/transactions.md) para ver o quadro completo das partidas dobradas no Midaz.


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