Overview
Because payment processing across African mobile networks and banking systems is asynchronous, Niobi notifies your server of the final transaction outcome by sending an HTTP POST callback request to thecallback_url specified in your collection request.
Terminal Callback Guarantee (payment_step: 2)
- The callback is delivered for both successful (
status: "success",statusCode: "000000") and failed (status: "failed",statusCode: "000005") payments. - Update your application’s order state based on both the
statusandstatusCodefields delivered insideparams. See our Transaction Status Codes Reference for details.
Callback Payload Structure
Incoming callbacks from Niobi follow the standard signed envelope structure:1. Successful Collection Callback (payment_step: 2)
2. Failed Collection Callback (payment_step: 2)
Callback Parameter Specification
Verifying Inbound Callback Signatures
To ensure that an incoming callback genuinely originated from Niobi and has not been forged or tampered with:- Extract Signature: Extract
signaturefrom the incoming root JSON object and remove it. - Inject Secret Key: Add
"senderKey": "YOUR_SECRET_KEY"into the payload object. - Sort Keys (Recursive K-Sort): Alphabetically sort all keys recursively.
- Flatten & Hash: Convert to key-value query string format concatenated with
&, and hash with SHA-256. - Compare: Compare your computed hash with the
signaturefrom Step 1. If they match, the callback is authentic.
Dual-Layer Confirmation: Querying Transaction Status
As an additional layer of confirmation, Niobi encourages querying the transaction status alongside listening for callbacks. Combining the incoming asynchronous callback with an on-demand status query gives your system independent, double-verified confirmation before updating customer balances or fulfilling high-value orders.Endpoint
POST /api/v3/get-unified-transaction-status
Request Parameters (params Object)
Sample Signed Status Query Request
Sample Status Query Response
Reconciling Query Results:
status: "success"(status_code: "000000"): The collection was successfully authorized and credited to your merchant wallet. You can safely fulfill the order or credit the user’s account.status: "failed"(status_code: "000005"): The collection failed or was declined by the payer. Mark the payment as failed.status: "pending"(status_code: "000001"): Authorization is still in progress with the upstream provider. Do not take action on this state (do not fulfill orders or mark as failed). Keep the transaction in a pending state and await the asynchronous callback (payment_step: 2) or re-query after a brief delay.
status_code (snake_case) at its top level. The terminal callback’s params.statusCode field, along with params.failureReason (failureCode/failureMessage) on failed collections, shown earlier on this page, are camelCase.
Callback Receiver Implementation Guidelines
1. Respond Promptly with HTTP 200
1. Respond Promptly with HTTP 200
Your callback listener should respond with an HTTP
200 OK status as quickly as possible (ideally within 3 to 5 seconds). Perform long-running background tasks (e.g. sending customer confirmation emails or generating PDFs) asynchronously in a background job queue after returning 200 OK.2. Implement Idempotent Processing
2. Implement Idempotent Processing
In rare cases of network timeouts between Niobi and your server, callback notifications may be retried. Ensure your callback handler uses
params.reference or params.third_party_reference_1 to verify whether a transaction has already been processed and credited before applying balance updates.3. Avoid Aggressive Polling Loops
3. Avoid Aggressive Polling Loops
Rely on the
payment_step: 2 callback as the primary notification mechanism. Do not continuously poll the status API in a tight loop while waiting for a callback; if a callback has not been received after a while, you can query the Get Transaction Status API (POST /api/v3/get-unified-transaction-status) using spaced intervals.Resending Callbacks via the Payment Portal
You can resend callbacks in case of a delivery failure through the payment portal. To do this, access the specific transaction and click on Resend Callback.
Resending a failed callback delivery directly from the transaction details modal in the payment portal
When can a callback be resent?
The Resend Callback option can only be triggered via the payment portal for a deposit or payout request in cases where the callback was not delivered correctly to your server (for example, if your listener experienced downtime, timed out, or returned an HTTP error). It is not displayed for callbacks that were already acknowledged with HTTP 200.
The Resend Callback option can only be triggered via the payment portal for a deposit or payout request in cases where the callback was not delivered correctly to your server (for example, if your listener experienced downtime, timed out, or returned an HTTP error). It is not displayed for callbacks that were already acknowledged with HTTP 200.

