Protocol implementation

Our API can communicate with the POI using JSON or XML messages and adheres to the Nexo Retailer Protocol. All requests and responses follow a standard message header-body structure

1. API Message Structure

Each API request you send is contained within a SaletoPOIRequest object. In this, you must provide the MessageHeader object and the appropriate Request body object corresponding to the transaction type.

Component Purpose Examples
Header

Identifies the transaction type, the POI being used, and unique transaction identifiers.

Includes ProtocolVersion, ServiceID, POIID, and MessageCategory.

Body

Contains the core request or response object for the transaction type.

A PaymentRequest object when making a payment, or a PaymentResponse object when receiving a result.

2. Request Message

MessageHeader Request

The following fields are required in every request's MessageHeader:

Name Required Type Description
ProtocolVersion

String

Version of the Nexo protocol; currently 3.1

MessageClass

Enum

The context of the request; almost always Service but it can also be Device or Event

MessageCategory

Enum

The type of transaction (e.g., Payment or Input); specified in the documentation for each flow

MessageType

Enum

Always Request

ServiceID

String

Your unique ID for this request (1-10 alphanumeric characters).  The Service ID acts as a unique tracking number for each transaction "conversation," allowing the system to match a specific request to its response and prevent duplicate payments by identifying if the same message was sent twice. We do not have any control on this field, we just echo it (if you send always 0, it will not prevent the system from working).

SaleID

String

Your unique ID for the POS system sending the request

POIID

String

The ID of the target POI

Request Header example
"SaleToPOIRequest": {
    "MessageHeader": {
        "ProtocolVersion": "3.1",
        "MessageClass": "Service",
        "MessageCategory": "Payment",
        "MessageType": "Request",
        "SaleID": "POSSystemID12345",
        "ServiceID": "0207111104",
        "POIID": "V400m-324688179"
    },
    "PaymentRequest": {...}
}

Review the full schema on the API specification page for required fields.

Request body

The fields required in the request body vary according to the operation being performed. You can find specific examples and reference information detailing the needs for each operation within our Local API documentation online.

Name         Required Type Description        
ProtocolVersion

String

Version of the Nexo protocol; currently 3.1

MessageClass

Enum

The context of the request; almost always Service but it can also be Device or Event

MessageCategory

Enum

The type of transaction (e.g., Payment or Input); specified in the documentation for each flow

MessageType

Enum

Always Request

ServiceID

String

Your unique ID for this request (1-10 alphanumeric characters).

SaleID

String

Your unique ID for the POS system sending the request

POIID

String

The ID of the target POI

Request Header & Body example
{
  "MessageHeader": {
    "MessageCategory": "Payment",
    "MessageClass": "Service",
    "MessageType": "Request",
    "POIID": "Terminal_01",
    "ProtocolVersion": "3.1",
    "SaleID": "POS001",
    "ServiceID": "86"
  },
  "PaymentRequest": {
    "PaymentData": {
      "PaymentType": "Normal"
    },
    "PaymentTransaction": {
      "AmountsReq": {
        "Currency": "EUR",
        "RequestedAmount": 12.34
      }
    },
    "SaleData": {
      "SaleTransactionID": {
        "TimeStamp": "2025-11-29T22:05:55.029",
        "TransactionID": "12345"
      }
    }
  }
}

Review the full schema on the API specification page for required fields.

3. Response message

Responses are contained within a single object (similar to SaleToPOIResponse) and include the MessageHeader and the corresponding Response body object.

  • Response header: it echoes the values you provided in the request. The only exception is the MessageType, which is always Response.

  • Response body: it will include a transaction identifier and data needed to generate receipts.

In a HTTP integration, for asynchronous messages, you only receive an ok response from the API. The MessageHeader and response body are sent in response to a GET.

MessageHeader Response

The MessageHeader you receive in the response echoes the values you provided in the request. The only exception is the MessageType, which is Response.

The following example shows the header you would receive in response to the example payment request provided above.

Request Header & Body example
  "MessageHeader": {
    "MessageCategory": "Payment",
    "MessageClass": "Service",
    "MessageType": "Response",
    "POIID": "Terminal_01",
    "ProtocolVersion": "3.1",
    "SaleID": "POS001",
    "ServiceID": "102"
  },

Review the full schema on the API specification page for required fields.

Response body

The values you receive in the response body depends on the type of transaction request you made. We provide examples and reference information for each transaction type throughout our point-of-sale documentation.

The response body will often include a transaction identifier, and data you can use to generate your receipts.

Example of a Response:

Request Header & Body example
{
  "MessageHeader": {
    "MessageCategory": "Payment",
    "MessageClass": "Service",
    "MessageType": "Response",
    "POIID": "Terminal_01",
    "ProtocolVersion": "3.1",
    "SaleID": "POS001",
    "ServiceID": "102"
  },
  "PaymentResponse": {
    "MarketpayPaymentExtensions": {
      "ApplicationID": "A0000000041010",
      "BankID": "519303",
      "PANSequenceNumber": "00",
      "TVR": "0000040001"
    },
        "PaymentResult": {
      "AmountsResp": {
        "AuthorizedAmount": "123",
        "Currency": "EUR"
      },
      "MerchantOverrideFlag": false,
      "OnlineFlag": true,
      "PaymentAcquirerData": {
        "AcquirerID": "40105611508",
        "AcquirerPOIID": "00000001",
        "ApprovalCode": "511725",
        "MerchantID": "198703093982001"
      },
      "PaymentInstrumentData": {
        "CardData": {
          "EntryMode": "Contactless",
          "MaskedPAN": "XXXXXXXXXXXX1676",
          "PaymentBrand": "MASTERCARD"
        },
        "PaymentInstrumentType": "Card"
      },
      "PaymentType": "Normal"
    },
    "POIData": {
      "POITransactionID": {
        "TimeStamp": "2025-11-29T22:17:23.359",
        "TransactionID": "13"
      }
    },
    "Response": {
      "AdditionalResponse": "000",
      "Result": "Success"
    },
    "SaleData": {
      "OperatorID": "App2AppOperator",
      "SaleTransactionID": {
        "TimeStamp": "2025-11-29T22:16:58.354",
        "TransactionID": "12345"
      },

    "PaymentReceipt": [
      {
        "DocumentQualifier": "CashierReceipt",
        "OutputContent": {
          "OutputFormat": "Text",
          "OutputText": [
            {
              "EndOfLineFlag": true,
              "Text": "POTWIERDZENIE DLA"
            },
            {
              "EndOfLineFlag": true,
              "Text": "SPRZEDAWCY"
            },
            {
              "EndOfLineFlag": true,
              "Text": "BRAK PARAGONU DO"
            },
            {
              "EndOfLineFlag": true,
              "Text": "ZAKUPU"
            },
            {
              "EndOfLineFlag": true,
              "Text": "MARKET PAY PRECERT"
            },
            {
              "EndOfLineFlag": true,
              "Text": "120 RUE REAUMUR"
            },
            {
              "EndOfLineFlag": true,
              "Text": "75002 PARIS"
            },
            {
              "EndOfLineFlag": true,
              "Text": "Mastercard"
            },
            {
              "EndOfLineFlag": true,
              "Text": "BEZSTYKOWY"
            },
            {
              "EndOfLineFlag": true,
              "Text": "XXXXXXXXXXXX1676 00"
            },
            {
              "EndOfLineFlag": true,
              "Text": "AID: A0000000041010"
            },
            {
              "EndOfLineFlag": true,
              "Text": "TVR: 0000040001"
            },
            {
              "EndOfLineFlag": true,
              "Text": "29-11-2025 22:17"
            },
            {
              "EndOfLineFlag": true,
              "Text": "NUMER REFERENCYJNY: 13"
            },
            {
              "EndOfLineFlag": true,
              "Text": "KWOTA:EUR 123,00"
            },
            {
              "EndOfLineFlag": true,
              "Text": "Zaakceptowana"
            }
          ]
        },
        "RequiredSignatureFlag": false
      },
      {
        "DocumentQualifier": "CustomerReceipt",
        "OutputContent": {
          "OutputFormat": "Text",
          "OutputText": [
            {
              "EndOfLineFlag": true,
              "Text": "RECU PORTEUR"
            },
            {
              "EndOfLineFlag": true,
              "Text": "PAS DE REÇU POUR"
            },
            {
              "EndOfLineFlag": true,
              "Text": "L'ACHAT"
            },
            {
              "EndOfLineFlag": true,
              "Text": "MARKET PAY PRECERT"
            },
            {
              "EndOfLineFlag": true,
              "Text": "120 RUE REAUMUR"
            },
            {
              "EndOfLineFlag": true,
              "Text": "75002 PARIS"
            },
            {
              "EndOfLineFlag": true,
              "Text": "Mastercard"
            },
            {
              "EndOfLineFlag": true,
              "Text": "SANS CONTACT"
            },
            {
              "EndOfLineFlag": true,
              "Text": "XXXXXXXXXXXX1676 00"
            },
            {
              "EndOfLineFlag": true,
              "Text": "AID: A0000000041010"
            },
            {
              "EndOfLineFlag": true,
              "Text": "29-11-2025 22:17"
            },
            {
              "EndOfLineFlag": true,
              "Text": "NUMÉRO DE RÉFÉRENCE: 13"
            },
            {
              "EndOfLineFlag": true,
              "Text": "MONTANT:EUR 123,00"
            },
            {
              "EndOfLineFlag": true,
              "Text": "Approuvé"
            }
          ]
        },
        "RequiredSignatureFlag": false
      }
    ],
    }
  }
}

Review the full schema on the API specification page for required fields.

Transaction identifier

In each response, the POI returns a transaction identifier: POIData.POITransactionID.TransactionID. You must store each TransactionID as it is a key data to perform some additional operations such as: 

  • Void a transaction (Cancel),
  • Transaction Status check,
  • Card acquisition payment,
  • Preauthorization

Receipt data

In transaction responses, the result can contain a PaymentReceipt object. You can add the key-value pairs from this object to the receipt that you print, display, or email to your shopper.

In the PaymentReceipt object, there is RequiredSignatureFlag which indicates that the cardholder payment receipt requires a physical signature by the Customer.

4. Identify the POI

The Diagnosis allows the Point of Sale (POS) application to retrieve the hardware's unique Serial Number. The primary interest in using the Serial Number validation is fraud prevention and system integrity.

The POS can perform a quick check during login to retrieve POI's unique serial number. By comparing this number against a stored record, your system can immediately detect if an unauthorized or unknown terminal has been swapped into the setup. This creates a simple, secure, verifiable binding between the POS software and the physical POI device.

You will find below a simple proposition of implementation:

  1. First installation: retrieve and store POI's Serial Number through a Diagnosis request. First installation should be trusted as per installation process.

  2. Next login: POS runs a new Diagnosis request. If the returned Serial Number does not match the stored value, the POS must alert the user to confirm if POI was legitimately changed or not.

You could also compare the Serial Number with the known Serial Number from your Database. This can be made easier for P2PE compliant customers which have to follow Payment Terminals whole lifecyle.