OPI Proxy

This page is currently only available in English.

Ultima versione Repository GitHub

The Nexi OPI Proxy gives integrators a much cleaner way to work with Nexi terminals in Switzerland.

Instead of building a direct TCP and XML integration against OPI, you run one local Docker service and call a smaller HTTP and JSON API. The proxy keeps the OPI transport, XML message handling, terminal callbacks, receipts, and transaction follow-up logic inside the service.

The idea is simple: your application talks HTTP and JSON, the proxy talks OPI to the terminal.

Esempio di richiesta e risposta di pagamento JSON Nexi OPI Proxy

Start using the Nexi OPI Proxy today!

Check out the Nexi OPI Proxy on GitHub, built to make terminal integrations over the OPI protocol much simpler and save you a lot of unnecessary headaches. 😉

richiehug/nexi-opi-proxy

What a First Payment Looks Like

One of the nicest things about the proxy is that payments can be initiated by simple requests. To start a payment, just call /terminals/:terminalAlias/payment.

{
  "reference": "ORDER-1001",
  "amount": 49.90,
  "currency": "CHF"
}

The proxy accepts the request, starts the terminal flow, and gives your application a stored transactionId. Your application can then look up the transaction result by querying /transactions/:transactionId.

{
  "transaction": {
        "transactionId": "33866707-9cd9-45fd-bd71-e743c879691c",
        "reference": "ORDER-1001",
        "amount": "49.90",
        "currency": "CHF",
        "terminalAlias": "my-terminal",
        "deviceTerminalId": "300XX9999",
        "type": "payment",
        "paymentKind": "sale",
        "status": "succeeded",
        ...
    },
    "requestId": "32ddbf3f-b402-4572-96f3-ec4ba94a77ac"
}

And that is the beauty the OPI proxy: your application can stay close to a modern API model, while the proxy handles the OPI conversation with the terminal. No custom TCP framing in your POS. No manual XML request building. No terminal callback handling in your checkout application.

Why Integrators Use the Proxy

Direct OPI is proven and powerful, but it pushes a lot of low-level responsibility into the POS.

A direct OPI integration usually needs to handle:

  • framed TCP messaging
  • XML request construction
  • XML response parsing
  • DeviceRequest and DeviceResponse handling
  • receipt and journal handling
  • terminal-specific operational behaviour
  • transaction reference storage for later capture, cancel, refund, and reprint

The proxy keeps that complexity out of the POS codebase and lets modern applications integrate over HTTP instead. For many integrators, this means a smaller integration surface, faster testing, and less terminal-specific code in the main checkout application.

What the Proxy Abstracts

The proxy hides:

  • TCP socket handling to the terminal
  • OPI XML request generation
  • OPI XML response parsing
  • terminal callback handling during live flows
  • receipt storage and transaction-linked receipt lookup
  • selectable JSON or SQLite runtime persistence
  • stored transaction follow-up for capture, cancel, refund, and receipt retrieval

From the POS side, the model becomes:

  • HTTP requests
  • JSON payloads
  • bearer tokens
  • stable terminalAlias values
  • stored transactionId based follow-up actions

The POS no longer needs to understand every OPI detail directly. It only needs to call the proxy API and handle the resulting transaction state.

What You Can Do Today

The current public proxy covers:

  • health checks
  • terminal info
  • terminal status
  • terminal ping
  • payment and preauthorisation
  • terminal-side refund
  • receipt reprint
  • transmit
  • close day
  • selectable sync or async handling for long-running terminal operations
  • activate and deactivate
  • abort
  • terminal reset
  • stored transaction lookup
  • capture, cancel, and refund by transactionId
  • receipt lookup by transactionId
  • latest and recent receipt lookup by terminalAlias
  • forced acceptance

Runtime and Security Model

The public distribution is Docker-first. That means:

  • clone the public repo and run with Docker
  • keep merchant-owned state in config/, data/, logs/, and certs/
  • generate config/auth.json during initialization
  • use HTTP on localhost for simple local setups; use HTTPS by default for non-local traffic

The proxy supports bearer-token authentication with route-level scopes such as:

  • terminals:read
  • terminals:write
  • transactions:read
  • transactions:write
  • receipts:read
  • admin:manage

GET /health stays public for health checks.

When the Proxy Is a Good Fit

The proxy is a strong fit when:

  • your team prefers HTTP and JSON over raw TCP and XML
  • you want OPI complexity out of the POS codebase
  • you want transaction-based follow-up actions such as capture, cancel, refund, or receipt lookup
  • you want a local integration surface that is easier to support operationally
  • you want terminal aliases instead of hard-coding terminal IPs and ports throughout your POS
  • you want a cleaner separation between checkout logic and terminal protocol handling

When Direct OPI May Still Be the Better Fit

A direct OPI integration may still be the better fit when:

  • your system already has a mature OPI stack
  • you need full control over every OPI message
  • you want to implement terminal-specific behaviour directly in the POS
  • your architecture does not allow a local proxy service
  • your unattended flow needs direct custom control over terminal-side delivery confirmation

The proxy is not meant to remove OPI as an option. It gives integrators a simpler path when they do not want to own the low-level protocol integration themselves.