Overview
Building a reliable, automated disbursement pipeline requires strict wallet balance monitoring, rigorous recipient data validation, idempotency controls, and disciplined error handling. Follow these operational best practices to prevent failed transfers, avoid double-payouts, and maintain ledger integrity.1. Merchant Wallet Balance Management & Pre-Check
Unlike collections, disbursements directly debit your Niobi merchant wallet in real time.Pre-Checking Wallet Balance via API
Before triggering automated or batch disbursement routines, query your current wallet balance using the Get Account Balance API (POST /api/v3/get-unified-balance):
Key Balance Fields:
available_balance(Primary Indicator): Always evaluateavailable_balanceto determine if you have sufficient funds to cover the payout principal plus transaction fees. Do not rely ontotal_balance, as it includes funds that are currently locked or in-flight (on_hold_balance/unsettled_balance).- Why
available_balanceContains Decimal Points: You may notice fractional decimal values (e.g.185843.4) in your balance. These fractional values are the cumulative result of percentage-based transaction fee deductions across various payment corridors.
Best Practices for Balance Operations:
- Maintain Safety Buffers: Set up automated alerts on your server when your
available_balanceapproaches operational thresholds (e.g. less than 20% of estimated daily volume). - Handle Insufficient Balance Gracefully: If an initiation returns
status_code: "000005"with"Insufficient merchant wallet balance", pause your payout queue, notify your treasury team to top up, and avoid flooding the endpoint with automated retries.
2. The Double-Verification Reconciliation Recipe for Payouts
For payroll disbursements, large vendor payments, or automated cross-border transfers, implement Niobi’s recommended double-verification recipe: rely on thepayment_step: 2 callback as your primary signal, fall back to a status query if it hasn’t arrived, and only close out the payout once that confirmed status is reconciled against your own internal payout records:
Reconciliation Checklist:
- Inbound Signature Verification: Always verify the incoming SHA-256 callback signature using your integration Secret Key (
senderKey) before parsing the payload. - Concurrency Lock & Idempotency Check: Acquire a row-level database lock on
payment_referencebefore processing balance updates. If both a callback and a status query arrive concurrently, only the first thread processes the reconciliation while the second safely exits. - Triple-Point Data Match: Confirm that all three attributes match your internal payout instruction:
- Status & Code: Both
status: "success"andstatusCode: "000000"(Success Code 000000). - Amount & Currency: The disbursed
amountmatches the intended transfer amount. - Reference: The
payment_referenceorthird_party_reference_1matches your internal payout ID.
- Status & Code: Both
- Atomic Ledger Settlement: Update your local transfer record to
SETTLEDinside a single atomic database transaction.
3. Recipient Phone & Account Validation Rules
Improper MSISDN or bank account formatting is the leading cause of instant disbursement rejections.Formatting Rules:
- Digits Only: Strip all spaces, plus signs (
+), hyphens, parentheses, or symbols from phone numbers and bank accounts. - Phone Number Length: Between 8 and 15 digits (including country code).
- International Prefix without Plus: Always prepend the destination country code, but omit the leading
+or local trunk0.
4. Idempotency & Reference Generation Best Practices
To prevent duplicate payouts caused by network retries or transient connection errors:Generating References on Your Side
Generating your own tracking references (payment_reference and third_party_reference_1) directly on your backend before dispatching requests is strongly recommended:
- Format: Use structured, easily traceable identifiers (such as
PAYOUT-2026-USER45-001or a UUIDv4). - Safe Retries: If an API call times out before receiving a response, resubmitting the request with the same reference guarantees that Niobi will not execute a duplicate transfer.
- Audit & Status Queries: Having your own reference stored locally lets you reconcile asynchronous callbacks (
payment_step: 2) or query the Get Transaction Status API using your own identifier.
Enforcing Strict Uniqueness (is_third_party_reference_1_unique)
To have Niobi automatically reject duplicate disbursement submissions, pass the uniqueness flag in your request params:
1 (or true), Niobi verifies that no prior transaction exists with that reference. If a duplicate reference is detected, Niobi immediately blocks the transfer and returns:
Key Rules for Payout Uniqueness:
- Assign Unique References per Payout: Every distinct payout instruction must carry a unique
payment_referenceorthird_party_reference_1. - Generate Unique Salt per Request: Always generate a fresh random
saltstring for each API call to ensure cryptographic uniqueness and prevent replay attacks. - Avoid Blind Retries with New References: If an HTTP request times out, never generate a new reference to retry the same payout. Re-send with the original reference or query status first.
5. Error Handling & Retry Policies
1. Handling 4xx Client Errors (Do Not Auto-Retry)
1. Handling 4xx Client Errors (Do Not Auto-Retry)
Examples:
Action: Do not retry automatically. Check parameter validation, verify your signature generation algorithm, ensure required corridor fields (such as Cameroon sender details) are supplied, and correct the payload before resending. See 400 Client Errors for code breakdowns.
400 Bad Request, 403 Request not verified, validation errors.Action: Do not retry automatically. Check parameter validation, verify your signature generation algorithm, ensure required corridor fields (such as Cameroon sender details) are supplied, and correct the payload before resending. See 400 Client Errors for code breakdowns.
2. Handling 5xx Server Errors (Retry with Exponential Backoff)
2. Handling 5xx Server Errors (Retry with Exponential Backoff)
Examples:
Action: Implement exponential backoff (e.g. retry after 2s, 4s, 8s, 16s) up to a maximum of 3 to 5 attempts. If timeouts persist, check payout status using your reference before re-initiating.
500 Internal Server Error, 502 Bad Gateway, 504 Gateway Timeout.Action: Implement exponential backoff (e.g. retry after 2s, 4s, 8s, 16s) up to a maximum of 3 to 5 attempts. If timeouts persist, check payout status using your reference before re-initiating.
3. Handling Failed Callbacks (Recipient Inactive / Reversal)
3. Handling Failed Callbacks (Recipient Inactive / Reversal)
Examples:
Action: Funds are automatically refunded to your merchant wallet. Notify the recipient or prompt them to provide an active, registered phone number or bank account.
status: "failed", statusCode: "000005", failureReason.failureCode: "DS-008".Action: Funds are automatically refunded to your merchant wallet. Notify the recipient or prompt them to provide an active, registered phone number or bank account.

