GET. ClassAtlas always answers with XML and HTTP 200, and the outcome is the code of the status element. The protocol began as iPay’s specification (payment-gateway.doc, version 1.03) and is now the one every Provider uses (ADR 0074). This page records how ClassAtlas implements it.
Endpoint
The examples on this page use iPay’s address. TBC Pay sends exactly the same requests to its own.
Planned (CA-1147): TBC Pay’s address does not answer yet.
Checks, in order
Every request passes these checks in this order. The first one that fails decides the answer.
The IP check runs before the school is resolved, so a stranger never opens a school’s database or uses up its rate limit. Authentication runs after, because each school’s credentials live in its own database (ADR 0029).
Any unexpected error on this route is answered with code 99, never with an HTML error page.
Authentication
IP allow-list
Only the Providers’ servers are accepted. A Provider gives ClassAtlas the addresses it calls from, and one list serves every school and every Provider.- The check uses the address the connection came from, not
X-Forwarded-For, which any caller can forge (ADR 0028). - An address on the list still needs that Provider’s credentials and secret key at the school.
Credentials
Each school has its ownUSERNAME, PASSWORD and secret key at each Provider, stored encrypted in the school’s database. The username and the password are both compared before answering, in constant time, so a wrong username and a wrong password take the same time.
HASH_CODE
HASH_CODE is the MD5 of every parameter value, in the order the parameters arrive, followed by the school’s secret key, in uppercase hex.
HASH_CODEitself is left out, wherever it appears in the request.- Values are taken URL-decoded and joined with no separator.
- The order is the order of arrival, not a fixed list. If a Provider adds a parameter, the hash still validates (ADR 0026).
pay, with test values and the secret key DemoSecretKey123:
Whether a Provider hashes the decoded or the raw value is unconfirmed. It only matters for
EXTRA_INFO, the one parameter that could carry characters needing encoding, and iPay has confirmed it sends nothing there. A Provider’s test run against a school before go-live settles it.Parameters
A parameter is required in the operations listed, unless marked optional.
The upper limit on
PAY_AMOUNT is the largest amount a transaction can hold.
Responses
Every response is onepay-response document: a status with a code and a text, a timestamp in Unix seconds, and the operation’s result when it succeeds. A refusal also carries retry.
Refusal
retry is false except when the school’s rate limit was hit. Telling a Provider a refused payment may be retried when it may not is how a double payment happens.
Operations
debt
Returns what the student owes and what it is made of.Request
Response
debt is the student’s charges less their balance, never below zero, in tetri. It is read from the same balance view the ClassAtlas panel uses, so the bank and the school always see the same number.
additional-info is what the payer reads. The values carry the whole line, and the names are only keys, because the specification does not say whether a Provider displays the names. The text is always in Georgian, whatever the application’s language.
While the student owes,
balance is the credit already counted against the charges, so the charges less the balance equal debt. When they owe nothing it is their credit, so a parent can tell “we are square” from “the school does not know my child”.
verify
Answers whether a payment may go ahead. It records nothing, because in the teller flow it is sent before the customer has handed over any money. It refuses only a student who has left the school and owes nothing (code 9). There is no upper limit on the amount: a parent may pay more than they owe.Response
pay
Records the payment and returns its receipt number.Request
Response
- The
verifycheck runs again, because a teller’s order can be paid long after it was created. - One transaction is written for the student.
receipt-idis its ID in ClassAtlas. - Everything else, from paying off charges to messaging the family, follows from that transaction. See How ClassAtlas records a Lookup payment.
PAYMENT_ID is recorded once per Provider and channel. The same ID arriving again on the same channel is answered with code 8 and records nothing. A retry after a lost response therefore gets code 8, not the original receipt-id. iPay has confirmed that codes 8 and 18 mean the same thing to them.
There is no operation to cancel a payment.
ping
Answers whether the school can take payments right now. It passes every authentication check, then reads the student balance view that every money operation depends on.Request
Status codes
Parameter errors are reported in a fixed order: a missing parameter (4), then an unknown service (10), then an amount out of range (7), then any other bad value (5). Code 18 exists in the specification, but ClassAtlas never sends it.