2. How the message model works

The Local API follows the nexo Sale-to-POI protocol, version 3.1. Every exchange is a pair of JSON messages, a request from your POS and a response from the terminal, and every message has the same two-part shape.

Request and response structure

A request carries a MessageHeader and one operation body named after the operation, for example a PaymentRequest or a LoginRequest:

{
  "MessageHeader": { ... },
  "PaymentRequest": { ... }
}

The response echoes the header — with MessageType set to Response — and returns the matching body, for example a PaymentResponse carrying a Response object with a Result of Success, Failure, or Partial.

Note

Over HTTP, messages are sent flat, exactly as shown. Over the TCP/IP socket the same messages are wrapped in a SaleToPOIRequest / SaleToPOIResponse envelope. See Transport bindings: TCP/IP vs HTTP.

The MessageHeader

The header identifies the operation and routes the message. Its fields:

"MessageHeader": {"ProtocolVersion":"3.1","MessageClass":"Service","MessageCategory":"Payment","MessageType":"Request","ServiceID":"823","SaleID":"POS_01","POIID":"POI_01"}
Field Purpose
ProtocolVersion Always 3.1 for this API
MessageClass Service for transactions, Device / Event for display and notifications
MessageCategory The operation: Login, Payment, Reversal, Abort, TransactionStatus, Admin, …
MessageType Request or Response
ServiceID Unique identifier of the message pair — the basis of duplicate detection
SaleID your identified of POS system / lane
POIID your identifier of the terminal

Note

See the Local API reference on MuleSoft for the full schema of every message and body.

How the message model works

Every Local API operation uses the same message discipline — the Nexo Retailer (Sale-to-POI v3.1) model. Once you understand five rules, every operation behaves predictably. This article is the reference for those rules; operation guides link here instead of repeating them.

Note

App-to-App uses this same message model — only the delivery mechanism differs. If you integrate both, these rules apply unchanged.

Rule 1: ServiceID identifies the message in your logs, nothing more

The ServiceID is a message identifier in the header. The terminal does not use it, does not enforce uniqueness, and applies no control to it — the same value on every request will not prevent the terminal from working. Vary it per request anyway: it is the cheapest way to correlate requests and responses in logs when investigating an incident, yours and Market Pay's.

The important consequence: there is no terminal-side duplicate-payment protection based on message identifiers. If your POS sends a payment twice, the cardholder can be charged twice. Protecting against duplicates is POS-side discipline — never re-send a payment to resolve uncertainty; resolve it with Checking transaction status instead.

Rule 2: two transaction identities, two owners

  • SaleTransactionID (in SaleData) — created by you: your transaction reference plus a timestamp.
  • POITransactionID (in POIData of the response) — created by the terminal.

Store the POITransactionID of every approved payment. Reversals, refund references queries use the POITransactionID, not your SaleTransactionID. Referencing the wrong one is the most common cause of "transaction not found" failures.

Rule 3: read Result, then ErrorCondition

Every response carries Response.Result (Success, Failure, or Partial). On Failure, ErrorCondition says why, and each value implies a different POS reaction:

ErrorCondition Meaning Your reaction
Aborted Cardholder or POS cancelled Offer retry
Busy Terminal already processing Wait, retry later
NotAllowed Service disabled or no session open Check Login state and configuration
LoggedOut Session expired Re-Login, then retry
MessageFormat Malformed request Fix the request — do not retry as-is
Refusal Declined by issuer/acquirer Read the response code; inform cashier

Related

  • Transport bindings (HTTP & TCP/IP): how these messages travel and how responses are delivered.
  • Taking a payment: the model applied to the core operation.
  • Troubleshooting: duplicate payment: what re-sending causes in the field.