NEWIntroducing Mono Prove: Transforming Identity Verification and Customer Onboarding experiences
Mono Blog

How to build a robust credit-decisioning system with Mono Lookup APIs

Apr 19, 2024Engineering

Share article

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:

  1. Obtaining App keys: Get the necessary API keys from the Mono dashboard.

  2. 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.

  3. Frontend setup: Installation of React dependencies and designing the user interface.

  4. Credit decision making: Utilizing the collected data to make informed credit decisions.

What you will need

Before we start with the implementation, ensure that:

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.

Getting your Mono App keys

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.

backend implementationIn 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:

npm installOnce 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 the accountSchema 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.

Sample BVN controller

  • 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 the User model to find the corresponding user document. If the user is found, their data is returned in the response.

Sample identity controller

  • 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 the accountNumberLookup 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.

Sample Account controller

  • 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 the User 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 the Report model.

Sample credit history controller

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 the bankLookup controller function and /account-number mapped to the accountNumberLookup 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.

frontend implementation

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.

Setting up the rootsAdditionally, 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 as useState and useNavigate 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.

Pages and components set upUsers 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 the Identity, AllBankAccounts, and CreditHistory components to display respective sections. Implement functions to scroll to the next and previous sections smoothly using the window.scrollTo method. Utilize conditional rendering to display the current section based on the sectionIndex. Include JSX markup to render the dashboard layout including navigation buttons styled with the FaChevronCircleUp and FaChevronCircleDown icons for smooth scrolling between sections.

ComponentsIdentity.jsIn 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.

Identity ComponentsRender 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.

Bank Account ComponentsInside 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.

Account component

  • 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.

credit history componentUtilize 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.

Credit decision makingWe 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.

Like what you read?

Become a subscriber and receive notifications about blog posts, company events and announcements, products and more.

Next Read

Oct 2, 2024Engineering

Building an automated loan recovery process with Mono Direct Debit APIs

Read the story
Building an automated loan recovery process with Mono Direct Debit APIs
Jul 15, 2024Engineering

How to Implement the Mono Telco Data API

Read the story
How to Implement the Mono Telco Data API

Start building with Mono today

a Flutterwave company

2026 © Mono Technologies Nigeria Limited

trust mark NIGtrust mark QR Codeiso-iec27001iso-iec27002iso-iec27003

Disclaimer:
The information provided on this website is intended for general informational purposes only and does not constitute financial, legal, or professional advice. While we strive to ensure that the content presented is accurate and up-to-date, we make no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability, or availability with respect to the website or the information, products, services, or related graphics contained on the website for any purpose. Any reliance you place on such information is therefore strictly at your own risk.

Our platform is designed to ensure secure access to financial accounts for the purposes of retrieving statements, monitoring transactions in real-time, and verifying customer identities. Despite our use of advanced security protocols to protect sensitive information, we cannot guarantee the absolute security of your data. Users are advised to independently verify the accuracy and completeness of all information obtained through our services before making any financial or business decisions.

Furthermore, while we endeavor to keep the website running smoothly, we take no responsibility for, and will not be liable for, the website being temporarily unavailable due to technical issues beyond our control. In no event will we be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this website.

This website may contain links to other websites which are not under the control of our company. We have no control over the nature, content, and availability of those sites. The inclusion of any links does not necessarily imply a recommendation or endorse the views expressed within them.

By using this website, you agree to these terms and acknowledge that any reliance on the information provided here is at your own risk. If you have any questions regarding this disclaimer or the website's content, please contact us directly.