Fees & Billing API
Last updated August 2, 2026
This reference is generated from the current Express route definitions and their handlers. It documents route-level authentication and authorization; deployment-wide middleware may add further checks.
Conventions
- Base API origin:
https://api.classgrid.in - Authentication: authenticated routes use the Classgrid session/JWT recognized by
isAuthenticated. - JSON is the default request and response format unless an endpoint explicitly accepts multipart data or redirects.
- Path parameters are always required.
- A field marked
nomeans the static handler scan did not find a direct required-field check; business rules may still make it conditionally required. - Role checks can also accept
super_adminthrough the shared authorization middleware where implemented.
This document contains 35 route definitions from 6 source files.
fees.routes.js
Mounted at: /api/fees
GET /api/fees/institution-profile
Auth: isAuthenticated, attachInstitutionProfile()
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachInstitutionProfile()
What it does: Retrieves institution profile.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include institution_profile, fee_profile, learner_record_profile.
Source: server/src/routes/fees.routes.js:14; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/structures
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Creates or processes structures.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include structure, message. Explicit status codes include 201, 500. Server error
Source: server/src/routes/fees.routes.js:37; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/structures
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Retrieves structures.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include structures, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:102; handler inline handler in server/src/routes/fees.routes.js.
DELETE /api/fees/structures/:id
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Deletes structures.
Path parameters:
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include message. Explicit status codes include 500. Fee structure deleted
Source: server/src/routes/fees.routes.js:123; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/assign
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Creates or processes assign.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, records. Explicit status codes include 404, 500. Structure not found
Source: server/src/routes/fees.routes.js:142; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/pay
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Creates or processes pay.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, payment, new_status, new_paid. Explicit status codes include 403, 404, 500. Students cannot record payments
Source: server/src/routes/fees.routes.js:185; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/students
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Retrieves students.
Path parameters: None detected in the route or handler.
Query parameters:
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include fees, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:243; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/me
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Retrieves me.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include fees, payments, summary, razorpay_configured, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:271; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/payments
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Retrieves payments.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include payments, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:312; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/analytics
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Retrieves analytics.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include success, totalCollection, totalPayable, totalPending, totalStudents, paidCount, partialCount, unpaidCount, overdueCount, collectionRate, charts, defaulters, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:334; handler inline handler in server/src/routes/fees.routes.js.
PATCH /api/fees/students/:id/block
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Updates students block.
Path parameters:
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, record. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:430; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/razorpay/order
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Creates or processes razorpay order.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, order_id, amount, currency, key_id, student_fee_id, student_name, student_email. Explicit status codes include 400, 404, 500. Fee record not found
Source: server/src/routes/fees.routes.js:452; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/razorpay/verify
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Verifies the supplied information.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, payment, new_status. Explicit status codes include 400, 404, 500. Razorpay not configured for this organization
Source: server/src/routes/fees.routes.js:529; handler inline handler in server/src/routes/fees.routes.js.
POST /api/fees/razorpay/webhook
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: None at route level
What it does: Creates or processes razorpay webhook.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message. Explicit status codes include 400, 500. Invalid webhook signature
Source: server/src/routes/fees.routes.js:605; handler inline handler in server/src/routes/fees.routes.js.
PUT /api/fees/razorpay/config
Auth: isAuthenticated, requireRole("org_admin")
Roles: org_admin
Middleware: isAuthenticated, attachOptionalInstitutionProfile, requireRole("org_admin")
What it does: Updates razorpay config.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, configured. Explicit status codes include 404, 500. Organization not found
Source: server/src/routes/fees.routes.js:690; handler inline handler in server/src/routes/fees.routes.js.
GET /api/fees/razorpay/config
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachOptionalInstitutionProfile
What it does: Retrieves razorpay config.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include configured, key_id_preview, message. Explicit status codes include 500. Server error
Source: server/src/routes/fees.routes.js:717; handler inline handler in server/src/routes/fees.routes.js.
fee-records.routes.js
Mounted at: /api/fee-records
File-wide middleware: isAuthenticated, attachInstitutionProfile({required:false})
GET /api/fee-records/institution-profile
Auth: isAuthenticated, attachInstitutionProfile({required:false}), attachInstitutionProfile()
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), attachInstitutionProfile()
What it does: Retrieves institution profile.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include institution_profile, fee_profile, learner_record_profile.
Source: server/src/routes/fee-records.routes.js:12; handler inline handler in server/src/routes/fee-records.routes.js.
POST /api/fee-records/create
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
Roles: org_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
What it does: Assign a fee record to one or multiple students in bulk. Sends a notification to each student about the new charge. Creates the requested resource.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, count. Explicit status codes include 201, 400, 500. studentIds, title, amount, and dueDate are required
Source: server/src/routes/fee-records.routes.js:29; handler inline handler in server/src/routes/fee-records.routes.js.
GET /api/fee-records/all
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
Roles: org_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
What it does: Admin view: All fee records across the org with student names populated. Supports filters: ?status=pending&category=exam&overdue=true. Retrieves all.
Path parameters: None detected in the route or handler.
Query parameters:
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include total, records, message. Explicit status codes include 500. Server error
Source: server/src/routes/fee-records.routes.js:77; handler inline handler in server/src/routes/fee-records.routes.js.
GET /api/fee-records/summary
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
Roles: org_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin')
What it does: Admin dashboard: Financial overview with category-wise breakdown. Retrieves summary.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include overview, counts, categoryBreakdown, message. Explicit status codes include 500. Server error
Source: server/src/routes/fee-records.routes.js:106; handler inline handler in server/src/routes/fee-records.routes.js.
GET /api/fee-records/reminders
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin','faculty')
Roles: org_admin, faculty
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin','faculty')
What it does: Auto-flag overdue students and return the list. Also auto-updates status from 'pending' to 'overdue' for past-due records. Retrieves reminders.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include flaggedCount, totalOverdueStudents, totalOverdueAmount, reminders, message. Explicit status codes include 500. Server error
Source: server/src/routes/fee-records.routes.js:157; handler inline handler in server/src/routes/fee-records.routes.js.
PATCH /api/fee-records/:recordId/pay
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin','faculty')
Roles: org_admin, faculty
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole('org_admin','faculty')
What it does: Record a partial or full payment for a specific fee record. Updates pay.
Path parameters:
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include message, record. Explicit status codes include 400, 404, 500. Valid payment amount is required
Source: server/src/routes/fee-records.routes.js:228; handler inline handler in server/src/routes/fee-records.routes.js.
GET /api/fee-records/me
Auth: isAuthenticated, attachInstitutionProfile({required:false})
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachInstitutionProfile({required:false})
What it does: Student's own fee records with summary. Retrieves me.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include summary, records, message. Explicit status codes include 500. Server error
Source: server/src/routes/fee-records.routes.js:276; handler inline handler in server/src/routes/fee-records.routes.js.
GET /api/fee-records/student/:studentId
Auth: isAuthenticated, attachInstitutionProfile({required:false})
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachInstitutionProfile({required:false})
What it does: Faculty/Admin can view a specific student's fees. Retrieves student.
Path parameters:
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include message, student, summary, records. Explicit status codes include 403, 500. Access denied
Source: server/src/routes/fee-records.routes.js:304; handler inline handler in server/src/routes/fee-records.routes.js.
billing-checkout.routes.js
Mounted at: /api/billing/checkout
File-wide middleware: generalLimiter
GET /api/billing/checkout/session
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: generalLimiter
What it does: Retrieves session.
Path parameters: None detected in the route or handler.
Query parameters:
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include success, error, data. Explicit status codes include 400, 404.
Source: server/src/routes/billing-checkout.routes.js:42; handler inline handler in server/src/routes/billing-checkout.routes.js.
POST /api/billing/checkout/verify-otp
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: generalLimiter
What it does: Verifies the supplied information.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include success, error, data. Explicit status codes include 400, 404, 409, 429.
Source: server/src/routes/billing-checkout.routes.js:68; handler inline handler in server/src/routes/billing-checkout.routes.js.
POST /api/billing/checkout/confirm
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: generalLimiter
What it does: Creates or processes confirm.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include success, error, code, data. Explicit status codes include 400, 404.
Source: server/src/routes/billing-checkout.routes.js:134; handler inline handler in server/src/routes/billing-checkout.routes.js.
billing-demo.routes.js
Mounted at: /api/billing/demo
POST /api/billing/demo/session
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: None at route level
What it does: Creates (or refreshes) a 48-hour demo billing session. Returns the checkout URL + demo credentials. Protected: BILLING_DEMO_ENABLED must be "true". Creates or processes session.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include success, error, detail, data. Explicit status codes include 201, 403, 500, 502.
Source: server/src/routes/billing-demo.routes.js:47; handler inline handler in server/src/routes/billing-demo.routes.js.
GET /api/billing/demo/status
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: None at route level
What it does: Returns whether demo mode is active + a live checkout URL if a valid session exists. Called by the landing page on load to get the current demo link. Retrieves status.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include enabled, has_active_session, expires_at, error.
Source: server/src/routes/billing-demo.routes.js:193; handler inline handler in server/src/routes/billing-demo.routes.js.
billing-handoff.routes.js
Mounted at: /api/billing/handoff
POST /api/billing/handoff/initiate
Auth: isAuthenticated
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: generalLimiter, isAuthenticated
What it does: Creates a checkout only from a server-resolved payable. Client-provided amount, recipient email, merchant account, and arbitrary context are ignored. Creates or processes initiate.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include success, code, error, data. Explicit status codes include 201, 404, 409.
Source: server/src/routes/billing-handoff.routes.js:79; handler inline handler in server/src/routes/billing-handoff.routes.js.
POST /api/billing/handoff/resend-otp
Auth: None at route level
Roles: Public endpoint unless an upstream platform gate applies.
Middleware: generalLimiter
What it does: Resends the requested information.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include success, error, message. Explicit status codes include 400, 404, 429. OTP resent successfully
Source: server/src/routes/billing-handoff.routes.js:208; handler inline handler in server/src/routes/billing-handoff.routes.js.
payroll.routes.js
Mounted at: /api/payroll
File-wide middleware: isAuthenticated, attachInstitutionProfile({required:false})
GET /api/payroll/institution-profile
Auth: isAuthenticated, attachInstitutionProfile({required:false}), attachInstitutionProfile()
Roles: Any authenticated user, subject to organization, plan, and feature middleware listed below.
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), attachInstitutionProfile()
What it does: Retrieves institution profile.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include institution_profile, staff_assignment_profile, learner_record_profile.
Source: server/src/routes/payroll.routes.js:10; handler inline handler in server/src/routes/payroll.routes.js.
POST /api/payroll/calculate
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("org_admin","super_admin")
Roles: org_admin, super_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("org_admin","super_admin")
What it does: Admin limits. Calculate payroll.
Path parameters: None detected in the route or handler.
Query parameters: None detected in the route or handler.
Body:
Response: JSON response fields observed in the handler include success, message, data. Explicit status codes include 200, 400, 500. Invalid month format. Use YYYY-MM.
Source: server/src/routes/payroll.routes.js:19; handler calculatePayroll in server/src/controllers/payroll.controller.js.
GET /api/payroll/summary
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("org_admin","super_admin")
Roles: org_admin, super_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("org_admin","super_admin")
What it does: Get payroll summary.
Path parameters: None detected in the route or handler.
Query parameters:
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include success, message, data. Explicit status codes include 200, 400, 500. Month is required.
Source: server/src/routes/payroll.routes.js:20; handler getPayrollSummary in server/src/controllers/payroll.controller.js.
GET /api/payroll/me
Auth: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("faculty","teacher","org_admin")
Roles: faculty, teacher, org_admin
Middleware: isAuthenticated, attachInstitutionProfile({required:false}), requireRole("faculty","teacher","org_admin")
What it does: Faculty personal route. Get my payslip.
Path parameters: None detected in the route or handler.
Query parameters:
Body: None detected in the route or handler.
Response: JSON response fields observed in the handler include success, message, data. Explicit status codes include 200, 400, 404, 500. Month is required.
Source: server/src/routes/payroll.routes.js:23; handler getMyPayslip in server/src/controllers/payroll.controller.js.