Appearance
Progressive Loan Configuration
Apache Fineract supports two loan schedule types: Cumulative and Progressive. Progressive is the modern default for new deployments and is required for any product that needs dynamic interest recalculation, stage-wise disbursements, or BNPL-style workflows.
This guide covers how Progressive loans work and how to configure them via the API.
Cumulative vs Progressive
Cumulative
In a Cumulative loan, the full repayment schedule is calculated upfront from the total committed amount, including any planned future tranches. The schedule is fixed at the point of disbursement and does not change when additional disbursements are made.
- Simpler to understand and predict
- Suited for single-disbursement products with fixed terms
- Does not recalculate when tranches are released
Progressive
In a Progressive loan, the repayment schedule is recalculated from the current period onward every time a new disbursement is made. Each tranche accrues interest only from its own disbursement date.
- EMI (or principal-per-period) adapts dynamically as new funds are released
- Suited for BNPL, construction lending, stage-funded business loans, revolving credit
- Requires
isInterestRecalculationEnabled: true
Which should I use?
Use Progressive for any product where disbursements happen in multiple stages or where outstanding balance can change after origination. Use Cumulative only for simple, fully-disbursed-at-once products.
Loan Product Configuration
When creating or updating a loan product, the following fields control the schedule type and processing behaviour.
Required Fields for Progressive
json
{
"loanScheduleType": "PROGRESSIVE",
"loanScheduleProcessingType": "HORIZONTAL",
"transactionProcessingStrategyCode": "advanced-payment-allocation-strategy",
"isInterestRecalculationEnabled": true
}| Field | Value | Meaning |
|---|---|---|
loanScheduleType | PROGRESSIVE | Enables progressive schedule recalculation |
loanScheduleProcessingType | HORIZONTAL | Allocates payments within a period before moving to the next (recommended) |
transactionProcessingStrategyCode | advanced-payment-allocation-strategy | Required for progressive products; enables the payment allocation array |
isInterestRecalculationEnabled | true | Triggers recalculation when disbursements, repayments, or charges occur |
Interest Recalculation Settings
json
{
"interestCalculationPeriodType": 0,
"interestRecalculationCompoundingMethod": 0,
"rescheduleStrategyMethod": 4,
"recalculationRestFrequencyType": 2,
"recalculationRestFrequencyInterval": 1
}| Field | Value | Meaning |
|---|---|---|
interestCalculationPeriodType | 0 (Daily) | Daily interest calculation; most accurate for progressive products |
interestRecalculationCompoundingMethod | 0 (None) | No compounding on unpaid interest |
rescheduleStrategyMethod | 4 (Adjust last unpaid period) | When recalculation occurs, adjusts only the last unpaid installment |
recalculationRestFrequencyType | 2 (Daily) | Recalculate the outstanding balance daily |
recalculationRestFrequencyInterval | 1 | Every 1 day |
Payment Allocation
The paymentAllocation array controls how incoming payments are distributed across components. The order in the array defines the priority.
json
{
"paymentAllocation": [
{
"transactionType": "DEFAULT",
"paymentAllocationOrder": [
{ "paymentAllocationRule": "PAST_DUE_PENALTY", "order": 1 },
{ "paymentAllocationRule": "PAST_DUE_FEE", "order": 2 },
{ "paymentAllocationRule": "PAST_DUE_INTEREST", "order": 3 },
{ "paymentAllocationRule": "PAST_DUE_PRINCIPAL", "order": 4 },
{ "paymentAllocationRule": "DUE_PENALTY", "order": 5 },
{ "paymentAllocationRule": "DUE_FEE", "order": 6 },
{ "paymentAllocationRule": "DUE_INTEREST", "order": 7 },
{ "paymentAllocationRule": "DUE_PRINCIPAL", "order": 8 },
{ "paymentAllocationRule": "IN_ADVANCE_PENALTY", "order": 9 },
{ "paymentAllocationRule": "IN_ADVANCE_FEE", "order": 10 },
{ "paymentAllocationRule": "IN_ADVANCE_INTEREST", "order": 11 },
{ "paymentAllocationRule": "IN_ADVANCE_PRINCIPAL", "order": 12 }
],
"futureInstallmentAllocationRule": "NEXT_INSTALLMENT"
}
]
}The standard priority order is: overdue penalties first, then overdue fees, overdue interest, overdue principal, then current-period components in the same order, then future components last.
futureInstallmentAllocationRule controls where excess payments are applied when the current installment is fully covered:
NEXT_INSTALLMENT- apply to the next upcoming installmentLAST_INSTALLMENT- apply to the final installment first (reduces term)REAMORTIZATION- redistribute the excess across all remaining installments
Multi-Disbursement (Tranches)
For stage-funded products:
json
{
"multiDisburseLoan": true,
"maxTrancheCount": 5,
"outstandingLoanBalance": 100000
}| Field | Meaning |
|---|---|
multiDisburseLoan | Enables multiple disbursement tranches |
maxTrancheCount | Maximum number of disbursements allowed |
outstandingLoanBalance | Maximum total outstanding at any point (credit limit) |
Down Payment (Optional)
json
{
"enableDownPayment": true,
"disbursedAmountPercentageForDownPayment": 25.0,
"enableAutoRepaymentForDownPayment": true
}When enabled, a percentage of each disbursed tranche is automatically applied as a repayment on disbursement day. Useful for BNPL and hire-purchase products.
Charge-off Behaviour
Controls what happens to outstanding interest when a loan is charged off:
json
{
"chargeOffBehaviour": "ZERO_INTEREST"
}| Value | Behaviour |
|---|---|
ZERO_INTEREST | Stop accruing interest after charge-off |
REGULAR | Continue normal accrual after charge-off |
ACCELERATE_MATURITY | Move all future installments to be due immediately |
Full Product Creation Example
bash
POST /fineract-provider/api/v1/loanproducts
Authorization: Basic <base64>
Fineract-Platform-TenantId: default
Content-Type: application/jsonjson
{
"name": "BNPL Progressive Loan",
"shortName": "BNPL01",
"currencyCode": "USD",
"digitsAfterDecimal": 2,
"principal": 5000,
"minPrincipal": 100,
"maxPrincipal": 50000,
"numberOfRepayments": 12,
"repaymentEvery": 1,
"repaymentFrequencyType": 2,
"interestRatePerPeriod": 1.5,
"interestRateFrequencyType": 2,
"amortizationType": 1,
"interestType": 0,
"interestCalculationPeriodType": 0,
"loanScheduleType": "PROGRESSIVE",
"loanScheduleProcessingType": "HORIZONTAL",
"transactionProcessingStrategyCode": "advanced-payment-allocation-strategy",
"isInterestRecalculationEnabled": true,
"interestRecalculationCompoundingMethod": 0,
"rescheduleStrategyMethod": 4,
"recalculationRestFrequencyType": 2,
"recalculationRestFrequencyInterval": 1,
"multiDisburseLoan": true,
"maxTrancheCount": 3,
"outstandingLoanBalance": 50000,
"paymentAllocation": [
{
"transactionType": "DEFAULT",
"paymentAllocationOrder": [
{ "paymentAllocationRule": "PAST_DUE_PENALTY", "order": 1 },
{ "paymentAllocationRule": "PAST_DUE_FEE", "order": 2 },
{ "paymentAllocationRule": "PAST_DUE_INTEREST", "order": 3 },
{ "paymentAllocationRule": "PAST_DUE_PRINCIPAL", "order": 4 },
{ "paymentAllocationRule": "DUE_PENALTY", "order": 5 },
{ "paymentAllocationRule": "DUE_FEE", "order": 6 },
{ "paymentAllocationRule": "DUE_INTEREST", "order": 7 },
{ "paymentAllocationRule": "DUE_PRINCIPAL", "order": 8 },
{ "paymentAllocationRule": "IN_ADVANCE_PENALTY", "order": 9 },
{ "paymentAllocationRule": "IN_ADVANCE_FEE", "order": 10 },
{ "paymentAllocationRule": "IN_ADVANCE_INTEREST", "order": 11 },
{ "paymentAllocationRule": "IN_ADVANCE_PRINCIPAL", "order": 12 }
],
"futureInstallmentAllocationRule": "NEXT_INSTALLMENT"
}
],
"locale": "en",
"dateFormat": "dd MMMM yyyy",
"accountingRule": 2
}Key field reference:
| Field | Type code | Meaning |
|---|---|---|
repaymentFrequencyType | 2 | Monthly |
interestRateFrequencyType | 2 | Per month |
amortizationType | 1 | Equal installments |
interestType | 0 | Declining balance |
accountingRule | 2 | Accrual-based accounting |
Creating a Progressive Loan Account
Once the product is configured, create a loan account against it:
bash
POST /fineract-provider/api/v1/loansjson
{
"clientId": 1,
"productId": 5,
"principal": 10000,
"loanTermFrequency": 12,
"loanTermFrequencyType": 2,
"numberOfRepayments": 12,
"repaymentEvery": 1,
"repaymentFrequencyType": 2,
"interestRatePerPeriod": 1.5,
"amortizationType": 1,
"interestType": 0,
"interestCalculationPeriodType": 0,
"transactionProcessingStrategyCode": "advanced-payment-allocation-strategy",
"loanScheduleType": "PROGRESSIVE",
"expectedDisbursementDate": "01 March 2025",
"disbursementData": [
{
"expectedDisbursementDate": "01 March 2025",
"principal": 5000
},
{
"expectedDisbursementDate": "01 June 2025",
"principal": 5000
}
],
"dateFormat": "dd MMMM yyyy",
"locale": "en"
}The disbursementData array defines the planned tranches. The schedule is initially calculated from the first tranche. When the second tranche is disbursed, Fineract recalculates the remaining installments from that date forward.
How Recalculation Works at Disbursement
When the second tranche (5000 on 01 June 2025) is disbursed:
- Outstanding principal increases from remaining balance to remaining balance + 5000
- Interest is recalculated from the disbursement date at the new outstanding balance
- Remaining installments are recalculated using
rescheduleStrategyMethod=4(adjust last unpaid period) - Previously paid installments are not affected
This means the borrower's EMI changes slightly after each new disbursement, reflecting the actual funds received rather than a fixed upfront commitment.
Interest Refunds
Progressive loans support interest refund on early repayment via supportedInterestRefundTypes:
json
{
"supportedInterestRefundTypes": ["MERCHANT_ISSUED_REFUND", "PAYOUT_REFUND"]
}When a merchant refund transaction is posted, Fineract automatically calculates and reverses the proportional interest for the refunded amount.
Verifying the Schedule
After creating and approving a loan, retrieve the repayment schedule to verify it:
bash
GET /fineract-provider/api/v1/loans/{loanId}/repaymentscheduleEach installment in the response shows principalDue, interestDue, feeChargesDue, penaltyChargesDue, and totalDueForPeriod. After a second disbursement, re-fetch the schedule to confirm recalculation has occurred.
Common Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
Using CUMULATIVE strategy code with a progressive product | Schedule does not recalculate | Use advanced-payment-allocation-strategy |
isInterestRecalculationEnabled: false on a progressive product | No recalculation on new disbursements | Set to true |
recalculationRestFrequencyType not set to Daily (2) | Inaccurate interest between recalculation dates | Set to 2 (Daily) |
Missing paymentAllocation array | 400 error on product creation | Include the full paymentAllocation array |
Not including disbursementData on multi-disburse loan creation | Only one tranche planned | Always include disbursementData even if dates are estimates |