Operations

Loan Servicing Operations Guide

This guide covers post-disbursement operations introduced for Fineract feature parity: staged disbursement, delinquency pause, waivers, top-ups, prepayment schedule recalculation, backdated payments, re-aging, custom fields, maker-checker approvals, and floating interest rates.

Use it alongside the Loan Product Setup Guide, which covers origination-side configuration.


Table of Contents

  1. Staged Disbursement
  2. Delinquency Pause / Resume
  3. Interest and Fee Waivers
  4. Loan Top-Up
  5. Prepayment Schedule Recalculation
  6. Backdated Payments
  7. Re-Aging
  8. Custom Fields
  9. Maker-Checker Approvals
  10. Floating Interest Rates

Staged Disbursement

Products flagged staged disbursement release the approved amount in ordered tranches instead of one payment.

Setup

  1. Product Config → Disburse tab → enable Staged Disbursement and define stages (name, percentage or amount, required documents).
  2. Each stage can carry required_documents — the release is blocked until those borrower documents are on file.

Releasing a tranche

Loan detail → Manage funding → the stage panel lists all tranches in order.

UIAPI
Stage listGET /api/v1/loans/:id/disbursement-stages
Release next stagePOST /api/v1/loans/:id/disbursement-stages/release — body includes stage_id, disbursement method, destination, date, narration

Each released stage becomes its own disbursement request and flows through the normal verify → process → confirm pipeline. Rejecting a stage disbursement returns the stage to PENDING so it can be released again.

Rules

  • Stages release in order; only one tranche may be in-flight at a time.
  • Stage 1 activates the loan and runs normal disbursement validation; later stages post against an active loan.
  • Deductible fees are taken from the first tranche.
  • Interest accrues on drawn principal only — the subledger PRINCIPAL balance is the accrual basis.
  • The single-shot POST /disbursements endpoint is rejected for staged products; tranches cannot be bypassed.

Delinquency Pause/Resume

Suspend delinquency machinery on a loan during restructuring talks, disaster relief, or disputes.

UIAPI
Loan → ⋯ → Pause DelinquencyPOST /api/v1/servicing/delinquency/pause/:loan_id { reason }
Loan → ⋯ → Resume DelinquencyPOST /api/v1/servicing/delinquency/resume/:loan_id
HistoryGET /api/v1/servicing/delinquency/pauses/:loan_id

While paused:

  • Late fee assessment is skipped (both the daily AssessLateFees run and the per-payment fee path).
  • Escalation/DPD progression excludes the loan.
  • IFRS/regulatory stage migration is suspended.

Pause does not stop interest accrual, payments, or staff relief actions (waivers still work). Pause/resume is audit-recorded.


Interest and Fee Waivers

ActionEndpointBehaviour
Waive accrued interestPOST /api/v1/servicing/delinquency/waive-interest/:loan_id { amount, reason }Capped at outstanding interest; posts a negative INTEREST_WAIVER subledger entry; audited as INTEREST_WAIVED
Waive late feePOST /api/v1/servicing/delinquency/waive-fee/:fee_id { reason }Marks the fee WAIVED and reverses it in the subledger

UI: loan detail → ⋯ menu → Waive Interest (amount + reason).


Loan Top-Up

Increase an active performing loan's principal — the new amount posts as an additional disbursement tranche through the same subledger/GL machinery as staged disbursement, and the unpaid schedule is rebuilt on the new outstanding principal.

UIAPI
Loan → ⋯ → Top-Up Loan (amount + reason)POST /api/v1/loans/:id/top-up

Requires the loan to be active and in good standing. The response includes the new principal_amount.


Prepayment Schedule Recalculation

When a borrower pays ahead of schedule, the product's prepayment recalc strategy decides what happens to the remaining installments:

StrategyEffect
NONE (default)Overpayment reduces principal; schedule unchanged
REDUCE_EMISame installment count/dates; lower installment amount
REDUCE_TERMSame installment amount; trailing installments dropped

Set it on Product Config → Payment tab → Prepayment Schedule Recalculation, or PUT /api/v1/products/:id/config/payment with prepayment_recalc_strategy.

Recalculation runs inside the payment transaction: PAID/PARTIAL rows are preserved, unpaid rows are rebuilt on the post-payment principal, and the advertised installment (payment_amount) is updated for REDUCE_EMI.


Backdated Payments

