Skip to content

Fee Management

The apps.fees module handles fee schedule configuration and fee assessment on loans.

Fee Types

Fee Type Trigger
Origination On disbursement
Late On missed payment (grace period aware)
NSF On returned/reversed payment
Prepayment On early payoff
Modification On loan modification
Skip payment On deferred payment
Servicing Scheduled (recurring)
Other Manual assessment

Fee Schedules

Fee schedules define the rules for when and how fees are calculated. They are linked to loan products:

Field Description
product FK to loan product
fee_type Type of fee (see above)
calculation_method How the amount is computed (see below)
amount Flat amount or percentage value
trigger When the fee is assessed
grace_period_days Days after trigger before assessment
max_occurrences Maximum times this fee can be assessed per loan (unlimited if null)
min_amount Minimum fee amount (floor)
max_amount Maximum fee amount (cap)
is_waivable Whether this fee can be waived

Calculation Methods

Flat

Fixed dollar amount regardless of balance:

fee_amount = schedule.amount

Percentage of Balance

Percentage of the outstanding principal balance:

fee_amount = outstanding_balance × schedule.amount

Percentage of Payment

Percentage of the scheduled payment amount:

fee_amount = scheduled_payment × schedule.amount

Percentage of Amount

Percentage of an arbitrary amount (e.g., disbursement amount for origination fees):

fee_amount = reference_amount × schedule.amount

Tiered

Step-based pricing with brackets:

Balance up to $1,000:  $25
Balance $1,001-$5,000: $50
Balance over $5,000:   $75

Tiered calculations use the tiers JSONB field on the fee schedule.

Amount Caps

All calculation methods respect min_amount and max_amount:

fee_amount = max(min_amount, min(calculated_amount, max_amount))

Fee Triggers

Trigger When It Fires
on_origination When the loan is disbursed
on_delinquency When payment is missed (after grace period)
on_modification When a loan modification is applied
on_payment_miss When a scheduled payment is not received
scheduled On a recurring schedule (e.g., monthly servicing fee)
manual Manually assessed by a user

Grace Period

The grace_period_days field delays fee assessment after the trigger event. For late fees:

  1. Payment due date passes with no payment
  2. Grace period countdown begins
  3. Fee is assessed only after the grace period expires

Max Occurrences

The max_occurrences field limits how many times a fee can be assessed per loan. If null, the fee can be assessed unlimited times. This prevents excessive fee stacking.

Fee Assessment

Automated Assessment

Fees are assessed automatically based on their triggers:

  • Origination fees: Assessed during disbursement processing
  • Late fees: Assessed by the daily delinquency engine (see Collections)
  • Scheduled fees: Assessed by the daily scheduled fee Celery task
  • NSF fees: Assessed during payment reversal processing

Manual Assessment

Fees can be manually assessed via the API:

POST /api/v1/loans/{loan_id}/fees

Fee Record

Each assessed fee creates a Fee record:

Field Description
loan FK to loan
fee_schedule FK to the schedule that triggered it
amount Assessed amount
status pending, paid, waived, or forgiven
assessed_date When the fee was assessed
due_date When the fee is due

GL Entries

On Assessment

Account Debit Credit
Fees Receivable Fee amount
Fee Income Fee amount

On Waiver

Account Debit Credit
Fee Waiver Expense Fee amount
Fees Receivable Fee amount

On Payment

Fees are paid through the normal payment allocation process. GL entries:

Account Debit Credit
Cash Fee amount
Fees Receivable Fee amount

Fee Waivers

Waivable fees (where is_waivable = True on the schedule) can be waived:

  • Records the waiving user and timestamp
  • Posts GL reversal entries (DR Fee Waiver Expense, CR Fees Receivable)
  • Fee status changes to waived

See Also