Skip to main content
Schoolyi
School librarian arranging books and planning cards in a bright library

Browse docs

Getting started

Fees troubleshooting

Why bulk generate produces nothing, why a receipt email never arrives, why a waiver will not approve, and why autopay and dunning stay silent.

Getting started guide for day and boarding schools.

Last updated August 29, 2026

Fee tickets divide cleanly into three kinds: nothing was generated, money moved but the paperwork did not follow, or an automated reminder never fired. The first is almost always a fee structure that does not match the class. The second is almost always the email address on the record. The third is almost always the daily cron job, which is not installed on this school and which nothing inside the application replaces.

Telling a permission problem from a configuration problem

The two look identical from the desk and are diagnosed differently. A permission problem produces a 403 and the same result for the same person on every student: the fee screens require one of Platform Admin, Principal, Vice Principal, Support Staff - Finance, or the office Admin role, and no amount of data fixing changes that. A configuration problem produces an empty list, a zero count, or a specific message naming a grade, a year, or a fee structure, and it follows the record rather than the person - a colleague with a different role sees exactly the same emptiness. Ask one question first: does a Principal see it too? If yes, it is configuration.

Setup and generation

SymptomCauseFix
Bulk generate loads no studentsNo class selected, or the class has no ACTIVE members for the yearPick a class or All classes and press Load preview first - the run button does nothing until a roster is loaded. Place students in the section at /classes.
Preview lists students but nothing is createdNo fee structure matches the classStructures at /fees/fee-structures must be active, belong to the selected academic year, and target that class; a grade-level structure only applies to students with no active enrolment.
Generation fails for the whole school with a 409More than one academic year is marked currentFix the year at /academic-year. The generator refuses to guess when the current-year invariant is broken.
Amounts changed on the structure but not on the billsInstances are written onceExisting lines are keyed on fee structure and instalment number and are never rewritten by a later run. Waive or adjust the old lines at /fees/waivers.
Instalments fall on the wrong datesDates are derived, not entered per instalmentEach instalment is the structure amount divided by the instalment count, dated from the structure due date and spaced by twelve divided by the instalment count in months.
Transport charge missing from a billStop fee or the TRN fee typeAssign the stop at /transport/assignments with a monthly fee above zero, and create a fee type with the code TRN first - the sync looks it up and stops silently if it is absent.
GST not shown on the receiptTax configuration offConfigure rates at /fees/settings/gst, or /fees/settings/vat for schools billing VAT.

Collection, receipts, and online pay

SymptomCauseFix
No Pay button for the familyOnline payment is disabledFEES_ONLINE_PAYMENT_MODE accepts simulated, razorpay, stripe, telr, or disabled, and defaults to disabled when nothing is set. Configure it at /fees/settings/payment-gateway.
Receipt email marked FAILEDSMTP is unreachable or unconfiguredConfirm delivery at /settings/email-test, then resend with POST /api/fees/receipts/{receiptNumber}/email or the resend action on /fees/payments and /fees/receipts.
Receipt email marked NO_EMAILNeither the student nor an active guardian record has an addressAdd an email to the guardian at /parents. The lookup takes the primary active guardian when the student has none.
A waiver was approved but the balance is unchangedThe waiver was not attached to a fee instanceOnly a waiver carrying a feeInstanceId is applied to a bill on approval. A standalone waiver record is bookkeeping.
Cannot decide a pending waiver or refundSelf-approval block, or the high-value ruleThe approver cannot be the requester. Amounts at or above 10,000, or 25 per cent of the instance, need Principal or Vice Principal rather than Platform Admin.

Reminders that never arrive

Autopay, the dunning ladder, and scheduled notices all run from scripts/run-school-cron.sh, which has to be added to crontab with FEES_CRON_SECRET set. That job is not installed here, so none of them has ever advanced. Even once it is installed, be careful about what each channel means. Dunning moves an overdue instance one ladder step per run and sends according to that step: in-app writes a notification to the student account, email uses SMTP, SMS calls a bundled provider that prints the message to the server log and returns success, and WhatsApp writes a further in-app notification containing a wa.me link for a member of staff to open by hand. A run reporting smsSent has logged, not sent.

Common questions

Quick answers in plain language.

Bulk generate reports zero fee instances created. What is actually missing?+

Generation matches fee structures to the class the student is actively enrolled in. If the student has an ACTIVE ClassStudent row, only structures whose classId equals that class are used; there is no fall-back to grade in that case. If the student has no active enrolment, the matcher falls back to structures with a null classId for the same grade. A structure that is inactive or attached to a different academic year is invisible either way, and the response says "No matching fee structures found" with the grade and year it looked for.

Why can a Platform Admin not approve a large fee waiver?+

High-value adjustments are restricted to Principal and Vice Principal specifically. An adjustment counts as high value when the absolute amount reaches FEE_HIGH_VALUE_ADJUSTMENT_INR, which defaults to 10,000, or when it is 25 per cent or more of the instance. Below that line Platform Admin, Principal, and Vice Principal can all approve. Nobody may approve their own request, whatever the role.

Does fee autopay actually charge the parent?+

No. POST /api/fees/autopay/run-due walks active mandates and creates in-app reminder notifications that link to /fees/me. It records lastRunAt and sets nextRunAt to the same day next month, capped at the 28th. No money moves and no gateway is called, so a mandate is a reminder schedule rather than a standing instruction.

A payment was recorded but the family never got the receipt. Where did it go?+

The receipt email goes to the student record email first and only falls back to the primary active guardian email when the student has none. Students created by admissions enrolment without an email on the application are given a synthetic address ending in @students.local, so the send succeeds into nowhere. Clear the student email or check the payment row on /fees/payments, which carries a [RECEIPT_EMAIL:SENT], [RECEIPT_EMAIL:FAILED], or [RECEIPT_EMAIL:NO_EMAIL] marker in its notes.

Related searches

School leaders and IT teams often search for: how to module troubleshooting fees in school management software, best school software onboarding for K-12 schools, Schoolyi module troubleshooting fees guide, school ERP go live checklist, migrate from Excel to school ERP, and school software training guide.