Lending businesses rely heavily on accurate KYC (Know Your Customer), creditworthiness, and risk assessment processes to determine if a borrower is eligible for a loan. This means that, as a lender, you need to verify the identity of customers to prove their authenticity and understand their borrowing patterns to determine their capacity to repay loans collected.
Integrating Mono Lookup APIs into your credit-decisioning system can streamline these processes for your digital lending business, providing access to critical data such as potential borrowers’ verified account and identity information, and credit histories.
A few weeks ago, we hosted a developer session that explored how to leverage Mono APIs to build a robust credit-decisioning system. In this article, we will share a step-by-step guide for implementing three of Mono’s APIs in a sample demo app like the one we built called Fintrack360.
How Mono APIs can be utilised in your credit-decisioning process
Before we get into the implementation process, here are the Mono Lookup endpoints we used in the sample demo app we built and how you can feed it into your lending process:
Mono BVN Lookup API: This allows you to access a user's Bank Verification Number (BVN) information and verify their identity easily. With this lookup endpoint, you can also get a robust view of the users’ identity information and even check if the potential borrower has been blacklisted or not.
Mono Account Lookup API: This endpoint enables you to validate the authenticity of the account numbers provided by the users and confirm that it belongs to them. This helps you accurately verify borrowers during the loan application stage and reduce the chance of identity fraud.
Mono Credit History Lookup API: This allows you to retrieve a user’s historical and recent credit information directly from the two largest credit bureaus in Nigeria, and confirm their credit worthiness and eligibility for a loan faster and more securely.
Steps to be covered
We'll break down the implementation process into several key steps:
Obtaining App keys: Get the necessary API keys from the Mono dashboard.
Backend setup: Installation of dependencies for NodeJS, Express, and MongoDB, setting up database models, and creating controllers. Implementing identity verification, fetching bank account data, and retrieving recent and historical credit information.
Frontend setup: Installation of React dependencies and designing the user interface.
Credit decision making: Utilizing the collected data to make informed credit decisions.
What you will need
Before we start with the implementation, ensure that:
Node.js is installed locally. If not, here’s how to install it yourself
You understand and know how to set up projects with the MERN Stack
Retrieve your public and secret keys from your Mono dashboard.
Now, let's get started with the implementation.
1. Obtaining App keys
Log in to the Mono dashboard (create an account here if you don’t have one), and then navigate to your Apps page to create an App. Once created, a secret and public key is generated which we would later use to make API calls.
2. Backend implementation
Before we set up the backend, on your local computer, you can create a folder (Fintrack360-project) and create two separate sub-folders within it, titled frontend
and backend
.
In your IDE, navigate into the backend folder within the Fintrack360-project folder and proceed to instantiate node by running npm install
.
Next, you need to install the dependencies as shown below:
Once you have installed all the necessary dependencies. You can then proceed to create your models, controllers, and routes folders.
Setting up the database models in MongoDB
For this implementation, you will need two mongoDB models. They are:
User model: This Mongoose model defines the schema for users and their associated bank accounts. The
User
schema should include fields such as BVN, personal information, and an array of bank accounts. Each bank account is defined by theaccountSchema
which includes details like account name, number, type, designation, and institution information. The model facilitates the storage and retrieval of user and account data within a MongoDB database, providing a structured foundation for the application.Credit history model: This model defines the schema for generating credit reports. The
Report
schema includes nested structures such as credit history, address history, identification details, and profile information. Each credit history entry contains data such as institution name, opening balance, loan status, repayment frequency, and repayment schedule. Additionally, the model accommodates flexibility with mixed types for tenor and allows for deeply nested repayment schedules. With this schema, the application can efficiently store and retrieve comprehensive credit reports, facilitating robust credit assessment processes.
Setting up your environment variables
Next, set up environment variables to ensure smooth operation and security. Create a .env
at the root of your backend folder ****and then add the following detail:
PORT: Define the port number your server will listen on. For instance,
PORT=4000
assigns port 4000 for your application.MONGO_URI: Specify the connection URL for your MongoDB database. This URL typically includes the host, port, database name, and authentication credentials if required. Here’s how to get your mongoDB_URL.
MONO_SECRET_KEY: Provide your secret key for accessing Mono APIs. This key ensures secure communication between your application and Mono APIs.
MONO_TEST_KEY: Include a test key for development or testing purposes. This key allows you to interact with Mono APIs in a sandbox environment without affecting live data.
Remember to keep your environment variables secure and avoid committing them to version control systems to prevent unauthorized access to sensitive information. Use tools like .env
files to manage your environment variables locally and ensure proper configuration management in production environments.
Setting up your controllers
Once your models are set up, you need to create four different controllers to perform separate actions.
BVN controller This controller serves as the interface between our application and the Mono BVN Lookup API, which allows you to securely verify users’ BVN and retrieve their account and identity details. It should contain asynchronous functions for each API endpoint, handling requests and responses accordingly. The controller integrates with the
User
model to store and update user data as needed in the database.
Please note that to make the application very lightweight and easy to follow, this application doesn’t include any form of authentication i.e. Login or Register. The BVN functionality serves as our means of authentication and the UserID serves as the data point for retrieving every other user data required.
When a user completes the BVN authentication process, a UserId is generated and saved in association with the BVN to the database. This User ID is saved in the browser session and used when making further queries to the database.
Identity controller This controller,
getIdentityData
, retrieves identity data for a specified user from the database. The controller should accept a user ID as a parameter and query theUser
model to find the corresponding user document. If the user is found, their data is returned in the response.
Account controller This controller facilitates bank lookup and account number verification functionalities using the Mono Account Lookup API. The
bankLookup
function retrieves a list of available banks while theaccountNumberLookup
function validates a given account number against a specified bank.
Your bankLookup
function should send a request to the Mono Account Lookup API to fetch a list of banks. The retrieved bank names are then extracted and returned as a response.
Next, create the accountNumberLookup
function which accepts a bank name and account number as input. It first retrieves the list of banks from the Mono Account Lookup API to find the corresponding NIP code for the specified bank. Using this NIP code and the provided account number, a request is made to the Mono Account Lookup API to verify the account number's validity. The response containing the account details is then returned.
Credit history controller Create a function -
fetchCreditHistory
to retrieve credit history data for a user from a specified provider using the Mono Credit History Lookup API. It first queries theUser
model to find the user associated with the provided ID, extracts the user's BVN, and then sends a request to the Mono Credit History API endpoint to retrieve the user’s credit information. Upon receiving a response, it saves the data to the database using theReport
model.
Kindly note that in all the controllers, error handling is implemented to manage unexpected responses or failures during API calls, ensuring robustness and reliability in data retrieval and processing.
Setting up the Routes
This is a fundamental step in defining the endpoints through which your APIs will operate. Similar to creating the controllers, organizing routes requires creating four distinct route files:
BVN route: These routes are for handling various BVN-related operations in the BVN Controller. Here, you import controller functions for initiating BVN, verifying BVN, fetching BVN details, initiating bank account retrieval, and fetching bank account details.
Identity route: This route imports the
getIdentityData
controller function which handles the logic for retrieving identity data based on a provided ID.Account route: Here, you import the controller functions for retrieving a list of banks and performing account number lookup with
/bank-list
mapped to thebankLookup
controller function and/account-number
mapped to theaccountNumberLookup
controller function.Credit history route: This route imports the
fetchCreditHistory
controller function which handles the logic for retrieving credit history information.
3. Frontend implementation
Once you have completely set up the backend and tested your APIs, navigate to the root folder of the Fintrack360-Project. Begin with creating a React project in the folder by running npx create-react-app frontend
. Once this is done, navigate to the folder by running cd frontend
in your IDE terminal.
Next, install all the necessary dependencies for routing and styling.
Setting up the roots
First, set up the frontend routing using the React Router with Browser Router in the index file of your React application.
Next, navigate to the App.js
file in your React project directory. Set up your application's routing by importing necessary components and hooks from react-router-dom
. Ensure to import Routes
, Route
, useLocation
, and Navigate
.
Additionally, import your application's pages and components in the sample case we have Home, Navbar, Dashboard, and NotFound. Utilize the useLocation
hook to determine whether to render the Navbar
based on the current pathname. Inside the App
component, structure your routes using <Routes>
and define routes for each page using <Route>
. Don't forget to specify the path
and element
props for each route to render the appropriate component. Finally, export the App
component as the default export.
Setting up your routing config
Next, create a config
folder in your project directory. Inside the config
folder, create an axiosConfig.js
file. Set up your Axios instance in this file by importing Axios and creating a new instance using axios.create()
. Configure the base URL for your API requests using the baseURL
property.
You can set the base URL dynamically using process.env.REACT_APP_API_URL
to retrieve the API URL from environment variables. Alternatively, you can set a default base URL such as '<http://localhost:4000>'
for development purposes. Finally, export the configured Axios instance as the default export from the axiosConfig.js
file. This setup allows you to manage Axios configurations centrally and reuse the Axios instance throughout your application.
Pages and components set up
Here, create pages and component folders respectively. In the pages folder, we will create two files.
Pages/Home.js: This page serves as the landing page where users can connect their BVN, verify their bank account, and retrieve their credit history. Inside the
Home
component, utilize React hooks such asuseState
anduseNavigate
for managing component state and navigation.
Import necessary dependencies including the AxiosInstance for making API requests and various icons for UI elements. Implement functions for initiating BVN, verifying BVN, and fetching BVN details. Utilize conditional rendering to display different stages of the authentication process. Display loading spinners during API requests and handle form submissions accordingly. Lastly, include JSX markup to render the user interface, input fields, and buttons for user interaction.
Users input BVN, select a verification method (phone, email, etc.), and enter the OTP received. This data is then passed to the FetchBVN API, and upon success, users are redirected to view the retrieved information.
Pages/Dashboard.js: This page serves as the user dashboard where users can view their identity information, bank accounts, and credit history. Utilize React hooks such as
useState
to manage component state for tracking the current section index. Import theIdentity
,AllBankAccounts
, andCreditHistory
components to display respective sections. Implement functions to scroll to the next and previous sections smoothly using thewindow.scrollTo
method. Utilize conditional rendering to display the current section based on thesectionIndex
. Include JSX markup to render the dashboard layout including navigation buttons styled with theFaChevronCircleUp
andFaChevronCircleDown
icons for smooth scrolling between sections.
In the Components folder, we create several components for rendering information and input details on the dashboard where necessary. Some of these include:
Components/Identity.js:
This component is responsible for fetching and displaying user identity data. Inside the useEffect
hook, implement the logic to fetch identity data from the server using Axios and store it in the component's state.
Render JSX markup to display the fetched identity data including the user's profile photo, first name, last name, phone number, and gender. Utilize conditional rendering to display a loading indicator while the data is being fetched.
Components/BankAccounts.js:
This component manages and displays the user's bank account data. Utilize conditional rendering to display loading indicators and forms for initiating bank account fetch, verifying BVN, and fetching bank accounts. Implement functionality to handle user interactions such as selecting a verification method, inputting an OTP, and clicking on a bank account to view details.
Inside the useEffect
hook, implement the logic to fetch bank account data from the server using Axios and store it in the component's state.
Components/Account.js:
This component manages the process of linking a bank account. Implement the fetchBanks
function inside the useEffect
hook to fetch the list of available banks from the server using Axios. Implement functionality to handle bank selection using the react-select
component and input of the account number. Utilize conditional rendering to display different UI elements based on the verification status of the account.
Components/CreditHistory.js:
The component includes a form allowing the user to select a credit history provider (XDS, CRC, or both) and submit the request. Implement the handleProviderChange
function to update the selected provider in the component state when the user selects an option.
Utilize conditional rendering to display loading indicators while data is being fetched, the form for selecting the provider when no data is available, and the CreditHistoryTable
component to display the credit history data when available.
4. Credit decision making
Lastly, create a CreditHistoryTable
component to display the user's credit history. This component is responsible for rendering a table displaying the credit history information for each institution. The data retrieved from polling the credit history of a user can then be analysed to make credit decisions. In our case, this component computes the loan eligibility based on the number of open and closed loans.
We iterate through the creditHistory
array to calculate the counts of open and closed loans and implement conditional rendering to display a button indicating loan eligibility based on the computed result. If the closed loan count is greater than the open loan count, the user is eligible for a loan, and a green button with the "Eligible for Loan" message and the forward arrow icon is displayed. Otherwise, a red button with the "Ineligible for Loan" message and the cancel icon is shown.
When building your system, you may consider other data points like the loan amounts, and the consistency or inconsistency in repayments to generate a form of credit ranking or score to use in making your credit decisions.
Building a credit-decisioning system with the Mono Lookup APIs improves your identity verification process, streamlines the loan application process, and helps you better assess potential borrowers’ eligibility for credit facilities. By following the steps outlined in this article, developers and businesses can create robust and efficient credit-decisioning systems tailored to their lending needs. If you’d like to integrate any of our Mono Lookup APIs to your service, you can get started by creating a free Mono account here or reach out to our team at sales@mono.co.