To enable integration between your POS and the POI, we support four different Data Transport Layers. They are designed to cover a wide range of technical architectures, security needs, and deployment environments. Each protocol offers different capabilities in terms of performance, connectivity models, and implementation complexity, allowing POS providers to choose the method that best fits their ecosystem.
HTTP — A simple, lightweight request/response protocol ideal for local integrations where encryption is not required.
HTTPS — A secure version of HTTP using TLS, recommended for all environments where confidentiality, integrity, and authentication are essential.
TCP/IP — A persistent, bidirectional socket-based channel enabling real-time messaging, low latency, and continuous connections.
IPC (Android App-to-App) — A high-performance inter-process communication mechanism allowing Android POS applications to interact directly with the payment application running on the terminal.
These protocols provide flexible options for integrating payment capabilities, whether the POS and POI communicate over a local network, secure channels, or within the same Android device.
1. HTTP Protocol
Synchronous and Asynchronous management
The Market Pay Local API uses a mixed communication model based on the endpoint's requirements:
Synchronous (SYNC) Mode: Used for simple, direct actions where the POS waits for an immediate result. This follows a standard single request/response cycle (e.g.,
POST /statusreturnsRC 200 OKwith the response body).Asynchronous (ASYNC) Mode: Used for complex transactions that require user interaction or processing time. This involves the HTTP Polling cycle detailed below.
Asynchronous Management
The POS application manages the polling cycle through based on response codes and message types.
Asynchronous mechanism is used for all POST operations in ASYNC: /payment, /acquisition, /reversal, /balanceinquiry, and /giftcard and /update.
Polling loop mechanism
The Polling Loop is the mechanism used for Asynchronous (ASYNC) transactions, where the Point of Sale (POS) actively monitors the Payment Terminal (POI) for a final result after initiating a request. This loop replaces a persistent connection and is critical for managing transaction state and communication stability.
Initiation: The POS sends a
POSTrequest (e.g.,/payment) and receivesRC 202 Accepted, signaling the transaction is queued and the loop must begin.Continuation: The POS sends repeated
GETrequests (polling). The loop continues as long as the POI returns an intermediate status (RC 206 Partial Content,RC 201 Created, orRC 204 No Content).Termination (Success/Failure): The loop immediately stops (
break) when the POI returns a final status code (RC 200 OKfor the result orRC 423 Locked/RC 403 Forbiddenfor a fatal error).Exception: An unrecoverable internal error (like a parsing rejection) is delivered via an
RC 200 OKresponse containing anEventNotification, which also requires the POS to immediately stop polling.
Polling loop sequence diagram
This sequence diagram focuses exclusively on the continuous communication loop initiated after the initial RC 202 Accepted response. The cycle continues until a final transaction result or error forces a termination (break).
Click to View: Sequence Diagram
Transaction Status Codes
Flow Reference
This table defines the meaning and required actions for every HTTP response code encountered during a synchronous transaction or the asynchronous polling loop.
| RC | Status & Type | Content Delivered | Flow Result / Required POS Action |
|---|---|---|---|
200 |
OK (Final) | Full Body (PaymentResponse) or Failure Body (EventNotification). |
Transaction Finalized. The final result has been received. POS must STOP polling and finalize the transaction based on the content (success/failure). |
202 |
Accepted (Start) | None (Empty Body) | Transaction Started. The request was accepted and queued. The POS must immediately BEGIN polling (GET loop). |
423 |
Locked (No Operation) | None (Empty Body) | No current operation. It informs that no operation us in progress on this endpoint, no need to poll GET requests. |
403 |
Forbidden (Critical Error) | None (Empty Body) | Rejected. It informs that there is an operation in progress and not possible to start next one. The request is not allowed (e.g., already in progress, service not available...). The POS must STOP the transaction immediately and get result of previous via GET method |
Example of a Response:
Response 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"
},
"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
}
],
"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"
},
"SponsoredMerchant": {
"Address": "120 RUE REAUMUR\n75002 PARIS",
"CommonName": "MARKET PAY PRECERT",
"CountryCode": "FR",
"MerchantCategoryCode": "4411",
"RegisteredIdentifier": "198703093982001"
}
}
}
}
Review the full schema on the API specification page for required fields.
Example of EventNotification:
The message contains the core transaction metadata in the MessageHeader and the display instructions in the EventNotification body: TimeStamp and EventToNotify
EventNotification example
{
"MessageHeader": {
"MessageCategory": "EventNotification",
"MessageClass": "Service",
"MessageType": "Response",
"POIID": "POI_123",
"ProtocolVersion": "3.1",
"SaleID": "POS001",
"ServiceID": "823"
},
"EventNotification": {
"TimeStamp": "2025-04-02T15:48:47.596+02:00",
"EventToNotify": "Reject"
}
}
Review the full schema on the API specification page for required fields.
ASYNC Polling Intermediate Codes
These codes are exclusively returned to a GET polling request and require the POS application to continue the monitoring loop until a final status (RC 200/423) is reached.
In ASYNC, POS will receive Display Request sent by the POI via the polling cycle. Its primary function is to instruct the POS on what information to display or what operational status has been reached during a transaction.
| RC | Name | Content Delivered | Interpretation / Required Action |
|---|---|---|---|
201 |
Created | Body (DisplayRequest) |
Customer Action Required. The POI needs the customer to interact (e.g., PIN entry, card selection). POS must display the message and continue polling. |
206 |
Partial Content | Body (DisplayRequest or EventNotification) |
Status Update. Provides intermediate status data. POS must handle the notification and continue polling. |
204 |
No Content | None (Empty Body) | Processing. The transaction is active, but the POI has no status updates ready yet. POS must continue polling (checking again later). |
Display Request Structure Breakdown
The message contains the core transaction metadata in the MessageHeader and the display instructions in the DisplayRequest.DisplayOutput body:
| Field | Purpose |
|---|---|
Device |
Specifies information should be displayed. |
InfoQualify |
Indicates the type of information being sent (e.g., a status update vs. an instruction). |
OutputContent.OutputFormat |
Format of the content to display or print |
OutputContent.OutputText |
The specific status string (WaitingForCard, PinRequired, BankAuthorization, ApplicationSelection). The POS should translate this string into the appropriate localized message. |
Example of DisplayRequest :
Display request example
{
"MessageHeader":{
"MessageCategory":"Display",
"MessageClass":"Service",
"MessageType":"Request",
"POIID":"PayOnSite",
"ProtocolVersion":"3.1",
"SaleID":"POS_01",
"ServiceID":"102"
}
"DisplayRequest":{
"DisplayOutput":[
{
"Device":"CashierDisplay",
"InfoQualify":"Status",
"OutputContent":{
"OutputFormat":"Text",
"OutputText":[
{
"Text":"WaitingForCard"
}
]
},
"ResponseRequiredFlag":false
}
]
},
}
Review the full schema on the API specification page for required fields.
Technical & Functional Rules
| Rule | Description |
|---|---|
| Initial Request (ASYNC) | The POS sends a POST request to the POI (e.g., /payment) and must immediately begin the polling cycle upon receiving RC 202 Accepted. |
| Timeout to Manage | The POS must manage a transaction timeout. If the maximum waiting time (120 seconds) is exceeded without receiving the final response (200 or 204), the POS should display an error and send an /abort request. |
| Retry Logic | Retry logic should be based on the HTTP response code. For example, if the POI is unavailable (e.g., connection error), the POS may retry the initial POST request. Do not retry polling GET requests until the timeout is exceeded. |
| Synchronous Data Flow | Ensure the POS does not allow the transaction to proceed or accept new user input until the final response is received or the timeout is exceeded. |
2. HTTPS
HTTPS (Hypertext Transfer Protocol Secure) is HTTP layered over SSL/TLS encryption. This is the required standard for all communication over the public internet, ensuring data integrity and confidentiality. The communication is between the POS/terminal and a central payment gateway (the Cloud API), not directly between the POS and the terminal.
You will find additional information on our Cloud API page and on our online documentation. Our Cloud API does not follow yet the Nexo Retailer structure.
How does it work?
Request: The POS sends a synchronous HTTPS request to the Cloud API (the gateway).
Routing: The Cloud API securely routes the request to the specific terminal.
Result (Asynchronous via Webhook): The POS often does not wait for the final result. Instead, the Cloud API immediately sends an initial response acknowledging the request. When the transaction finishes at the terminal, the Cloud API sends an automated, separate HTTPS POST message (a Webhook) to a predefined URL on the POS server to deliver the final status.
Implementation Details
Security: Requires valid SSL/TLS certificates and mandatory signature validation for inbound webhooks.
Webhooks (optional): The POS server must expose a public, dedicated HTTPS endpoint to receive webhook notifications. It must handle acknowledgment (HTTP 200 OK) promptly.
Error Handling: The POS must handle duplicate webhooks and manage transaction state separately (the state is defined by the webhook, not the initial request).
Addressing: The terminal only needs general internet connectivity; its IP address is usually dynamic and irrelevant to the POS request.
3. TCP/IP Protocol
What It Is
The TCP/IP protocol provides a low-level foundation for communication by establishing a reliable, persistent connection (Socket) between two programs running on the local network. This protocol is typically chosen for applications requiring guaranteed, ordered data delivery and maximum control over the connection state.
How It Works
- Connection: The POS application (client) initiates a connection to the POI (server) using the POI's IP address and port number. This connection remains open and active throughout the transaction session.
- Data Stream: All Nexo JSON or XML messages are sent as a continuous stream of data through this socket.
- No Polling: Unlike HTTP, the POS does not need to send repeated GET requests; the POI can push intermediate status and the final result directly to the POS via the open socket.
Implementation Details:
Message Framing
Because TCP treats data as a continuous byte stream (without predefined message boundaries), the developer must implement a framing mechanism to correctly parse individual Nexo messages:
- Requirement: The POS must read the stream to correctly identify the start and end of each JSON/XML message. If the POS sends two JSON messages immediately, the POI receives them as one long stream (e.g., {"Msg1":...}{"Msg2":...}).
- Mechanism: This is achieved using a Length-Prefix (4 bytes), in the message header, with a fixed-length field indicating the total byte size of the following message body. The POS reads the length field, then reads exactly that many bytes for the complete message.
Connection management and state:
The POS is responsible for maintaining the stability and persistence of the socket connection:
Connection Persistence: The socket connection should be kept open and active throughout the transaction session to allow the POI to push notifications and the final result directly to the POS (no polling required).
Keep-Alive: Implement a keep-alive mechanism (e.g., sending regular, non-transactional ping messages) to prevent network devices (like firewalls or load balancers) from timing out and closing the idle socket connection.
Reconnection: The POS application must include robust logic to automatically detect a broken connection and attempt to re-establish the socket quickly to avoid transaction interruption.
Error handling
Developers must distinguish between a transaction failure and a communication failure:
Communication Error: If the POS loses the socket connection before a final response is received, the POS should not automatically assume the transaction failed. It must attempt to reconnect and send a
/diagnosisrequest to determine the outcome.Transaction Error: If the POI replies with a Nexo response indicating a business error, the socket connection remains active, but the POS must finalize the transaction flow.
Configuration
- Addressing: Requires the POS to use a Static IP address or a DHCP reservation for the POI to ensure a known connection endpoint.
- Error Handling: The POS must implement logic to detect broken connections, manage socket keep-alives, and attempt reconnection gracefully.
4. Inter-Process Communication (IPC)
IPC (Inter-Process Communication) is a set of mechanisms that enables two or more isolated applications or processes running on the same Android device to communicate. For our App-to-App application, the mechanism used is AIDL (Android Interface Definition Language), which allows the POS application to securely call methods directly on a service running within the separate Payment Application (POI).
You will find more details on the dedicated page: App-to-App integration. Our App-to-App integration does not follow yet the nexo retailer protocol.
How It Works
Instead of simply launching the Payment App via an Intent and waiting for a result, this process establishes a direct, secure connection:
Service Binding: The POS App (client) explicitly initiates a bind to a service exposed by the Payment App (server). This connection is established using the Android OS framework.
AIDL Interface: The two apps share the same AIDL interface definitions. The POS App uses the generated stub classes to invoke methods defined in the interface (e.g.,
makePayment(amount, reference)).Synchronous/Asynchronous Call: The Payment App processes the request (e.g., engages the card reader) and uses a Callback mechanism defined in the AIDL interface to return the transaction outcome (success or failure) to the POS App.
Implementation Details
Dependency: Requires the integration of a vendor-provided SDK/Library (e.g., an AAR file) and the associated AIDL interface files into your Android POS project.
Security: The communication is secured locally by the Android OS and often validated by caller signing certificate verification (in professional integrations) to ensure only authorized apps can communicate.
Addressing: No network configuration (IP/Ports) is required, as the communication is handled by the local device kernel.