nomba-sdk
v1.0.0
Published
Robust, type-safe, and secured Node.js SDK for the Nomba API.
Maintainers
Readme
Nomba Node.js SDK
A robust, secured, and strongly-typed Node.js client library for the Nomba API.
Exposes support for Virtual Accounts, Checkout, Transfers, Terminals/POS integrations, transparent OAuth2 token caching/auto-refreshing, secure timing-safe webhook verification, and custom error-handling wrappers.
Features
- Transparent Token Management: Cache and auto-refresh API access tokens internally without manual intervention.
- Timing-Safe Webhooks: Defend against timing attacks using secure signature validation.
- Auto-Retries with Exponential Backoff: Gracefully handle temporary API failures.
- Rich Typings: Written in TypeScript with complete interfaces for all request and response schemas.
- Clean Sub-modules: Clean, structured client API endpoints matching the Nomba dashboard.
Installation
npm install nomba-sdkGetting Started
1. Initialization
Configure the SDK using your dashboard credentials. Do not expose your production credentials in your source code; load them from environment variables instead.
import { Nomba } from 'nomba-sdk';
const nomba = new Nomba({
clientId: process.env.NOMBA_CLIENT_ID!,
clientSecret: process.env.NOMBA_CLIENT_SECRET!,
accountId: process.env.NOMBA_ACCOUNT_ID!,
environment: 'sandbox', // 'sandbox' (default) or 'production'
timeout: 30000, // request timeout in milliseconds (default: 30000)
retries: 2, // retry failed 5xx/network requests (default: 2)
});Submodule Usage
1. Virtual Accounts
Generate static or dynamic bank accounts for collections.
// Create a static virtual account (no expiry, no expected amount)
const staticAccount = await nomba.virtualAccounts.create({
accountRef: 'ref_unique_123',
accountName: 'John Doe',
});
console.log('Account Number:', staticAccount.data.bankAccountNumber);
// Create a dynamic virtual account (expires in 1 hour)
const dynamicAccount = await nomba.virtualAccounts.create({
accountRef: 'ref_unique_456',
accountName: 'Jane Smith',
expiryDate: '2026-06-30 18:00:00',
expectedAmount: 5000.00, // NGN 5,000.00
});2. Transfers (Disbursals)
Verify accounts and perform bank transfers.
// 1. Get banks and bank codes
const { data: banks } = await nomba.transfers.getBanks();
// 2. Lookup and verify destination account holder
const lookup = await nomba.transfers.lookupAccount({
accountNumber: '0123456789',
bankCode: '058',
});
console.log('Account Name:', lookup.data.accountName);
// 3. Initiate Transfer (idempotent using merchantTxRef)
const transfer = await nomba.transfers.initiate({
amount: 2500, // NGN 2,500.00
accountNumber: '0123456789',
accountName: lookup.data.accountName,
bankCode: '058',
merchantTxRef: 'unique_transfer_reference_123',
narration: 'Payment for services rendered',
});3. Hosted Checkout
Redirect customers to a pre-built payment checkout page.
const checkout = await nomba.checkout.createOrder({
order: {
orderReference: 'checkout_order_ref_999',
amount: '12000.00',
currency: 'NGN',
customerEmail: '[email protected]',
callbackUrl: 'https://yourwebsite.com/payment/callback',
orderMetaData: {
productId: 'prod_9988',
},
},
});
console.log('Checkout URL:', checkout.data.checkoutLink);4. POS Terminals
Manage and push payment requests to physical hardware.
// List assigned terminals
const { data } = await nomba.terminals.list({ limit: 10 });
// Push payment prompt (e.g. prompt card insertion for NGN 15.00)
const push = await nomba.terminals.pushPayment('terminal_id_abc', {
merchantTxRef: 'pos_payment_ref_789',
amount: 1500, // 1500 kobo = NGN 15.00
currency: 'NGN',
});5. Transaction Verification
Verify payment status using orderReference or transactionRef.
const verification = await nomba.transactions.verify(
'unique_transfer_reference_123',
'transactionRef' // or 'orderReference'
);
if (verification.data.status === 'SUCCESS') {
console.log('Transaction succeeded!');
}Webhook Verification
Secure your webhook endpoint. The verification function verifies requests using HMAC-SHA256 and prevents timing attacks using crypto.timingSafeEqual.
import { verifyWebhookSignature } from 'nomba-sdk';
// In your Express webhook controller:
app.post('/webhook', (req, res) => {
const rawBody = req.body; // Ensure raw body is parsed as string or Buffer
const signature = req.headers['nomba-signature'] as string;
const webhookKey = process.env.NOMBA_WEBHOOK_KEY!; // Webhook secret key
const isValid = verifyWebhookSignature(rawBody, signature, webhookKey);
if (!isValid) {
return res.status(401).send('Invalid webhook signature');
}
// Webhook is authentic, proceed to process the event
const event = JSON.parse(rawBody.toString());
console.log('Webhook event:', event);
res.status(200).send('OK');
});Error Handling
The SDK exposes clean error wrappers so you can handle issues granularly:
import {
NombaAPIError,
NombaNetworkError,
NombaValidationError
} from 'nomba-sdk';
try {
await nomba.transfers.initiate({ /* ... */ });
} catch (error) {
if (error instanceof NombaValidationError) {
console.error('Local validation failed:', error.message);
} else if (error instanceof NombaAPIError) {
console.error('API Error Code:', error.code);
console.error('API Error Message:', error.description);
console.error('HTTP Status Code:', error.statusCode);
} else if (error instanceof NombaNetworkError) {
console.error('Network failed/timed out:', error.message);
}
}License
MIT
