Skip to main content

Overview

Actions are commands you send to the WebSocket API to interact with terminals. Each action has a specific request format and returns a corresponding response.
ActionDescription
getTerminalsRetrieve a list of available terminals
paymentInitiate a payment request
pingKeep-alive heartbeat

getTerminals

Request a list of available terminals in your group.

Request

{
  "action": "getTerminals"
}

Response

{
  "action": "terminalsResponse",
  "terminals": [
    {
      "connectionId": "abc123xyz",
      "deviceId": "TERM-001",
      "connectedAt": "2024-01-15T10:30:00.000Z",
      "lastActivity": "2024-01-15T10:35:00.000Z",
      "status": "online",
      "metadata": {}
    }
  ],
  "timestamp": "2024-01-15T10:35:30.000Z"
}

Response Fields

FieldTypeDescription
terminalsarrayList of available terminals
terminals[].connectionIdstringUnique connection identifier
terminals[].deviceIdstringStable device identifier (if configured)
terminals[].connectedAtstringISO 8601 timestamp of connection
terminals[].lastActivitystringISO 8601 timestamp of last activity
terminals[].statusstringonline, offline, or reconnecting
terminals[].metadataobjectCustom terminal metadata
timestampstringISO 8601 timestamp of the response

Code Examples

function getTerminals(ws) {
  ws.send(JSON.stringify({ action: 'getTerminals' }));
}

// Handle response
ws.on('message', (data) => {
  const message = JSON.parse(data.toString());

  if (message.action === 'terminalsResponse') {
    const terminals = message.terminals;

    console.log(`Found ${terminals.length} terminal(s)`);

    terminals.forEach((terminal) => {
      console.log(`- ${terminal.deviceId}: ${terminal.status}`);
    });

    // Store terminals for payment operations
    availableTerminals = terminals;
  }
});

payment

Initiate a payment request to a terminal. The terminal processes the payment and returns the result via a paymentComplete push notification.

Request

{
  "action": "payment",
  "terminalId": "TERM-001",
  "paymentRequest": {
    "transactionId": "TXN-20240115-001",
    "amount": "99.99",
    "currency": "USD",
    "paymentMethod": "CARD",
    "products": [
      {
        "id": "PROD-001",
        "name": "Widget",
        "price": "99.99",
        "quantity": 1
      }
    ],
    "customerInfo": {
      "customerId": "CUST-123",
      "email": "customer@example.com"
    },
    "metadata": {
      "orderId": "ORD-12345"
    }
  }
}

Parameters

action
string
required
Must be "payment"
terminalId
string
required
The terminal identifier to send the payment to. Resolved as deviceId first, falling back to connectionId. See Terminal ID Resolution.
paymentRequest
object
required
The payment details

Message Sent to Terminal

When you send a payment action, the terminal receives:
{
  "action": "paymentRequest",
  "desktopId": "desktop-connection-id",
  "paymentRequest": {
    "transactionId": "TXN-20240115-001",
    "amount": "99.99",
    "currency": "USD",
    "paymentMethod": "CARD",
    "products": [...],
    "customerInfo": {...},
    "metadata": {...}
  },
  "timestamp": "2024-01-15T10:37:00.000Z"
}

Response

The payment result is delivered via a paymentComplete push notification when the terminal finishes processing.

Code Examples

function initiatePayment(ws, terminalId, paymentData) {
  const request = {
    action: 'payment',
    terminalId: terminalId,
    paymentRequest: {
      transactionId: `TXN-${Date.now()}`,
      amount: paymentData.amount,
      currency: paymentData.currency || 'USD',
      paymentMethod: 'CARD',
      products: paymentData.products || [],
      customerInfo: paymentData.customer || {},
      metadata: {
        orderId: paymentData.orderId
      }
    }
  };

  ws.send(JSON.stringify(request));
  console.log(`Payment initiated: ${request.paymentRequest.transactionId}`);

  return request.paymentRequest.transactionId;
}

// Handle payment completion
ws.on('message', (data) => {
  const message = JSON.parse(data.toString());

  if (message.action === 'paymentComplete') {
    const response = message.paymentResponse;

    if (response.status === 'SUCCESS') {
      console.log(`Payment successful: ${response.transactionId}`);
      console.log(`Authorization: ${response.authorizationCode}`);
      // Update order status, print receipt, etc.
    } else {
      console.error(`Payment failed: ${response.errorMessage}`);
      // Handle failure, notify customer
    }
  }
});

// Usage
const txnId = initiatePayment(ws, 'TERM-001', {
  amount: '99.99',
  orderId: 'ORD-12345',
  products: [
    { id: 'PROD-001', name: 'Widget', price: '99.99', quantity: 1 }
  ]
});

Error Responses

ErrorMessageCause
Bad RequestterminalId is requiredMissing terminal ID
Bad RequestpaymentRequest is requiredMissing payment data
Not FoundTerminal connection not foundTerminal not connected
ForbiddenCannot send message to connection in different groupGroup mismatch

ping / pong

Keep-alive mechanism to maintain connection health and detect stale connections.

Ping Request

{
  "action": "ping"
}

Pong Response

{
  "action": "pong",
  "timestamp": "2024-01-15T10:38:00.000Z"
}
SettingValue
Ping interval30 seconds
Pong timeout10 seconds
Reconnect on failureYes

Code Examples

let pingTimeout;
let heartbeatInterval;

function startHeartbeat(ws) {
  heartbeatInterval = setInterval(() => {
    ws.send(JSON.stringify({ action: 'ping' }));

    pingTimeout = setTimeout(() => {
      console.log('Connection timeout - reconnecting');
      ws.terminate();
    }, 10000);
  }, 30000);
}

function handlePong() {
  clearTimeout(pingTimeout);
}

ws.on('message', (data) => {
  const message = JSON.parse(data.toString());

  if (message.action === 'pong') {
    handlePong();
  }
});

Server-Initiated Pong

The server may also send pong messages to check client responsiveness. Your client should update its activity tracking when receiving these messages.

Error Response Format

All error responses follow this format:
{
  "error": "Bad Request",
  "message": "terminalId is required"
}

Common Errors

ErrorMessageCause
Bad RequestInvalid JSON in message bodyMalformed JSON in request
Bad RequestterminalId is requiredMissing required field
Bad RequestpaymentRequest is requiredMissing payment data
Not FoundConnection not foundInvalid connection ID
Not FoundTerminal connection not foundTerminal not connected
ForbiddenOnly desktop devices can request terminal listWrong device type
ForbiddenCannot send message to connection in different groupGroup mismatch
Internal Server ErrorFailed to process messageServer-side error

Next Steps