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

# Overdraft de Saldo

> Habilita el Balance Overdraft controlado en Midaz con operaciones de split automáticas, prioridad de reembolso de crédito y límites para cuentas BNPL o de liquidación.

El Balance Overdraft te permite debitar un saldo más allá de sus fondos disponibles. El saldo primario nunca queda negativo. Midaz rastrea el déficit como **OverdraftUsed** y divide la operación entre el saldo primario y un saldo companion interno. Cuando llegan créditos, Midaz paga el overdraft primero. Cualquier excedente va al Available.

Este mecanismo soporta líneas de crédito, BNPL, cuentas de liquidación, anticipo salarial y cualquier producto que necesite posiciones negativas controladas.

## Dirección del saldo

***

Los saldos llevan un campo `direction` que define cómo los débitos y créditos afectan al saldo:

| Dirección | Comportamiento                    | Uso típico                                             |
| --------- | --------------------------------- | ------------------------------------------------------ |
| `credit`  | Débito disminuye, crédito aumenta | Cuentas corrientes, billeteras, reservas               |
| `debit`   | Débito aumenta, crédito disminuye | Préstamos, seguimiento de overdraft, cuentas por pagar |

Al crear un saldo, Midaz usa un `direction` explícito cuando se proporciona y, si no, el `defaultDirection` del Tipo de Cuenta. Si ninguno está definido, las Cuentas externas usan `debit`; todas las demás usan `credit`.

<Note>
  Defines la dirección en el momento de la creación. Es **inmutable**. El saldo companion de overdraft (descrito a continuación) siempre usa `direction=debit`.
</Note>

## Configuraciones del saldo

***

El objeto `settings` en un saldo controla el comportamiento de overdraft:

| Campo                   | Tipo             | Descripción                                                                                            |
| ----------------------- | ---------------- | ------------------------------------------------------------------------------------------------------ |
| `allowOverdraft`        | boolean          | Habilita overdraft en este saldo                                                                       |
| `overdraftLimitEnabled` | boolean          | Define si se impone un límite                                                                          |
| `overdraftLimit`        | string (decimal) | Monto máximo de overdraft. Requerido cuando `overdraftLimitEnabled` es `true`. Debe ser mayor que `0`. |

<Note>
  El objeto `settings` también contiene `balanceScope`. Identifica un saldo transaccional (el predeterminado) o un saldo interno gestionado por el sistema, como el companion de overdraft. Puedes establecer `balanceScope: "transactional"` cuando creas o actualizas un saldo público. No puedes establecer `balanceScope: "internal"` a través de la API pública.
</Note>

## Modos de configuración

***

### Sin overdraft (por defecto)

El comportamiento estándar. Midaz rechaza cualquier débito que exceda el saldo disponible.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "checking",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": false
    }
  }
  ```
</CodeGroup>

### Overdraft ilimitado

La posición derivada puede quedar negativa sin tope. El saldo persistido `Available` se mantiene en `0`, mientras Midaz registra el déficit como `OverdraftUsed`. Usa esto para cuentas de liquidación o pool, donde las posiciones negativas son normales y las concilias externamente.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "settlement",
    "assetCode": "USD",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": false
    }
  }
  ```
</CodeGroup>

### Overdraft limitado

