About transactions
Learn how transactions are recorded and processed in Blnk
Overview
Transactions are used to enable money movement between two or more balances. These can be payments, transfers, settlements, internal treasury management, etc. All transactions in Blnk are recorded with the double entry principle, i.e., there is a source and a corresponding destination for each transaction entry.
In this guide, you’ll learn:
- Transaction properties
- Recording a transaction
- How transactions work in Blnk
- Managing insufficient funds
Transaction properties
-
Immutability: Once recorded, transactions in Blnk cannot be modified or deleted. This fundamental property ensures the integrity and reliability of your transaction history, preventing any unauthorized alterations. See also: Transaction hashing
-
Idempotency: Each transaction in Blnk produces the same result whether executed once or multiple times. This is crucial for maintaining data consistency, especially during network failures or system retries.
Blnk implements idempotency by requiring a unique
reference
for every transaction. This reference serves as a transaction identifier, preventing duplicate processing and ensuring consistent outcomes.
Recording a transaction
To record a transaction, call the record-transaction endpoint:
With the following request body:
If this is your first transaction, the participating balances will start at 0. To ensure the transaction is successful, enable overdrafts as shown above, allowing the source balance to go negative.
Learn more about Overdrafts and Negative Balances.
Field | Description | Required | Type |
---|---|---|---|
amount | The transaction amount. | Yes | float |
reference | Your unique reference to ensure idempotency. | Yes | string |
currency | Short code for your asset class. See also: Asset classes | Yes | string |
precision | Precision for the currency/asset passed. See also: Precision | No | int64 |
source | Sender’s balance ID | Yes | string |
destination | Recipient’s balance ID. | Yes | string |
description | Description or narration of the transaction. | No | string |
meta_data | Custom data associated with the transaction | No | object |
Passing detailed data with the meta_data
object is encouraged; it provides you with 360-degree insights about each transaction record. Examples of data you can pass include sender_name
, account_number
, bank_name
, receiver_name
, payment_id
, ip_address
, location
, payment_method
, etc.
Next, you can view a list of all transactions in your ledger:
How transactions work in Blnk
Every transaction goes through multiple states in Blnk, and each state change is recorded as a separate record in the database. This gives you complete traceability, allowing to see the lifecycle of a transaction from initiation to completion.
Each state is connected to the previous state through a parent_transaction
attribute. Here’s how it works:
Transaction lifecycle
By default, every transaction begins in a QUEUED
state.
QUEUED
state altogether and directly process your transactions. Learn more: Skip Transaction QueueWithin milliseconds of being queued, Blnk processes it and transitions it to one of three possible states:
INFLIGHT
: If the transaction request includes"inflight": "true"
.APPLIED
: If the inflight transaction is committed.VOID
: If the inflight transaction is voided.
APPLIED
: If inflight is not enabled.REJECTED
: If thesource
has insufficient funds and"allow_overdraft"
is not enabled.
Here’s an example response when you record a new transaction on Blnk:
Record creation and tracking
When a transaction moves to its next state (INFLIGHT
, APPLIED
, or REJECTED
), Blnk creates a new record that maintains a connection to the original queued transaction. This connection is maintained in two ways:
- Parent-Child Relationship: The new record’s
parent_transaction
field stores the original transaction’stransaction_id
. This creates a clear lineage between related transaction records. - Reference Tracking: To ensure each record remains uniquely identifiable while preserving its relationship to other states, Blnk:
- Uses the same base reference as the original transaction.
- Appends a
_q
suffix to create a unique reference.
For example, if the original transaction has:
The next state’s record would have:
Tracking transaction status
You can track the final state of your transactions using either of these methods:
- Reference Search: Query transactions using the original reference. Blnk will return the
INFLIGHT
orAPPLIED
record associated with that reference. - Parent Transaction Search: Look up transactions using the original
transaction_id
as a parent transaction identifier. This returns the same result as the reference search but uses the parent-child relationship instead of the reference string.
Discarded transactions
A discarded transaction is not recorded in the ledger. Blnk discards transactions for one reason:
- Duplicate reference: Your new transaction
reference
matches an existingreference
in your ledger. Blnk requires uniquereference
values per transaction. Options are timestamps (e.g. UNIX timestamp), random string or UUID (e.g.ref_e55c4f33-bff7-4c30-9b9f-5d2d10a29b7a
), or a business identifier like anorder_id
.
apply_overdraft
instead of allow_overdraft
.Skip transaction queue
The skip_queue
feature allows you to bypass the default transaction queuing system outlined above and process transactions directly. This is useful for scenarios where you need real-time transaction processing while still maintaining data consistency.
How it works
When you enable skip_queue
, the transaction:
- Bypasses the normal queuing process
- Executes immediately on the balance
- Uses distributed locks via Redis to maintain consistency
- Applies optimistic locking at the database level
When to use skip_queue
Use skip_queue
for:
- Real-time payment processing in your ledger
- Interactive user sessions requiring immediate feedback
- Time-sensitive financial operations
Avoid using for:
- Complex transactions with multiple steps or dependencies
- Transactions requiring external service validation
blnk.json
Configuration FileManaging insufficient funds
You can handle insufficient funds scenarios in two ways: through automatic rejection handling when transactions are attempted with insufficient balance, and through proactive balance checking before initiating transactions.
1. Automatic rejection
When a transaction is posted where the source
balance has insufficient funds, Bink automatically handles this scenario to maintain ledger integrity. Blnk:
- Rejects the transaction.
- Records this rejection in your ledger using the same state tracking mechanism we discussed above (i.e.
QUEUED
→REJECTED
). - Sends a webhook notification to inform your system of the state change and new ledger record.
reference
or parent_transaction
) to know if the transaction was successful or rejected.2. Proactive balance verification
Instead of waiting for a transaction.rejected
webhook, you can implement a preemptive balance check in your workflow. Here’s how:
First, query the balance of the sender using:
This allows you to make an informed decision before initiating a transaction:
- If the balance is sufficient, proceed with posting your transaction.
- If the balance is insufficient, you can gracefully handle this scenario in your application by notifying the customer immediately, avoiding the need for webhook handling.
Insufficient funds for inflight transactions
For a detailed understanding of how insufficient funds can be managed in inflight scenarios, please refer to our Applying inflight guide.
Need help?
We are very happy to help you make the most of Blnk, regardless of whether it is your first time or you are switching from another tool.
To ask questions or discuss issues, please contact us or join our Discord community.
Manage your Blnk Ledger and explore advanced features (access control & collaboration, anomaly detection, secure storage & file management, etc.) in one dashboard.
Was this page helpful?