Skip to main content
Balance Overdraft lets you debit a balance beyond its available funds. The primary balance never goes negative. Midaz tracks the deficit as OverdraftUsed and splits the operation between the primary balance and an internal companion balance. When credits arrive, Midaz repays the overdraft first. Any remainder flows to Available. This mechanism supports credit lines, BNPL, settlement accounts, earned wage access, and any product that needs controlled negative positions.

Balance direction


Balances carry a direction field that defines how debits and credits affect the balance:
You set direction at creation time. It is immutable. The overdraft companion balance (described below) always uses direction=debit.

Balance settings


The settings object on a balance controls overdraft behavior:
The settings object also carries a system-managed balanceScope field. It separates internal balances (like the overdraft companion) from transactional balances. You do not set this field directly.

Configuration modes


No overdraft (default)

The standard behavior. Midaz rejects any debit that exceeds the available balance.

Unlimited overdraft

The balance can go negative without a cap. Use this for settlement or pool accounts, where negative positions are normal and you reconcile them externally.

Limited overdraft

The balance can go negative up to a defined limit. The most common mode for consumer credit products.
When overdraftLimitEnabled is true, you must set overdraftLimit to a positive decimal string. If you omit it or set it to "0", Midaz returns error 0172 - ErrInvalidBalanceSettings.

How overdraft works


Operation split

When a debit transaction exceeds the available funds, Midaz automatically splits the operation:
  1. The debit consumes all remaining Available and floors it at 0.
  2. Midaz accrues the excess as OverdraftUsed on the primary balance.
  3. Midaz creates a companion operation on the internal "overdraft" balance (described below). This operation records the liability as a double-entry debit.
Example: Balance has Available = 300. A debit of 500 arrives. The transaction succeeds as a single atomic operation. The caller does not need to handle the split — Midaz does it automatically.
If you configure a limit, Midaz checks the resulting OverdraftUsed against overdraftLimit before it processes the transaction. If the result exceeds the limit, Midaz rejects the transaction with error 0167 - ErrOverdraftLimitExceeded.

Automatic repayment (refund split)

When a credit arrives and OverdraftUsed > 0, Midaz prioritizes repayment:
  1. Midaz applies the credit to OverdraftUsed first and reduces the debt.
  2. Any remaining amount after OverdraftUsed reaches 0 flows to Available.
  3. A companion operation on the "overdraft" balance records the repayment.
Example: OverdraftUsed = 200, Available = 0. A credit of 350 arrives.
Repayment is automatic. You cannot bypass it. Midaz reduces overdraft positions as early as possible, which keeps the balance healthy.

Cancelling a pending overdraft transaction

When you cancel a PENDING transaction that drew overdraft, Midaz keeps the companion balance in step with the primary balance:
  1. The cancel reverses the original hold and any overdraft drawn during the pending window. OverdraftUsed returns to its value before the hold.
  2. A companion CREDIT operation on the "overdraft" balance shrinks the liability by the exact amount drawn.
  3. Midaz applies the primary cancel and the companion credit in the same atomic batch. The two balances never drift out of sync.
Midaz keeps the companion balance in step with the primary balance. This holds across the hold, commit, and cancel phases of any pending transaction that touches overdraft.

Position


Every balance response includes a computed position block. It gives a real-time view of the balance state:
Do not cache the position block for accounting purposes. Midaz never persists it — it computes the block at query time from the current balance state.

Companion balance


When you update a balance to set allowOverdraft to true for the first time, Midaz auto-provisions a companion balance under the same account. The companion balance records the liability side of the double-entry. Midaz creates it once per account and reuses it across every overdraft draw and repayment. This balance is fully system-managed:
  • You cannot create, modify, or delete it through the public API.
  • Midaz reserves the key "overdraft". A request that creates a balance with this key returns error 0170 - ErrReservedBalanceKey.
  • It mirrors the liability as a proper double-entry record, so the ledger stays balanced.
