@hassanmehdi98/fineract-api-client
v0.1.4
Published
TypeScript client for Fineract APIs
Maintainers
Readme
Fineract API Client
TypeScript client for interacting with specific Fineract client-related APIs. This library provides type-safe methods for creating and retrieving client information from a Fineract instance.
Installation
npm install @hayeeder/fineract-api-client
# or
yarn add @hayeeder/fineract-api-clientUsage
First, configure and create an instance of the FineractSDK:
import {
createFineractSDK,
FineractSDKConfig,
} from "@hayeeder/fineract-api-client";
const sdkConfig: FineractSDKConfig = {
baseURL: "https://your-fineract-host.com", // Replace with your Fineract base URL
tenantId: "default", // Your Fineract tenant ID
username: "mifos", // Your Fineract username
password: "password", // Your Fineract password
timeout: 30000, // Optional: request timeout
};
const fineractSDK = createFineractSDK(sdkConfig);Example 1: Create a New Client
import { CreateClientRequest } from "@hayeeder/fineract-api-client";
async function createNewClient() {
const clientData: CreateClientRequest = {
officeId: 1,
fullname: "Jane Doe API",
active: true,
activationDate: "2024-07-28", // Use yyyy-MM-dd format
dateFormat: "yyyy-MM-dd",
locale: "en",
legalFormId: 1, // Ensure this ID is valid in your Fineract setup
};
try {
const response = await fineractSDK.client.createClient(clientData);
console.log("Client Created:", response);
// The actual ID of the created client is usually in response.resourceId or response.clientId
const clientId = response.resourceId;
if (clientId) {
console.log("New Client ID:", clientId);
}
} catch (error) {
console.error("Failed to create client:", error);
}
}
createNewClient();Example 2: Get Client Details
async function getClient(clientId: number) {
try {
const clientDetails = await fineractSDK.client.getClientDetails(clientId);
console.log("Client Details:", clientDetails);
} catch (error) {
console.error(`Failed to get client ${clientId}:`, error);
}
}
// Assuming a client with ID 123 exists
// getClient(123);Complete Client Creation Workflow
To successfully create a client and set up all required accounts and details, follow these steps using the relevant APIs from the SDK:
Step 1. Create the SME Client
API:
fineractSDK.sme.create()Description: Use the SME API to create a new client (SME) in Fineract.
Example:
const smeResponse = await fineractSDK.sme.create({ officeId: 1, // Hardcoded to 1 because currently we only have head office fullname: "Acme Corporation", active: true, // Hardcoded to always true activationDate: "2024-07-28", // Use yyyy-MM-dd format i.e. can be Today's date dateFormat: "yyyy-MM-dd", locale: "en", legalFormId: 2, // Hardcoded to 2 meaning client in fineract langauge externalId: "LOS-EXT-123456", // Replace with actual externalId i.e. masterCompanyId from LOS }); const clientId = smeResponse.resourceExternalId; // external unique identifier i.e. externalId from LOS
2. Add Virtual Account Number (Datatables API)
- API:
fineractSDK.datatable.addEntry(datatableName, entryData) - Description: Add virtual account number for the client using the Datatables API. The datatable name and required fields depend on your Fineract configuration.
- Example:
// adding virtual account number await fineractSDK.datatable.addEntry("dt_client_virtual_account_number", { client_id: clientId, // get the clientId with fineractSDK.client.getClientDetails(externalId) API virtualAccountNumber: 123456, // replace with actual virtual account number from LOS });
2.1. Add Remitter Details (Datatables API) IMP: This step is only required for SMEs with RBF product enabled
- API:
fineractSDK.datatable.addEntry(datatableName, entryData) - Description: Add remitter details for the client using the Datatables API. The datatable name and required fields depend on your Fineract configuration.
- Example:
// adding remitter name await fineractSDK.datatable.addEntry("dt_client_remitter_names", { client_id: clientId, // get the clientId with fineractSDK.client.getClientDetails(externalId) API remitterName: "Remitter Name", // replace with actual remitter name from LOS });
2.2. The 3-Step Process for Creating Savings Accounts
Creating any type of savings account (including Fallback, Cash Margin, or Collection accounts) is a three-step process. The account must be created, then approved, and finally activated to become fully functional.
- Create: Call
fineractSDK.savingsaccounts.create()to create the account record. This returns asavingsId. - Approve: Call
fineractSDK.savingsproducts.approve()using thesavingsId. This moves the account to an "approved" state. - Activate: Call
fineractSDK.savingsproducts.activate()using thesavingsId. This makes the account "active" and ready for transactions.
API:
fineractSDK.savingsaccounts.create(),fineractSDK.savingsproducts.approve(),fineractSDK.savingsproducts.activate()Description: A complete workflow for creating, approving, and activating a savings account.
Example:
// The ID of the client for whom the account is being created const clientId = 123; // The ID of the savings product (e.g., for a Fallback Account) const productId = 456; // Step 1: Create the savings account const savingsAccount = await fineractSDK.savingsaccounts.create({ clientId: clientId, productId: productId, submittedOnDate: "2024-07-28", // Use current date dateFormat: "yyyy-MM-dd", locale: "en", }); const savingsId = savingsAccount.savingsId; // Step 2: Approve the savings account const approvalResponse = await fineractSDK.savingsproducts.approve( savingsId, { approvedOnDate: "2024-07-28", // Use current date dateFormat: "yyyy-MM-dd", locale: "en", } ); // Step 3: Activate the savings account const activationResponse = await fineractSDK.savingsproducts.activate( savingsId, { activatedOnDate: "2024-07-28", // Use current date dateFormat: "yyyy-MM-dd", locale: "en", } ); console.log("Savings account created, approved, and activated successfully!");
3. Create Fallback Account (Savings Account API)
- API:
fineractSDK.savingsaccounts.create() - Description: Every SME should have one fallback account at the time of creation. It is type of savings account which will be used to store funds which cannot be categorised.
- Example:
Make sure to approve and activate the account as described aboveconst fallbackAccount = await fineractSDK.savingsaccounts.create({ clientId: clientId, // get the clientId with fineractSDK.client.getClientDetails(externalId) API productId: FALLBACK_PRODUCT_ID, // get all savings products with fineractSDK.savingsproducts.getAll() and filter by shortName=FBSA i.e. fallback savings account to get productId to be sent submittedOnDate: "2024-07-28", // This should be current date dateFormat: "yyyy-MM-dd", locale: "en", }); const fallbackAccountId = fallbackAccount.resourceId;
4. Create Cash Margin Account (Savings Account API)
- API:
fineractSDK.savingsaccounts.create() - Description: Every SME should have cash margin account at the time of creation. It is type of savings account which will be used to store security deposits of 5%, 10% etc while disbursing loan
- Example:
Make sure to approve and activate the account as described aboveconst cashMarginAccount = await fineractSDK.savingsaccounts.create({ clientId: clientId, productId: CASH_MARGIN_PRODUCT_ID, // get all savings products with fineractSDK.savingsproducts.getAll() and filter by shortName=CMSA i.e. cash margin savings account dateFormat: "yyyy-MM-dd", locale: "en", }); const cashMarginAccountId = cashMarginAccount.resourceId;
Summary of Steps and APIs:
- Create SME Client:
fineractSDK.sme.create() - Add Virtual Account & Remitter Details:
fineractSDK.datatable.addEntry() - Create Fallback Savings Account:
fineractSDK.savingsaccounts.create() - Create Cash Margin Savings Account:
fineractSDK.savingsaccounts.create()
Note: Replace datatable names, product IDs, and field names as per your Fineract instance configuration.
Important API Paths:
The API paths used in this SDK (/fineract-provider/api/v1/clients and /fineract-provider/api/v1/clients/{clientId}) are based on common Fineract setups and the provided clients.ts example. You must verify these paths against your Fineract instance's API documentation or the underlying ClientApi implementation you were using. You may need to adjust these paths in src/api/fineract-client-api.ts if they differ.
How to get repayment schedule without creating loan
1. Calculate Loan Repayment Schedule (Loan Accounts API)
API:
fineractSDK.loansaccounts.getRepaymentSchedule()Description: Calculate and retrieve the repayment schedule for a loan before actually creating the loan account. This is useful for showing the user the expected repayment plan based on their input parameters.
Example:
const repaymentSchedule = await fineractSDK.loansaccounts.getRepaymentSchedule({ productId: 1, // get all loan products with fineractSDK.loanproducts.getAll() and filter by externalId=REVENUE_BASED_FINANCING submittedOnDate: "28 May 2025", // Date the loan application is submitted expectedDisbursementDate: "30 May 2025", // Expected date of disbursement loanTermFrequency: 3, // Number of periods (e.g., months) loanTermFrequencyType: 2, // Frequency type (0=Days, 1=Weeks, 2=Months, 3=Years) numberOfRepayments: 3, // Total Number of installments to repay: Used like every [repaymentEvery] [repaymentFrequencyType] for [numberOfRepayments] repaymentEvery: 1, // Repayment interval (e.g., every 1 month) repaymentFrequencyType: 2, // Repayment frequency type (0=Days, 1=Weeks, 2=Months, 3=Years) interestType: 0, // Interest type (0 = flat, 1 = declining balance) amortizationType: 1, // Amortization type (0=Equal principle payments, 1=Equal installments) - Fetch this from loan product details in amortizationType.id interestCalculationPeriodType: 3, // Interest calculation period type - Fetch this from loan product details in interestCalculationPeriodType.id interestRatePerPeriod: 1, // Interest rate per period -> 1 means 10% transactionProcessingStrategyCode: "mifos-standard-strategy", // Hardcoded to mifos-standard-strategy dateFormat: "yyyy-MM-dd", // Hardcoded to yyyy-MM-dd - Date format used in the request locale: "en", // Locale clientId: 1, // // get the clientId with fineractSDK.client.getClientDetails(externalId) API loanType: "individual", // Type of loan principal: 100000, // Principal amount - Input from LOS }); console.log( "Repayment Schedule:", JSON.stringify(repaymentSchedule, null, 2) );API Path Used:
/fineract-provider/api/v1/loans?command=calculateLoanScheduleReference: See
src/api/fineract-loansaccounts-api.tsandsrc/types/loansaccounts.tsfor full request/response details.
Note: This API does not create a loan, it only returns the calculated schedule based on the input parameters. Use this to preview repayment plans before submitting a loan application.
How to create loan application for SME
1. Create RBF collection account (Savings Account API)
- API:
fineractSDK.savingsaccounts.create() - Description: Every SME should have collection account based on product at the time of creation. It is type of savings account which will be save funds collected from SME. For each Loan Account i.e Loan Application, we must have corresponding collection account
- Example:
Make sure to approve and activate the account as described aboveconst cashMarginAccount = await fineractSDK.savingsaccounts.create({ clientId: clientId, productId: RBF_COLLECTION_ACCOUNT, // get all savings products with fineractSDK.savingsproducts.getAll() and filter by shortName=RBF i.e. Rbf collection savings account dateFormat: "yyyy-MM-dd", locale: "en", }); const cashMarginAccountId = cashMarginAccount.resourceId;
2. Create Loan Account (Loan Accounts API)
API:
fineractSDK.loansaccounts.create()Description: Create a new loan account for a client in Fineract. This will actually create the loan in the system and return the created loan's details.
Example:
const newLoan = await fineractSDK.loansaccounts.create({ productId: 1, // get all loan products with fineractSDK.loanproducts.getAll() and filter by filter by externalId=REVENUE_BASED_FINANCING linkAccountId: 123, // ID of the collection account you created above submittedOnDate: "28 May 2025", // Date the loan application is submitted expectedDisbursementDate: "30 May 2025", // Expected date of disbursement - can be anything in future loanTermFrequency: 3, // Number of periods (e.g., months) loanTermFrequencyType: 2, // Frequency type (0=Days, 1=Weeks, 2=Months, 3=Years) numberOfRepayments: 3, // Total Number of installments to repay: Used like every [repaymentEvery] [repaymentFrequencyType] for [numberOfRepayments] repaymentEvery: 1, // Repayment interval (e.g., every 1 month) repaymentFrequencyType: 2, // Repayment frequency type (0=Days, 1=Weeks, 2=Months, 3=Years) interestType: 0, // Interest type (0 = flat, 1 = declining balance) amortizationType: 1, // Amortization type (0=Equal principle payments, 1=Equal installments) - Fetch this from loan product details in amortizationType.id interestCalculationPeriodType: 1, // Interest calculation period type - Fetch this from loan product details in interestCalculationPeriodType.id transactionProcessingStrategyCode: "mifos-standard-strategy", // Hardcoded to mifos-standard-strategy interestRatePerPeriod: 1, // Interest rate per period -> 1 means 10% dateFormat: "yyyy-MM-dd", // Hardcoded to yyyy-MM-dd - Date format used in the request locale: "en", // Locale clientId: 1, // // get the clientId with fineractSDK.client.getClientDetails(externalId) API loanType: "individual", // Type of loan principal: 100000, // Principal amount }); console.log("Loan Created:", JSON.stringify(newLoan, null, 2));API Path Used:
/fineract-provider/api/v1/loansReference: See
src/api/fineract-loansaccounts-api.tsandsrc/types/loansaccounts.tsfor full request/response details.
Note: This API will create a loan account in Fineract. Make sure all required fields are provided and valid as per your Fineract instance configuration.
How to get loan application data from Fineract to show on SME dashboard
API:
fineractSDK.loanaccounts.getSummaryById()Description: Get loan summary information from Fineract
Example:
const loan = await fineractSDK.loanaccounts.getSummaryById(123); console.log("Loan:", JSON.stringify(loan, null, 2)); const totalDisbursedAmount = loan.netDisbursalAmount; const totalOutstandingAmount = loan.summary.totalOutstanding; const interestRate = loan.annualInterestRate; const duration = loan.termFrequency; const durationUnit = loan.termPeriodFrequencyType.value; // To get next due payment const [year, month, day] = loan.delinquent.nextPaymentDueDate;This will return you the information of the loan summary you need to show on SME dashboard for a given loan application.
How to get loan application schedule from Fineract to show on SME dashboard per loan application
API:
fineractSDK.loanaccounts.getRepaymentScheduleById()Description: Get loan repayment schedule information from Fineract
Example:
const loan = await fineractSDK.loanaccounts.getRepaymentScheduleById(123); console.log("Loan:", JSON.stringify(loan, null, 2)); const loanAmount = loan.approvedPrincipal; const totalOutstandingAmount = loan.summary.totalOutstanding; const interestRate = loan.annualInterestRate; const duration = loan.termFrequency; const durationUnit = loan.termPeriodFrequencyType.value; // To get Issued on date const [year, month, day] = loan.timeline.actualDisbursementDate; // Repayment periods, first item in the array is always the disbursement information which we ignore const schedule = loan.repaymentSchedule.periods; // Follow this for all items, except for the index 0 const amount = schedule[1].totalInstallmentAmountForPeriod; const [dueYear, dueMonth, dueDay] = schedule[1].dueDate; const remaining = schedule[1].totalOutstandingForPeriod; const status = schedule[1].status;This will return you the information of the loan summary along with repayment schedule
Development
- Build:
npm run build - Test:
npm run test - Lint:
npm run lint - Run Examples:
npm run dev(Ensure you updatesrc/examples/run-examples.tswith your Fineract instance details) - Generate Docs:
npm run build:docs(Output indocs/folder)
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