La posición derivada puede quedar negativa hasta un límite definido. El saldo persistido `Available` se mantiene en `0`, mientras Midaz registra el déficit como `OverdraftUsed`. Este es el modo más común para productos de crédito al consumidor.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "checking",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "5000.00"
    }
  }
  ```
</CodeGroup>

<Warning>
  Cuando `overdraftLimitEnabled` es `true`, debes establecer `overdraftLimit` como una cadena decimal positiva. Si lo omites o lo estableces en `"0"`, Midaz devuelve el error `0172 - ErrInvalidBalanceSettings`.
</Warning>

## Cómo funciona el overdraft

***

### Split de operación

Cuando una transacción de débito excede los fondos disponibles, Midaz divide automáticamente la operación:

1. El débito consume todo el Available restante y lo fija en **0**.
2. Midaz acumula el excedente como **OverdraftUsed** en el saldo primario.
3. Si Midaz encuentra el saldo interno `"overdraft"` (descrito a continuación), crea una operación companion. Esta operación registra el pasivo como un débito de partida doble. Si no encuentra ese saldo, Midaz omite la operación companion; el saldo primario sigue acumulando **OverdraftUsed**.

**Ejemplo:** Saldo con Available = 300. Llega un débito de 500.

| Paso    | Available | OverdraftUsed | Descripción                                                 |
| ------- | --------- | ------------- | ----------------------------------------------------------- |
| Antes   | 300       | 0             | Estado normal                                               |
| Después | 0         | 200           | 300 consumidos del Available, 200 acumulados como overdraft |

La transacción se procesa como una única operación atómica. El llamador no necesita manejar el split — Midaz lo hace automáticamente.

<Note>
  Si configuras un límite, Midaz compara el OverdraftUsed resultante con el `overdraftLimit` **antes** de procesar la transacción. Si el resultado excede el límite, Midaz rechaza la transacción con el error `0167 - ErrOverdraftLimitExceeded`.
</Note>

### Reembolso automático (refund split)

Cuando llega un crédito y `OverdraftUsed > 0`, Midaz prioriza el reembolso:

1. Midaz aplica el crédito primero al **OverdraftUsed** y reduce la deuda.
2. Cualquier monto remanente después de que OverdraftUsed llegue a 0 va al **Available**.
3. Si Midaz encuentra el saldo interno `"overdraft"`, una operación companion en él registra el reembolso. Si no encuentra ese saldo, Midaz omite la operación companion; el crédito sigue reembolsando el **OverdraftUsed** del saldo primario.

**Ejemplo:** OverdraftUsed = 200, Available = 0. Llega un crédito de 350.

| Paso    | Available | OverdraftUsed | Descripción                            |
| ------- | --------- | ------------- | -------------------------------------- |
| Antes   | 0         | 200           | Overdraft activo                       |
| Después | 150       | 0             | 200 reembolsados, 150 van al Available |

<Tip>
  El reembolso es automático. No puedes omitirlo. Midaz reduce las posiciones de overdraft lo antes posible, lo que mantiene el saldo saludable.
</Tip>

### Cancelación de transacción pendiente con overdraft

Cuando cancelas una transacción `PENDING` que consumió overdraft:

1. La cancelación revierte el hold original y cualquier overdraft consumido durante la ventana pending. `OverdraftUsed` regresa a su valor previo al hold.
2. Si Midaz encuentra el saldo interno `"overdraft"`, una operación `CREDIT` companion en él reduce el pasivo por el monto exacto consumido. Si no encuentra ese saldo, Midaz omite la operación companion; la cancelación primaria sigue restaurando el `OverdraftUsed`.
3. Cuando Midaz crea el crédito companion, aplica la cancelación primaria y el crédito companion en el **mismo batch atómico**, de modo que los dos saldos no se desincronizan.

Mientras el saldo interno `"overdraft"` existe, Midaz lo mantiene sincronizado con el saldo primario en las fases de hold, commit y cancel de cualquier transacción pending que toque el overdraft.

## Position

***

Toda respuesta de saldo incluye un bloque computado `position`. Ofrece una vista en tiempo real del estado del saldo:

| Campo                     | Descripción                                                                                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `available`               | `position.available` derivado. Puede ser negativo cuando el saldo persistido tiene `Available = 0` y `OverdraftUsed > 0`.                        |
| `onHold`                  | Refleja `Balance.OnHold` — fondos reservados por operaciones pendientes.                                                                         |
| `overdraftLimitAvailable` | Margen restante no negativo de overdraft. Es `"0"` cuando un límite configurado se usa por completo y se omite cuando el overdraft es ilimitado. |

<Warning>
  No almacenes en caché el bloque `position` con fines contables. Midaz nunca lo persiste — computa el bloque en el momento de la consulta a partir del estado actual del saldo.
</Warning>

## Saldo companion

***

Cuando actualizas un saldo para establecer `allowOverdraft` en `true` por primera vez, Midaz auto-aprovisiona un **saldo companion** bajo la misma cuenta. El saldo companion registra el lado del pasivo en la partida doble. Midaz lo crea una sola vez por cuenta y lo reutiliza en cada draw y reembolso de overdraft.

| Propiedad        | Valor         | Por qué                                                                           |
| ---------------- | ------------- | --------------------------------------------------------------------------------- |
| `key`            | `"overdraft"` | Clave reservada del sistema                                                       |
| `direction`      | `debit`       | El companion rastrea un pasivo — los débitos lo aumentan, los créditos lo reducen |
| `scope`          | `internal`    | Bloquea operaciones directas de usuarios                                          |
| `allowSending`   | `true`        | Necesario para operaciones DEBIT en el companion (consumo de overdraft)           |
| `allowReceiving` | `true`        | Necesario para operaciones CREDIT en el companion (reembolsos de overdraft)       |

Este saldo es **completamente gestionado por el sistema**:

* No puedes crearlo, modificarlo ni eliminarlo a través de la API pública.
* Midaz **reserva** la clave `"overdraft"`. Una solicitud que crea un saldo con esta clave devuelve el error `0170 - ErrReservedBalanceKey`.
* Refleja el pasivo como un registro de partida doble, de modo que el ledger se mantiene equilibrado.

<Note>
  El valor `scope: "internal"` bloquea las operaciones directas de usuarios, sin importar las flags de permiso anteriores. Midaz rechaza cualquier operación directa sobre este saldo con el error `0168 - ErrDirectOperationOnInternalBalance`. El companion solo se mueve a través del enrichment de overdraft conducido por el sistema.
</Note>

## Estado de overdraft en las operaciones

***

Toda operación expone el estado de overdraft en los bloques `balance` y `balanceAfter`. El campo `overdraftUsed` registra el overdraft consumido antes y después de la operación. Esto ofrece un rastro de auditoría completo sin una consulta separada al saldo.

Para operaciones que no tocan el overdraft, ambos valores son `"0"`.

Las operaciones companion gestionadas por el sistema en el saldo `"overdraft"` usan `type: "OVERDRAFT"` (en mayúsculas). El campo `direction` lleva el ciclo de vida: `"debit"` para un draw, `"credit"` para un reembolso.

<CodeGroup>
  ```json Débito primario consumiendo overdraft theme={null}
  {
    "type": "DEBIT",
    "direction": "debit",
    "amount": { "value": "500" },
    "accountAlias": "@user123",
    "balanceKey": "checking",
    "balance": {
      "available": "300",
      "onHold": "0",
      "version": 1,
      "overdraftUsed": "0"
    },
    "balanceAfter": {
      "available": "0",
      "onHold": "0",
      "version": 2,
      "overdraftUsed": "200"
    }
  }
  ```

  ```json Companion de draw de overdraft 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"
    }
  }
  ```
</CodeGroup>

Tanto la operación primaria como la companion comparten el mismo par `overdraftUsed` antes/después. Ambas reflejan la transición de overdraft del saldo primario, por lo que el ciclo de vida es visible desde cualquiera de las filas. La columna interna `snapshot` (JSONB) en la tabla `operations` almacena los mismos valores para indexación y reconstrucción histórica. Esta columna no forma parte del JSON público. En su lugar, los valores aparecen en `balance.overdraftUsed` y `balanceAfter.overdraftUsed`. Midaz puede agregar contexto futuro generado por el sistema al snapshot sin romper el contrato público.

<Tip>
  Las operaciones companion heredan el `routeId` de la operación primaria. Para cada route compatible con overdraft, configura las rúbricas `debit` y `credit` del asiento `overdraft`; Midaz exige ambas. Midaz resuelve `routeCode` y `routeDescription` a partir de la rúbrica que coincide con la dirección de la companion.
</Tip>

## Eventos de overdraft

***

En tiempo de ejecución, Midaz habilita la publicación de eventos de overdraft a menos que `RABBITMQ_OVERDRAFT_EVENTS_ENABLED` se establezca explícitamente en `false`. La configuración de entorno de ejemplo incluida establece la flag en `false`; un despliegue que parte de ese ejemplo no publica eventos de overdraft hasta que configuras la flag en `true`.

<CodeGroup>
  ```bash Entorno theme={null}
  # La configuración de ejemplo deshabilita la publicación de eventos de overdraft. El runtime la habilita salvo que la flag sea explícitamente false.
  RABBITMQ_OVERDRAFT_EVENTS_ENABLED=false

  # Opcional: enruta los eventos de overdraft hacia una exchange dedicada.
  # Cuando no está definido, se usa la exchange por defecto del broker.
  RABBITMQ_OVERDRAFT_EVENTS_EXCHANGE=transaction.overdraft_events.exchange
  ```
</CodeGroup>

### Tipos de evento

| Evento              | Descripción                                                                         |
| ------------------- | ----------------------------------------------------------------------------------- |
| `overdraft.drawn`   | Se consumió overdraft — OverdraftUsed aumentó                                       |
| `overdraft.repaid`  | Se reembolsó parcialmente el overdraft — OverdraftUsed disminuyó pero permanece > 0 |
| `overdraft.cleared` | Se liquidó totalmente el overdraft — OverdraftUsed llegó a 0                        |

### Ejemplo de payload del evento

<CodeGroup>
  ```json JSON expandable theme={null}
  {
    "source": "midaz",
    "eventType": "balance",
    "action": "overdraft.drawn",
    "timestamp": "2026-04-28T14:30:00.000000Z",
    "version": "v3.0.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"
    }
  }
  ```
</CodeGroup>

<Tip>
  Usa los eventos de overdraft para activar flujos de trabajo downstream — acumulación de intereses, notificaciones al cliente, alertas de riesgo o procesos de cobro automático.
</Tip>

## Casos de uso

***

### Sobregiro de cuenta corriente (cheque especial)

Crédito clásico al consumidor. La posición derivada de la cuenta corriente puede quedar negativa hasta un límite preaprobado; el saldo persistido `Available` se mantiene en `0` y el monto pendiente se registra como `OverdraftUsed`.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "checking",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "2000.00"
    }
  }
  ```
