Fees and payments
Monthly fees and invoices
Bill a batch monthly instead of once, generate this month's invoices, take payment against one, and correct a wrong invoice without deleting anything.
Last updated August 15, 2026
What you'll do
Switch a batch from a single course fee to a monthly fee, let CampusQ raise an invoice for each enrolled student every month, collect against those invoices, and correct the ones that are wrong.
Before you start
- Read Enrollments, fees and payments first. Monthly billing sits beside the frozen enrollment total, not on top of it, and the two behave differently on purpose.
- A decision on the batch's Monthly fee and, if you charge one, its Admission fee.
- Fee Invoices read permission to see the screen, create to raise or generate, update to adjust, waive, cancel or reinstate. Taking money needs Payments create — deliberately a separate permission.
- Your centre's due-day setting, if you have set one. See SMS and notifications for where it lives and for the reminders that ride on it.
The one decision that matters: one-time or monthly
Every batch has a Billing cycle with two values, set on the batch form (see Courses, batches and schedules):
| Billing cycle | What happens |
|---|---|
| One-time (course fee) | Students are charged the course fee once. Payments are credited against the enrollment total, exactly as before. This is the behaviour described on the Enrollments page, unchanged. |
| Monthly | A fee invoice is raised for every enrolled student each month. The admission fee, if set, is invoiced once when the student joins. |
The consequence is worth stating plainly, because it decides where you look for a student's debt:
- On a one-time batch, what a student owes is
Enrollment Total − Amount Paid, visible on the Enrollments screen. - On a monthly batch, the enrollment total is frozen at 0 and every taka the student owes lives in invoices on this screen.
The two are separated by design — an amount is either an enrollment balance or an invoice, never both, so nothing is ever counted twice on your dashboard or in Outstanding Dues.
A monthly batch needs a monthly fee: A monthly batch needs a monthly fee greater than zero.
Switching an existing batch to Monthly
Changing the billing cycle does not rewrite totals that are already frozen. A batch with fifty students who each owe ৳1 200 against their enrollment keeps owing that ৳1 200 after you flip the batch to Monthly; from that point forward they also start receiving monthly invoices.
That is deliberate. Silently zeroing fifty real debts because somebody changed a dropdown would be far worse than the alternative. But it does mean that switching mid-course leaves you collecting from two places for those students. Either switch at a natural boundary — a new batch, or a batch nobody has been billed on yet — or plan to settle the frozen balances by hand.
It also doubles their due reminders. The reminder guard is once per debt per day, not once per student per day, so a student carrying a frozen enrollment balance alongside an unpaid monthly invoice receives two reminder SMS on the same night, one naming each amount, and each one costs a credit. That is the intended behaviour — being told about only one of two amounts you owe is worse — but it is the direct and immediate consequence of flipping this dropdown on a batch that has already been billed. Settle the frozen balances if you want one message per student. See SMS and notifications.
Generate this month's invoices
Invoices are raised automatically by a nightly run, so in normal operation you do nothing. The manual route exists for the first month, for a batch you have just configured, and for the day you want the invoices in front of you now.
Go to Fee Invoices — Monthly and admission fees raised against enrollments. — and press Generate invoices. The button's own tooltip is the rule: Raise this month's invoices now instead of waiting for the nightly run.
The dialog is Generate fee invoices, and it opens with a reassurance you should believe: This is the same routine that runs every night. Running it again is safe: invoices that already exist are skipped, not duplicated.
| Field | Notes |
|---|---|
| Business date | Defaults to today. The month this date falls in is the period that gets billed. |
| Due day offset | 0–27, and empty by default on purpose: Leave empty to use your centre's configured due day. Set a value only to override it for this run. Leave it alone unless you genuinely mean to override your own setting for one run. |
Press Run now. You get a Result for block:
| Line | What it means |
|---|---|
| Admission invoices created | Students who joined this month and whose batch has an admission fee. |
| Monthly invoices created | One per billable enrollment on a monthly batch. |
| Total created | The two above, added up. |
| Enrollments considered | How many rows the run looked at before deciding. |
| Skipped — invoice already existed | Normal. The nightly run, or an earlier press of this button, got there first. |
| Skipped — no fee configured | The batch is billed monthly but has no monthly or admission fee set. |
The screen is explicit that a skip is not a failure: Skipped rows are not failures. "Already existed" means the nightly run got there first; "no fee configured" means the batch has no monthly or admission fee set. And when a run produces nothing at all: Nothing was created. Every enrollment considered was either already invoiced for this period or has no fee configured on its batch.
Which students get invoiced
Four rules decide, and each one has caught somebody out:
- Billable enrollments are Pending and Active only. Pending counts on purpose — it is the onboarding flow's pre-approval state and centres leave real, attending students sitting in it. Completed means the course is over; Suspended is a deliberate act that pausing billing must respect.
- Dropped enrollments are never invoiced. A student who left and re-enrolled is billed once, not twice.
- Admission is billed in the month the student joins, never back-dated. Setting an admission fee on a batch that already has two hundred students does not invoice all two hundred retroactively and leave them immediately overdue.
- There is no proration. A student who joins on the 28th is invoiced the full month, exactly like one who joined on the 1st.
That last one is a deliberate choice and the opposite of how teacher salaries work (see Salary and payroll). The reasoning: a fee is a price your centre sets, and a part-month first invoice invites an argument at the desk over the one bill a new family reads most closely. A salary is one month's pay split across whatever pay structures covered the month, so it must be split.
If your centre wants proration, say so — it is a configuration question, not a rebuild.
Raise a single invoice by hand
Raise invoice on the toolbar, for anything the monthly run will not produce: a one-off exam fee, a book charge, a re-issued admission fee.
| Field | Notes |
|---|---|
| Enrollment | Required. Search by student or enrollment number. |
| Fee type | Admission, Monthly or Other. Defaults to Monthly. |
| Period | A month, defaulting to the current one. |
| Amount due | Leave blank to use the batch's configured fee. |
| Due date | When it becomes overdue, and therefore when a reminder can fire. |
| Notes | Optional, and keep it under 500 characters — that is what the invoice record stores. The form will let you type up to 1 000, but anything past 500 fails when it is saved. |
Press Raise invoice. You get Invoice raised — An invoice was raised for .
Admission and Monthly are unique per enrollment and period. A second one is refused: An invoice of this type already exists for this enrollment and period. Change the period, or open the existing invoice instead. The Other type is deliberately repeatable, so you can raise two different one-off charges in the same month.
Read the list
Columns are Student, Batch, Fee type, Period, Due, Paid,
Remaining, Due date, Status and Actions. An overdue row carries a
badge like 12d overdue.
The five statuses:
| Status | Meaning |
|---|---|
| Pending | Raised, nothing collected. |
| Partially paid | Something collected, something still outstanding. |
| Paid | Settled in full. |
| Waived | You forgave the balance. The invoice stays on record. |
| Cancelled | Raised in error and voided. The invoice stays on record. |
Filters: Course, Batch (Select a course first until you pick one), Fee type, Status, Period, and an Outstanding only switch. Then Apply, or Clear filters.
Arriving from a student or an enrollment elsewhere in the app narrows the screen and says so: Showing invoices for one enrollment or student only.
Take a payment
Take payment on the row, available while the invoice is Pending or Partially paid and something is still remaining. It needs Payments create permission, not Fee Invoices update — somebody who may correct a bill is not automatically somebody who may handle cash.
The dialog leads with — outstanding on this invoice.
- Amount — pre-filled with the whole balance. Cannot exceed the outstanding balance.
- Method — Cash, Bank transfer, Credit card, Debit card, Online payment, Cheque, Other, bKash, Nagad, Rocket. Defaults to Cash.
- Payment date — defaults to today.
- Transaction ID — fill this in for anything that is not cash. It is what you will search for when a transfer is queried.
- Notes if the payment needs explaining.
- Record payment.
You get Payment recorded — A receipt was written and the income posted to the cash book. Both halves of that sentence matter: a receipt number exists for the family, and the money has landed in your cash book under the right category. See Accounts and expenses.
Overpaying is refused: That is more than the outstanding balance on this invoice.
Correct an invoice: four actions, no delete
There is no delete. An invoice is a financial record, so every correction is a new, reasoned entry rather than an edit. Four actions share one dialog, and all four demand a reason:
| Action | Use it when | What the dialog says |
|---|---|---|
| Adjust amount | The figure is wrong. | Correct the amount due on this invoice. The old and new amounts are both kept. |
| Waive invoice | You have decided not to collect it. | Forgive the outstanding balance. The invoice stays on record as waived. |
| Cancel invoice | It should never have existed. | Void an invoice raised in error. Nothing is deleted — the invoice stays on record as cancelled. |
| Reinstate invoice | You waived or cancelled it by mistake. | Undo a waiver or cancellation and make this invoice live again. |
Adjust asks for a New amount due, with the guard rail stated: has already been collected — the new amount cannot be lower than that.
Every one of the four requires Reason — Why is this change being made?, up to 500 characters — under the note The reason is written to the invoice's audit trail along with your name and the time. Press Confirm.
Write the reason for a stranger. "Waived — flood damage to family home, agreed with the director 2026-08-11" is an audit record. "wrong" is not.
The audit trail
Audit trail is on every row, always. Unlike enrollment fee adjustments, invoice history is visible in the app — you do not have to ask support.
The dialog explains itself: Every waiver, cancellation and amount change on this
invoice, with who made it and why. Columns are When, Change, Amount,
Status and Reason, with amount and status shown as old → new. The change
kinds are Amount adjusted, Waived, Cancelled and Reinstated. An
untouched invoice reads Nothing has changed yet — This invoice has not been
adjusted, waived or cancelled.
This is the ISO 9001 and ISO 27001 answer to "who changed this figure, when, and why". Treat it as the record; the invoice Notes field is not.
Notes
- Raising an invoice does not move any money. An unpaid invoice is a debt, not cash. Raising, adjusting, waiving, cancelling and reinstating post nothing to the cash book. Only a payment does. See Accounts and expenses.
- The nightly run does the work. Manual generation exists for the first month and for impatience; it is safe to press twice.
- Due dates drive reminders. Automated due reminders fire on your configured threshold days after the due date, and they will not double-send with the manual trigger. See SMS and notifications.
- No proration, ever, for student fees — and full proration for teacher pay. They are different kinds of number; see Salary and payroll.
- Outstanding Dues can show both sources. The report's Include monthly fee invoices toggle decides — see Reports.
- Audit and document control. Invoices are financial records: no delete, no hard-edit, every correction appended with actor, timestamp and a mandatory reason.
- Synthetic examples only.
Demo Student 1,৳1,200and12d overduehere are invented.
Troubleshooting
I switched the batch to Monthly and the students' old dues are still there. Correct and intended. Frozen enrollment totals are never rewritten by a billing-cycle change. Settle them on the Enrollments screen, or accept that those students are billed from two places until they are clear — and that they receive a reminder SMS for each of the two debts.
Raising the invoice failed with a database error and no useful message. Almost always an over-long Notes value. The form accepts up to 1 000 characters but the invoice record stores 500, so a longer note is rejected at save time with a raw error rather than a field-level warning. Shorten the note to under 500 characters and save again.
Generation created nothing. Read the result block. Either every enrollment was already invoiced for the period, or the batch has no monthly or admission fee set. Both are named explicitly.
A student who is clearly attending was not invoiced. Check their enrollment status. Only Pending and Active are billable — Completed, Suspended and dropped are not.
A student who joined on the 27th got billed a whole month. That is the rule: no proration, a full month regardless of the join day.
"An invoice of this type already exists for this enrollment and period." Admission and Monthly are one per enrollment per period. Open the existing invoice instead, or use fee type Other if this really is a separate charge.
"Money has already been collected against this invoice." You are trying to cancel an invoice with receipts against it. Refund or delete the receipt first — cancelling would leave posted income standing against a voided document.
"The new amount is lower than what has already been collected." Refund the receipt first, then adjust the invoice down.
"This enrollment is completed or suspended, so it cannot be invoiced." Reactivate the enrollment if the student is still studying, then raise the invoice.
Take payment is missing from the row. Either the invoice is already Paid, Waived or Cancelled, or you do not have the Payments create permission. Fee Invoices update is not enough.