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 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 transaction is completed and the result is returned directly in the response.
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 acts as the envelope for your message. It contains technical metadata required for routing and tracking.
- ProtocolVersion: Must be set to
5.1-WL1.0.0. - ExchangeIdentification: A unique ID for this specific message exchange. You must generate this; the response will use the same ID so you can match them.
- MessageFunction: Defines the category of the message.
- InitiatingParty: Identifies your system (the Merchant).
- Async Fields:
WebhookUrlandNumberOfRetries(Required for asynchronous requests).
The ServiceRequest contains the actual business logic. It is divided into three parts:
- Environment: Describes the hardware involved (Merchant ID, POI ID, Card details).
- Context: Describes the sale conditions (e.g., is the cardholder present? Is it a refund? What is the cashier ID?).
- ServiceContent: The specific operation data. For a payment, this is where you define the
TransactionType(e.g.,CardPayment,Refund) and theTotalAmount.
Example structure of a Payment Request:
{
"SaleToPOIServiceRequest": {
"Header": {
"MessageFunction": "SaleFinancialServiceRequest",
"ProtocolVersion": "5.1-WL1.0.0",
"ExchangeIdentification": "unique-id-001",
"WebhookUrl": "https://example.com/webhook",
"NumberOfRetries": 3,
...
},
"ServiceRequest": {
"PaymentRequest": {
"PaymentTransaction": {
"TransactionType": "CardPayment",
"TransactionDetails": {
"TotalAmount": 10.50,
"Currency": "EUR"
}
}
}
}
}
}
Interpreting the response
Just like the request, the response is wrapped in a root object (SaleToPOIServiceResponse) containing a Header and a Body.
When parsing the response (whether received via Webhook or Sync response), you should look at the Response object nested within the body to determine the outcome.
The Response field will contain one of three values:
- Success: The operation completed successfully. You should check the
PaymentReceiptfor customer/merchant printing data. - Failure: The request failed. You must check the
ResponseReasonandAdditionalResponseInformationfor details. - Warning: The operation may have succeeded, but with conditions
If a transaction fails, the API provides detailed diagnostics:
- ResponseReason: A standard short code indicating why it failed (e.g.,
Refusal,WrongPIN,DeviceOut,UserCancel). - 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).