Posting a payment with a past payment_date triggers automatic re-evaluation inside the same transaction:

  1. Interest accrual catches up from the value date.
  2. If payments valued on or before that date covered everything due by that date, late fees assessed after it are reversed (waived with reason BACKDATED_PAYMENT) and the subledger is corrected atomically.

A backdated payoff can therefore flip a loan to PAID_OFF with the wrongful fees removed.

Limitation: this reverses late fees, not a full ledger rebuild — DPD recomputes on the next delinquency run, and interest is not re-accrual-reversed for the backdated window.


Re-Aging

When enabled on the collections policy, a delinquent loan whose amount-past-due reaches zero after a payment is reset to CURRENT classification with a LOAN_REAGED audit event.

Enable per policy: Collections → policy form → Re-age loans on cure, or include reaging_enabled: true in the collections policy payload. Defaults off — existing policies are unaffected.

This is the cure-based variant; it does not implement "N consecutive on-time payments while still overdue".


Custom Fields

Attach arbitrary typed data to any entity — the Fineract datatable equivalent.

  • GET /api/v1/custom-fields/:entityType/:entityId — list fields
  • PUT /api/v1/custom-fields/:entityType/:entityId — create/update a field (body: field_name, field_value, value_type)
  • DELETE /api/v1/custom-fields/:entityType/:entityId/:fieldName — remove a field
Entity typesLOAN, BORROWER, APPLICATION, PRODUCT, GROUP, COLLATERAL
Value typesSTRING, NUMBER, BOOLEAN, DATE — validated on write

UI: loan detail → Details tab → Custom Fields card (staff only). Use for tenant-specific attributes that don't warrant a schema change.


Maker-Checker Approvals

Any configured operation can require a second user to approve before it executes.

For makers

Submit the action as usual (waive interest, top-up, waive fee). If the operation is policy-gated, the response is 202 PENDING_APPROVAL and nothing executes yet — the UI shows "Submitted for approval".

For checkers

Admin → Maker-Checker (/admin/checker):

  • Review pending commands with full payloads
  • Approve & Execute — runs the operation immediately, attributed to the original maker
  • Reject — discards it
  • The maker cannot decide their own submission (self-approval is rejected)
APIPurpose
GET /api/v1/checker/commands?status=PENDINGInbox
POST /api/v1/checker/commands/:id/approveApprove + execute (loan.approve permission)
POST /api/v1/checker/commands/:id/rejectReject
PUT /api/v1/checker/policiesToggle per command type (organization.manage)

Policy-gated command types

WAIVE_INTEREST, WAIVE_LATE_FEE, LOAN_TOP_UP are wired today. DISBURSEMENT_REVERSAL, PAYMENT_REVERSAL, SAVE_PAYMENT_CONFIG, RATE_INDEX_ENTRY are reserved command types. Policies default off — existing behavior is unchanged until you enable one.


Floating Interest Rates

Price a product as index + spread so outstanding loans reprice when the base rate moves.

Setup

  1. Admin → Rate Indices (/admin/rate-indices) — create a benchmark (e.g. POLICY_RATE) and post its initial rate.
  2. Product Config → Floating tab — enable floating, select the index, set the spread (percentage points), and choose what happens on repricing:
    • REDUCE_EMI — same term, installment amount adjusts
    • REDUCE_TERM — same installment, term adjusts

Equivalent API: PUT /api/v1/products/:id/config/floating-rate.

How it works

  • At origination the loan snapshots the product's index+spread and stores index + spread as its interest rate. Origination fails if the index has no effective rate.
  • Posting a new index entry (POST /api/v1/rate-indices/:id/entries) reprices every active loan linked to the index: interest_rate is updated and unpaid installments are rebuilt per the reprice strategy — in one transaction per loan.
  • Entries effective in the past or future do not trigger mass repricing; the new rate applies from its effective date for accrual.
  • The response reports how many loans repriced.

Limitation: repricing is forward-looking — accrual posted between the entry's effective date and its posting date is not re-processed.


Quick Reference

CapabilitySurface
Tranche releaseLoan → Manage funding → stage panel
Pause/resume delinquencyLoan → ⋯ menu
Waive interest / top-upLoan → ⋯ menu
Prepayment strategy, schedule shapeProduct Config → Payment tab
Floating rateProduct Config → Floating tab; Admin → Rate Indices
Re-agingCollections policy form
Custom fieldsLoan → Details tab → Custom Fields
Checker inbox & policiesAdmin → Maker-Checker