Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.digiflecttech.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Save App repayment system covers two related workflows: previewing what a loan will cost before committing to it, and recording actual payments against an active loan. You can generate a repayment schedule for any amount and duration without creating a loan, which is useful for showing members a cost breakdown upfront. Once a loan is active, members (or admins) can record repayments until the balance is cleared.

Generate a repayment schedule

Calculate the full repayment breakdown for a hypothetical loan without creating any records. Use this to preview monthly installments and total interest before the member submits a request.
POST /api/loans/repayment-schedule

Request body

amount
number
required
The loan principal to calculate the schedule for.
duration_months
number
required
The repayment duration in months. The schedule will contain one entry per month.

Response fields

total_repayment
number
required
Total amount to be repaid (principal plus interest).
monthly_installment
number
required
Equal monthly payment amount. Calculated as total_repayment / duration_months.
interest_amount
number
required
Total interest charged over the full duration. Calculated as amount × (interest_rate / 100) × (duration_months / 12).
schedule
object[]
required
Array of monthly payment entries, one per month.

Example

curl --request POST \
  --url 'https://api.saveapp.example.com/api/loans/repayment-schedule' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "amount": 600000,
    "duration_months": 6
  }'
Sample response
{
  "total_repayment": 630000,
  "monthly_installment": 105000,
  "interest_amount": 30000,
  "schedule": [
    { "month": 1, "due_date": "2024-07-25T00:00:00", "amount": 105000 },
    { "month": 2, "due_date": "2024-08-24T00:00:00", "amount": 105000 },
    { "month": 3, "due_date": "2024-09-23T00:00:00", "amount": 105000 },
    { "month": 4, "due_date": "2024-10-23T00:00:00", "amount": 105000 },
    { "month": 5, "due_date": "2024-11-22T00:00:00", "amount": 105000 },
    { "month": 6, "due_date": "2024-12-22T00:00:00", "amount": 105000 }
  ]
}

Record a loan repayment

Record a payment against an active loan. The loan’s repaidAmount increases by the payment and, once repaidAmount reaches totalDue, the loan status automatically becomes COMPLETED.
POST /api/loans/{id}/repay
Partial repayments are fully supported. You do not need to pay the full outstanding balance in a single transaction — any amount greater than zero and less than or equal to the remaining balance is accepted.

Path parameters

id
string
required
The unique identifier of the loan to repay.

Request body

amount
number
required
The repayment amount. Must be greater than 0 and must not exceed the outstanding balance (totalDue - repaidAmount).
paymentMethod
string
required
The payment channel used. Examples: "mobile_money", "cash". Minimum 1 character.
phoneNumber
string
Ugandan phone number associated with the payment, required when paymentMethod is "mobile_money". Must match the pattern ^\+?256[0-9]{9}$.

Eligibility rules

  • The loan must be in APPROVED, ACTIVE, or OVERDUE status.
  • Members can only repay their own loans; admins can repay any loan.
  • The payment amount must not exceed the remaining balance.
  • When repaidAmount >= totalDue after the payment, the loan status changes to COMPLETED and repaidAmount is capped at totalDue.

Response fields

success
boolean
required
true when the repayment was recorded successfully.
message
string
required
Confirmation message, e.g. "Loan repayment recorded".

Example

curl --request POST \
  --url 'https://api.saveapp.example.com/api/loans/loan_abc123/repay' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "amount": 105000,
    "paymentMethod": "mobile_money",
    "phoneNumber": "+256701234567"
  }'