</CodeGroup>

### Buy Now, Pay Later (BNPL)

Un proveedor de BNPL emite un crédito de compra contra el saldo del cliente. Esto crea una posición de overdraft inmediata que el cliente paga en cuotas.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "bnpl",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "10000.00"
    }
  }
  ```
</CodeGroup>

### Anticipo salarial (Earned Wage Access)

Los empleados retiran contra ingresos futuros. Los créditos de nómina liquidan la posición de overdraft cuando llegan.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "salary-advance",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "3000.00"
    }
  }
  ```
</CodeGroup>

### Anticipo de cuentas por cobrar de marketplace

Los vendedores reciben un anticipo sobre cuentas por cobrar futuras. Midaz paga el overdraft automáticamente conforme llegan las liquidaciones de ventas.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "receivables",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "50000.00"
    }
  }
  ```
</CodeGroup>

### Cuentas de liquidación / Pool (modo ilimitado)

Las cuentas de liquidación y pool rutinariamente quedan negativas durante el procesamiento intradía. El overdraft ilimitado evita rechazos artificiales mientras concilias la posición al final del día.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "settlement-pool",
    "assetCode": "USD",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": false
    }
  }
  ```
</CodeGroup>

### Líneas de crédito revolvente (B2B)

Las empresas retiran y pagan de una facilidad de crédito revolvente. El límite de overdraft representa la línea de crédito total.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "credit-line",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "500000.00"
    }
  }
  ```
</CodeGroup>

### Prefinanciamiento de seguros

Las aseguradoras prefinancian siniestros antes del cierre de los ciclos de cobro de primas. El overdraft cubre la brecha entre el pago y la cobranza.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "claims-prefin",
    "assetCode": "BRL",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "100000.00"
    }
  }
  ```
