Skip to main content

Understanding our protocol

The Terminal API is used for communication between your Electronic Cash Register (ECR) and the Payment Terminal (often referred to as the Point of Interaction, or POI).

The communication protocol is based on Nexo Retailer version 5.1. It uses JSON messages to handle everything from standard payments to refunds.

This guide uses the v2 API and protocol 5.1-WL2.1.1 in the latest API reference.

This article covers the two ways you can communicate with the API (Synchronous vs. Asynchronous) and the anatomy of the messages you will send and receive.

Communication modalities​

Our API supports two distinct integration patterns. Choosing the right one depends on your system architecture and how your POS handles network connections.

  • Synchronous processing is suitable for simple integrations where the client keeps the HTTP connection open until the terminal responds or the synchronous timeout is reached. A completed response carries its Nexo payload in data; a timeout acknowledgement carries only requestId.

  • Asynchronous processing is the recommended approach for most production use cases, especially when terminals require longer user interaction. In this mode, requests are acknowledged immediately, and final results are delivered asynchronously via webhooks.

Each modality is explained in detail in its dedicated guide:

Anatomy of a request​

Every message sent to the Terminal API follows a strict hierarchy defined by the Nexo Retailer standard. Whether you are sending a PaymentRequest or any other request, the envelope remains the same.

A standard request consists of two main blocks nested within a root object (e.g., SaleToPOIServiceRequest):

The header​

The Header acts as the envelope for your message. It contains technical metadata required for routing and tracking.

  • ProtocolVersion: Must be set to 5.1-WL2.1.1.
  • ExchangeIdentification: A UUID identifying an operation within a merchant. Generate a new UUID for a new operation and retain it when resending the same operation. Use it for duplicate handling, response correlation, and transaction-status lookup.
  • MessageFunction: Defines the category of the message.
  • CreationDateTime: The request creation time in ISO 8601 format.
  • InitiatingParty: Identifies your system (the Merchant).
  • SalesSystemInfo: Required in v2. Includes your Worldline-provided IntegratorId and at least one SaleSoftware entry with Type and Status.VersionNumber.
  • Async Fields: WebhookUrl and NumberOfRetries (Required for asynchronous requests).

The service request​

The ServiceRequest contains the operation data:

  1. Environment: Describes the hardware involved (Merchant ID, POI ID, Card details).
  2. Context: Describes the sale conditions (e.g., is the cardholder present? Is it a refund? What is the cashier ID?).
  3. ServiceContent: Identifies the operation, for example FinancialPaymentRequest.
  4. PaymentRequest: Contains PaymentTransaction, including the transaction type, identification, amount and currency.

Example structure of a Payment Request​

This asynchronous example uses POST /api/v2/merchants/{umid}/terminals/{utid}/payments. Replace the identifiers and software details, use current timestamps and a UUID for each new request, and supply your publicly reachable HTTPS webhook. This example requests one webhook-delivery retry. For the synchronous endpoint and a complete cURL command, see Sending your first request.

{
"SaleToPOIServiceRequest": {
"Header": {
"MessageFunction": "SaleFinancialServiceRequest",
"ProtocolVersion": "5.1-WL2.1.1",
"ExchangeIdentification": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"CreationDateTime": "2026-09-25T10:00:00+02:00",
"InitiatingParty": {
"Identification": "YOUR_MERCHANT_ID",
"Type": "Merchant"
},
"SalesSystemInfo": {
"IntegratorId": "YOUR_INTEGRATOR_ID",
"SaleSoftware": [
{
"Type": "ECR",
"Status": {
"VersionNumber": "1.0.0"
}
}
]
},
"WebhookUrl": "https://example.com/terminal-api/webhook",
"NumberOfRetries": 1
},
"ServiceRequest": {
"ServiceContent": "FinancialPaymentRequest",
"PaymentRequest": {
"PaymentTransaction": {
"TransactionType": "CardPayment",
"TransactionIdentification": {
"TransactionDateTime": "2026-09-25T10:00:00+02:00",
"TransactionReference": "R26197055"
},
"TransactionDetails": {
"Currency": "EUR",
"TotalAmount": 104.11
}
}
},
"Environment": {
"POI": {
"Identification": {
"Identification": "YOUR_TERMINAL_ID"
}
}
}
}
}
}

Interpreting the response​

In v2, synchronous payloads and asynchronous webhook payloads use the same envelope: the Nexo message is under data, alongside a requestId for tracing. For a financial service response, inspect data.SaleToPOIServiceResponse.ServiceResponse and its Response object. Handle SaleToPOIMessageRejection when the message is rejected.

For asynchronous operations, HTTP 202 Accepted acknowledges new work; HTTP 200 OK can acknowledge an existing exchange. Both acknowledgement bodies contain transactionId, status, and requestId at the root. The Nexo result is delivered separately to the webhook. A synchronous timeout acknowledgement has no Nexo business payload; retain its requestId.

The transaction-status endpoint returns utid, status, and a recorded responsePayload when available, also at the root. These delivery states do not establish payment approval. HTTP error responses contain message and requestId; v2 has no code field.

Response statuses​

The current Response schema defines the Response field values as:

  • Successful: Request processing succeeded. Inspect the operation-specific payment result and receipt data where present.
  • Failed: Request processing failed. Inspect ResponseReason and AdditionalResponseInformation for details.

Use the current response schemas for the operation you send; HTTP delivery status alone is not payment approval.

Troubleshooting failures​

If a transaction fails, the API provides detailed diagnostics:

  • ResponseReason: A standard short code indicating why it failed (e.g., Refusal, WrongPIN, DeviceOut, Cancel).
  • AdditionalResponseInformation: A detailed string, often formatted as ERROR_CODE:DETAILED_MESSAGE, to help developers debug integration issues (e.g., WPI_ERR_COND_MISSING_MANDATORY_PARAMETER).