Typical Flows
Looking for a simpler integration path?
The Nexi OPI Proxy hides the TCP, XML, callback, and receipt-handling complexity behind a local HTTP and JSON API.
This page focuses on the flows integrators usually care about first. It is not meant to be a complete schema reference. The goal is to show how the most common retail flows map into OPI and what to watch out for when you implement them.
Quick Links
The Flows Most Teams Start With
For most attended retail integrations, the practical starting set is:
- sale
- refund
- receipt reprint
- terminal info, status, and network ping
- close day
If your merchant setup needs more, the next typical layer is:
- reversal
- preauthorisation
- capture of a preauthorisation
- cancellation of a preauthorisation
- abort
- activate / deactivate
- transmission / submit
Sale
A standard sale uses:
CardServiceRequestRequestType="CardPayment"
Minimal sale request
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2001"
RequestType="CardPayment"
ReferenceNumber="ORDER-2001"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en">
<POSTimeStamp>2026-04-08T10:30:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>12</ClerkID>
</POSdata>
<TotalAmount Currency="CHF">49.90</TotalAmount>
</CardServiceRequest>Notes
DeviceRequesthandling is part of the flow- receipt output normally comes back through
DeviceRequest - if tips are enabled, the terminal can return a different final total than the original request
- if DCC is enabled, the terminal drives the DCC conversation during the payment flow
- for unattended terminals, a successful authorisation may be followed by a DeliveryBox request
- if the approved merchant setup supports Forced Acceptance, direct OPI can request it with
<ForceAcceptance>true</ForceAcceptance>inPOSdataafter OPI indicates that online authorisation cannot be reached; see Integration
Preauthorisation
Preauthorisation typically uses:
CardServiceRequestRequestType="CardReservation"
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2101"
RequestType="CardReservation"
ReferenceNumber="RES-2101"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en">
<POSTimeStamp>2026-04-08T10:45:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>12</ClerkID>
</POSdata>
<TotalAmount Currency="CHF">150.00</TotalAmount>
</CardServiceRequest>What to store from the response
If you plan to capture or cancel later, store the response references from the successful reservation, especially:
ApprovalCodeTrxReferenceNumber- the POS-side reference you sent
- terminal-side identifiers needed by the target profile
Adjustment and Final Capture Rules
An existing reservation can be increased with a top-up adjustment more than once. A normal adjustment increases the reserved amount and does not complete the final charge.
The final sale reservation may capture an amount that is lower than or equal to the currently reserved amount. If the final amount is higher, increase the reservation first. The cardholder and card are required again for this final step.
If DCC applies, it is shown again during the final sale reservation. It is not shown again during a normal reservation adjustment.
Align the exact adjustment and capture request model with the target terminal profile. For the general merchant-facing lifecycle, see Reservation.
Capture After Preauthorisation
In practice, capture is usually implemented as a follow-up CardPayment that references the original reservation.
Typical fields used from the original authorisation:
ApprovalCodeTrxReferenceNumber
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2102"
RequestType="CardPayment"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en"
ApprovalCode="123456"
TrxReferenceNumber="384999238">
<POSTimeStamp>2026-04-08T11:15:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>12</ClerkID>
</POSdata>
<TotalAmount Currency="CHF">120.00</TotalAmount>
</CardServiceRequest>- do not assume
ApprovalCodealone is enough everywhere - keep the original reservation response data
- align the exact capture reference model with the target terminal profile
Cancel a Reservation
Cancellation typically uses:
CardServiceRequestRequestType="PaymentReversal"
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2301"
RequestType="PaymentReversal"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en"
ApprovalCode="492321"
TrxReferenceNumber="384999238">
<POSTimeStamp>2026-04-08T12:10:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>99</ClerkID>
</POSdata>
</CardServiceRequest>Refund
Refunds typically use:
CardServiceRequestRequestType="PaymentRefund"
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2201"
RequestType="PaymentRefund"
ReferenceNumber="REF-2201"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en"
RequestTransactionInformation="true">
<POSTimeStamp>2026-04-08T12:00:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>99</ClerkID>
</POSdata>
<TotalAmount Currency="CHF">25.00</TotalAmount>
</CardServiceRequest>- refund permissions should be enforced by the POS
- refund availability depends on terminal and merchant configuration
- receipt handling matters here just as much as on payments
Receipt Reprint
Integrated setups should support reprint.
Typical OPI mapping:
CardServiceRequestRequestType="TicketReprint"
<?xml version="1.0" encoding="utf-8"?>
<CardServiceRequest WorkstationID="POS-1"
RequestID="2401"
RequestType="TicketReprint"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en">
<POSTimeStamp>2026-04-08T12:20:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>12</ClerkID>
</POSdata>
</CardServiceRequest>The terminal will typically resend output through DeviceRequest.
Terminal Info and Status
These are service flows, not card flows.
Common examples:
GetInfoGetStatus
These are especially useful during setup, diagnostics, and support.
The Nexi OPI Proxy also exposes GET /terminals/:terminalAlias/ping as a lightweight network check. It sends four ICMP packets to the configured terminal IP and returns only whether the terminal answered.
Close Day
For the Swiss market, the practical daily-operation service flow to focus on here is CloseDay.
Example close-day request:
<?xml version="1.0" encoding="utf-8"?>
<ServiceRequest WorkstationID="POS-1"
RequestID="2501"
RequestType="CloseDay"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<POSdata LanguageCode="en">
<POSTimeStamp>2026-04-08T23:00:00+02:00</POSTimeStamp>
<ShiftNumber>1</ShiftNumber>
<ClerkID>12</ClerkID>
</POSdata>
</ServiceRequest>Submit and Transmit
In some merchant setups, transactions are submitted automatically. In others, explicit transmission remains relevant.
Typical mapping:
ServiceRequestRequestType="TransmitTrx"
After offline transactions, submit/transmit must complete before normal online payments continue. Treat this as part of connectivity recovery, not as a separate housekeeping task. See Offline Payments for more details.
Abort
Abort is useful when a card flow is in progress and the POS needs to interrupt it.
Typical mapping:
CardServiceRequestRequestType="AbortRequest"
This does not replace proper unknown-result recovery after transport failure.
Activate and Deactivate
Some setups require explicit terminal login or logout style flows.
Typical service mappings:
LoginLogOff
Whether these flows are needed depends on terminal behaviour and merchant setup.
Device Interaction Is Part of Every Serious Flow
During many of the flows above, the terminal can send DeviceRequest back to the POS.
Typical reasons:
- cashier display output
- receipt printer output
- e-journal output
- cashier input
- unattended DeliveryBox handling
The POS must respond with a matching DeviceResponse.
Example output callback
<?xml version="1.0" encoding="utf-8"?>
<DeviceRequest WorkstationID="POS-1"
RequestID="2001"
RequestType="Output"
SequenceID="1"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<Output OutDeviceTarget="Printer">
<TextLine>MERCHANT RECEIPT</TextLine>
<TextLine>AMOUNT CHF 49.90</TextLine>
</Output>
</DeviceRequest>Matching response
<?xml version="1.0" encoding="utf-8"?>
<DeviceResponse WorkstationID="POS-1"
RequestID="2001"
RequestType="Output"
OverallResult="Success"
xmlns="http://www.nrf-arts.org/IXRetail/namespace">
<Output OutDeviceTarget="Printer" OutResult="Success" />
</DeviceResponse>Practical flow advice
- store references from successful transactions
- keep
RequestIDunique - treat receipt handling as part of the transaction itself
- test DCC and tip behaviour only if enabled for the merchant
- do not assume optional fields are universally supported
Unattended
Unattended terminals still start from the normal CardPayment flow. The extra topic is DeliveryBox, where the terminal asks whether the product or service was actually delivered after authorisation.
This only matters for unattended terminal profiles that require terminal-side delivery confirmation. For most teams, it is a separate integration topic from the attended flow set, and many self-service estates are wired either directly over OPI with a dedicated controller or through MDB. The detailed unattended flow, XML examples, and test focus are documented on Unattended Terminals.
If you do not want to handle OPI directly
If you prefer an HTTP and JSON integration instead of TCP and XML, the Nexi OPI Proxy hides these flows behind a simpler local API: OPI Proxy