← Back

ZamZam SchoolPay API

Payment (query/quote/pay) and operational (register/list students) endpoints.

Base URL

https://www.zamzamtest.santimschool.com/api/v1

Authentication (API Key)

Send your key in X-Api-Key or Authorization: Bearer .... Keys are created in the Admin Panel as either:

  • Payment — scopes query, quote, pay (school optional)
  • Operational — scopes register, list (must be bound to one school)
curl -H "X-Api-Key: YOUR_KEY" "https://www.zamzamtest.santimschool.com/api/v1/students/STU-123/query"

Operational — Register student

POST /api/v1/students — requires operational key with register

  • Required: firstName, lastName, grade, section, parentName, parentPhone
  • grade / section must match school Params
  • parentPhone: 9-digit local number (after +251)
  • sendSms: optional boolean (default true)
curl -X POST \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_OPERATIONAL_KEY" \ -d '{ "firstName": "Sara", "lastName": "Kebede", "grade": "Grade 5", "section": "A", "parentName": "Abebe Tesfaye", "parentPhone": "912345678", "sendSms": true }' \ "https://www.zamzamtest.santimschool.com/api/v1/students"

Operational — Register students (bulk)

POST /api/v1/students/bulk — requires operational key with register

  • Body: students array (1–50) with the same fields as single register
  • sendSms: optional boolean (default true) for the whole batch
  • All-or-nothing: if any row fails validation, none are created
  • Success returns each system-generated studentId in data.students
curl -X POST \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_OPERATIONAL_KEY" \ -d '{ "sendSms": true, "students": [ { "firstName": "Sara", "lastName": "Kebede", "grade": "Grade 5", "section": "A", "parentName": "Abebe Tesfaye", "parentPhone": "912345678" }, { "firstName": "John", "lastName": "Doe", "grade": "Grade 6", "section": "B", "parentName": "Mary Doe", "parentPhone": "923456789" } ] }' \ "https://www.zamzamtest.santimschool.com/api/v1/students/bulk"

Operational — List students

GET /api/v1/students — requires operational key with list

  • q: optional search
  • page: default 1
  • perPage: default 20, max 100
curl -H "X-Api-Key: YOUR_OPERATIONAL_KEY" \ "https://www.zamzamtest.santimschool.com/api/v1/students?q=Sara&page=1&perPage=20"

1) Query — check student payment info

GET /api/v1/students/{studentId}/query — requires payment key with query

  • include: comma-separated fields (default: summary + charges as returned by service).
  • chargeFilter: all, open, payable, paid, optional
  • sourceTypes: fee_plan, fee_assignment, penalty, adhoc (comma-separated)
  • syncPenalties: true/false (default true)
  • paymentLimit: limit payment history rows (default 20)
curl -H "X-Api-Key: YOUR_KEY" \ "https://www.zamzamtest.santimschool.com/api/v1/students/STU-123/query?include=summary,charges,openCharges&chargeFilter=payable"

2) Quote — select periods/charges and lock the total

POST /api/v1/quote — requires payment key with quote

Quote is short-lived (default 30 minutes, configurable by ttlMinutes). You can select billing “periods” in flexible ways using selection.mode.

Common fields

  • studentId (required)
  • ttlMinutes (optional, default 30)
  • amount (optional): expected total; server verifies sum matches within tolerance

selection.mode options

  • charge_ids (default): selection.chargeIds as an array of studentChargeId.
  • installment_ids: selection.installmentIds selects tuition installments by feePlanInstallmentId. Optional: selection.includePenalties (default true).
  • all_open: applies every currently open charge.
  • auto_amount: selection.amount (server allocates in allocation order).
  • due_date_range: selection.startDate and selection.endDate (inclusive, format YYYY-MM-DD). Optional: selection.includePenalties (default true).
POST https://www.zamzamtest.santimschool.com/api/v1/quote { "studentId": "STU-123", "ttlMinutes": 30, "selection": { "mode": "due_date_range", "startDate": "2026-07-01", "endDate": "2026-09-30", "includePenalties": true } }

3) Pay — confirm paid amount

POST /api/v1/pay — requires payment key with pay

To be safe against retries, use reference as an idempotency key. If the same key is sent again, the server returns the existing payment.

Using a quote (recommended)

curl -X POST \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_KEY" \ -d '{ "quoteId": "PUT_QUOTE_ID_HERE", "reference": "TXN-998877", "method": "bank", "paidAt": "2026-07-08T12:30:00Z", "notes": "Mobile banking" }' \ "https://www.zamzamtest.santimschool.com/api/v1/pay"

Without quote

Send studentId and either: (a) allocations (chargeId -> amount), or (b) selection + amount.

Error format

{ "ok": false, "error": "message", "code": 401 }