Push to Terminal Integration Guide
Integration with the Halo backend to manage devices for Push to Terminal.
1. Overview
Push to Terminal allows a merchant system to register devices and push payment requests to them via Firebase push notification. The device management API provides CRUD operations for managing devices. Push payment is initiated via POST /consumer/push.
2. Device Management API
2.1 List Devices
Retrieve all devices registered by the authenticated user.
GET https://kernelserver.{env}.haloplus.io/devices
Path Parameters
| Name | Type | Description |
|---|---|---|
| env* | String | The backend environment [dev, qa, prod] |
Headers
| Name | Type | Description |
|---|---|---|
| x-api-key* | String | The API Key retrieved from the Merchant Portal (JWT can be used instead) |
| Authorization* | String | The JWT retrieved from logging in. (API Key can be used instead) |
- 200: OK
- 401: Unauthorized
[
{
"id": "07b6cbe3-c4c3-4214-b279-ccb516c26573",
"deviceInstallationId": "AA1A109DF2C4208F3ABBC062A343464C",
"friendlyName": "Front Counter",
"hasFirebaseToken": true,
"createdAt": "2026-07-02T12:41:59.344Z"
}
]
{
"httpStatusCode": 401,
"errorCode": 100,
"message": "E100 (Unauthorised): Unauthorized"
}
2.2 Register Device
Register a device with its Firebase token and friendly name. If the device already exists (same deviceInstallationId + user), it will be updated.
POST https://kernelserver.{env}.haloplus.io/devices
Path Parameters
| Name | Type | Description |
|---|---|---|
| env* | String | The backend environment [dev, qa, prod] |
Headers
| Name | Type | Description |
|---|---|---|
| Content-Type* | String | Content Type of the Request: application/json |
| x-api-key* | String | The API Key retrieved from the Merchant Portal (JWT can be used instead) |
| Authorization* | String | The JWT retrieved from logging in. (API Key can be used instead) |
Request Body
| Name | Type | Description |
|---|---|---|
| deviceInstallationId* | String | The device installation ID from the Halo.Go app |
| firebaseToken* | String | Firebase Cloud Messaging token for push notifications |
| friendlyName* | String | Human-readable name for the device (max 32 characters) |
- 201: Created
{
"id": "07b6cbe3-c4c3-4214-b279-ccb516c26573",
"deviceInstallationId": "AA1A109DF2C4208F3ABBC062A343464C",
"friendlyName": "Front Counter"
}
2.3 Update Device Friendly Name
Update the friendly name of a registered device.
PUT https://kernelserver.{env}.haloplus.io/devices/:deviceId
Path Parameters
| Name | Type | Description |
|---|---|---|
| env* | String | The backend environment [dev, qa, prod] |
| deviceId* | String | The device ID (UUID from GET /devices) |
Headers
| Name | Type | Description |
|---|---|---|
| Content-Type* | String | Content Type of the Request: application/json |
| x-api-key* | String | The API Key retrieved from the Merchant Portal (JWT can be used instead) |
| Authorization* | String | The JWT retrieved from logging in. (API Key can be used instead) |
Request Body
| Name | Type | Description |
|---|---|---|
| friendlyName* | String | Name for the device (1-32 characters) |
- 200: OK
- 500: Not Found
{
"id": "07b6cbe3-c4c3-4214-b279-ccb516c26573",
"friendlyName": "Back Office"
}
{
"httpStatusCode": 500,
"errorCode": 134,
"message": "E134 (DataError): Device not found or not associated with this user"
}
2.4 Remove Device
Remove a device from the user's list. This is a permanent deletion.
DELETE https://kernelserver.{env}.haloplus.io/devices/:deviceId
Path Parameters
| Name | Type | Description |
|---|---|---|
| env* | String | The backend environment [dev, qa, prod] |
| deviceId* | String | The device ID (UUID from GET /devices) |
Headers
| Name | Type | Description |
|---|---|---|
| x-api-key* | String | The API Key retrieved from the Merchant Portal (JWT can be used instead) |
| Authorization* | String | The JWT retrieved from logging in. (API Key can be used instead) |
- 200: OK
- 500: Not Found
{
"id": "07b6cbe3-c4c3-4214-b279-ccb516c26573"
}
{
"httpStatusCode": 500,
"errorCode": 134,
"message": "E134 (DataError): Device not found or not associated with this user"
}
3. Push Payment API
3.1 Push Payment to Device
Push a payment request to a registered device via Firebase push notification.
POST https://kernelserver.{env}.haloplus.io/consumer/push
Path Parameters
| Name | Type | Description |
|---|---|---|
| env* | String | The backend environment [dev, qa, prod] |
Headers
| Name | Type | Description |
|---|---|---|
| Content-Type* | String | Content Type of the Request: application/json |
| x-api-key* | String | The API Key retrieved from the Merchant Portal (JWT can be used instead) |
| Authorization* | String | The JWT retrieved from logging in. (API Key can be used instead) |
Request Body
| Name | Type | Description |
|---|---|---|
| deviceId* | String | The device ID (UUID from GET /devices) |
| amount* | Number | Payment amount (minimum 0.01) |
| currency* | String | 3-letter ISO currency code (e.g. ZAR, USD) |
| merchantReference* | String | Unique reference for this payment |
- 201: Push Sent
- 500: Device Not Found
- 400: Validation Error
{
"reference": "cef48d2a-c634-4edc-b891-48cd1d52249f",
"status": "sent"
}
{
"httpStatusCode": 500,
"errorCode": 134,
"message": "E134 (DataError): Device not found or not associated with this user"
}
{
"httpStatusCode": 400,
"errorCode": 103,
"message": "E103 (InvalidJSON): should have required property 'amount'"
}
4. Integration Example
- Node.js
- cURL
const axios = require('axios');
const BASE_URL = 'https://kernelserver.prod.haloplus.io';
const API_KEY = 'your-api-key';
const headers = { 'x-api-key': API_KEY, 'Content-Type': 'application/json' };
// Step 1: Register a device
await axios.post(`${BASE_URL}/devices`, {
deviceInstallationId: 'AA1A109DF2C4208F3ABBC062A343464C',
firebaseToken: 'fcm-token-from-device',
friendlyName: 'Front Counter'
}, { headers });
// Step 2: List devices
const devices = await axios.get(`${BASE_URL}/devices`, {
headers: { 'x-api-key': API_KEY }
});
// Step 3: Update device friendly name
const device = devices.data[0];
await axios.put(`${BASE_URL}/devices/${device.id}`, {
friendlyName: 'Back Office'
}, { headers });
// Step 4: Push payment to device
const push = await axios.post(`${BASE_URL}/consumer/push`, {
deviceId: device.id,
amount: 25.00,
currency: 'ZAR',
merchantReference: 'ORDER-001'
}, { headers });
console.log('Push reference:', push.data.reference);
// Step 5: Remove a device
await axios.delete(`${BASE_URL}/devices/${device.id}`, {
headers: { 'x-api-key': API_KEY }
});
# Register a device
curl -X POST https://kernelserver.prod.haloplus.io/devices \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deviceInstallationId": "AA1A109DF2C4208F3ABBC062A343464C",
"firebaseToken": "fcm-token-from-device",
"friendlyName": "Front Counter"
}'
# List devices
curl -X GET https://kernelserver.prod.haloplus.io/devices \
-H "x-api-key: YOUR_API_KEY"
# Update device friendly name
curl -X PUT https://kernelserver.prod.haloplus.io/devices/07b6cbe3-c4c3-4214-b279-ccb516c26573 \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"friendlyName": "Back Office"
}'
# Push payment to device
curl -X POST https://kernelserver.prod.haloplus.io/consumer/push \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deviceId": "07b6cbe3-c4c3-4214-b279-ccb516c26573",
"amount": 25.00,
"currency": "ZAR",
"merchantReference": "ORDER-001"
}'
# Remove a device
curl -X DELETE https://kernelserver.prod.haloplus.io/devices/07b6cbe3-c4c3-4214-b279-ccb516c26573 \
-H "x-api-key: YOUR_API_KEY"