Terminal Management
Discover terminals and send trigger commands. List terminals requires terminals:read; sending triggers requires terminals:trigger.
/api/v1/{system}/listTerminalsš terminals:readList terminals belonging to a branch. Returns terminal IDs, config IDs, online status, and assigned gateways. Tenant-isolated.
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| branchId | long (query) | Yes | Branch user ID |
| excludeConfigId | long (query) | No | Exclude a specific terminal (useful for the caller's own terminal) |
Response Example
{
"status": true,
"data": [
{
"configId": 42, // long ā pass to requestTerminal / capabilities
"terminalId": "T-123", // string ā opaque terminal id
"accessId": "<branch access id>", // string? ā pass to requestTerminal
"terminalTag": "Till 1", // string? ā operator label
"laneTag": "A", // string? ā physical lane id
"posTag": "front-desk", // string? ā pos pairing hint
"active": true, // bool ā admin hasn't disabled the terminal
"activated": true, // bool ā merchant has completed pairing
"online": true, // bool ā currently connected on WebSocket
"currency": "NZD", // string
"queueDestination": "/queue/terminal/42", // string ā STOMP destination for cloud-ws
"channels": { // map<string,bool> ā enabled gateways
"card": true,
"wechat": true,
"alipay": true,
"unionPay": false,
"centraPay": true
}
}
]
}https://payus.co.nzAuthentication
/api/v1/terminal/capabilitiesSecret-free capability lookup for a terminal: which channels are enabled (wechat/alipay/unionPay/centraPay), the resolved gateway for each, and QR timing. Use it to offer only the channels the backend has enabled ā never hardcode the channel list. Ownership-checked; returns no credentials (unlike /terminal/info, which is for the on-device app).
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | long (query) | Yes | Terminal config ID |
Response Example
{
"status": true,
"data": {
"configId": 123,
"terminalId": "TERM-001",
"channels": { "wechat": true, "alipay": true, "unionPay": false, "centraPay": true },
"wechatGatewayConfig": { "id": 100, "gatewayName": "E-Payments", "testMode": false,
"supportsWechat": true, "supportsAlipay": true, "supportsUnionpay": false },
"qrDisplayMs": 180000,
"qrGraceMs": 210000,
"paymentTimeoutMs": 360000,
"configVersion": 3
}
}https://payus.co.nzAuthentication
/api/v1/terminal/statusLightweight liveness poll ā far cheaper than /terminal/info and secret-free. Returns activation/active flags and a derived reason. Call it on app resume, cold start, and before starting a transaction; block the trading UI when active or activated is false. Ownership-checked.
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | long (query) | Yes | Terminal config ID |
Response Example
{
"status": true,
"data": {
"configId": 123,
"terminalId": "TERM-001",
"activated": true,
"active": true,
"reason": "ACTIVE"
}
}https://payus.co.nzAuthentication
/api/v1/terminal/leafCertLAN TLS leaf material (Q-022, Option B). Returns the terminal's per-terminal certificate + private key and the PayUs CA cert, so the on-device LAN server can run TLS and peers verify each other against the PayUs CA. Minted lazily on first fetch and persisted, so re-fetches are stable until rotation. Ownership-checked; the private key never leaves the owning tenant. (The matching per-branch LAN HMAC secret is delivered as lanSecret on the activation response and /terminal/info.)
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | long (query) | Yes | Terminal config ID |
Response Example
{
"status": true,
"data": {
"configId": 123,
"terminalId": "TERM-001",
"leafCertPem": "-----BEGIN CERTIFICATE-----\nā¦",
"leafKeyPem": "-----BEGIN PRIVATE KEY-----\nā¦",
"caCertPem": "-----BEGIN CERTIFICATE-----\nā¦",
"notAfter": "2028-07-14T10:30:00Z"
}
}https://payus.co.nzAuthentication
/api/v1/{system}/requestTerminalš terminals:triggerSend a trigger command to a terminal via WebSocket. If the terminal is offline there is no durable queue ā the command is NOT delivered and NOT replayed; requestStatus reports deliveryStatus TERMINAL_OFFLINE (vs SENT). Re-issue once the terminal is back online (listTerminals.online). See /docs/cloud-ws for the full hub ā terminal flow (how the result comes back on your STOMP queue, or via requestStatus below).
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| configId | long | Yes | Target terminal config ID (from listTerminals) |
| terminalId | string | Yes | Terminal id (from listTerminals) |
| branchId | long | Yes | Branch id |
| accessId | string | Yes | Branch access id ā same value sent in the activation payload; also returned by listTerminals |
| requestType | string | Yes | PAY | REFUND | CANCEL | PRINT |
| grandTotal | string (decimal) | No | Required for PAY and REFUND ā the amount. Decimal string, 2 places, range 0.01ā999999.99 (e.g. "12.50"). For REFUND omit for a full refund. |
| referenceId | string | No | Partner reference (PAY and REFUND). Strongly recommended on PAY: it is the idempotency key ā a retry carrying the same referenceId returns the original request instead of charging twice. |
| tipAmount / feeAmount / donationAmount / discount | string (decimal) | No | PAY only. Modifier portions of grandTotal, declaration-only (used to reconcile lineItems; NOT forwarded to the terminal and do not change the charge). Declare the tip here when it is included in grandTotal. |
| lineItems | LineItem[] | No | PAY only, optional itemised basket (max 200). Same per-line shape as payNow: name, quantity (decimal string), unitPriceCents/lineTotalCents/taxCents (integer cents), sku?, category?. Reconciled strictly (±1c): sum(lineTotalCents) must equal grandTotal ā tip ā fee ā donation + discount; malformed or out-of-balance ā HTTP 400 ERR_INVALID_LINE_ITEMS / ERR_LINE_ITEM_MISMATCH. Persisted and keyed to the sale by referenceId, so send one. |
| body | string | No | Required for PRINT ā the receipt text |
Response Example
{
"status": true,
"data": {
"id": 7, // numeric ā poll requestStatus with this id
"status": false, // boolean ā terminal has not reported a result yet
"executed": false, // boolean ā set true once the terminal runs it
"requestType": "PAY",
"configId": 123,
"referenceId": "ORD-42",
"deliveryStatus": "SENT", // SENT | TERMINAL_OFFLINE
"requestInfo": null // string ā the terminal's result JSON, once available
}
}https://payus.co.nzAuthentication
/api/v1/{system}/requestStatusš terminals:readPoll for the result of a previously sent trigger. Equivalent to subscribing on STOMP and waiting for the COMMAND_RESULT frame ā pick whichever fits your controller (see /docs/cloud-ws).
Auth: Bearer JWT
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | long | Yes | Numeric request id (data.id) returned by requestTerminal |
Response Example
{
"status": true,
"data": {
"id": 7, // numeric
"status": true, // boolean ā terminal has reported a result
"executed": true, // boolean ā the terminal ran the command
"requestType": "PAY",
"configId": 123,
"referenceId": "ORD-42",
"deliveryStatus": "SENT", // SENT | TERMINAL_OFFLINE
// requestInfo is a STRING holding the terminal's result JSON ā parse it for the detail
"requestInfo": "{\"paymentStatus\":\"SUCCESS\",\"tradeNo\":\"TRADE-123\",\"grandTotal\":\"12.50\",\"channel\":\"WECHAT\",\"currency\":\"NZD\"}"
}
}https://payus.co.nz