By Benjamin Ononogbu 2nd May, 2025
A customer reserved account is a feature that facilitates businesses with the ability to generate permanent personalized account numbers for their customers giving them the ability to make payments to the business anytime and anywhere
With a reserved account customers are assured of owning account numbers that belong to them alone just like their usual bank account number that isn’t shared among different persons.
We will demonstrate how the Nodejs library can be used to simplify interacting with Monnify reserved account APIs, handling access token management and providing proper validation messages and API responses.
Businesses that involves the use of a wallet:
Here, an account number is reserved
for each customer's wallet to enable them to top up by simply transferring to that account.
Examples of this are Super Agents, Investment Applications, Betting Platforms, Logistics Applications, etc.
{
"name": "monnify-node",
"version": "1.0.0",
"description": "A sample usage of the monnify nodejs lib",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "benji",
"license": "ISC"
}
Is this OK? (yes).
npm install monnify-nodejs-lib express body-parser cors crypto
Next we create two folders in the root directory called service and controller; where the service folder is for managing service level requests and controller for managing request handlers.
And on the index.js, we instantiate the express server making index.js an entry point for starting the server.
import router from "./router.js"
import express from 'express'
import bodyParser from "body-parser";
const requestRouter = router
const notFound = (req, res, next) => {
res.status(404);
res.json({
status: 404,
msg: "Resource was not found",
});
};
const handleError = (error, req, res, next) => {
console.log(error);
res.status(error.status || 500);
res.json({
status:"failed",responseBody:" An error occurred while processing your request"
});
};
const app = express()
app.use(bodyParser.urlencoded({extended : true}))
app.use(bodyParser.json())
app.use("/api/v1",requestRouter)
app.use(notFound);
app.use(handleError);
const PORT = process.env.PORT || 4111;
app.listen(PORT, console.log("Server started at port: " + PORT))
As described above, the code starts with an import of necessary installed libraries, then proceeds to configure a default HTTP 404 and HTTP 500 handler.
We then proceed to configure a parser(using body-parser) for parsing json request and urlencoding request url. And finally after instantiating the express application, the base api url is configured along with the server startup port of which the server is made to listen on.
Next on the service/apiService.js file, we handle instantiation of the monnify nodejs lib and implementation for reserved account creation, details retrieval and deallocation. An abridged implementation of this is as follows:
import {MonnifyAPI} from "monnify-nodejs-lib"
const config = {
MONNIFY_APIKEY: {YOURMONNIFYAPIKEY},
MONNIFY_SECRET: {YOURMONNIFYSECRET}
}
config.env = {APIENVIRONMENT}
const monnifyClient = new MonnifyAPI(config)
async function getAccessToken(){
try{
const response = await monnifyClient.getToken()
if (response[0] === 200){
return response[1]
}else{
throw new Error(JSON.stringify(response[1]))
} }
catch(err){
console.log(err)
return false
}
}
async function createVirtualAccount(payload){
try{
const authToken = await getAccessToken()
if (!authToken){
throw new Error("Could not create virtual account at the moment as token is not available")
}
const response = await monnifyClient.reservedAccount.createReservedAccount(authToken,payload)
if(response[0] === 200){
return response[1]
}else if (response[0] >= 400 && response[0] < 500){
return response[1]
}else{
throw new Error(json.Stringify(response[1]))
}
}
catch(err){
console.log(err)
return false
}
}
With the Monnify nodejs lib, access token generation is cached and expiration time is managed too, overhauling the tasks of properly managing such expiration. As shown above, we first instantiate the library with necessary configurations like API and SecretKey, next the instantiated library provides a reserved account class which has a createReservedAccount method for account creation.
Finally, we implement a handler in controller/trxController.js to handle requests sent to the routers as shown below:
import apiService from "../services/apiService.js"
async function generateReservedAccount(req, res, next){
try{
const resp = await apiService.createVirtualAccount(req.body)
if(resp){
if(resp.requestSuccessful === true){
const response = {
"status":"success",
"responseBody":resp.responseBody
}
return res.status(200).send(response)
}else{
const response = {
"status":"failed",
"responseBody":resp.responseMessage
}
return res.status(400).send(response)
}
}else{
const response = {
"status":"failed",
"responseBody":"Service is currently unavailable"
}
return res.status(500).send(response)
}
}
catch(err){
console.log(err)
next(err)
}
}
This section of the code is a request handler for reserved account creation request sent to the endpoint configured below in router.js
import {Router} from "express"
const router = new Router()
import trx from "./controllers/trxController.js"
router.post("/trx/reservedAccount", trx.generateReservedAccount)
router.get("/trx/reservedAccount/:accountReference", trx.getReservedAccount)
router.delete("/trx/reservedAccount/:accountReference", trx.deallocateReservedAccount)
export default router;
As we have seen so far, the nodejs library provided a layer of abstraction over the Monnify reserved account API making account creation equivalent to a method call and voila, virtual accounts are created!!.
You can see a full implementation of the code sample here