How Niobi Ensures Idempotency
In financial API integrations, network drops, client timeouts, and automated retries can cause the same API request to be transmitted multiple times. Idempotency guarantees that initiating the same payment operation multiple times produces the exact same outcome as initiating it once. It prevents double-payouts to recipients, duplicate prompt pushes to payers, and replay attacks.The Dual-Reference Architecture
Every transaction that reaches Niobi operates on two distinct, complementary identifiers:-
Niobi Transaction Reference (
depositId/reference):- Generated automatically by Niobi when an API request is initialized (
depositIdfor collections,referencefor payouts). - Returned in the initial API response upon request initiation.
- Included in all subsequent asynchronous callbacks (
payment_step: 2) and status queries.
- Generated automatically by Niobi when an API request is initialized (
-
Merchant Reference (
third_party_reference_1/payment_reference):- Generated on your backend before dispatching the API request (e.g.
ORDER-2026-001orTX-DISB-9901). - Represents your internal transaction or order identifier.
- Serves as your idempotency key to prevent duplicates and enable automated reconciliation.
- Generated on your backend before dispatching the API request (e.g.
Your SystemMerchant Tracking Layer
third_party_reference_1: “TX-ORD-9001”payment_reference: “PAYOUT-REF-1001”Niobi SystemNiobi Transaction Layer
depositId: “dep_12345678”reference: “ref_98765432”Returned upon initial request.
How It Works
Niobi binds your merchant reference to a unique transaction reference upon initial receipt. When a reference uniqueness flag (is_third_party_reference_1_unique: 1 and/or is_third_party_reference_2_unique: 1) is enabled, Niobi enforces duplicate prevention. This active duplicate rejection is currently enforced on disbursements (payouts) only: collection requests accept third_party_reference_1/third_party_reference_2 and their uniqueness flags and Niobi still stores them against the transaction, but a duplicate collection request is not currently rejected based on these flags.
1. Request Initiation & Transaction Reference Assignment
When your server submits a payout or collection request, Niobi assigns a unique transaction reference and maps yourthird_party_reference_1 to the record.
2. Active Duplicate Prevention (is_third_party_reference_1_unique / is_third_party_reference_2_unique)
To prevent accidental double-payouts during retries or network timeouts, include "is_third_party_reference_1_unique": 1 and/or "is_third_party_reference_2_unique": 1 in params:
Flag Requirement:
Duplicate detection only executes for a reference whose flag is passed as
Duplicate detection only executes for a reference whose flag is passed as
1 in the request payload. If a flag is omitted or set to 0, Niobi will not check that reference and will process the retry as a new transaction. If both flags are set to 1, Niobi checks third_party_reference_1 first, then third_party_reference_2, and immediately rejects the request on whichever one first matches an existing record, without evaluating further.Terminal States & Reference Binding
Once a transaction reaches a terminal status (000000 - Success or 000005 - Failed), both your merchant reference and Niobi’s transaction reference are permanently recorded:
- Finality: A terminal status indicates the payment has completed.
- Duplicate Protection: Resubmitting with the same
third_party_reference_1whenis_third_party_reference_1_unique: 1is passed immediately rejects duplicate execution (Duplicate third_party_reference_1 was found!). - Verifying Outcome: To check the state of an already-submitted transaction, query the Get Transaction Status API rather than re-initiating the request.
- Failed Transactions: A
000005 - Failedstatus represents finality (such as invalid account details, payer decline, or timeout).
Retrying Failed Transactions
If a transfer or collection fails definitively and you need to re-attempt the payment (such as after the customer provides a new phone number or corrects their account details), you must use a newthird_party_reference_1.
The previous reference cannot be reused to initiate a new transfer.
Recommended Pattern: Append a Retry Suffix
Benefits of the Suffix Pattern:
- Traceability: Correlate all attempts related to the same underlying logical order.
- Webhook Mapping: Match asynchronous callback notifications (
payment_step: 2) back to the specific retry attempt. - Audit Trail: Maintain an immutable history in your database of each payment attempt and its specific outcome.
Uniqueness Identifiers Reference
Webhook Callback Idempotency on Your Server
Because webhook callbacks traverse public networks, Niobi may re-deliver a terminal callback (payment_step: 2) if your server took longer than 5 seconds to respond with HTTP 200 OK or encountered temporary connectivity issues.
Ensure your webhook listener handles duplicate callbacks safely:
Callback Receiver Best Practices:
- Verify Inbound Signature: Always verify the incoming SHA-256 signature using your integration Secret Key (
senderKey) before parsing data. - Check State Before Crediting: Check whether
third_party_reference_1or Niobi’sreferencehas already been credited in your database. - Return HTTP 200 on Duplicates: If a callback is received for an already settled order, acknowledge receipt immediately with HTTP
200 OKwithout duplicating financial credits. - Use Concurrency Locks: Use database row-level locking or unique constraints on
third_party_reference_1to prevent concurrent threads from processing duplicate webhooks simultaneously.

