Skip to navigation

Interactions & Status

Retrieve results by polling or WebSocket, cancel reads, and manage terminal sessions.

read-card and charge-card are queue-based: they return 202 Accepted immediately with an interaction_id, and the outcome is retrieved later.

Retrieving the result

Interaction status values

StatusMeaning
pendingIn progress. result is null. Only pending interactions can be cancelled.
succeededThe workflow completed. For charge-card, this includes declines — see Handling declines.
failedThe workflow could not complete (e.g., the terminal was unavailable).
cancelledCancelled via the cancel endpoint or at the device.
Interactions expire after 3 minutes

After the TTL, the status endpoint returns 404 — the same response as an interaction that never existed or a wrong device_id. Retrieve results promptly and persist anything you need.

Cancelling

DELETE /api/terminal/{device_id}/cancel/{interaction_id} cancels a pending read-card interaction on the terminal. It returns 200 with no body on success, or 422 if the interaction is no longer pending.

charge-card interactions can't be cancelled through the API

Charging is a processing flow whose outcome depends on timing at the terminal and processor. Once a charge-card interaction starts, wait for its final status and check result.

Sessions

ping, read-card, charge-card, and print-receipt auto-connect a terminal session if none is active, so calling connect first is optional. Use connect to pre-warm a terminal or force a reconnect (force: true); use disconnect to release the device.

Real-time updates (WebSocket)

By default, interaction status is retrieved by polling the status endpoint. For applications that want instant updates without polling, the Terminal API also supports an optional WebSocket connection that pushes status changes as they happen. This works for both read-card and charge-card interactions.

Why a separate token?

This flow uses its own token rather than your access token. Browser and native WebSocket clients can only pass credentials via the connection URL (query string), not request headers, and putting a long-lived access token into a URL risks it being captured in server logs, proxy logs, or browser history.

To avoid that risk, the WebSocket flow uses a short-lived, single-use token that is only valid for establishing one socket connection. It expires after 60 seconds or on first use, whichever comes first, and cannot be reused for a second connection or for REST calls.

How it works

1

Request a WebSocket token

POST /api/ws-token. Returns a single-use token valid for 60 seconds.

2

Open the WebSocket connection

Connect to wss://javelin.runpayments.io/cable?token={token}. Once used, the token is invalidated; if the connection drops, request a new token before reconnecting.

3

Start the interaction

POST /api/terminal/{device_id}/read-card or /charge-card. Returns an interaction_id.

4

Subscribe to the channel

terminal_job:{interaction_id}. The channel is scoped to that single interaction.

5

Receive status updates

Events are pushed as the interaction moves through pending → succeeded / failed / cancelled. The pushed payload matches the polling response (interaction_id, status, result, updated_at).

Example

POST /api/ws-token
→ { "token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }
POST /api/terminal/{device_id}/charge-card
→ { "interaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" }
Connect: wss://javelin.runpayments.io/cable?token=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Subscribe: terminal_job:3fa85f64-5717-4562-b3fc-2c963f66afa6
← { "status": "pending", ... }
← { "status": "succeeded", "result": { ... } }

Other things to keep in mind

  • Tokens are single-use. Request a new token for every new WebSocket connection, including reconnects.
  • Tokens expire in 60 seconds. Request the token immediately before connecting, not in advance.
  • Channels are per-interaction. You need the interaction_id before subscribing, so queue the interaction first.
  • WebSocket connections are multi-interaction. Once open, a connection isn’t single-use — you don’t need a new connection or a new token to handle another interaction.
  • This does not start an interaction. The WebSocket only delivers updates for an interaction already in progress.
  • Status alone doesn’t mean approved. A declined charge-card still arrives as succeeded — see Handling declines.