Transactions

About Transactions

A transaction moves money between balances in a ledger.

Payments, transfers, settlements, and treasury moves are all transactions. Create the balances inside a ledger first.

Transaction properties

  1. Double entry: Every transaction has a source and a destination. See Double entry.

  2. Immutability: Once recorded, a transaction cannot be modified or deleted. See Transaction hashing.

  3. Idempotency: The same request produces the same result each time you send it.

Queue and skip queue

When you record a transaction, Blnk queues it by default and processes it asynchronously. The call returns first with a QUEUED status, and a worker picks it up and processes it eventually.

The initial QUEUED response signifies that the request was accepted; final results can be verified via events or polling.

Alternatively, you can set skip_queue to true to apply transactions synchronously. Blnk tries to process it immediately, and return the final result in the response.

Managing insufficient funds

Blnk always checks the source before it records a transaction. Available balance is calculated as balance - inflight_debit_balance.

We subtract inflight debit because it is the amount reserved from the balance. If the amount is higher than the available balance, the result depends on the queue.

The API first returns a QUEUED transaction. The worker then records a separate REJECTED transaction.

That record points back with parent_transaction and stores the reason in meta_data.blnk_rejection_reason. Blnk sends a transaction.rejected webhook for it.

With the default queue, Blnk records REJECTED on the first failure. If insufficient-fund retries are enabled, it records REJECTED only after those retries are exhausted.

When skip_queue: true, Blnk processes the request immediately and returns 400 TXN_INSUFFICIENT_FUNDS.

The rejected attempt is not recorded, so the reference is not used. You can retry the same reference after the source has enough funds.

Discarded transactions

Some requests are not recorded in the ledger.

  1. Duplicate reference: The reference matches one already in the ledger. Use a unique value, such as a timestamp, a UUID like ref_e55c4f33-bff7-4c30-9b9f-5d2d10a29b7a, or an order_id.

  2. Zero amount: The amount is 0. Blnk does not record a zero amount.

  3. Insufficient funds with skip_queue: true: The rejected attempt is not recorded. See Managing insufficient funds.