The scope: "internal" value blocks direct user operations, regardless of the permission flags above. Midaz rejects any direct operation on this balance with error 0168 - ErrDirectOperationOnInternalBalance. The companion moves only through system-driven overdraft enrichment.

Overdraft state on operations


Every operation exposes the overdraft state on the balance and balanceAfter blocks. The overdraftUsed field records the overdraft consumed before and after the operation. This gives a complete audit trail without a separate balance query. For operations that do not touch overdraft, both values are "0". System-managed companion operations on the "overdraft" balance use type: "OVERDRAFT" (uppercase). The direction field carries the lifecycle: "debit" for a draw, "credit" for a repayment.
Both the primary and the companion operation share the same overdraftUsed before/after pair. They mirror the primary balance’s overdraft transition, so the lifecycle is visible from either row. The internal snapshot JSONB column on the operations table stores the same values for indexing and historical reconstruction. This column is not part of the public JSON wire. The values surface on balance.overdraftUsed and balanceAfter.overdraftUsed instead. Midaz can add future system-generated context to the snapshot without breaking the public contract.
Companion operations inherit the primary operation’s routeId. Midaz resolves their routeCode and routeDescription independently from the route’s overdraft rubric. If the route has no overdraft entry, both stay empty.

Overdraft events


Midaz publishes lifecycle events to RabbitMQ when overdraft state changes. Publication is enabled by default. Set the flag to "false" to opt out.

Event types

Example event payload

Use overdraft events to trigger downstream workflows — interest accrual, customer notifications, risk alerts, or automatic collection processes.

Use cases


Checking account overdraft (cheque especial)

Classic consumer credit. The customer’s checking balance can go negative up to a pre-approved limit. Interest accrues on the outstanding amount.

Buy Now, Pay Later (BNPL)

A BNPL provider issues a purchase credit against the customer’s balance. This creates an immediate overdraft position that the customer repays in installments.

Earned Wage Access / Salary advance

Employees draw against future earnings. Payroll credits clear the overdraft position when they arrive.

Marketplace receivables advance

Sellers receive an advance on future receivables. Midaz repays the overdraft automatically as sales settlements arrive.

Settlement / Pool accounts (unlimited mode)

Settlement and pool accounts routinely go negative during intraday processing. Unlimited overdraft avoids artificial rejections while you reconcile the position by end-of-day.

Revolving credit lines (B2B)

Businesses draw and repay from a revolving credit facility. The overdraft limit represents the total credit line.

Insurance pre-financing

Insurers pre-finance claims before premium collection cycles close. The overdraft covers the gap between payout and collection.

Loyalty programs (advanced points)

Customers redeem points before they earn them. The overdraft tracks the point deficit and clears as customers accrue new points.

Protection rules


Overdraft introduces several immutability and access constraints to maintain ledger integrity:
  • Direction is immutable. Once you set a balance’s direction at creation, you cannot change it.
  • Internal balances block writes. You cannot create, delete, or update the "overdraft" companion balance through the public API — a PATCH returns error 0175.
  • Reserved keys. Midaz reserves the key "overdraft" for the system-managed companion balance.
  • Disabling overdraft preserves outstanding debt. You can set allowOverdraft: false while OverdraftUsed > 0 to block future draws, while incoming credits still repay the existing debt.
  • Limit cannot drop below usage. If OverdraftUsed = 200, Midaz rejects overdraftLimit: "100" with error 0173, so repay below the new ceiling first or set a higher limit.
  • Optimistic concurrency. Balance updates use version-based concurrency control, and Midaz rejects a stale write with error 0174 — retry with the latest version.
For the complete catalog of overdraft-related error codes (0167–0175), see the Midaz error list.

Next steps


  • Learn about Balances — the foundation that overdraft builds on.
  • Understand Operations to trace how overdraft splits appear in the ledger.
  • Set up the Event Publisher to consume overdraft lifecycle events.
  • Explore Transactions for the full picture of double-entry accounting in Midaz.