</CodeGroup>

### Programas de fidelización (puntos anticipados)

Los clientes canjean puntos antes de acumularlos. El overdraft rastrea el déficit de puntos y se liquida conforme los clientes acumulan nuevos puntos.

<CodeGroup>
  ```json JSON theme={null}
  {
    "key": "loyalty-points",
    "assetCode": "POINTS",
    "settings": {
      "allowOverdraft": true,
      "overdraftLimitEnabled": true,
      "overdraftLimit": "10000"
    }
  }
  ```
</CodeGroup>

## Reglas de protección

***

El overdraft introduce varias restricciones de inmutabilidad y acceso para mantener la integridad del ledger:

* **La dirección es inmutable.** Una vez que defines la `direction` de un saldo en la creación, no puedes cambiarla.
* **Los saldos internos bloquean escrituras.** No puedes crear, eliminar ni actualizar el saldo companion `"overdraft"` a través de la API pública — un PATCH devuelve el error `0175`.
* **Claves reservadas.** Midaz reserva la clave `"overdraft"` para el saldo companion gestionado por el sistema.
* **Deshabilitar overdraft preserva la deuda pendiente.** Puedes establecer `allowOverdraft: false` mientras `OverdraftUsed > 0` para bloquear nuevos retiros, mientras que los créditos entrantes siguen pagando la deuda existente.
* **El límite no puede bajar del uso.** Si `OverdraftUsed = 200`, Midaz rechaza `overdraftLimit: "100"` con el error `0173`, así que paga por debajo del nuevo techo primero o establece un límite mayor.
* **Concurrencia optimista.** Las actualizaciones de saldo usan control de concurrencia basado en versión, y Midaz rechaza una escritura obsoleta con el error `0174` — reintenta con la versión más reciente.

Para el catálogo completo de los códigos de error relacionados con overdraft (0167–0175), consulta la [Lista de errores de Midaz](/es/reference/midaz/error-list).

## Próximos pasos

***

* Conoce los [Saldos](/es/midaz/balances) — la base sobre la que se construye el overdraft.
* Entiende las [Operaciones](/es/midaz/operations) para rastrear cómo los splits de overdraft aparecen en el ledger.
* Configura el [Event Publisher](/es/midaz/event-publisher) para consumir eventos del ciclo de vida del overdraft.
* Explora las [Transacciones](/es/midaz/transactions) para la visión completa de la contabilidad de partida doble en Midaz.
