# Flow & Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/faq Answers to common questions about activating, connecting, configuring, and updating Marshall Pro devices. ## Connecting the device to your POS or simulator To connect to the device, use the TCP protocol through port 5050. No physical connection to your computer is required. For your device's Wifi connection setup, see [Configuring Wifi (and IP)](/docs/integrate-pos-device/marshall-pro/faq#configuring-wifi-and-ip) below. For LAN, see [Configuring ETH (and IP)](/docs/integrate-pos-device/marshall-pro/faq#configuring-eth-and-ip). ### Activating the device Scan the QR code displayed on the device's screen using your phone's camera. Image (1) You're redirected to a landing page where you enter the required details. After submission, a verification code is sent by email. Enter it on the landing page to complete the device activation. Landing page for entering device activation details ### Getting the device's details (serial number, IP) Disconnect the link to the device and wait 30 seconds. Device screen showing Out of Service status Click five times on the top-right corner of the screen, then select **Device Info**. Device menu with the Device Info option highlighted Device Info shows the device's serial number, along with its cellular and Ethernet communication details. In this example, the device has an eSIM and is also connected to Wifi. Device Info screen showing serial number and connectivity details To return to the device's idle screen for making transactions, click the top-left arrow, then select **Payment App**. ### Configuring wifi (and IP) VPOSM over Marshall supports either DHCP or Static IP, depending on how you want the device to work. DHCP is the default. Click 5 times on the top-right corner of the screen, then select **Technician Menu**. Technician Menu opened on the device Enter the code (123123 by default), then scroll down to the **Communication** section. Technician Menu with the Communication section highlighted Select **Wifi**, then select the relevant network. Communication section with the Wifi option Click the gear icon for the relevant network, then select **Advanced**. Network settings with the gear icon highlighted Advanced network settings screen Scroll down to **IP Settings**, which is set to DHCP by default, and switch it to **Static**. Fill in the IP details. IP settings showing the option to switch from DHCP to Static ### Configuring ETH (and IP) On the Wifi settings screen, tap the back arrow at the top-left to return to the device's system settings. Device system settings screen Tap **Network & Internet**. System settings with the Network and Internet option Tap **Ethernet**, then turn it on using the toggle. Tap the Ethernet row again to open Ethernet Settings. Network and Internet settings with the Ethernet option Ethernet toggle and settings row In Ethernet Settings, select **Static**, then fill in the IP details. Ethernet Settings screen with the Static option ## Triggering the apps update process (accessing the CasHub app) Nayax Fuel initiates firmware updates from a separate platform called CasHub. The update process updates each relevant application individually, rather than as a single package, in two stages: download and update. Once the download finishes, Nayax Fuel's support team sends the device a request to start the update for the desired applications. You can also trigger the update yourself. Turn on the device and use one of the following options: 1. Leave the device powered on overnight. It resets automatically at approximately 3-4 AM, at which point the device collects and starts the updates. 2. Manually access the CasHub app to trigger the download and installation of the updates. To trigger the update manually, follow these steps: Disconnect the link to the device and wait 30 seconds. Device screen showing Out of Service status Click five times on the top-right corner of the screen, then select **Technician Menu**. Enter the password 123123. Technician Menu password prompt Scroll down to **Dev Mode** and enter the password 321321. Technician Menu with the Dev Mode option Select **Wifi**, then select the back arrow to return to the Android settings. Wifi settings within Dev Mode Android settings screen Go to **Apps & Notifications**, then select **See All Apps** (in this example, the device has 24 apps). Android settings with the Apps and Notifications option Full list of apps on the device Select the CasHub app and open it. App list with CasHub selected CasHub app info screen Click **Status**, then select the three dots in the top-right corner and choose **Connect**. CasHub app Status screen CasHub app menu with the Connect option The screen displays "Connecting..." both at the top and in the table below. If this persists for more than one minute, the process has likely stalled. CasHub app showing the Connecting status The download and update of the apps begins. CasHub app downloading updates Once all apps finish downloading and updating, a "Finished" line appears. CasHub app showing the Finished status Some apps can only be downloaded, not installed, at this stage, since the device can't update applications that are currently running. This applies to: * Nayax Fuel FuelApp * Nayax Launcher * Update Service * VPOS Service For these, **reboot** the device afterward. The apps update during the device's power-up sequence, and a "Castles: Updating (application)" notification appears for about one minute. **"vpos\_media keeps stopping" error** This error happens because the Vendapp crashes, which isn't relevant to your setup. This can occur if the Vendapp is set as the default application: Error notification showing vpos_media has stopped or if the relevant parameter value is empty or missing (in either case, the device defaults to Vendapp). If the parameter is correctly set to Fuel and you still get this error, update the Vendapp. Parameter setting correctly configured to Fuel # FuelApp Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/fuelapp-release-notes What changed in each FuelApp version, and what it means for your integration. FuelApp is the payment application that runs on the VPOS terminal at the dispenser. Its version number is separate from the Marshall Pro protocol version, so a FuelApp release does not change the protocol your POS or forecourt controller (FCC) speaks. Subscribe to the RSS feed using the icon at the top of the page to get notified when a new version is added. ### Extra characters in a scanned QR code Scanning a QR code for payment could add extra characters to the code. ### Charge amount adjustment before authorization You can now adjust the charge amount after the card has been detected and before it is authorized. ### Single-step Pay flow FuelApp now supports a Pay flow that combines card detection, authorization, and settlement into one step. ### Configurable display time for the e-receipt QR code Merchants can now set how long the e-receipt QR code stays on screen. This is a per-merchant configuration, so the same integration can show the code for a different length of time at different sites. ### Larger keypad for PIN and code entry PIN and code entry prompts now use a larger on-screen keypad instead of the small system keyboard. ### IFSF reconciliation and receipt printing accuracy Terminal reconciliation and receipt printing are more accurate on setups that use the International Forecourt Standards Forum (IFSF) protocol. The fix covers transaction IDs, the terminal ID, and print timing on reversals. ### Reliability when a payment is canceled in progress Several defects could occur when a payment was canceled while it was still in progress. ### Support for the ANDI integration protocol FuelApp now supports ANDI, an additional payment-terminal integration protocol, on certain dispenser hardware setups. ### Custom card-detect screen and tap-to-continue button Sites can now show a branded card-detect screen with a tap-to-continue button. This is a per-site configuration, so the same integration can show a different card-detect screen at different sites. ### Remove Card prompt after chip transactions The terminal now shows a **Remove Card** prompt after a chip transaction instead of only sounding a beep. ### Digital e-receipt by QR code After a payment, the terminal can show a QR code the customer scans to get a digital receipt. Merchants enable this per site, so the screen does not appear unless the site has it turned on. ### Language menu limited to enabled languages The language menu now lists only the languages enabled for the site, instead of the full list. ### Clearer status icons The terminal shows clearer on-screen icons for the card-blocked and transaction-canceled messages. ### Card reader ignoring a stop request The card reader sometimes did not respond to a stop or cancel request. ### App stuck on Initializing after a terminal update FuelApp could stay on the **Initializing** screen after a payment terminal software update. ### Dark screen before the idle screen A dark screen could appear for several seconds before the idle screen after a card was tapped or inserted. This fix also improves overall app stability, including a rare crash and restart after extended use on some older hardware. ### Frozen screen on a card retry The screen could freeze when a card had to be presented again during payment. This included a case where **Transaction Canceled** appeared after the customer had already canceled on purpose. ### PIN pad registering the wrong key PIN pad buttons sometimes registered a different key than the one pressed. ### Masked entry showing typed digits Masked numeric entry did not hide typed digits on some input screens. ### PIN keypad layout in Hebrew The PIN entry keypad displayed incorrectly on terminals set to Hebrew. ### Wrong screen after canceling a payment Canceling a payment could briefly show the wrong screen before the terminal settled on the correct one. ### Old message reappearing A previous message could flash back onto the screen for a split second. ### Yellow flash between screens A brief yellow flash appeared during screen transitions. FuelApp does not use the standard package other Nayax devices use, so it has no single minimum terminal version. Running 1.10.02 requires the companion apps to be set to the versions below. | Companion app | Version | | :- | :- | | Launcher | 1.0.44 | | TechApp | 1.0.80 | | Update Service | 1.0.0.58 | | VPOS Service | 00\_00\_03\_78 | ## Version history FuelApp 1.10.02 is the first version tracked on this page. ## See also * [Overview](/docs/integrate-pos-device/marshall-pro/getting-started/index) * [Error Codes](/docs/integrate-pos-device/marshall-pro/messaging-protocol/error-codes) * [cardDetect](/docs/integrate-pos-device/marshall-pro/methods/payment/card-detect) * [stopCardDetect](/docs/integrate-pos-device/marshall-pro/methods/payment/stop-card-detect) * [displayScreen](/docs/integrate-pos-device/marshall-pro/methods/display/display-screen) # Best Practices Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/best-practices Optimize your VPOS integration for reliability and user experience. ### Request IDs Every request must have a unique identifier. * **Format**: Alphanumeric with hyphens (e.g., `refuel-12345`). * **Context**: Include business logic in the ID to make logs easier to read. ### Amount handling VPOS uses **minor units** to avoid floating-point errors. * If `decimalPlace` is 2, **\$1.00** is sent as `100`. * If `decimalPlace` is 3, **\$1.00** is sent as `1000`. ### Conventional timeouts The client system should manage timeouts to ensure the terminal doesn't hang indefinitely: | Phase | Suggested Timeout | | :- | :- | | **Card Detection** | 30–60 Seconds | | **User Input** | 60–120 Seconds | | **Authorization** | 10–30 Seconds | ### Error handling * **Logging**: Always store the `errorCode` and `errorMessage`. * **Retries**: Do not retry **DECLINED** transactions. A decline is a final response from the bank; the user must provide a different payment method. # Forecourt Architecture Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/forecourt-architecture The Marshall Pro (Fuel) integrates into a complex ecosystem involving local hardware, forecourt controllers, and multiple backend authorization engines. Forecourt Architecture ### The forecourt (on-site) The forecourt consists of the physical hardware interacting with customers and fuel dispensers. The Nayax terminal where the **Cardholder** initiates the transaction. It communicates via Cellular, Ethernet, or Wi-Fi. To ensure interoperability, the system supports industry-standard protocols: * **Marshall Protocol:** For direct device-to-app communication. * **IFSF / Conexxus:** Standardized communication for international fuel retail environments. The "brain" of the site. It manages the **Dispensers** via a Pump Comms Protocol and links them to the POS and Nayax terminal. The system managing the c-store in the forecourt environment. Local servers managing inventory, pricing, and site configuration. ## Nayax payment server Beyond the physical site, the **Nayax Payment Server** acts as a central hub, using **Amazon SQS** for reliable message queuing to ensure no transaction data is lost. The transactions are routed to different engines depending on the card type or customer profile: * **Fleet Transactions:** Specialized processing for commercial vehicle cards. * **3rd Party Auth Engine:** Connection to external banking or payment processors. * **Loyalty Servers:** Validates rewards, discounts, and member-specific pricing. * **Payment Gateway/Acquirer:** Final settlement for standard consumer credit/debit cards. # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/index The Marshall Pro (Fuel) protocol is a command-based JSON interface designed for clear communication between a Point-of-Sale (POS) or ForeCourt Controller (FCC) and VPOS payment terminals. Built specifically for the fueling and service industries, this protocol allows your system to manage the entire customer journey with precision. It provides a unified way to handle hardware interactions using standard UTF-8 JSON messages over a stable network connection. *Looking for vending machine integration instead? See [Marshall](/docs/integrate-pos-device/marshall/marshall-sdk) for VMC (vending machine controller) integration.* Connect your AI assistant to Nayax documentation for instant answers. **Supported hardware** Marshall Pro (Fuel) currently supports the **VPOS Media-5 (VPOSM5)** terminal only. No other terminal model is supported at this time. ## Key capabilities Identify customers and loyalty participants via card or QR code without requiring immediate authorization. Execute quick, single-phase sales or complex two-phase authorizations tailored for fuel dispensing. Control the terminal screen to display branded messages, custom menus, and collect user-specific data. Access integrated thermal printers directly to generate receipts, vouchers, and session summaries. ### Why Marshall Pro? The protocol simplifies complex forecourt logic into predictable JSON exchanges. Whether you are managing a high-volume gas station or a standalone kiosk, Marshall Pro ensures that your payment and loyalty workflows remain synchronized and secure. # Integration Process Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/marshall-pro-integration-process A step-by-step guide to integrating with Nayax The Nayax integration process ensures a seamless and efficient implementation, providing technical support at every stage. From initial setup to production deployment, Nayax teams work closely with partners or customer developers to meet all technical and operational requirements. ## Stages of the process The integration process is divided into five main stages: 1. Kickoff Meeting 2. Integration Setup 3. Development Phase 4. Testing & Certification 5. Production Setup Each stage is structured to provide technical support and essential resources, ensuring smooth and efficient implementation. ### Kickoff Meeting The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator’s project, the technical teams, and the Nayax Integration Engineer. ### Integration Setup This initial stage establishes the technical foundation for the integration. 1. **Assignment of Integration Engineer:** A Nayax integration engineer is assigned as the primary focal point for the partner or customer developer. 2. **Configuration:** The engineer configures the Nayax Core (backend) and sets up the device with the relevant transaction flow in the integration environment. 3. **Welcome Email:** At the end of this phase, the engineer sends a welcome email with all necessary resources, including the URL, SDK, documentation, tokens, and other required development tools. ### Development Phase This stage focuses on the partner or customer developing their solution. 1. **Partner/Customer Development:** The partner or customer developer creates their solution using the Nayax API/SDK. 2. **Support:** During this phase, the integration engineer provides assistance for any issues or "how-to" queries to ensure progress. **Support for OCPP/OCPI Integrations** For integrations based on **OCPP/OCPI** standards, this step is not relevant, as these integrations follow predefined flows according to the standard protocol. ### Testing & Certification This stage verifies that the integration meets Nayax’s standards: 1. **Certification Test Requirements:** Nayax shares specific requirements for certification tailored to the integration type and transaction flow. 2. **Testing:** The partner or customer developer performs a series of tests (typically 9–15, depending on the integration type and flow). 3. **Review:** The Nayax integration engineer reviews the results of these tests to ensure all criteria are met. 4. **Certification:** Upon successfully completing all tests, Nayax issues a certification letter confirming the integration is ready for deployment. ### Production Setup The final stage ensures a smooth deployment in a live environment: 1. **Production Environment Configuration:** Nayax configures the integration in the production environment, including the machine model setup. 2. **Support for Testing:** The integration engineer provides support during production lab or field tests to confirm successful deployment. The Nayax integration process provides a structured, step-by-step approach that ensures reliable and efficient implementation. By collaborating closely with partners and customers, Nayax delivers high-quality solutions that meet industry standards and support successful deployments in the market. # Marshall Pro Network Requirements Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/network-requirements Ports, domains, and IP ranges to whitelist so Marshall Pro terminals, including VPOS Media-5, can connect to Nayax. Marshall Pro (Fuel) supports the VPOS Media-5 terminal alongside forecourt controllers. Before you deploy any Marshall Pro hardware, your network team must open the following ports, domains, and IP ranges for outbound traffic to Nayax's cloud. ## Network prerequisites A DHCP connection gives Marshall Pro terminals plug-and-play network access, and Nayax recommends it over a static IP assignment. If your network requires a static IP, provide Nayax with the following details before deployment: * IP address * Ethernet gateway address * DNS address * Ethernet subnet mask Static IP configuration requires coordination with Nayax support. DNS resolution is mandatory for all Nayax device communication; blocking DNS prevents the terminal from reaching Nayax entirely. Nayax Android-based devices use Google Public DNS (`8.8.8.8`). This address must be reachable from your network. ## Registered IP ranges As an alternative to whitelisting individual domains, you can whitelist the full Nayax registered IP ranges. The table below lists global ranges that cover all regions, plus narrower per-country ranges for Israel, Germany, and the United States. | Scope | IP range | | :- | :- | | Global range | `185.159.232.0/22` | | Global range | `195.184.224.0/22` | | Israel (IL) | `185.159.232.0/24` | | Germany (DE) | `185.159.234.0/24` | | United States (US) | `185.159.233.0/24` | The Israel, Germany, and United States ranges are subsets of the `185.159.232.0/22` global range. Whitelisting that global range alone already covers all three; you don't need to add the country-specific rows separately unless your firewall policy requires narrower rules. ## Required ports Open the following ports for outbound traffic from the Marshall Pro network. | Port | Protocol | Purpose | | :- | :- | :- | | 443 | TCP | HTTPS for core services, onboarding, and CommerceAPI | | 9000 | TCP | Nayax device communication | | 9005 | TCP | Telemetry | | 5000 | TCP | Nayax device communication | | 26520 | TCP | Boot server connection | | 8883 | TCP | MQTT (AWS IoT) for the PayBridge service | | 53 | UDP/TCP | Google Public DNS (`8.8.8.8`), used by Android OS | ## Required domains Add the following domains to your firewall or proxy's allowlist. Wildcard entries (`*.domain`) cover all subdomains. ### Core domains These domains are mandatory for all Marshall Pro deployments. | Domain | Purpose | | :- | :- | | `*.nayax.com` | Nayax platform services | | `*.nayax.net` | Nayax platform services | | `commerceapib.nayax.com` | Nayax Core CommerceAPI server (port 443) | | `commerceapi.nayax.com` | Nayax Core CommerceAPI server (port 443) | | `mrs.nayax.com` | Nayax device onboarding, ROS (port 443) | | `www.nayax.com` | Internet connectivity check (ICMP / ping) | | `checkip.amazonaws.com` | External IP verification (port 443) | | `geoprimary.nayax.net` | TLV engine, geo-primary gateway (port 9000) | | `broker2.nayax.com` | MQTT broker for real-time messaging and telemetry (port 1883) | | `brokerst1.nayax.com` | MQTT broker, alternate (port 1883) | | `eu-broker5.nayax.com` | MQTT broker, alternate (port 1883) | | `brokerir1.nayax.com` | MQTT broker, alternate (port 1883) | | `hawkbit-vposm-prod.nayax.com` | HawkBit OTA update server for VPOS devices (port 443) | ### DCS access URLs The Nayax Device Control System (DCS) requires the following URLs to be reachable for browsing and use: * `il1.nayax.net` (port 443) * `il2.nayax.net` (port 443) * `backup.nayax.net` (port 443) * `boot.nayax.net` (port 443) ### Third-party service domains These domains support certificate validation, security checks, and cloud storage that Nayax services use: * `s3.amazonaws.com` * `s3.eu-central-1.amazonaws.com` * `seal.verisign.com` * `www.verisign.com` * `extended-validation-ssl.verisign.com` * `trustsealinfo.verisign.com` ## VPOS Media-5 (Castles Technology) VPOS Media-5 uses a separate terminal management system (TMS) from Castles Technology for application deployment, firmware updates, and remote configuration. Deploying VPOS Media-5 on Marshall Pro requires the Castles TMS domains below, in addition to the core requirements above. ### Castles TMS domains The following Castles TMS domains handle application, firmware, and configuration delivery for VPOS Media-5. | Domain | Port(s) | Purpose | | :- | :- | :- | | `ctms-gw.eu.cashub.cloud` | 443, 1883 | TMS gateway for application and firmware updates | | `cstore-gw.eu.cashub.cloud` | 443 | Application store gateway | | `rcg.eu.cashub.cloud` | 443 | Remote configuration | | `file.eu.cashub.cloud` | 443 | File delivery service | | `prod-eu-cashub.s3.eu-west-2.amazonaws.com` | 443 | AWS S3 storage for packages | | `prod-eu-cashub.s3.dualstack.eu-west-2.amazonaws.com` | 443 | AWS S3 dual-stack storage | ### Connectivity checklist Use this checklist to confirm you've whitelisted everything a VPOS Media-5 deployment needs, combining the Castles TMS domains above with the core requirements earlier on this page: * All ports and domains in Required Ports and Required Domains above * All Castles TMS domains above * The HawkBit OTA update server (`hawkbit-vposm-prod.nayax.com`, port 443), which every VPOS device needs * If you're deploying in Israel, also whitelist the Israel-based deployment addresses below If you don't whitelist the Castles TMS domains and the HawkBit OTA server (`hawkbit-vposm-prod.nayax.com`), VPOS Media-5 devices can't receive software updates, security patches, or configuration changes. ## Israel-based deployments This section applies only to deployments in Israel. It lists additional addresses to whitelist for payment processing and local service connectivity. | Service | Domain / URL | IP address | Port | Remarks | | :- | :- | :- | :- | :- | | Shva (EMV) | `emv.shva.co.il` | `193.142.151.159` | 443 | Payment clearing, mandatory | | CommerceAPI (IL) | `il-commerceapib.nayax.com`, `il-commerceapi.nayax.com` | — | 443 | Israel regional CommerceAPI | | Graylog SPI | `log.modularity.co.il` | `34.245.120.119` | 12202 | Device logging service | The Shva EMV address is mandatory for all card-present transactions that go through the Israeli payment network. Without it, card-present transactions fail. ## Remote support (optional) For remote technical support sessions, Nayax may need TeamViewer access. | Domain | Ports | Purpose | | :- | :- | :- | | `*.teamviewer.com` | 5938, 443, 80 | Remote technical support | ## Important notes These notes apply across every Marshall Pro deployment, regardless of device or region: * All connections are outbound from Marshall Pro devices to the Nayax Cloud; no inbound firewall rules are required. * If your network uses a web proxy, add the domains listed above to its bypass list. * IP addresses and domains on this page are subject to change; Nayax notifies customers of any updates. ## See also * [Forecourt Architecture](/docs/integrate-pos-device/marshall-pro/getting-started/forecourt-architecture) * [Integration Process](/docs/integrate-pos-device/marshall-pro/getting-started/marshall-pro-integration-process) # Security & Digital Signatures Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/getting-started/security-digital-signatures Implement RSA SHA-256 signatures for secure data entry. Certain commands, such as `displayInput`, require a digital signature to ensure the integrity of the request. ### Key management The client system is responsible for generating an **RSA SHA-256** private-public key pair. * The **Private Key** must be maintained securely on your server. * The **Public Key** is used by the VPOS to verify the request. ### C# implementation Below is an example of how to sign a message and verify the signature using PKCS#1 padding. ```csharp C# theme={null} static string SignMessage(string message, string privateKeyBase64) { using (RSA rsa = ImportPrivateKey(privateKeyBase64)) { byte[] messageBytes = Encoding.UTF8.GetBytes(message); byte[] signature = rsa.SignData(messageBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); return Convert.ToBase64String(signature); } } static bool VerifySignature(string message, string signatureBase64, string publicKeyBase64) { using (RSA rsa = ImportPublicKey(publicKeyBase64)) { byte[] messageBytes = Encoding.UTF8.GetBytes(message); byte[] signature = Convert.FromBase64String(signatureBase64); return rsa.VerifyData(messageBytes, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } } ``` # Error Codes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/messaging-protocol/error-codes This page provides a reference of error codes. All errors share the same response structure and are returned in the `errorCode` and `errorMessage` fields. ### Protocol errors | Code | Meaning | | :- | :- | | **1001** | Invalid JSON | | **1002** | Unknown command | | **1003** | Required parameter missing | | **1004** | Parameter invalid value | | **1005** | Invalid `displayInput` prompt signature | ### Payment errors | Code | Meaning | | :- | :- | | **2001** | Try another card | | **2002** | Use magnetic reader | | **2003** | Please check your phone | | **2004** | Use contact reader | | **2005** | Card blocked | | **2006** | Present one card only | | **2007** | Transaction canceled | | **2008** | General payment error | | **2009** | Remove card | | **2010** | Remove card beep | | **2011** | Card removed | | **2012** | Use smart card reader | ### General errors | Code | Meaning | | :- | :- | | **3001** | FuelApp error | | **3002** | VPOS service error | ### Error handling best practices To ensure a high-quality integration, follow these guidelines: * **Logging**: Always log both the `errorCode` and the descriptive `errorMessage` to facilitate debugging. * **Retries**: Implement client-side retry logic if the terminal does not respond within the expected window. * **Safety**: Never automatically retry a declined transaction without a direct user action. * **Typical Timeouts**: Use the following time windows for client-side monitoring: * **Card Detection:** 30–60 seconds. * **User Input:** 60–120 seconds. * **Authorization:** 10–30 seconds. **User Feedback** Always provide clear visual feedback on the POS screen during wait times or when an error occurs to keep the customer informed. # Example: Fuel Station Flow Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/messaging-protocol/example-fuel-station-flow A step-by-step guide through a standard fueling transaction. The following sequence illustrates a typical Pay-at-the-Pump workflow, combining payment detection, user interaction, and final settlement. ### Step 1: enable the reader The system starts by activating the terminal to wait for a card or mobile wallet. ```json theme={null} { "command": "cardDetect", "requestId": "fuel-001", "data": { "amount": 50000, "tranType": 1, "channels": ["CTLS", "CHIP", "SWIPE"] } } ``` ### Step 2: confirm payment location Once a card is detected, ask the user if they are paying here or inside. ```json theme={null} { "command": "displayConfirm", "requestId": "fuel-002", "data": { "title": "Choose Payment Method", "yesLabel": "Pay at Pump", "noLabel": "Pay in Store", "yesImage": "payatpump", "noImage": "payinstore" } } ``` ### Step 3: fuel type selection Prompt the user to select their desired fuel grade. ```json theme={null} { "command": "displaySelect", "requestId": "fuel-003", "data": { "title": "Select Fuel Type", "options": [ {"tag": "87", "label": "Unleaded 87"}, {"tag": "89", "label": "Unleaded 89"}, {"tag": "DSL", "label": "Diesel"} ], "showTags": true } } ``` ### Step 4: authorize max amount Call the authorization command to place a hold on the funds based on the initial cardDetect amount. ```json theme={null} { "command": "authorize", "requestId": "fuel-004" } ``` ### Step 5: show fueling screen Update the terminal display to show a looping animation while the pump is active. ```json theme={null} { "command": "displayScreen", "requestId": "fuel-005", "data": { "title": "Fueling...", "mediaId": "fueling", "fitImage": "FULL", "loop": true } } ``` ### Step 6: settle actual amount When the nozzle is holstered, call settle with the final transaction amount. ```json theme={null} { "command": "settle", "requestId": "fuel-006", "data": { "transactionId": "TXN-20260113-004000", "amount": 7850 } } ``` ### Step 7: print receipt Finalize the process by providing a physical or digital record of the transaction. ```json theme={null} { "command": "print", "requestId": "fuel-007", "data": { "printData": "Fuel Receipt\nUnleaded 87\n15.7 gal @ $5.00/gal\nTotal: $78.50" } } ``` # Request and Response Format Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/messaging-protocol/request-response-format The Marshall Pro protocol uses a unified JSON structure for every message. This consistency allows you to build a single "wrapper" in your code to handle all terminal communications. ## Request object Every command sent from your system to the VPOS must follow this structure: | Field | Type | Required | Description | | :- | :- | :- | :- | | command | `string` | Yes | The name of the API method (e.g., `"status"`, `"pay"`). | | requestId | `string` | Yes | A unique ID used to track the response. | | data | `object` | No | A container for the specific parameters of the command. | ### Request example ```json theme={null} { "command": "", "requestId": "", "data": { "param1": "value1", "param2": "value2" } } ``` ## Response object The terminal's response always mirrors your `requestId` so your system knows exactly which command is being answered. ### Success response If the command is processed successfully, the terminal returns the requested information inside the `data` object. ```json theme={null} { "requestId": "", "data": { "status": "success", "details": "..." } } ``` ## Error response If an issue occurs, the response will include an error code and a descriptive message. ```json theme={null} { "requestId": "", "errorCode": 400, "errorMessage": "Invalid command parameters" } ``` # TCP Communication Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/messaging-protocol/tcp-communication ## Connection & protocol The VPOS acts as a **TCP/IP server** on **Port 5050**. Your system (POS/FCC) acts as the client and must initiate the connection. Communication is bidirectional over a persistent socket. **Single-Connection Rule** The terminal supports only one active connection; a new socket attempt will automatically close the previous one. The protocol uses a **Command-Response Pattern**. All client commands must include a `requestId`, which the terminal echoes back in its response to facilitate transaction tracking. ### TCP message format To ensure data integrity, every message sent over the TCP socket (both commands and responses) must use a two-byte length prefix. This tells the receiver exactly how many bytes of JSON data follow in the stream. | Byte | Field | Description | | :- | :- | :- | | 0-1 | Length Prefix | The length of the JSON message in bytes (excluding the prefix itself). | | 2-N | JSON Content | The actual message payload in UTF-8 format. | #### Encoding Example For a JSON command like `{"command":"pay","amount":5000}` (30 bytes total): **Binary Representation:** ```text theme={null} [0x00][0x1E]{"command":"pay","amount":5000} ``` **Big Endian (Network Order)** The length prefix is sent with the Most Significant Byte (MSB) first. ```text theme={null} Calculation: $(MSB \times 256) + LSB = \text{Total Bytes}$ Example: A 300-byte message results in 0x01, 0x2C. 1*256+44 = 300. ``` # API Introduction Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/api The Marshall Pro (Fuel) protocol is a high-performance, command-based interface designed for fuel retail environments. It allows your Point-of-Sale (POS) or Forecourt Controller (FCC) to manage the full lifecycle of a transaction—from card detection to final settlement. Unlike cloud APIs, the Marshall Pro (Fuel) protocol runs locally on your station's network. The VPOS terminal acts as a persistent TCP/IP server waiting for your application to connect. The API is categorized into four functional areas to help you build a complete customer journey: Supports single-phase (`pay`) and two-phase (`authorize` + `settle`) fuel transactions. Read card data without an immediate charge—perfect for Loyalty and Customer ID. Take control of the terminal screen to show custom menus, fuel types, or prompts. Directly trigger the integrated thermal printer for customer receipts. See [Request and Response Format](/docs/integrate-pos-device/marshall-pro/messaging-protocol/request-response-format) for more information. **Socket Management:** The VPOS server maintains a single active session. If your application opens a new socket, the server automatically terminates the previous connection to ensure data integrity. # displayConfirm Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/display/display-confirm Prompt the customer for a simple Yes/No or OK/Cancel confirmation. The `displayConfirm` method presents the customer with a binary choice on the terminal screen. This serves as a streamlined way to handle user consent or simple decision points within the transaction flow. Use this method to: * Ask for agreement on terms, such as "Do you agree to a \$100 pre-authorization hold?" * Confirm physical actions, like "Is the nozzle back in the holster?" * Prompt the user for receipt preferences, such as "Would you like a printed receipt?" * Offer quick prompts for additional services, like "Add a car wash for \$5.00?" Examples of the two-choice option prompts on a Nayax device:
## Requests The request requires a `title` and the text for the specific prompt. You can customize the labels of the two buttons to fit your specific use case. The following example shows a typical request: ```json theme={null} { "command": "displayConfirm", "requestId": "req-010", "data": { "title": "Do You Want A Receipt?", "yesLabel": "Pay at pump", "noLabel": "Pay in store", "yesImage": "payatpump", "noImage": "payinstore" } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"displayConfirm"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **title** | string | Yes | The header text displayed at the top of the confirmation box. | | **message** | string | Yes | The specific question or prompt text shown to the user. | | **confirmLabel** | string | No | The text for the affirmative button (Defaults to "Yes" or "OK"). | | **cancelLabel** | string | No | The text for the negative button (Defaults to "No" or "Cancel"). | This is a **text only** request example: ```json theme={null} { "command": "displayConfirm", "requestId": "req-010", "data": { "title": "Confirm Amount", "yesLabel": "Confirm", "noLabel": "Cancel" } } ``` This is an **image only** request example: ```json theme={null} { "command": "displayConfirm", "requestId": "req-011", "data": { "title": "Choose Payment Method", "yesImage": "payatpump", "noImage": "payinstore" } } ``` This is a **text and image** request example: ```json theme={null} { "command": "displayConfirm", "requestId": "req-012", "data": { "title": "Select Service", "yesLabel": "Pay at Pump", "noLabel": "Pay in Store", "yesImage": "payatpump", "noImage": "payinstore" } } ``` ## Responses The terminal returns the user's choice immediately after a button is pressed. The following example shows a typical response: ```json theme={null} { "requestId": "req-010", "data": { "selectedIndex": 0 } } ``` ### Response parameters The `data` object contains the outcome of the confirmation prompt: | Name | Type | Description | | :- | :- | :- | | **confirmed** | boolean | Returns `true` if the user selected the affirmative button, and `false` otherwise. | | **state** | string | Returns `COMPLETED` upon a button press or `CANCELLED` if the user timed out. | # displayInput Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/display/display-input Request specific alphanumeric input from the customer via the terminal interface. The `displayInput` method allows the client application to prompt the customer for specific information using the terminal's keypad or touchscreen. This serves as an essential tool for workflows that require additional data points beyond standard card details. Use this method to: * Prompt for identification and security details like a PIN, Zip Code, or custom "Employee ID" for fleet cards. * Request operational metadata such as Odometer readings, Unit Numbers, or Hubometer values. * Ask for specific customer inputs like "Enter Pump Number" or "Enter Phone Number" for loyalty programs. Example of the display prompt on a Nayax device: displayInput ## Requests When calling this method, you must define the prompt and its corresponding cryptographic signature. All prompt/signature pairs are managed via the `prompts.json` file on your device. If you require a new or custom prompt, please email your request to the support team, and we will provide the updated file and signature for you. ```json theme={null} { "command": "displayInput", "requestId": "req-008", "data": { "title": "Loyalty", "prompt": "Enter mobile number", "signature": "HvWRJ2...", "inputType": "NUMERIC", "minLength": 6, "maxLength": 10, "mask": false, "skipButton": true, "skipButtonText": "Skip" } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"displayInput"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **title** | string | No | The heading text displayed at the top of the input screen. | | **prompt** | string | Yes | The input question (must match the signed value in `prompts.json`). | | **signature** | string | Yes | The signature provided for the specific prompt. | | **inputType** | string | No | `NUMERIC`, `ALPHANUMERIC`, or `PASSWORD` (masked). | | **minLength** | integer | No | The minimum number of characters required to submit. | | **maxLength** | integer | Yes | The maximum number of characters allowed. | | **mask** | boolean | No | If `true`, hides the user's input (replaces characters with dots/asterisks) for passwords. | | **skipButton** | boolean | No | If `true`, a button is displayed to bypass the input. | | **skipButtonText** | string | No | The label for the skip button (e.g., "Skip"). | ## Responses The terminal returns the data entered by the customer once they press the Enter (→) key on the keyboard. The following example shows a typical response: ```json theme={null} { "requestId": "req-008", "data": { "value": "0501234567" } } ``` The following example shows a canceled/skipped response: ```json theme={null} { "requestId": "req-008", "data": { "key": "SKIP/CANCEL" } } ``` ### Response parameters The `data` object contains the following fields: | Name | Type | Description | | :- | :- | :- | | **value** | string | The actual string entered by the user. | | **key** | string | Indicates the action taken if the input was not completed (e.g., `SKIP/CANCEL`). | # displayScreen Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/display/display-screen Control the terminal's visual interface to display custom messages to the customer. The `displayScreen` method allows the client application (POS/FCC) to take control of the terminal's display. This serves to guide the customer through the fueling process by showing status updates, instructions, or custom alerts that are not part of the standard payment flow. Use this method to: * Direct the customer with workflow instructions like "Please Lift Handle" or "Insert Fuel Nozzle." * Inform the user of system status updates, such as "Pump 4 Authorized" or "Tank Full." * Display localized or custom error messages if a pump-side issue occurs. * Show custom welcome messages or promotional text during idle moments to reinforce branding. Examples of display prompts on a Nayax device:
## Requests All requests must include the `command`, `requestId`, and the specific text content you wish to display. The following example shows a typical request: ```json theme={null} { "command": "displayScreen", "requestId": "req-007", "data": { "title": "Welcome", "line1": "Ready to Process Payment", "line2": "Please select payment method", "textColor": "WHITE", "alignmentHor": "CENTER", "alignmentVer": "TOP", "mediaId": "idle", "fitImage": "FULL", "loop": false } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"displayScreen"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **text** | string | Yes | The message to be displayed on the terminal screen. | | **timeout** | integer | No | Duration (in seconds) the message should remain visible before returning to the default screen. | ## Responses The terminal returns a simple acknowledgement once the screen has been updated with the requested text. The following example shows a typical response: ```json theme={null} { "requestId": "req-007" } ``` ### Response parameters The response confirms that the terminal has processed the visual update: | Name | Type | Description | | :- | :- | :- | | **requestId** | string | Echoes the unique identifier of the original request. | | **status** | string | Returns `SUCCESS` if the message was successfully rendered on the display. | # displaySelect Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/display/display-select Present the customer with a list of options for selection on the terminal screen. The `displaySelect` method allows the client application to present a menu or a list of choices to the customer. This serves as a key component for interactive workflows where the user must make a decision before the transaction can proceed. Use this method to: * Offer product selections between different fuel grades, such as Regular, Mid-grade, or Premium. * Enable language selection to allow the customer to choose their preferred language for the session. * Present service options like adding a car wash or selecting a specific pump number. * Provide loyalty choices, such as asking the user to "Use Points" or "Save for Later." Examples of the menu display prompts on a Nayax device:
## Requests All requests must include a `title` for the menu and an array of `options`. Each option should have a label that the customer will see. The following example shows a typical request: ```json theme={null} { "command": "displaySelect", "requestId": "req-009", "data": { "title": "Please Select Fuel Type", "options": [ {"tag": "87", "label": "Unleaded 87"}, {"tag": "89", "label": "Unleaded 89"}, {"tag": "93", "label": "Unleaded 93"}, {"tag": "DSL", "label": "Diesel"}, {"tag": "BIO", "label": "Bio-diesel"} ], "showTags": true } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"displaySelect"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **title** | string | Yes | The header text displayed above the options list. | | **options** | array | Yes | A list of strings representing the choices available to the user. | | **timeout** | integer | No | Duration (in seconds) before the menu auto-closes if no selection is made. | ## Responses The terminal returns the index or the value of the option selected by the customer. The following example shows a typical response: ```json theme={null} { "requestId": "req-009", "data": { "selectedIndex": 0 } } ``` ### Response parameters The `data` object contains the result of the customer's interaction: | Name | Type | Description | | :- | :- | :- | | **selectedIndex** | integer | The zero-based index of the option chosen from the original list. | | **selectedValue** | string | The text label of the option that was selected. | | **state** | string | Returns `COMPLETED` upon selection or `CANCELLED` if the user exited the menu. | # info Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/general/info Exchange system metadata and retrieve terminal configuration settings. The `info` method exchanges version information and device metadata between the client application (POS/FCC) and the VPOS terminal. This typically serves as the first command sent after establishing a TCP connection to ensure compatibility between both systems. Use this method to: * Exchange vendor, model, and serial number details for system identification. * Synchronize software and hardware versions to ensure protocol feature alignment. * Retrieve critical terminal settings, such as the defined decimal place for transaction amounts. ## Requests All requests must include the `command` and a unique `requestId`. The `data` object should contain the details of the client system making the request. The following example shows a typical request: ```json theme={null} { "command": "info", "requestId": "req-020", "data": { "vendor": "Nayax Fuel", "model": "FCC-3000", "serialNumber": "FCC-12345678", "swVersion": "1.2.3.4", "hwVersion": "4.3.2.1" } } ``` ### Parameter definitions The table below describes the parameters provided by your system in this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **vendor** | string | Yes | The vendor name of the client system (e.g., "Nayax Fuel"). | | **model** | string | Yes | The model identifier of the POS or FCC hardware. | | **serialNumber** | string | Yes | The unique serial number of the client system. | | **swVersion** | string | Yes | The current software version of the client application. | | **hwVersion** | string | Yes | The hardware version of the client device. | ## Responses The VPOS terminal returns its own hardware and software specifications, along with regional settings required for payment processing. The following example shows a typical response: ```json theme={null} { "requestId": "req-020", "data": { "serialNumber": "P129901X251AD", "osVersion": "16.0", "appVersion": "2.3.4.5", "paymentVersion": "0.0.2.68", "decimalPlace": 2 } } ``` ### Response parameters Below are the parameters returned by the VPOS terminal: | Name | Type | Description | | :- | :- | :- | | **serialNumber** | string | The unique serial number of the VPOS terminal. | | **osVersion** | string | The operating system version running on the device. | | **appVersion** | string | The version of the primary terminal application. | | **paymentVersion** | string | The specific version of the payment processing module. | | **decimalPlace** | integer | The number of decimal places to be used for all transaction amounts (e.g., `2` means an amount of `5000` represents `$50.00`). | # status Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/general/status Retrieve the current operational state of the VPOS terminal. The `status` method retrieves the current operational state of the VPOS payment terminal. This endpoint is essential for monitoring hardware readiness before initiating a transaction or checking the progress of a long-running user interaction. Use this method to: * Verify the reader is idle and ready before sending a payment command. * Determine if the terminal is currently waiting for card interaction or processing data. * Identify if the terminal is offline or in a "not ready" state to track hardware health. Example of the display prompt on a Nayax device: displaySelect ## Requests Requests for this endpoint are straightforward and do not require a `data` object. You must only provide the standard `command` and a unique `requestId`. ```json theme={null} { "command": "status", "requestId": "req-021" } ``` ### Parameter definitions The table below describes the common fields required for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"status"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | ## Responses The VPOS terminal returns the current state of the card reader as an integer value. ```json theme={null} { "requestId": "req-021", "data": { "reader": 1 } } ``` ### Reader values The `reader` integer shows the current state code of the payment reader hardware. Use the following table to map its operational meaning: | Value | State | Description | | :- | :- | :- | | **0** | Not Ready (Unusable) | The terminal is offline, disconnected, or initializing. | | **1** | Idle | The terminal is idle and the reader is not detecting cards. | | **2** | Waiting for Card | The reader is active and prompted for a user's payment method. | | **3** | Processing | A transaction or command is currently being executed. | # authorize Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/authorize Initiate a financial pre-authorization on a previously detected payment method. The `authorize` method places a financial hold (pre-authorization) on a previously identified card. This represents the second phase of a two-step transaction, occurring after a successful `cardDetect` call. Use this method to: * Guarantee payment by reserving a maximum dollar amount before the fueling session begins. * Verify card validity and fund availability before the pump is activated. * Capture a final amount that is less than or equal to the initial hold. Example of the authorization prompt on a Nayax device: Authorize ## Requests This command relies on the card data stored in the terminal's session buffer from the preceding detection phase. A `data` object is not required, but optional fields can be included to pass product and user context to the terminal. The following example shows a minimal request: ```json theme={null} { "command": "authorize", "requestId": "req-002" } ``` The following example shows a request with optional data fields: ```json theme={null} { "command": "authorize", "requestId": "req-002", "data": { "products": ["Diesel", "Unleaded", "CNG"], "userData": ["NYX-1234", "932747"] } } ``` ### Parameter definitions The table below describes the fields for the authorization request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"authorize"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **products** | array of strings | No | List of allowed product names (e.g., `["Diesel", "Unleaded"]`). | | **userData** | array of strings | No | Arbitrary user data to associate with the transaction, such as plate number or odometer reading. | ## Responses The terminal returns a response after communicating with the financial gateway. A successful response contains the `transactionId`, which is mandatory for the subsequent settlement. The following example shows a typical response: ```json theme={null} { "requestId": "req-002", "data": { "transactionId": "TXN-20260113-003000", "authorizedAmount": 50000, "state": "AUTHORIZED", "cardBrand": "MASTERCARD", "cardEntryMode": "CHIP", "maskedPan": "************5678", "aid": "A0000000031010" } } ``` ### Response parameters Below are the parameters returned in the `data` object upon a successful authorization: | Name | Type | Description | | :- | :- | :- | | **transactionId** | string | The unique ID for this authorized hold. **Save this value** for the `settle` command. | | **authorizedAmount** | integer | The exact amount approved and held by the bank (refer to `decimalPlace`). | | **state** | string | Returns `AUTHORIZED` upon success. | | **cardBrand** | string | The brand of the card used (e.g., MASTERCARD). | | **cardEntryMode** | string | The method used to read the card (e.g., CHIP). | | **maskedPan** | string | The masked card number for logging and receipt printing. | | **aid** | string | The Application Identifier for the EMV transaction. | # cardDetect Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/card-detect Enable the reader to detect and read payment methods without immediate authorization. The `cardDetect` method activates the terminal's reader to identify and capture data from a payment method (Card or QR) without initiating a financial hold or charge. It serves as a versatile tool for workflows where customer identification must precede the payment phase. Use this method to: * Recognize customers via loyalty cards or mobile QR codes to apply personalized discounts. * Retrieve masked card data to welcome returning users or verify membership status. * Use card data to determine eligible fuel types or promotions before requesting authorization. * Accept Contactless (CTLS), Chip (EMV), Magnetic Stripe (Swipe), and QR code scanning. Example of the card detection prompt on a Nayax device: cardDetect ## Requests All requests must include the `command` and a unique `requestId`. While this method does not authorize funds, an `amount` must be provided for display purposes on the terminal screen. The following example shows a typical request: ```json theme={null} { "command": "cardDetect", "requestId": "req-005", "data": { "amount": 50000, "tranType": 1, "channels": ["CTLS", "CHIP", "SWIPE"] } } ``` ### Parameter definitions The table below describes the parameters available for the detection request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **amount** | integer | Yes | The amount to display on the screen during detection (refer to `decimalPlace`). | | **tranType** | integer | No | `1`: Pre-authorization, `2`: Pre-selection (Default is `1`). | | **channels** | array | No | Defines allowed payment methods: `CTLS`, `CHIP`, `SWIPE`, or `QR`. Defaults to all if omitted. | | **buttonMediaId** | string | No | Optional button displayed below the channels image. Currently supported value: `useQR`. | ## Responses The VPOS terminal returns a response once the user interacts with the reader or a QR code is successfully scanned. The following example shows a typical **credit card** response: ```json theme={null} { "requestId": "req-005", "data": { "state": "CARD_READ", "cardBrand": "VISA", "cardEntryMode": "CTLS", "maskedPan": "************1234", "aid": "A0000000031010" } } ``` The following example shows a typical **QR code** response: ```json theme={null} { "requestId": "req-005", "data": { "state": "CARD_READ", "cardEntryMode": "QR", "qrCode": "1168743871706458" } } ``` The following example shows a **button press** response: ```json theme={null} { "requestId": "req-005", "data": { "state": "BUTTON_PRESS" } } ``` **Note:** When using `cardDetect` for non-credit card methods (such as proprietary QR codes) or when a button is pressed, the client system is responsible for any subsequent authorization or settlement logic. The reader is automatically disabled after a QR code scan or button press. ### Response parameters The response data is categorized by the entry mode used by the customer: | Name | Type | Description | | :- | :- | :- | | **state** | string | `CARD_READ` upon a successful card or QR detection; `BUTTON_PRESS` when the optional button is pressed. | | **cardEntryMode** | string | The method used to capture the data: `CTLS`, `CHIP`, `SWIPE`, or `QR`. Not present for `BUTTON_PRESS`. | | **cardBrand** | string | The brand of the detected card (e.g., VISA, MASTERCARD). | | **maskedPan** | string | The masked Primary Account Number for identification purposes. | | **aid** | string | The Application Identifier for EMV-based transactions. | | **qrCode** | string | The raw data string captured from a scanned QR code. | # detectAndAuth Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/detect-and-auth Detect, read, and pre-authorize funds in a single-phase operation. The `detectAndAuth` method combines card detection and pre-authorization into a single command. It is the primary method used for Pay-at-the-Pump transactions, streamlining the workflow by activating the reader and requesting a financial hold in one step. Use this method to: * Simultaneously activate the reader and prepare the authorization request to reduce total transaction time. * Reserve funds immediately upon card tap, dip, or swipe to allow for instant pump activation. * Minimize the logic required between card detection and authorization by handling both through a unified command. ## Requests All requests must include the `command`, `requestId`, and the `amount` to be held. The terminal will remain in a "Waiting for Card" state until a payment method is presented or a timeout occurs. The following example shows a typical request: ```json theme={null} { "command": "detectAndAuth", "requestId": "req-1-3", "data": { "amount": 50000, "tranType": 1, "channels": ["CTLS", "CHIP", "SWIPE"] } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **amount** | integer | Yes | The amount to hold/pre-authorize in minor units (refer to `decimalPlace`). | | **tranType** | integer | No | `1`: Pre-authorization, `2`: Pre-selection (Default is `1`). | | **channels** | array | No | Defines allowed payment methods: `CTLS` (Contactless), `CHIP` (EMV), `SWIPE` (Magnetic Stripe), or `QR`. Defaults to all if omitted. | ## Responses The terminal returns a response only after the card has been successfully read and the authorization has been processed by the payment gateway. The following example shows a typical **credit card** response: ```json theme={null} { "requestId": "req-1-3", "data": { "transactionId": "TXN-20260113-003000", "authorizedAmount": 50000, "state": "AUTHORIZED", "cardBrand": "MASTERCARD", "cardEntryMode": "CHIP", "maskedPan": "************5678", "aid": "A0000000031010" } } ``` The following example shows a typical **QR code** response: ```json theme={null} { "requestId": "req-005", "data": { "state": "CARD_READ", "cardEntryMode": "QR", "qrCode": "1168743871706458" } } ``` **Note:** If a QR code is used, the client system is responsible for any external authorization and settlement logic. ### Response parameters Below are the parameters returned in the `data` object upon a successful transaction: | Name | Type | Description | | :- | :- | :- | | **transactionId** | string | The unique ID for the authorized transaction. **Save this value** for the `settle` command. | | **authorizedAmount** | integer | The final amount approved and held by the bank. | | **state** | string | Returns `AUTHORIZED` upon success. | | **cardBrand** | string | The brand of the detected card (e.g., MASTERCARD). | | **cardEntryMode** | string | The method used to capture data: `CTLS`, `CHIP`, `SWIPE`, or `QR`. | | **maskedPan** | string | The masked card number for receipt and logging purposes. | | **aid** | string | The Application Identifier for EMV-based transactions. | # pay Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/pay Process an immediate, single-phase payment transaction. The `pay` method initiates an immediate transaction where detection, authorization, and settlement occur in one continuous flow. Unlike the two-phase fuel workflow, this serves fixed-price sales or "Pay-Inside" scenarios where the final amount is known before the card is presented. Use this method to: * Facilitate instant fulfillment for car washes, vacuum stations, or kiosk items where the price remains fixed. * Simplify integration by removing the need for a separate settlement call. * Increase throughput in high-traffic environments where users pay a set fee and move on quickly. ## Requests All requests must include the `command`, `requestId`, and the exact `amount` to be charged. The terminal will activate the reader and wait for the customer to present their payment method. The following example shows a typical request: ```json theme={null} { "command": "pay", "requestId": "req-001", "data": { "channels": ["CTLS", "CHIP", "SWIPE"], "amount": 5000, "volume": 30000, "product": "Diesel" } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **amount** | integer | Yes | The exact amount to be charged (refer to `decimalPlace`). | | **channels** | array | No | Defines allowed payment methods: `CTLS`, `CHIP`, `SWIPE`, or `QR`. Defaults to all if omitted. | ## Responses The terminal returns a response only after the payment has been fully authorized and captured by the gateway. The following example shows a typical response: ```json theme={null} { "requestId": "req-001", "data": { "transactionId": "TXN-20260113-001234", "state": "SETTLED", "amount": 5000, "cardBrand": "VISA", "cardEntryMode": "CTLS", "maskedPan": "************1234", "aid": "A0000000031010", "timeStamp": "2026-01-13T14:30:05Z" } } ``` ### Response parameters Below are the parameters returned in the `data` object upon a successful payment: | Name | Type | Description | | :- | :- | :- | | **transactionId** | string | The unique identifier for the completed transaction. | | **amount** | integer | The final amount that was successfully charged. | | **state** | string | Returns `SETTLED` (or `PAID`) upon success. | | **cardBrand** | string | The brand of the card used (e.g., VISA, MASTERCARD). | | **cardEntryMode** | string | The method used to read the card (e.g., CTLS). | | **maskedPan** | string | The masked card number for receipts. | | **approvalCode** | string | The bank-issued authorization code for the charge. | # Periodic Reconciliation Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/periodic-reconciliation Maintain system integrity by querying and settling open transactions to ensure all fueling sessions are correctly finalized. This guide walks through the periodic reconciliation flow. This maintenance sequence is designed to run at regular intervals to identify any transactions that were not settled during the normal flow (e.g., due to a network timeout or hardware reset), ensuring that revenue is captured and the terminal remains in a healthy state. ## Reconciliation flow Visualize the Periodic Reconciliation process with the diagram below, which illustrates the sequence from disabling the reader to batch-settling open transactions. periodic-reconciliation Below is a breakdown of the sequence: 1. Your system sends the `stopCardDetect` command to the VPOS to prevent new transactions from starting during reconciliation. 2. Your system triggers a `query` command to request a list of all transactions currently pending settlement. 3. For every open transaction returned by the VPOS, your system sends a `settle` command. 4. The VPOS returns an **OK** for each successful settlement. 5. Once reconciliation is complete, your system sends the `cardDetect` command to re-enable the reader for new consumers. # Post-Pay Flow Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/post-pay Process immediate payments for fixed-price services or completed transactions without the need for pre-authorization. This guide walks through the post-pay flow. Unlike pre-authorization sequences, this simplified flow is used when the final transaction amount is known upfront or the service has already been provided, resulting in an immediate "Pay and Go" experience for the consumer. ## Payment flow Visualize the Post-Pay process with the diagram below, which illustrates the direct sequence from reader activation to successful payment and receipt printing. post-pay Below is a breakdown of the sequence: 1. Your system initiates the transaction by sending the `pay` command to the VPOS terminal. 2. The VPOS enables the reader, detects the card, and processes the payment. Upon success, it returns an **OK** response to your system. 3. Your system sends a `displayScreen` command to the VPOS to show the confirmation message: **"Thank you."** 4. If a physical record is needed, your system triggers the `print` command. # query Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/query Retrieve the open (unsettled) transaction. The `query` method allows the client application to poll the terminal for the current status of a specific transaction using its `requestId` or `transactionId`. This serves as a critical safety mechanism for handling network timeouts or application crashes, ensuring the POS and the terminal remain in sync regarding the payment outcome. Use this method to: * Recover transaction states by checking the final outcome if the original response was lost due to a connection drop. * Verify the current status of a transaction—such as pending, authorized, or declined—without re-triggering the payment logic. * Retrieve transaction metadata for local logging, auditing, and reconciliation support. ## Requests To query a transaction, you must provide the identifier associated with the original request. The following example shows a typical request: ```json theme={null} { "command": "query", "requestId": "req-006", "data": { "filter": "AUTHORIZED" } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Field | Type | Required | Description | | :- | :- | :-: | :- | | **command** | `string` | Yes | Always `query` for this request type. | | **requestId** | `string` | Yes | A unique identifier for the request, returned in the response. | | **filter** | `string` | No | Filter by status: `AUTHORIZED`, `ALL`, `SETTLED`, `FAILED`, or `EXPIRED`. | | **transactionId** | `string` | No | Specific ID to query a single transaction. | | **fromDate** | `string` | No | Start range for the query (ISO 8601). | | **toDate** | `string` | No | End range for the query (ISO 8601). | ## Responses The terminal returns the current known state of the transaction. If the transaction is still in progress, the response will reflect its current phase. The following example shows a typical response: ```json theme={null} { "requestId": "req-006", "data": { "transactions": [ { "transactionId": "TXN-20260113-003000", "state": "AUTHORIZED", "amount": 50000, "timeStamp": "2026-01-13T15:00:30Z" } ] } } ``` ### Response parameters The `data` object will contain the most recent information available for that specific request: | Field | Type | Description | | :- | :- | :- | | **requestId** | `string` | Matches the `requestId` sent in the original request. | | **transactions** | `array` | A list of transaction objects matching the query. | | **transactionId** | `string` | The unique identifier for the transaction. | | **state** | `string` | The current status of the transaction (e.g., `AUTHORIZED`, `SETTLED`). | | **amount** | `number` | The authorized amount if `state` is `AUTHORIZED`; otherwise, the settled amount. | | **timeStamp** | `string` | The authorization creation time in Nayax servers (ISO 8601). | # settle Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/settle Finalize a pre-authorized transaction with the actual fueling amount. The `settle` method is the final step in the fuel transaction lifecycle. It "captures" or finalizes a previously authorized transaction once the dispensing process is complete, ensuring the customer is only charged for the exact amount of fuel delivered. Use this method to: * Convert a temporary pre-authorization hold into a final financial charge. * Finalize the transaction with an amount that is typically less than or equal to the original authorized hold. * Complete the transaction sequence to generate final logs and release the session. ## Requests To call this method, you must provide the `transactionId` received during the `authorize` or `detectAndAuth` phase, along with the final `amount`. The following example shows a typical request: ```json theme={null} { "command": "settle", "requestId": "req-003", "data": { "transactionId": "TXN-20260113-003000", "amount": 42000, "volume": 30000, "product": "Diesel" } } ``` ### Parameter definitions The table below describes the required fields for the settlement request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **amount** | integer | Yes | The final actual amount to be charged (refer to `decimalPlace`). | | **transactionId** | string | Yes | The unique identifier returned by the previous authorization response. | *** ## Responses The terminal returns a response confirming that the transaction has been successfully settled and the financial record has been updated. The following example shows a typical response: ```json theme={null} { "requestId": "req-003", "data": { "transactionId": "TXN-20260113-003000", "state": "SETTLED", "settledAmount": 42000, "timeStamp": "2026-01-13T11:00:00Z" } } ``` ### Response parameters Below are the parameters returned in the `data` object upon a successful settlement: | Name | Type | Description | | :- | :- | :- | | **transactionId** | string | The unique identifier of the settled transaction. | | **amount** | integer | The final amount that was captured. | | **state** | string | Returns `SETTLED` (or `COMPLETED`) upon success. | | **approvalCode** | string | The authorization code provided by the banking network. | | **responseMessage** | string | A text description of the settlement result (e.g., "Transaction Approved"). | # stopCardDetect Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/stop-card-detect Deactivate the terminal reader and cancel the card detection phase. The `stopCardDetect` method is a utility command used to manually deactivate the terminal's reader. This serves to maintain control over the user experience when a transaction is abandoned or a different workflow is required. Use this method to: * Terminate the detection phase if a customer cancels the operation at the pump or POS. * Close the reader safely if a locally managed timeout is reached without user interaction. * Clear the reader state to prepare the terminal for a different command or a return to the idle screen. Example of the stop detection screen on a Nayax device: stopCardDetect ## Requests This request is a simple trigger and does not require a `data` object. You must provide the standard `command` and a unique `requestId`. The following example shows a typical request: ```json theme={null} { "command": "stopCardDetect", "requestId": "req-004" } ``` ### Parameter definitions The table below describes the required fields for the stop request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"stopCardDetect"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | ## Responses The terminal acknowledges the command once the reader has been successfully disabled. The following example shows a typical response: ```json theme={null} { "requestId": "req-004" } ``` ### Response parameters The response confirms the termination of the detection session: | Name | Type | Description | | :- | :- | :- | | **requestId** | string | Echoes the unique identifier of the original request. | # Two-Phase Pre-Authorization Flow Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/payment/two-phase-pre-authorization Enable external data collection and manual authorization triggers for fueling sessions. This guide walks through the **Two-Phase Pre-Authorization** fueling flow. This sequence allows for external data collection (such as plate numbers) after the card is detected but *before* the authorization request is sent, providing a more flexible validation process for fueling sessions. ## Payment flow Visualize the 2-phase pre-authorization process in the following diagram, which illustrates the separation between card detection, user input, and the final authorization. pre-auth-flow Below is a breakdown of the sequence: 1. Your system triggers the `cardDetect` command to enable the VPOS reader. 2. Once a card is detected, the VPOS sends a confirmation back to your system. 3. Your system sends a `displayInput` command to the VPOS to prompt the user (e.g., "Enter plate#"). 4. The user enters the data on the VPOS terminal, which is sent back to your system as a "user entry". 5. After receiving the required input, your system sends the `authorize` command to the VPOS. 6. The VPOS confirms the card is authorized with an **OK** response. 7. Your system sends a `displayScreen` command to show "Start refuel" to the consumer. 8. The fueling session takes place (**Start refuel → End refuel**). 9. Your system sends the `settle` command to the VPOS to capture the final transaction amount. 10. Your system displays a "Thank you" message and optionally triggers the `print` command for a receipt. # print Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall-pro/methods/utility/print Trigger the integrated thermal printer to generate custom receipts or documents. The `print` method provides direct access to the VPOS terminal's integrated thermal printer. This allows the client application to generate physical records for the customer, such as transaction receipts, loyalty vouchers, or fueling summaries. Use this method to: * Print finalized sale details, including merchant info, masked card data, and totals for transaction receipts. * Generate a physical record of the volume, grade, and price per unit after the nozzle is holstered. * Provide customers with discount codes or reward vouchers based on their current purchase. * Print diagnostic or status reports directly at the station for maintenance logs. ## Requests The request includes the raw text content or structured data you wish to print. You can use standard escape characters for basic formatting like new lines. The following example shows a typical request: ```json theme={null} { "command": "print", "requestId": "req-012", "data": { "printData": "Transaction Receipt\n-------------------\nAmount: $20.00\nDate: 2026-01- 13\nApproved" } } ``` ### Parameter definitions The table below describes the parameters available for this request: | Name | Type | Required | Description | | :- | :- | :- | :- | | **command** | string | Yes | Set to `"print"`. | | **requestId** | string | Yes | A unique identifier for tracking the response. | | **content** | string | Yes | The text data to be printed. Use `\n` for line breaks. | | **cutPaper** | boolean | No | If `true`, the printer will perform a full cut after the content is printed (if hardware supports it). | ## Responses The terminal returns an acknowledgment once the print job has been successfully queued or completed by the hardware. The following example shows a typical response: ```json theme={null} { "requestId": "req-012", "data": { "printed": true, "characterCount": 71 } } ``` ### Response parameters The response confirms the status of the peripheral action: | Name | Type | Description | | :- | :- | :- | | **requestId** | string | Echoes the unique identifier of the original request. | | **status** | string | Returns `SUCCESS` if the print job was accepted, or `ERROR` if the printer is out of paper or disconnected. | # Capabilities Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/additional-resources/capabilities The information regarding the SDK's flags is being sent within the FirmwareInfo() function during the pairing process. Each of those bits turn on/off another function as following:
Bit Description
`0-5` Irrelevant for Marshall
`6` **Multi session.** Peripheral works in Multi sessions mode.
`7` **Peripheral will approve Contactless proprietary cards.** Peripheral is connected to its server and authorizes its proprietary Contactless prepaid cards. NOTE: Once this bit is set, system will support 3rd party proprietary cards ONLY! i.e. there is no possibility to accept other proprietary cards.
`8` **Vend request price is not final.** Combined with Multi session support bit, enables a Pre-Authorization-like transaction flow.
`9` **Peripheral will approve Magnetic stripe proprietary cards.** Peripheral is connected to its server and authorizes its proprietary Magstripe prepaid cards. NOTE: Once this bit is set, system will support 3rd party proprietary cards ONLY! i.e. there is no possibility to accept other proprietary cards.
`10` **Expanded Currency** Support 4 Bytes Price (Range: 0 - 4,294,967,295). NOTE: This capability is available for VPOS Media family ONLY!
`11` **Peripheral will approve QR code proprietary cards.** Peripheral is connected to its server and authorizes its proprietary QR code cards. NOTE: Once this bit is set, system will support 3rd party proprietary cards ONLY! i.e. there is no possibility to accept other proprietary cards.
For example, if you're working with Multisession+ Price not final, the capabilities value would be: 0b0101000000=320 in decimal, and it would show the same in Nayax Core: # Display Control (Screen Display) Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/additional-resources/marshall-display Display Control is a Preselection feature that allows a transaction process to begin by selecting a product on the Nayax device, with the consumer selecting the desired product by touching the relevant screen on the device. The configuration of said screens can be done in 2 ways: The first, more common one, is done via the "Display Control" command to the device, which can be sent from the peripheral at any point of the device being in idle- meaning once "onReady()" has been triggered: ```c C theme={null} "vmc_vend_event_on_ready" event in vmc_vend_event_handler_cb ``` ```csharp C# theme={null} onReady(config); ``` ```java Java theme={null} onReady(config); ``` This event means that: • The VPOST/VPOSM device is fully initialized • Communication is established and stable • The system is ready to accept Display Control commands **Implementation Example:** For the C SDK, you can see this pattern in the provided example code in mymain\_always\_idle.c: ```c C theme={null} static __bool vmc_vend_event_handler_cb(int event_id, void *data) { switch (event_id) { case vmc_vend_event_on_ready: // This is the correct place to send display control handler_display_control(&display); break; // ... other cases } return result; } ``` ```csharp C# theme={null} public override void onReady(vmc_vend_t.vend_session_t session) { // vmc is ready for new session logger.d(TAG, "ready for new session"); // This is the correct place to send display control } ``` **Important Notes - C SDK** **Required Configuration Change** Please also make this important configuration update in your project: File: makefile.include Change: Set MARSHALL\_MSG\_ARRAY\_SIZE to 4 MARSHALL\_MSG\_ARRAY\_SIZE = 4 This ensures sufficient message buffer allocation for display control operations. • Do not modify any files in vpos (such as vmc\_vend.c, vmc\_link.c) • Using vmc\_vend\_event\_on\_ready ensures proper timing without arbitrary delays The second is via sending a command via Nayax Core (Nayax's backoffice)- more on that below. **Note:** * The device’s limitation is up to 12 objects per Layout. * Use %c in the beginning of the label value to show a clock icon. Once either configuration has been sent, it will remain on the device (no need to resend it after every transaction; only after the pairing process). ## Display control related commands ### Updating the screens As can be seen in the PowerPoint above, once the Display Control command has been sent, the device would respond with a Display Status command, letting it know whether or not the device received said command and its validity. ### Starting a transaction Once a consumer has selected a product (screen) on the device, the device would respond with information the peripheral regarding which screen was selected, to which it should respond with a "Vend Request" with the relevant product code and price in order for the transaction process to begin. ## Possible layouts- VPOST only (except for layouts 7,8 which are also relevant for media) ### Layouts relevant for VPOSM only: ## Layout examples ### Layout ID 1 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(1); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 2x3"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text 1"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "Text 2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 2, "%cText 3"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text 1"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "Text 2"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 2, "%cText 3"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(1); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 2x3"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "Text 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 2, "%cText 3"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "Text 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 2, "%cText 3"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 2x3"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 2; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text1"); lbl->object_id = index; lbl->label_num_in_layout = 0; label_t *lbl = &labels[index]; sprintf(lbl->label, "Text2"); lbl->object_id = index; lbl->label_num_in_layout = 1; label_t *lbl = &labels[index]; sprintf(lbl->label, "%cText3"); lbl->object_id = index; lbl->label_num_in_layout = 2; } layout.layout_id = 1; // 2x3 layout.labels_num = 7; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 2 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(2); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 2x2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text 2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "%cText 3"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text 2"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "%cText 3"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(2); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 2x2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "%cText 3"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "%cText 3"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 2x2"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 2; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text2"); lbl->object_id = index; lbl->label_num_in_layout = 0; label_t *lbl = &labels[index]; sprintf(lbl->label, "%cText3"); lbl->object_id = index; lbl->label_num_in_layout = 1; } layout.layout_id = 2; // 2x2 layout.labels_num = 5; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 3 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(3); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 4x1"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text 1"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text 2"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "Text 3"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "Text 4"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(3); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 4x1"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "Text 3"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "Text 4"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 4x1"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 4; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text%d", index); lbl->object_id = index; lbl->label_num_in_layout = 0; } layout.layout_id = 3; // 4x1 layout.labels_num = 5; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 4 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(4); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 4x2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "%cText"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "%cText"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "Text"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 1, "%cText"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "Text"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 1, "%cText"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(4); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 4x2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "%cText"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "%cText"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "Text"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 1, "%cText"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "Text"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 1, "%cText"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 4x2"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 4; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text"); lbl->object_id = index; lbl->label_num_in_layout = 0; label_t *lbl = &labels[index]; sprintf(lbl->label, "%cText"); lbl->object_id = index; lbl->label_num_in_layout = 1; } layout.layout_id = 4; // 4x2 layout.labels_num = 9; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 5 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(5); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 6x1"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "13"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "14"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "15"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "16"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 0, "17"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 0, "18"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(5); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 4x2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "13"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "14"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "15"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "16"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 0, "17"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 0, "18"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 6x1"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 6; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "%d", index); lbl->object_id = index; lbl->label_num_in_layout = 0; } layout.layout_id = 5; // 6x1 layout.labels_num = 7; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 6 ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(6); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 6x2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "13"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "5"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "14"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "5"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "15"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 1, "5"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "16"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 1, "5"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 0, "17"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 1, "5"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 0, "18"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 1, "5"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(6); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout 6x2"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "13"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "5"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "14"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "5"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "15"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 1, "5"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "16"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 1, "5"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 0, "17"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 1, "5"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 0, "18"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 1, "5"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout 6x2"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 6; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "%d", index); lbl->object_id = index; lbl->label_num_in_layout = 0; label_t *lbl = &labels[index]; sprintf(lbl->label, "5"); lbl->object_id = index; lbl->label_num_in_layout = 1; } layout.layout_id = 6; // 6x2 layout.labels_num = 13; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 7 \*\*Note: \*\*You can have up to 6 values: values 4-6 would appear once you scroll down. ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(7); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout H Scroll 1"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text value 1"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text value 2"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "Text value 3"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "Text value 4"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 0, "Text value 5"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 0, "Text value 6"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(7); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout H Scroll 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text value 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text value 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "Text value 3"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "Text value 4"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 0, "Text value 5"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 0, "Text value 6"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout H Scroll 1"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 6; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text value %d", index); lbl->object_id = index; lbl->label_num_in_layout = 0; } layout.layout_id = 7; // Layout H Scroll 1 layout.labels_num = 7; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 8 \*\*Note: \*\*You can have up to 6 values: values 4-6 would appear once you scroll down. ```java Java theme={null} // allocate layout marshall_t.msg_display_control_t.layout_t ui_context = m_vmc.general.display_control_create_layout(8); // add label m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Layout H Scroll 2"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Text value 1"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "10"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Text value 2"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "20"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 0, "Text value 3"); m_vmc.general.display_control_layout_add_label(ui_context, 3, 1, "30"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 0, "Text value 4"); m_vmc.general.display_control_layout_add_label(ui_context, 4, 1, "40"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 0, "Text value 5"); m_vmc.general.display_control_layout_add_label(ui_context, 5, 1, "50"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 0, "Text value 6"); m_vmc.general.display_control_layout_add_label(ui_context, 6, 1, "60"); // apply layout on screen m_vmc.general.display_control_apply_layout(ui_context); ``` ```csharp C# theme={null} // allocate layout Object ui_context = vmc_instance.general.display_control_create_layout(8); // add label vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Layout H Scroll 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Text value 1"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "10"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "Text value 2"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "20"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 0, "Text value 3"); vmc_instance.general.display_control_layout_add_label(ui_context, 3, 1, "30"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 0, "Text value 4"); vmc_instance.general.display_control_layout_add_label(ui_context, 4, 1, "40"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 0, "Text value 5"); vmc_instance.general.display_control_layout_add_label(ui_context, 5, 1, "50"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 0, "Text value 6"); vmc_instance.general.display_control_layout_add_label(ui_context, 6, 1, "60"); // apply layout on screen vmc_instance.general.display_control_apply_layout(ui_context); ``` ```c C theme={null} static void handler_display_control(void *aux_data) { display_t display; layout_t layout; label_t labels[30]; int index = 0; __strcpy(labels[index].label, "Layout H Scroll 1"); labels[index].object_id = index; labels[index].label_num_in_layout = index; index++; for (; index < 6; index++) { label_t *lbl = &labels[index]; sprintf(lbl->label, "Text value %d", index); lbl->object_id = index; lbl->label_num_in_layout = 0; label_t *lbl = &labels[index]; label_price= index*10; sprintf(lbl->label, "%d", label_price); lbl->object_id = index; lbl->label_num_in_layout = 1; } layout.layout_id = 8; // Layout H Scroll 2 layout.labels_num = 13; layout.buttons_num = 0; vmc_general_apply_display_control(&display); } ``` ### Layout ID 9- VPOSM only! ```java Java theme={null} m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Do You Want A Receipt?"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 0, "Yes"); m_vmc.general.display_control_layout_add_label(ui_context, 1, 1, "@shapes/positive"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "No"); m_vmc.general.display_control_layout_add_label(ui_context, 2, 1, "@shapes/square"); ``` ```csharp C# theme={null} vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Do You Want A Receipt?"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 0, "Yes"); vmc_instance.general.display_control_layout_add_label(ui_context, 1, 1, "@shapes/positive"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 0, "No"); vmc_instance.general.display_control_layout_add_label(ui_context, 2, 1, "@shapes/square"); ``` ```c C theme={null} WIP ``` One or two big buttons will appear in the middle. The first is in yellow and text in black, and the other (if it exists) is in black with text in white. ### Layout ID 10- VPOSM only ```java Java theme={null} m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Ready To refuel"); // add label m_vmc.general.display_control_layout_add_media(ui_context, 1, "@assets/x_red.png"); ``` ```csharp C# theme={null} vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Ready To refuel"); // add label vmc_instance.general.display_control_layout_add_media(ui_context, 1, "@assets/x_red.png"); ``` ```c C theme={null} WIP ``` Including title (optional, can be Null), and the element to be presented (Image/Animation). ### Layout ID 11- VPOSM only ```java Java theme={null} m_vmc.general.display_control_layout_add_label(ui_context, 0, 0, "Loyalty"); m_vmc.general.display_control_layout_add_input(ui_context, 1, 1, 15, "Phone Number"); //for the optional button: m_vmc.general.display_control_layout_add_label(ui_context, 2, 0, "Optional Button"); ``` ```csharp C# theme={null} vmc_instance.general.display_control_layout_add_label(ui_context, 0, 0, "Loyalty"); vmc_instance.general.display_control_layout_add_input(ui_context, 1, 1, 15, "Phone Number"); //for the optional button: vmc_instance.display_control_layout_add_label(ui_context, 2, 0, "Optional Button"); ``` ```c C theme={null} WIP ``` Including: Title, Subtitle, and Input Field ## Nayax Core configurations **Important:** This feature is supported only in **“Always Idle”** mode. This means that you need to have "Always Idle" configuration set up *both on the device level (via Nayax Core) as well as have it be set to "true" on the peripheral level (via the SDK)* You can see the flag's location in the [SDK Flags](/docs/integrate-pos-device/marshall/get-started/sdk-flags-descriptions#/)page, under "Configurations flags". | Attribute Group | Attribute Name | Attribute Value | | :- | :- | :- | | **MDB** | Cashless MDB address | Marshall VMC | | | MDB flags | 02 Preselection Enabled | | | MDB Level 3 Optional Features | Enable “Always Idle” state | | **Card Readers** | Card Reader MDB Level | 3 | | | Transaction start method | Product | | | Transaction Start Ignore List | Ignore None | | | VPOS Read Source Enabled | All Read Sources Enabled (Default) | | | VPOS Button Function | 01 External cancel | | **Payment** | Choose Product Timeout | > 0 | | | Default Credit | > 0 (highest product's amount) | | | EMV Price Table | C%100 | | | Payment Flags | Allow Pre-Selection on Pre-Paid cards | | **VMC** | Session Time Out (minutes) | > 0 | ## Updating the screens via Nayax Core A Nayax Core attribute has been introduced that allows operators to dynamically update text, prices, and configurations on selection screens- the screens that appear when the device is in idle mode, waiting for a consumer to select a product by selecting (touching) one of said screens. This attribute enables sending structured data from Nayax Core to the peripheral. This information is then processed and displayed on the Marshall selection screen. The attribute definition is as follows: | Attribute | Value | | - | - | | **ID** | 7700 | | **Name** | Marshall Screens Info | | **Group** | VMC | | **Maximum Length** | 400 characters | This sends a JSON-formatted string containing details about selection screens, including layout configurations, text labels, prices, and timing. ## JSON logic recommendation The JSON string should include necessary instructions for each selection screen. The format is flexible, allowing operators to specify only the required parameters. See the structure in the code block below: ```json theme={null} { "Screen Name 1": { "layout_id": , "content": { "layout_title": "", "text_1": "<text>", "text_2": "<text>", "text_3": "<text>", "text_4": "<text>" }, "prices": { "price_1": "<price>", "price_2": "<price>" }, "timing": { "time_1": "<time>", "time_2": "<time>" }, "buttons": "<comma-separated list of button IDs>" }, "Screen Name 2": { "layout_id": <ID>, "content": { ... }, "prices": { ... } } } ``` <Warning> **Validate the JSON** **The JSON validity and defined prices are solely the operator's responsibility.** It is highly recommended to validate the JSON using a JSON validator before sending it to a remote machine since incorrectly formatted JSON may cause display errors or unexpected behavior. </Warning> ## Example See the JSON below. It is sending the instructions to update the display of an Air Vac machine. ```json theme={null} { "Select product from 2 options": { "layout_id": 2, "content": { "layout_title": "Select Air/Vac", "text_1": "Air", "text_2": "$2", "text_3": "%c 5 min", "text_4": "Vac", "text_5": "$3", "text_6": "%c 10 min" }, "prices": { "price_1": "2", "price_2": "3" }, "buttons": "104" } } ``` The packet built from this JSON is the following: ``` Packet = 0x01 0x02 0x0100 0x02 0x0C 0x00 0x00 “Select Air/Vac” 0x02 0x08 0x01 0x00 “Air” 0x02 0x08 0x01 0x01 “$2” 0x02 0x08 0x01 0x02 “%c 5 min” 0x02 0x08 0x02 0x00 “Vac” 0x02 0x08 0x02 0x01 “$3” 0x02 0x08 0x02 0x02 “%c 10 min” 0x03 0x01 0x68 ``` <Note> **Packet Creation** Packets are created automatically by the SDK or Nayax Core. </Note> The image below would be the display result. <Frame> <img alt="" /> </Frame> # Transfer Data Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/additional-resources/marshall-ontransferdata onTransferData is the function for the "Transfer Data" Marshall command, which allows for information regarding the transaction to be sent both ways- usually from the device's (VPOS Touch / VPOS Media) end to the peripheral, but can also be sent from the peripheral to the device. In the `void onTransferData(byte[] data)` function the data follows the TLV (Tag-Length-Value) format, which consists of: * Tag (1 byte): Identifies the type of data. * Length (1 byte): Specifies the length of the value. * Value (N bytes): Contains the actual data. The transferred data can be one or more TLV structures, depending on the information being exchanged. ## Example If `onTransferData(byte\[] data)` receives the following bytes: ```text theme={null} 5 6 345678 ``` * 5 is the tag for Card BIN * 6 is the Length, in this case, 6 bytes * 345678 is the value of the First 6 digits of the card number. The system extracts the Card BIN as "345678". ## Tag descriptions The table below describes different types of data that can be transferred using this function: <table> <thead> <tr> <th> **Tag** </th> <th> **Tag Name** </th> <th> **Data Size** </th> <th> **Description** </th> </tr> </thead> <tbody> <tr> <td> `1` </td> <td> Transaction ID </td> <td> 8 bytes </td> <td> Unique identifier for the transaction. </td> </tr> <tr> <td> `2` </td> <td> "Choose Product" Timeout </td> <td> 2 bytes </td> <td> Timeout for the "Choose Product" prompt. </td> </tr> <tr> <td> `3` </td> <td> Card Type </td> <td> 1 byte </td> <td> Identifies the type of card used. More on that below. </td> </tr> <tr> <td> `4` </td> <td> Card Entry Mode </td> <td> 1 byte </td> <td> Identifies how the card was entered (swiped, tapped, inserted, etc.). More on that below. </td> </tr> <tr> <td> `5` </td> <td> Card BIN </td> <td> 6 bytes </td> <td> First 6 digits of the card number (ASCII). </td> </tr> <tr> <td> `6` </td> <td> Card PAN Hash </td> <td> 20 bytes </td> <td> SHA1 hash of the whole card PAN (to protect card data). </td> </tr> <tr> <td> `7` </td> <td> Proprietary Card UID </td> <td> MiFare- 4, 7, or 10 bytes Magstripe- up to 40 bytes QR- up to 255 bytes </td> <td> Unique identifier for proprietary cards. QR- numeric values only </td> </tr> <tr> <td> `8` </td> <td> VMC Authorization Status </td> <td> 1 byte </td> <td> Authorization result (0 = Approved, 1 = Declined). </td> </tr> <tr> <td> `9` </td> <td> COM Status </td> <td> 1 byte </td> <td> Communication status between the server and the device. </td> </tr> <tr> <td> `10` </td> <td> FTL Data </td> <td> Up to 500 bytes </td> <td> Raw data transferred at a lower level (MDB Level 3). </td> </tr> <tr> <td> `11` </td> <td> Create Layout </td> <td> 4 bytes </td> <td> Layout creation request. </td> </tr> <tr> <td> `12` </td> <td> Update Layout </td> <td> Up to 500 bytes </td> <td> Updates an existing layout using the ExtraData field. </td> </tr> <tr> <td> `13` </td> <td> Credit Card Last Four Digits </td> <td> 4 bytes (ASCII) </td> <td> Last four digits of the credit card (in ASCII). </td> </tr> <tr> <td> `14` </td> <td> Product Code </td> <td> 2 bytes </td> <td> Code identifying the purchased product. </td> </tr> <tr> <td> `15` </td> <td> Product Price </td> <td> 4 bytes </td> <td> Price of the product. </td> </tr> <tr> <td> `16` </td> <td> Customized Data / General Purpose </td> <td> Up to 500 bytes </td> <td> JSON-formatted custom data (specific details TBD). </td> </tr> <tr> <td> `17` </td> <td> Consumer ID </td> <td> Up to 500 bytes </td> <td> Unique consumer identifier (e.g., Passport, ID Number). ASCII string. </td> </tr> <tr> <td> `18` </td> <td> Main Software Version </td> <td> 14 bytes </td> <td> Version of the device's Main software running on the device. </td> </tr> <tr> <td> `19` </td> <td> POS Software Version </td> <td> 10 bytes </td> <td> Version of the device's POS software running on the device. </td> </tr> <tr> <td> `20` </td> <td> Default Credit </td> <td> 2 bytes </td> <td> Predefined credit amount as set in Nayax Core. </td> </tr> <tr> <td> `21` </td> <td> Monyx ID </td> <td> 9 bytes </td> <td> ID related to Monyx payment system as defined in Nayax Core. </td> </tr> <tr> <td> `22` </td> <td> Final Price </td> <td> 4 bytes </td> <td> Final transaction price after discounts. </td> </tr> <tr> <td> `23` </td> <td> Card Sub-Type </td> <td> 1 byte </td> <td> More detailed classification of the card type. More on that below. </td> </tr> <tr> <td> `24` </td> <td> Card Balance </td> <td> 4 bytes </td> <td> The remaining balance on the proprietary card. </td> </tr> <tr> <td> `25` </td> <td> Transfer to BLE </td> <td> N bytes </td> <td> Data to be transmitted over Bluetooth/BLE. Related to Nayax EV (internal Nayax request) </td> </tr> <tr> <td> `26` </td> <td> Select Brand </td> <td> 8 bytes </td> <td> *Relevant only for the Japanese market!* Peripheral->Device: Select the brand to pay, instead of having the brand selection screen before that. Device > Peripheral: After the pairing process, update the peripheral in the 64-bit bitfield of configured brands. </td> </tr> <tr> <td> `27` </td> <td> Proprietary Card Name </td> <td> N (up to 500) bytes </td> <td> Proprietary card Description, arrived from tag 239 from Nayax's server </td> </tr> <tr> <td> `28` </td> <td> Site ID </td> <td> 1 Byte </td> <td> Site ID information from Nayax's servers that arrives in the authorization response </td> </tr> </tbody> </table> Transfer Data format by card types: <table> <thead> <tr> <th> **Credit Card** </th> <th> **Proprietary Card** </th> </tr> </thead> <tbody> <tr> <td> Tag 3: Card Type (value in range "2"-"6") <br /> Tag 4: Entry Mode <br /> Tag 5: Card BIN <br /> Tag 6: Card PAN Hash <br /> Tag 13: Credit card last four digits <br /> Tag 1: Transaction ID <br /> Tag 9: COM Status </td> <td> Tag 3: Card Type (value of "1") <br /> Tag 4: Entry Mode (value of"1" if Magstripe, "4" if MiFare, "5" if HID, "10" if QR) <br /> Tag 7: Proprietary Card UID <br /> Tag 1: Transaction ID <br /> Tag 9: COM Status </td> </tr> </tbody> </table> Card Type: ``` typedef enum E_MarshallApi_TDCardType_tag { MARSHALLAPI_TRANSFER_DATA_UNKOWN_CARD_TYPE = 0, /* Unknown */ MARSHALLAPI_TRANSFER_DATA_PROPRIETARY_CARD_TYPE, /* Proprietary */ MARSHALLAPI_TRANSFER_DATA_VISA_CARD_TYPE, /* Visa */ MARSHALLAPI_TRANSFER_DATA_MASTER_CARD_CARD_TYPE, /* Master Card */ MARSHALLAPI_TRANSFER_DATA_CHINA_UNION_PAY_CARD_TYPE, /* China Union Pay */ MARSHALLAPI_TRANSFER_DATA_MAESTRO_CARD_TYPE = 5, /* Maestro */ MARSHALLAPI_TRANSFER_DATA_INTERAC_CARD_TYPE, /* Interac */ MARSHALLAPI_TRANSFER_DATA_MONYX_CARD_TYPE, /* Monyx */ MARSHALLAPI_TRANSFER_DATA_AMEX_CARD_TYPE, /* American Express */ MARSHALLAPI_TRANSFER_DATA_DINERS_CARD_TYPE, /* Diners */ MARSHALLAPI_TRANSFER_DATA_DISCOVER_CARD_TYPE = 10, /* Discover */ MARSHALLAPI_TRANSFER_DATA_EFTPOS_CARD_TYPE, /* EFTPOS */ MARSHALLAPI_TRANSFER_DATA_JCB_CARD_TYPE, /* JCB */ MARSHALLAPI_TRANSFER_DATA_MAGSTRIPE_CARD_TYPE, /* swiped payment */ MARSHALLAPI_TRANSFER_DATA_MONYX_APP_PREPAID_CARD_TYPE, /* Monyx App Prepaid */ MARSHALLAPI_TRANSFER_DATA_MONYX_APP_BALANCE_CARD_TYPE = 15, /* Monyx App Balance */ MARSHALLAPI_TRANSFER_DATA_EMONEY_CARD_TYPE, /* E-money */ MARSHALLAPI_TRANSFER_DATA_PURE_CARD_TYPE, /* Pure */ MARSHALLAPI_TRANSFER_DATA_CARD_TYPE_MAX, }E_MarshallApi_TDCardType; ``` Card Entry Mode: ``` typedef enum E_MarshallApi_TDCardEntryType_tag { MARSHALLAPI_TRANSFER_DATA_MSR_SWIPE_CARD_ENTRY_TYPE = 1, /* Mag stripes */ MARSHALLAPI_TRANSFER_DATA_CONTACTLESS_CARD_ENTRY_TYPE, /* Contactless */ MARSHALLAPI_TRANSFER_DATA_CONTACT_CARD_ENTRY_TYPE, /* Contact */ MARSHALLAPI_TRANSFER_DATA_MIFARE_CARD_ENTRY_TYPE, /* MiFare */ MARSHALLAPI_TRANSFER_DATA_HID_CARD_ENTRY_TYPE, /* HID */ MARSHALLAPI_TRANSFER_DATA_NFC_CARD_ENTRY_TYPE, /* NFC */ MARSHALLAPI_TRANSFER_DATA_CNOUS_CARD_ENTRY_TYPE, /* CNOUS */ MARSHALLAPI_TRANSFER_DATA_KEYPAD_ENTRY_TYPE, /* Keypad */ MARSHALLAPI_TRANSFER_DATA_MOBILE_ENTRY_TYPE, /* Mobile */ MARSHALLAPI_TRANSFER_DATA_QR_ENTRY_TYPE, /* QR */ MARSHALLAPI_TRANSFER_DATA_BLE_ENTRY_TYPE, /* BLE */ MARSHALLAPI_TRANSFER_DATA_LEGIC_CARD_ENTRY_TYPE, /* LEGIC */ MARSHALLAPI_TRANSFER_DATA_CARD_ENTRY_TYPE_MAX, }E_MarshallApi_TDCardEntryType; ``` Card Subtype: ``` typedef enum E_MarshallApi_TDSelectCardBrand_tag { MARSHALLAPI_BRAND_EMPTY = 0x0000000000000000, /* Unknown/Empty brand Sub-Type card */ /* 1st 2nd bytes: Japanese e-money brands */ MARSHALLAPI_BRAND_EMONEY_EDY = 0x0000000000000001, /* Proprietary Japanese e-money */ MARSHALLAPI_BRAND_EMONEY_WAON = 0x0000000000000002, /* Proprietary Japanese e-money */ MARSHALLAPI_BRAND_EMONEY_TRANSPORT_IC = 0x0000000000000004, /* Proprietary Japanese Transportation e-money - see below */ MARSHALLAPI_BRAND_EMONEY_ID = 0x0000000000000008, /* Proprietary Japanese e-money */ MARSHALLAPI_BRAND_EMONEY_QUICPAY = 0x0000000000000010, /* Proprietary Japanese e-money */ MARSHALLAPI_BRAND_EMONEY_NANACO = 0x0000000000000020, /* Proprietary Japanese e-money */ MARSHALLAPI_BRAND_EMONEY_PITAPA = 0x0000000000000040, /* Proprietary Japanese e-money */ /* 3rd 4th bytes: Credit card brands */ MARSHALLAPI_BRAND_EMV_VISA = 0x0000000000000100, /* Visa */ MARSHALLAPI_BRAND_EMV_MASTERCARD = 0x0000000000000200, /* Mastercard*/ MARSHALLAPI_BRAND_EMV_AMEX = 0x0000000000000400, /* American express */ MARSHALLAPI_BRAND_EMV_JCB = 0x0000000000000800, /* JCB */ MARSHALLAPI_BRAND_EMV_GENERAL = 0x0000000000001000, /* Generic credit card (VEND_PAY_METHOD_CREDIT_CARD)*/ MARSHALLAPI_BRAND_EMV_DISCOVER = 0x0000000000002000, /* Discover*/ MARSHALLAPI_BRAND_EMV_DINERS = 0x0000000000004000, /* Diners*/ MARSHALLAPI_BRAND_EMV_VISA_MASTER = 0x0000000000008000, /* VisaMaster combined brand*/ /* 5th 6th bytes: Free*/ /* 7th-14th bytes: QR brands */ /* 7,8: Japan */ MARSHALLAPI_BRAND_QR_PAYPAY = 0x0000000001000000, /* PayPay */ MARSHALLAPI_BRAND_QR_LINE_PAY = 0x0000000002000000, /* LinePay*/ MARSHALLAPI_BRAND_QR_RAKUTEN_PAY = 0x0000000004000000, /* RakutenPay*/ MARSHALLAPI_BRAND_QR_AU_PAY = 0x0000000008000000, /* AUPay*/ MARSHALLAPI_BRAND_QR_AEON_PAY = 0x0000000010000000, /* AEONPay */ MARSHALLAPI_BRAND_QR_D_BARAI = 0x0000000020000000, /* D Barai*/ MARSHALLAPI_BRAND_QR_MERUPAY = 0x0000000040000000, /* MeruPay */ MARSHALLAPI_BRAND_QR_J_COIN = 0x0000000080000000, /* J-Coin*/ /*9-13: East asia*/ MARSHALLAPI_BRAND_QR_WECHAT_PLUS = 0x0000000010000000, /* Monyx */ MARSHALLAPI_BRAND_QR_WECHAT = 0x0000000020000000, /* EFTPOS */ MARSHALLAPI_BRAND_QR_ALIPAY = 0x0000000040000000, /* INTERAC */ MARSHALLAPI_BRAND_QR_ALIPAY_PLUS = 0x0000000080000000, /* */ MARSHALLAPI_BRAND_QR_ALIPAY_HK = 0x0000000100000000, /* */ MARSHALLAPI_BRAND_QR_MAE_PAY = 0x0000000200000000, /* */ MARSHALLAPI_BRAND_QR_PROMPT_PAY = 0x0000000400000000, /* */ MARSHALLAPI_BRAND_QR_DUIT_PAY = 0x0000000800000000, /* */ MARSHALLAPI_BRAND_QR_TOUNCHNGO = 0x0000001000000000, /* */ MARSHALLAPI_BRAND_QR_BOOST = 0x0000002000000000, /* */ MARSHALLAPI_BRAND_QR_TRUE_MONEY = 0x0000004000000000, /* */ MARSHALLAPI_BRAND_QR_ZALO_PAY = 0x0000008000000000, /* */ MARSHALLAPI_BRAND_QR_SHOPEE_PAY = 0x0000010000000000, /* */ MARSHALLAPI_BRAND_QR_VIET = 0x0000020000000000, /* */ MARSHALLAPI_BRAND_QR_MOMO = 0x0000040000000000, /* */ MARSHALLAPI_BRAND_QR_GRAB_PAY = 0x0000080000000000, /* */ MARSHALLAPI_BRAND_QR_UNION_PAY = 0x0000100000000000, /* */ /*14: Other countries*/ MARSHALLAPI_BRAND_QR_SWISH = 0x0001000000000000, /* */ MARSHALLAPI_BRAND_QR_SATISPAY = 0x0002000000000000, /* */ /* 15th~ bytes: Other brands */ MARSHALLAPI_BRAND_OFFICE_PAY = 0x0100000000000000, /* Office Pay */ MARSHALLAPI_BRAND_NAYAX_PAY = 0x0200000000000000, /* Nayax Pay (VEND_PAY_METHOD_NAYAX_PREPAID)*/ MARSHALLAPI_BRAND_MONYX = 0x0400000000000000, /* Monyx */ MARSHALLAPI_BRAND_EFTPOS = 0x0800000000000000, /* EFTPOS */ MARSHALLAPI_BRAND_INTERAC = 0x1000000000000000, /* INTERAC */ MARSHALLAPI_BRAND_PURE = 0x2000000000000000, /* PURE */}E_MarshallApi_TDSelectCardBrand; ``` # Stability & Starvation Issues Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/additional-resources/stablity-issues # Introduction ## What can cause stability issues in the Marshall link? These stability issues usually happen due to not using proper hardware: 1. 24V/1.5A power source 2. If using a USB-to-COM adaptor, it must be a Chipi-X, the only type approved by Nayax's technical team. It has also been shown in the past that other types of adaptors may (and tend to) cause stability issues. 3. Issues with your machine's COM port (physical connection/ COM port management). 4. If using Marshall over LAN, it could be due to issues with your Ethernet connector, LAN communication, etc. Or due to "starving" the Marshall task- explained further below. ## You've mentioned that the Marshall task is being "starved". what does it mean? Once the Marshall task doesn't get enough priority to run, it's "starved" and may not behave properly. In that case, your machine would stop sending the "Keep Alive" signals. The device (VPOST/VPOSM) will detect that the machine is disconnected due to a missing "Keep Alive" and launch a new pairing process. Starvation is the worst problem you can have, and it can cause unexpected behavior depending on when it occurs (which I think you've seen), so it's very important to solve it. Those issues can cause weird behavior from the consumer's POV and even break the Marshall link, which shouldn't happen (and when it does, you won't be able to make or complete transactions). **Possible causes for the starvation of the Marshall task: not giving the Marshall a high enough priority to run, having your machine do other things which will cause it to not respond to Marshall (keepalives or other commands) in time, extensive file-writing other than the SDK's, etc.** ## What does it look like? Once the Marshall task is starved you'd see the following: ``` - In the log file of the SDK will be printed: "vmc_link: warning! sdk is not getting enough cpu! (starved for Xms)" or: " vmc_link: *** error: retransmitting... last_rx" Or: " lowlevel_serial: bytes available: 0 bytes " - And at the same laps of time, in the GTrace will be printed something along the lines of: Marshall: Sys,Err: No keep alive,Handle = 1 Marshall: Com error,Event = 1 Marshall: No keep alive message from the POS. retry number: 2 Marshall: Sys,Err: No keep alive,Handle = 1 Marshall: Com error,Event = 1 ``` Should your peripheral continue to not respond (each packet would be sent once and would have another possible 2 retries which would try and get a response from your machine- would go into details about it below in the section about keepalives)- the Marshall link would be deemed broken. Then, the device will repeatedly send the "Reset()" command to launch the Pairing process. This means the pairing process has been initiated, indicating that the VPOST/VPOSM is looking for a peripheral to communicate with. Once the machine responds to it (with the Firmware Info command)- it would complete the process by sending the Config command. Until the connection is established, you'd see resets on the Marshall log and "Marshall: peripheral not connected" in the Gtrace log. Once the Marshall pairing process is completed, a link is established between the VPOST/VPOSM and the peripheral. The following would appear in the Marshall log: ``` > [1661418016846+( 432ms)] marshall_t: received reset [1661418016847+( 1ms)] : rx: 09:00:00:6a:ff:ff:ff:ff:01:77:d6: [1661418016853+( 6ms)] : tx: 87:00:00:00:00:30:00:00:05:00:02:0b:01:40:01:6d: 61:72:73:68:61:6c:6c:2d:6a:61:76:61:2d:73:64:6b: 00:00:00:30:31:32:33:34:35:36:37:00:00:00:00:00: 00:00:00:00:00:00:00:30:2e:31:2e:35:2e:31:33:00: 00:00:00:00:00:00:00:00:00:00:00:30:31:32:33:34: 35:36:37:00:00:00:00:00:00:00:00:00:00:00:00:6d: 61:6e:75:66:00:00:00:00:00:00:00:00:00:00:00:00: 00:00:00:30:2e:31:2e:35:2e:31:33:00:00:00:00:00: 00:00:00:00:00:00:00:9d:4a: [1661418016874+( 21ms)] marshall_t: received config [1661418016875+( 1ms)] : rx: 2a:00:00:00:00:35:01:30:06:02:01:01:e8:03:00:00: 00:24:00:00:24:00:00:02:35:35:30:36:30:30:31:32: 38:31:32:33:34:33:34:30:00:02:01:68: [1661418017084+( 209ms)] marshall_t: received transfer_data [1661418017084+( 0ms)] marshall_t: default credit: 1000 [1661418017084+( 0ms)] marshall_t: main fw ver: 4.0.8.23-RC03 [1661418017084+( 0ms)] marshall_t: pos fw ver: 2203-rc09 [1661418017084+( 0ms)] marshall_t: monyx id: 06911447 [1661418017085+( 1ms)] : rx: 34:00:05:01:00:35:01:30:0a:14:02:e8:03:12:0e:34: 2e:30:2e:38:2e:32:33:2d:52:43:30:33:00:13:0a:32: 32:30:33:2d:72:63:30:39:00:15:09:30:36:39:31:31: 34:34:37:00:4b:89: [1661418017085+( 0ms)] : tx: 0a:00:00:01:01:30:00:35:00:00:bb:4b: [1661418017096+( 11ms)] vmc_link: vmc is online. time: Thu Aug 25 12:00:17 IDT 2022 [1661418017097+( 1ms)] vmc_socket_t: received event: [init_done], state: [init] [1661418017097+( 1ms)] Main: link with vpos serial: 0434321821006055 [1661418017097+( 0ms)] vmc_socket_t: changed state, from [init] to [idle] [1661418017097+( 0ms)] Main: main fw version: 4.0.8.23-RC03 [1661418017097+( 0ms)] Main: pos fw version: 2203-rc09 [1661418017097+( 0ms)] Main: monyx id: 06911447 [1661418017097+( 0ms)] Main: default credit: 1000 [1661418017098+( 1ms)] : tx: 16:00:01:01:01:30:00:35:31:01:00:68:65:6c:6c:6f: 20:74:68:65:72:65:76:09: [1661418017099+( 1ms)] : tx: 0a:00:00:02:01:30:00:35:00:00:39:93: [1661418017099+( 0ms)] vmc_vend_t: received status: 20 [1661418017099+( 0ms)] Main: device available [1661418017099+( 0ms)] vmc_socket_t: received status: 20 [1661418017115+( 16ms)] : rx: 0a:00:00:01:00:35:01:30:00:00:08:b0: And in Gtrace it would show: "Marshall sys: RCV - Firmware info - type - 0 subtype - 1 Marshall sys: RCV - Firmware info - Capabilities – 0" ``` ## How the "keepalive" mechanism works/what is the reason for the starvation The "no keep alive" means that your peripheral did not respond to the keep alive, which occurs every second (unless configured otherwise), and in that case, it would try to resend the packet. If there is no response, it would try again (1 original attempt 2 retried), and if this attempt fails, the Marshall link would be deemed broken. The pairing process (the establishment of communication between the VPOST/VPOSM and your charger) would be re-initiated. In some cases, starvation is caused by poor task handling or by extensive file writing (unrelated to the Marshall log writing). While a file is being written, all tasks are halted to prevent corruption of the flash. In addition, the starvation could be due to your peripheral doing tasks unrelated to Marshall, causing it not to respond to the Marshall task in time. ### Can I increase the time between keepalives? would that solve the starvation issue? The SDK is made to work best with a keepalive of 1 second, and increasing the keepalive to a higher amount won't solve the issue of starvation- it would just take much longer to realize there's some issue with the communication. We don't recommend having it set to more than 5 seconds. For example, if you had it configured to 30 seconds, it would take 3\*30=90 seconds for the SDK to realize there's an issue, and in that time, the VPOST may appear "frozen"/unresponsive, confusing consumers. Having keepalives occur every second is not what's overloading the processor; the issue is that the task doesn't get enough priority to start with. <Note> **Note:** For VPOSM, in case of Marshall over ETH, there's a need to set the keepalive to 10 seconds due to LAN requirements/limitations. </Note> ## Should I have the keepalives logged? would you be aware of any issues with them if they do not appear? You can have them written to the logs, but they would make it really hard to read, since you get a keepalive (and a response to it) every second. In an hour-long log, you'd have at least 3,600 records. The "debug level dump moderate" means that only the critical information would be logged, such as the pairing process, transactions, statuses, starvation warning etc., so if you'd have an issue with keepalives/packets going missing- you'd get the same warning/information in the "debug level dump moderate " logging versus " debug level dump all". Bottom line, I would highly recommend using "debug level dump moderate" instead of "debug level dump all". <br /> # C SDK Integration Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/c-sdk-integration <Warning> **C SDK Only** The functions and information on this page are relevant only for the **C SDK**. </Warning> This guide shows you how to integrate the **Marshall C SDK** into your platform. You will learn to configure essential serial port functions, implement required timer ticks, and set up the VMC configuration object to get the SDK running. The C SDK includes working implementations for Linux, Windows, or STM32 microcontrollers. If your platform differs, use these implementations as a reference to adapt the SDK accordingly onto your own platform. ## Pre-requisites Before running the C SDK, ensure you configure the following platform-specific elements: * **Serial Port Communication:** Implement methods for reading and writing bytes from your platform's serial port, which connects to Nayax's device. The SDK interacts with the hardware through this serial interface. You must implement the following functions: * `drv_usart_rx_byte()`: Reads a single byte from the serial port. * `drv_usart_rx_chunk()`: Reads multiple bytes in one operation. * `drv_usart_get_rx_pending()`: Returns the number of pending bytes in the serial buffer. * `drv_usart_tx_data()`: Sends data bytes to the VPOS device. * **Periodic Timer Tick:** Implement a periodic timer tick to invoke the `vmc_link_background()` function. This function should be called with an interval of 5 ms to 10 ms. Additionally, ensure the `cpu_platform_get_time()` function returns a continuously incrementing millisecond counter since the system startup. * **UART Communication Validation:** Verify that the UART communication with Nayax's device is fully functional. * Check for proper data transmission and reception. * Validate that event callbacks are triggered correctly. ## Integrate Marshall To get started with the C SDK, follow these steps. You can refer to the provided `mymain.c` file for a sample code and guidance on importing necessary namespaces into your project. 1. Instantiate a VMC configuration object: ```c C theme={null} vmc_config_t config; ``` 2. Fill in the appropriate fields. The following code block presents a standard configuration: ```c C theme={null} vmc_init() __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, “01234567”); __strcpy(config. vmc_manuf_code, “manuf”); config.multi_vend_support = __false; config.multi_session_support = __false; config.price_not_final_support = __false; config.reader_always_on = __false; config.always_idle = __false; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; ``` <Note> **Mandatory Fields** The customer machine information fields are mandatory for the VMC configuration. These are the `model`, `serial`, `hw_ver` and the `manuf_code`. Read more about these fields in [VMC Configuration Object](/docs/integrate-pos-device/marshall/get-started/vmc-configuration-object). </Note> 3. Configure the SDK and register to link events. ```c C theme={null} vmc_link_register_callback((vmc_link_event_handler_cb_t)vmc_link_event_handler_cb); vmc_vend_register_callback((vmc_vend_event_handler_cb_t)vmc_vend_event_handler_cb); vmc_general_register_callback((vmc_general_event_handler_cb_t)vmc_general_event_handler_cb); ``` 4. Start the SDK and wait for the `onReady()` event: ```c C theme={null} vmc_link_start() ``` ## Implement payment flows As explained in [Payment Flows](/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows), the Marshall SDK supports various payment flows. The pages below explain how to implement each in your VMC using the **C SDK**. <CardGroup> <Card icon="credit-card" title="C SDK single session" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/single-session"> Process one transaction at a time before the session resets. </Card> <Card icon="layer-group" title="C SDK multi-session" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-session"> Run multiple transactions independently for self-service environments. </Card> <Card icon="cubes" title="C SDK multi-vend" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-vend"> Let consumers purchase multiple products in a single payment session. </Card> </CardGroup> ## See also <CardGroup> <Card icon="sliders" title="VMC configuration object" href="/docs/integrate-pos-device/marshall/get-started/vmc-configuration-object"> Configure the parameters and flags that control your peripheral's behavior. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> # Certification Process Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/certification-proccess The Marshall certification process consists of a list of tests you, the customer, must complete after you complete the SDK's implementation. These tests are done to ensure stability before rolling out and to avoid unexpected, unwanted issues on your end. ## The certification process Once you've reached this point, you'd be asked to notify your Nayax integrator about it and we'd send you a certification test file to match the flow you're using (Single Session/ Multisession/ Multivend). The file includes explanations about the tests you need to do, as well as the steps that need to be done in order to complete each one of them. As would have been explained to you during the integration, I would need you to enable the SDK's logging (and keep those on even after rollout, as this is Nayax's main debugging tool which would allow us to assist with figuring out any possible issues you encounter after rollout) and have you send your Nayax integrator each test result in a different file. The testing process is not long (assuming that the implementation was done correctly), yet it covers most, if not all, edge cases. During testing, you will receive guidance and assistance from your Nayax integrator until completion. <Tip> Before sending a test result to your Nayax integrator, you can run it through the [Log Trace Comparator tool](/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator) to check it against known-good reference traces yourself. It's optional, but it can catch issues before you send the file over. </Tip> What happens once the certification is completed? And why is it important to allow rollout only after completing the certification? Once all of the mandatory tests are completed successfully, meaning your Nayax integrator has received the logs for them and approved of all of them- he would let you know that the integration and certification process have been completed successfully by sending you an official certification letter and notify the distributor about it, and only at this point would the distributor allow you to roll out. <Danger> **Important Note** The certification is valid for 3 years. To maintain compliance, you may be required to re-certify after this period to ensure your SDK implementation and Marshall-related services continue to operate as expected. </Danger> # C# & Java SDK Integration Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/marshall-csharp-java-integration This guide shows you how to integrate the **Marshall SDK** into your **C#** or **Java** application. You’ll learn how to: * Import the SDK package into your project * Create and configure a VMC settings object * Set up the serial (**COM**) port for communication * Register event listeners and start the SDK The instructions are presented side by side for both languages. ## Prerequisites Before you begin, make sure you have: * Downloaded the appropriate SDK files, `.jar` for **Java** or `.dll` for **C#**. * Identified the correct **COM** port for the Marshall cable. * For Java- ensure that you have Java 8 (also known as Java 1.8) and above. Note that for the newest version of Nayax's Java SDK (0.1.6.8) you'd need Java 11- but should you like us to, we can look into having it be compiled with Java 8. ## Integrate Marshall To perform the integration, follow the steps below: 1. Import the provided `.JAR` or SDK DLL file into your project. 2. Import the necessary namespaces in your code. <CodeGroup> ```java Java theme={null} import com.bitmick.marshall.models.*; ``` ```csharp C# theme={null} using com.bitmick.marshall.models; ``` </CodeGroup> 3. Instantiate a VMC configuration object: <CodeGroup> ```java Java theme={null} public vmc_configuration vmc_config = new vmc_configuration(); ``` ```csharp C# theme={null} vmc_configuration vmc_config = new vmc_configuration(); ``` </CodeGroup> 4. Fill in the appropriate fields. The following code block presents a standard configuration: <CodeGroup> ```java Java theme={null} public static void main(string[] args) { vmc_config.multi_vend_support = false; vmc_config.multi_session_support = false; vmc_config.price_not_final_support = false; vmc_config.reader_always_on = false; vmc_config.always_idle = false; vmc_config.vend_denied_policy = vmc_configuration.vend_denied_policy_cancel; vmc_config.explicit_vend_success = false; vmc_config.long_price = false; vmc_config.mifare_approved_by_vmc_support = false; vmc_config.mag_card_approved_by_vmc_support = false; vmc_config.qr_approved_by_vmc_support = false; vmc_config.dump_packets_level = vmc_configuration.debug_level_dump_moderate; vmc_config.debug = true; } ``` ```csharp C# theme={null} public class vend_machine vmc_config.multi_session_support = false; vmc_config.multi_vend_support = false; vmc_config.price_not_final_support = false; vmc_config.reader_always_on = false; vmc_config.always_idle = false; vmc_config.explicit_vend_success = false; vmc_config.vend_denied_policy = vmc_configuration.vend_denied_policy_cancel; vmc_config.long_price = false; vmc_config.mag_card_approved_by_vmc_support = false; vmc_config.mifare_approved_by_vmc_support = false; vmc_config.debug = true; vmc_config.dump_packets_level = vmc_configuration.debug_level_dump_moderate; ``` </CodeGroup> <Warning> **Mandatory Fields** The customer machine information is mandatory for the VMC configuration. These are the `model`, `serial`, `hw_ver`, and the `manuf_code`. Read more about these fields in [VMC Configuration Object](/docs/integrate-pos-device/marshall/get-started/vmc-configuration-object). </Warning> 5. Setup the **COM** port. <CodeGroup> ```java Java theme={null} m_vmc.link.set_serial_port(new pc_port("COM18", 115200)) ``` ```csharp C# theme={null} m_vmc.link.set_serial_port(new pc_port("COM18", 115200)) ``` </CodeGroup> <Warning> **COM Port** Make sure that you change the `COM` parameter to the one your Marshall cable is connected to. </Warning> * Note- in the near future we plan on having the possibility to use Marshall over ETH (supported only for VPOSM)- in that case, there would be no COM port but rather an IP address which would be under the same local network as the Nayax device, and optionally the relevant IP port (which by default should remain untouched \[has by default the value of "12345" which is meaningless]) <CodeGroup> ```java Java theme={null} m_vmc.link.set_serial_port(new eth_port("192.168.112.127", (short) 12345, false)); ``` ```csharp C# theme={null} vmc_instance = marshall_init(new eth_port("192.168.68.101", 12345)); ``` </CodeGroup> 6. Configure the SDK and register to link events. <CodeGroup> ```java Java theme={null} m_vmc.link.configure(vmc_config); m_vmc.link.set_events(new vmc_link_events()); ``` ```csharp C# theme={null} m_vmc.link.configure(vmc_config); m_vmc.link.set_events(new vmc_link_events()); ``` </CodeGroup> 7. Start the SDK and wait for the `onReady()` event: <CodeGroup> ```java Java theme={null} vmc_instance .start(); ``` ```csharp C# theme={null} m_vmc.link.start(); ``` </CodeGroup> <Note> **Using Android** On android, you either need support from your provider or use a FTDI chip, which we provide port implementation for. (see the “android” folder in the JAVA SDK release) </Note> ## See also <CardGroup> <Card icon="microchip" title="C SDK integration" href="/docs/integrate-pos-device/marshall/get-started/c-sdk-integration"> Integrate the Marshall C SDK into your platform. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> # Get Started Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/marshall-get-started The Marshall SDK provides an easy and comprehensive facility for using Nayax's VPOS Touch and VPOS Media devices, eliminating the hassle of working with the details of the Marshall protocol. Follow the quick-start demo, and you will be up and running quickly. <Danger> **Important note** Nayax only supports integrations that use our SDKs and that have gone through and completed the certification process (more on that in the "Certification process" page). </Danger> All SDKs have comprehensive APIs, detailed configuration options, and support for handling various vending scenarios. The following guide provides a quick-start approach to integrating and configuring these SDKs in your projects, ensuring a smooth setup and operation of Nayax payment systems. <Note> **Available Languages** For your convenience, we provide the SDK in C, C#, and JAVA. </Note> ## Integration Guides The integration process of the SDK can vary depending on the chosen language. The guides below will help you integrate your chosen SDK. <CardGroup> <Card icon="code" title="C# & Java SDK Integration" href="/docs/integrate-pos-device/marshall/get-started/marshall-csharp-java-integration"> Import the SDK package and integrate Marshall into your C# or Java application. </Card> <Card icon="terminal" title="C SDK Integration" href="/docs/integrate-pos-device/marshall/get-started/c-sdk-integration"> Integrate the Marshall C SDK into your C application. </Card> <Card icon="route" title="Integration Process" href="/docs/integrate-pos-device/marshall/get-started/marshall-integration-process"> Connect sessions and handle payments end to end with a step-by-step guide. </Card> </CardGroup> <Note> **SDK Access** Your chosen SDK will be provided to you after completing the onboarding with the Nayax team. </Note> ## Configuration & Certification Before you go live, review how to configure the VMC object and complete Nayax's certification process. <CardGroup> <Card icon="gears" title="VMC Configuration Object" href="/docs/integrate-pos-device/marshall/get-started/vmc-configuration-object"> Set the parameters and flags that control peripheral behavior. </Card> <Card icon="flag" title="SDK Flags" href="/docs/integrate-pos-device/marshall/get-started/sdk-flags-descriptions"> Configure vmc\_configuration flags that control peripheral behavior and capabilities. </Card> <Card icon="certificate" title="Certification Process" href="/docs/integrate-pos-device/marshall/get-started/certification-proccess"> Complete Nayax's required tests to certify your Marshall integration. </Card> </CardGroup> # Integration Process Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/marshall-integration-process A step-by-step guide to integrating with Nayax The Nayax integration process ensures a seamless and efficient implementation, providing technical support at every stage. From initial setup to production deployment, Nayax teams work closely with partners or customer developers to meet all technical and operational requirements. ## Stages of the process The integration process is divided into five main stages: 1. Kickoff Meeting 2. Integration Setup 3. Development Phase 4. Testing & Certification 5. Production Setup <Frame> <img /> </Frame> Each stage is structured to provide technical support and essential resources, ensuring smooth and efficient implementation. ### Kickoff Meeting The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator’s project, the technical teams, and the Nayax Integration Engineer. ### Integration Setup This initial stage establishes the technical foundation for the integration. 1. **Assignment of Integration Engineer:** A Nayax integration engineer is assigned as the primary focal point for the partner or customer developer. 2. **Configuration:** The engineer configures the Nayax Core (backend) and sets up the device with the relevant transaction flow in the integration environment. 3. **Welcome Email:** At the end of this phase, the engineer sends a welcome email with all necessary resources, including the URL, SDK, documentation, tokens, and other required development tools. ### Development Phase This stage focuses on the partner or customer developing their solution. 1. **Partner/Customer Development:** The partner or customer developer creates their solution using the Nayax API/SDK. 2. **Support:** During this phase, the integration engineer provides assistance for any issues or "how-to" queries to ensure progress. <Note> **Support for OCPP/OCPI Integrations** For integrations based on **OCPP/OCPI** standards, this step is not relevant, as these integrations follow predefined flows according to the standard protocol. </Note> ### Testing & Certification This stage verifies that the integration meets Nayax’s standards: 1. **Certification Test Requirements:** Nayax shares specific requirements for certification tailored to the integration type and transaction flow. 2. **Testing:** The partner or customer developer performs a series of tests (typically 9–15, depending on the integration type and flow). 3. **Review:** The Nayax integration engineer reviews the results of these tests to ensure all criteria are met. 4. **Certification:** Upon successfully completing all tests, Nayax issues a certification letter confirming the integration is ready for deployment. ### Production Setup The final stage ensures a smooth deployment in a live environment: 1. **Production Environment Configuration:** Nayax configures the integration in the production environment, including the machine model setup. 2. **Support for Testing:** The integration engineer provides support during production lab or field tests to confirm successful deployment. The Nayax integration process provides a structured, step-by-step approach that ensures reliable and efficient implementation. By collaborating closely with partners and customers, Nayax delivers high-quality solutions that meet industry standards and support successful deployments in the market. # SDK Flags Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/sdk-flags-descriptions The `vmc_configuration` object allows you to set various configuration flags. When using the Marshall SDK, these determine the behavior and capabilities of the peripheral (originally intended for vending machine controller -VMC). ## Configuration flags You can initiate these flags in the `main` method, as in the following code: <CodeGroup> ```java Java theme={null} public static void main(string[] args) { vmc_config.multi_vend_support = false; vmc_config.multi_session_support = false; vmc_config.price_not_final_support = false; vmc_config.reader_always_on = false; vmc_config.always_idle = false; vmc_config.vend_denied_policy = vmc_configuration.vend_denied_policy_cancel; vmc_config.explicit_vend_success = false; vmc_config.long_price = false; vmc_config.mifare_approved_by_vmc_support = false; vmc_config.mag_card_approved_by_vmc_support = false; vmc_config.qr_approved_by_vmc_support = false; vmc_config.dump_packets_level = vmc_configuration.debug_level_dump_moderate; vmc_config.debug = true; } ``` ```csharp C# theme={null} public class vend_machine vmc_config.multi_session_support = false; vmc_config.multi_vend_support = false; vmc_config.price_not_final_support = false; vmc_config.reader_always_on = false; vmc_config.always_idle = false; vmc_config.explicit_vend_success = false; vmc_config.vend_denied_policy = vmc_configuration.vend_denied_policy_cancel; vmc_config.long_price = true; vmc_config.mag_card_approved_by_vmc_support = false; vmc_config.mifare_approved_by_vmc_support = false; ``` ```c C theme={null} static void vmc_init(void) { config.multi_vend_support = __false; config.multi_session_support = __false; config.price_not_final_support = __false; config.reader_always_on = __false; config.always_idle = __false; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; } ``` </CodeGroup> ### Flag descriptions The table below provides a more detailed description of the flags. <table> <thead> <tr> <th> Parameter </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `multi_vend_support` </td> <td> boolean </td> <td> Enabling the sale and differentiation of multiple products in a single transaction. </td> </tr> <tr> <td> `multi_session_support` </td> <td> boolean </td> <td> Enables the device to handle multiple sessions simultaneously, which is useful for scenarios where various transactions may be open at the same time. </td> </tr> <tr> <td> `price_not_final_support` </td> <td> boolean </td> <td> Relevant for multi-session (pre-selection) flow only. Indicates that the authorization price received from the server is not final, meaning using it alongside Multi-session would have it behave similarly to a pre-authorization process, ensuring the balance isn't captured for a few days. You can read more on that in the [Multi-Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session#/) page. </td> </tr> <tr> <td> `reader_always_on` </td> <td> boolean </td> <td> It keeps the device's reader always turned on and ready to start transactions from the device's end instead of the peripheral. When used, a trigger for the product selection would be a card presentation or touching a button on the device instead of selecting a product on the peripheral's end. </td> </tr> <tr> <td> `always_idle` </td> <td> boolean </td> <td> The transaction starts with the consumer selecting a product on the peripheral. The peripheral can send the "Vend request" command without waiting for a "Begin Session" trigger. </td> </tr> <tr> <td> `vend_denied_policy` </td> <td> boolean </td> <td> irrelevant, N/A. </td> </tr> <tr> <td> `explicit_vend_success` </td> <td> boolean </td> <td> If you have a long vend operation you can set this flag to true, and then after you get the onVendApproved(), you can perform the slow vend operation and then on your time, call vend\_status(true/false) for vend success/failure, in order to conclude the transaction. (the onVendApproved would return a dummy "true", meaning it would release the thread but the SDK would still wait for your actual response regarding the vending result, which is what you'd do in the "vend\_status" command) </td> </tr> <tr> <td> `long_price` </td> <td> boolean </td> <td> Relevant only for VPOSM- allows for the price field to be 4 bytes long instead of 2 bytes.\ **Not yet supported** </td> </tr> <tr> <td> `mifare_approved_by_vmc_support` </td> <td> boolean </td> <td> Allows Mifare (prepaid) cards to be authorized by a third-party server. The card's data is being forwarded to the peripheral and it is up for it to approve/decline the card. </td> </tr> <tr> <td> `mag_card_approved_by_vmc_support` </td> <td> boolean </td> <td> Allows magnetic stripe proprietary cards authorized by a third-party server. The card's data is being forwarded to the peripheral and it is up for it to approve/decline the card. </td> </tr> <tr> <td> `qr_approved_by_vmc_support` </td> <td> boolean </td> <td> Allows QR codes to be authorized by a third-party server. The card's data is being forwarded to the peripheral and it is up for it to approve/decline the card. </td> </tr> <tr> <td> `debug` </td> <td> boolean </td> <td> Enables or disables log generation. </td> </tr> <tr> <td> `dump_packets_level` </td> <td> `vmc_configuration` </td> <td> Determines the level of detail required to log messages generated by the SDK. You can read more about this in the [Log generation](/docs/integrate-pos-device/marshall/log-analysis/log-generation) page. </td> </tr> </tbody> </table> # VMC Configuration Object Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/get-started/vmc-configuration-object The `vmc_configuration` class is used to set up various parameters and flags that control the behavior of the peripheral. Proper configuration is crucial for ensuring smooth operation and compatibility with different peripherals. ## Configuration object The code block below displays the `vmc_configuration` class for the available SDK languages. <CodeGroup> ```java Java theme={null} public class vmc_configuration public Object port_vpos; public int port_vpos_baud; public String serial; public String model; public String sw_ver; public int machine_type; boolean explicit_vend_success; public boolean price_not_final_support; public boolean mag_card_approved_by_vmc_support; public boolean mifare_approved_by_vmc_support; public boolean debug; public int dump_packets_level; public boolean reader_always_on; public boolean multi_session_support; public boolean multi_vend_support; public boolean always_idle; public ``` ```csharp C# theme={null} public class vmc_configuration public string port_vpos; public int port_vpos_baud; public string serial; public string model; public string sw_ver; public int machine_type; public bool reader_always_on; public bool multi_session_support; public bool multi_vend_support; public bool always_idle; public bool explicit_vend_success; public bool price_not_final_support; public bool mag_card_approved_by_vmc_support; public bool mifare_approved_by_vmc_support; public bool debug; public int dump_packets_level; ``` </CodeGroup> ### Object parameters The table below describes the parameters of the class. <table> <thead> <tr> <th> Parameter </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `port_vpos` </td> <td> String </td> <td> The PC COM port to which the Nayax device is connected. </td> </tr> <tr> <td> `port_vpos_baud` </td> <td> int </td> <td> The baud rate for the Nayax device communication port. </td> </tr> <tr> <td> `serial` </td> <td> String </td> <td> The serial number of the machine. This enables precise tracking, effective inventory management, and streamlined maintenance scheduling. </td> </tr> <tr> <td> `model` </td> <td> String </td> <td> Model name of the machine. It assists in troubleshooting by distinguishing different machine types in logs and reports. </td> </tr> <tr> <td> `sw_ver` </td> <td> String </td> <td> The software version of the peripheral. </td> </tr> <tr> <td> `machine_type` </td> <td> int </td> <td> The type of peripheral. </td> </tr> <tr> <td> `explicit_vend_success` </td> <td> bool </td> <td> Flag to indicate explicit vending status (success/failure). Relevant only for long vending process. </td> </tr> <tr> <td> `price_not_final_support` </td> <td> bool </td> <td> Indicates if the price is not final, meaning the settlement price can be different than the one authorized. Relevant for Multisession flow only. </td> </tr> <tr> <td> `mag_card_approved_by_vmc_support` </td> <td> bool </td> <td> Support for magnetic card approval by the peripheral. </td> </tr> <tr> <td> `mifare_approved_by_vmc_support` </td> <td> bool </td> <td> Support for MIFARE card approval by the peripheral. </td> </tr> <tr> <td> `debug` </td> <td> bool </td> <td> Enables or disables debugging. Enabling it is mandatory in order to generate the SDK's logs. </td> </tr> <tr> <td> `dump_packets_level` </td> <td> int </td> <td> Sets the level of packet logging for debugging purposes. </td> </tr> <tr> <td> `reader_always_on` </td> <td> bool </td> <td> It keeps the Nayax device's reader always enabled and ready for transactions. Used in cases in which the peripheral would like a card's presentation to be a trigger for product selection. </td> </tr> <tr> <td> `multi_session_support` </td> <td> bool </td> <td> Enables support for Multi-Session flow </td> </tr> <tr> <td> `multi_vend_support` </td> <td> bool </td> <td> Enables support for Multi-vend flow. </td> </tr> <tr> <td> `always_idle` </td> <td> bool </td> <td> Configures the device to start transactions by product selection and have the authorized amount appear on Nayax's device screen (instead of animations). </td> </tr> </tbody> </table> ## Mandatory fields When configuring a VMC (Vending Machine Controller), there are specific mandatory fields essential for the proper identification of the machine. Properly managing these fields leads to improved troubleshooting, enhanced system integration, and more efficient maintenance processes. Refer to the code block below for an example of the configuration for these mandatory fields. <CodeGroup> ```java Java theme={null} vmc_config = new vmc_configuration(); vmc_config.model = "marshall-java-sdk"; vmc_config.serial = "01234567"; vmc_config.hw_ver = "01234567"; vmc_config.manuf_code = "manuf"; ``` ```csharp C# theme={null} vmc_config = new vmc_configuration(); vmc_config.model = "marshall-java-sdk"; vmc_config.serial = "01234567"; vmc_config.hw_ver = "01234567"; vmc_config.manuf_code = "manuf"; ``` ```c C theme={null} vmc_init() __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, “01234567”); __strcpy(config. vmc_manuf_code, “manuf”); ``` </CodeGroup> The table below describes the parameters: | Parameter | Type | Description | | :- | :- | :- | | `model` | String | Model name of the machine. It assists in troubleshooting by distinguishing different machine types in logs and reports. | | `serial` | String | The serial number of the machine. This enables precise tracking, effective inventory management, and streamlined maintenance scheduling. | | `hw_ver` | String | Hardware version of the machine. It ensures that the correct firmware and software are used. Different hardware versions may require specific drivers or compatibility adjustments. | | `manuf_code` | String | Identifies the machine's manufacturer, enabling proper support and operation. | ### Nayax Core These parameters will be saved in Nayax Core. You can find them in **Operations > Machines**. Find and select your machine and open the **VMC** tab, as shown in the following image. <Frame> <img /> </Frame> ## See also <SeeAlso> <SeeAlsoCard title="C# & Java SDK Integration" href="/docs/integrate-pos-device/marshall/get-started/marshall-csharp-java-integration"> How the SDK is wired into a C# or Java application. </SeeAlsoCard> <SeeAlsoCard title="C SDK Integration" href="/docs/integrate-pos-device/marshall/get-started/c-sdk-integration"> How the C SDK is wired into an embedded platform. </SeeAlsoCard> <SeeAlsoCard title="SDK Flags" href="/docs/integrate-pos-device/marshall/get-started/sdk-flags-descriptions"> What each configuration flag controls. </SeeAlsoCard> </SeeAlso> # Installation Steps Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/installation-steps Touch devices include all Nayax devices with touch screens, such as the Nayax VPOS Touch and Onyx. These devices are designed for advanced functions like payments, monitoring, and network management. Media devices include the newer generation of touchscreens (VPOS Media 5 and, in the near future (not yet supported), VPOS Media 4 Mini), also known as VPOS Media 4S. It is also planned on the roadmap to have VPOS Media 10. <Note> **Note** We have VPOSM 4 and VPOSM 4S which are 2 separate devices. In the documents and manuals you'll see only mentions of VPOSM 4S as VPOSM 4 is not supporting Marshall. </Note> Below are the steps for installing these devices correctly. ## System requirements Before installation, the NayaxVend Management System (Nayax Core) must be updated via the backend. Please note that upon purchase, Nayax Support preconfigures the device with standard machine parameters. For specific machines, ensure the relevant parameters are updated in the system to match their requirements. For additional support or further information, contact your local Nayax Support team. <Note> **Note** For an integration, a SDK sample app is required to test real purchase scenarios. </Note> ## Installation- VPOS touch ### Insert SIM By default, the SIM card would already be installed. If not, ensure the SIM card is ready to be inserted and installed prior to starting the integration. 1. Locate the SIM socket at the top of the device. 2. Insert the SIM card into the socket securely, ensuring it is properly fitted. <Frame> <img /> </Frame> ### Connect Marshall cable Ensure all necessary components are ready before connecting the Marshall cable. 1. Insert the Touch device cable connector into the Nayax device. <Frame> <img /> </Frame> 2. Connect the COM 2 / Marshall connector to the PC. 3. Attach the power adaptor connector to the Marshall cable. ### Set up the network Now, it’s time to set up the network for your Touch device. To ensure everything runs smoothly, you must connect the cellular antenna and the LAN (Ethernet) cable. #### Connect the Antenna (Cellular) To enable cellular network connectivity, follow these steps: 1. Locate the SMA connector on the device. 2. Connect the antenna's **SMA female connector** to the **SMA male connector** on the Touch device. <Frame> <img /> </Frame> #### Optional- Connect the LAN Cable (Ethernet) To set up the wired network connection, insert the Ethernet cable into the device's LAN port. Ensure the other end of the cable is connected to a router or network switch. <Frame> <img /> </Frame> <Note> **Ethernet Connection Priority for the device's communication with Nayax's servers (not for Marshall communication)** When both Ethernet and SIM connections are active, the system automatically prioritizes the Ethernet connection. This ensures greater stability and faster network performance.\ Should there be any stability issues with the ETH connection- the device would switch to the SIM for communication, and after a period of time would attempt to re-connect to the ETH. **Marshall over ETH is not supported for VPOST** </Note> ## Installation - VPOS media ### Connect Marshall cable 1. Insert the Media device cable connector into the Nayax device.\ <ins>VPOSM5</ins>: <Frame> <img /> </Frame> <ins>VPOSM 4S</ins>: <Frame> <img /> </Frame> 2. <ins>**Marshall over RS232:**</ins> Connect the COM 2 (Marshall) connector to the PC either directly or via Chipi-x. Note that Chipi-x is the only USB-to-COM adapter approved by Nayax's technical team. <ins>VPOSM5:</ins> <Frame> <img /> </Frame> <ins>VPOSM 4S</ins>: <Frame> <img /> </Frame> <ins>**Marshall over ETH:**</ins> VPOSM5 and VPOSM4S support the feature of Marshall over ETH (LAN and WIFI). In that case, you can either connect your LAN connector to the device: <ins>VPOSM5:</ins> <Frame> <img /> </Frame> <ins>VPOSM4S:</ins> You'd use the USB-C-to-RJ45 connector cable (purchased separately) and connect it to the back of the device <Frame> <img /> </Frame> <Frame> <img /> </Frame> <br /> Or you can connect the device (VPOSM5/ VPOSM4S) to your WIFI network. <Note> **Note** The VPOS Media should be connected to the same local network as the peripheral. </Note> 3. For VPOSM5: Connect the antenna (optional if using ETH). As the manual that comes with the VPOS Media explains, put in the antenna: <Frame> <img /> </Frame> For VPOSM4S the antenna is built-in into the device itself (you won't see it, as it's inside of the device). # Marshall Integration Kit Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/sales-kit **VPOS Touch** The following components are part of the Touch device setup. Each plays a specific role during installation and operation: | Name | Description | Image | | :- | :- | :- | | **Touch Device** | The Nayax VPOS Touch Marshall device. | <Frame><img alt="" /></Frame> | | **Device Connector** | Connects power, cables, and additional accessories required for the device's operation. | <Frame><img alt="" /></Frame> | | **LAN (Ethernet Cable Port)** | Enables a wired connection to a router for internet access. | <Frame><img alt="" /></Frame> | | **Antenna** | Attaches cellular antenna for network communication. | <Frame><img alt="" /></Frame> | | **SIM** | SIM card for enabling data connectivity in Nayax Touch VPOS devices. | <Frame><img alt="" /></Frame> | | **Chipi-X USB2Com adaptor cable** | USB-to-serial adaptor cable for connecting Nayax Touch VPOS devices. | <Frame><img alt="" /></Frame> | | **24V DC power adaptor** | 24V DC power adaptor for powering Nayax Touch VPOS units. | <Frame><img alt="" /></Frame> | **VPOS Media5** The following components are part of the Media device setup. Each plays a specific role during installation and operation: <table> <thead> <tr> <th> Name </th> <th> Description </th> <th> Image </th> </tr> </thead> <tbody> <tr> <td> **Media Device** </td> <td> The Nayax VPOS Media Marshall device. </td> <td> <Frame> <img alt="" /> </Frame> </td> </tr> <tr> <td> **Device Connector** </td> <td> Used to connect power, cables, and additional accessories required for the device's operation. The cable consists of 3 parts. Appearing in the photo from left to right: The cable itself (the one with the RS-232 connector), the ANEX (the part with the blue cable), and the power adapter. </td> <td> <Frame> <img alt="" /> </Frame> </td> </tr> <tr> <td> **Antenna** </td> <td> Attaches cellular antenna for network communication. </td> <td> <Frame> <img alt="" /> </Frame> </td> </tr> <tr> <td> **SIM** </td> <td> SIM card for enabling data connectivity in Nayax VPOS Media devices. </td> <td> <Frame> <img alt="" /> </Frame> </td> </tr> <tr> <td> **Chipi-X USB2Com adaptor cable** </td> <td> USB-to-serial adaptor cable for connecting Nayax Touch VPOS devices. </td> <td> <Frame> <img alt="" /> </Frame> </td> </tr> </tbody> </table> <Danger> **Important:** The ETH cable should be connected directly to the device itself, and NOT via the Marshall cable. The RJ45 connector of the Marshall cable is not for LAN connectors but rather for DEX (as written on it). </Danger> <Frame> <img /> </Frame> **VPOS Media4S** The following components are part of the Media device setup. Each plays a specific role during installation and operation: | Name | Description | Image | | :- | :- | :- | | **Media Device** | The Nayax VPOS Media Marshall device. | <Frame><img alt="" /></Frame> | | **Device Connector** | Connects power, cables, and additional accessories required for the device's operation. | <Frame><img alt="" /></Frame> | | **Chipi-X USB2Com adaptor cable** | USB-to-serial adaptor cable for connecting Nayax Touch VPOS devices. | <Frame><img alt="" /></Frame> | | ETH adaptor (optional)- USB-C to RJ45 | Optional. Relevant in case you'd like the device to communicate with your peripheral through Marshall via ETH (as opposed to Wifi or serial connection with the cable) | <Frame><img alt="" /></Frame> | <Note> **Note:** VPOSM4S does not have a physical SIM card but rather an eSIM, and it also has an internal antenna. </Note> # Set Up Nayax Core for Marshall Integration Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/set-up-nayax-core-for-marshall-integration Once you have completed the Marshall installation process, follow the steps below to configure the Nayax device to support the Marshall functionality. ## Configure the machine model at the machine level This configuration enables your system to interact appropriately with the selected devices, ensuring efficient, optimal operation. Note that during the integration, your Nayax Integrator would be the one to set up virtual machines for you, but in case you'd like to learn how to do that yourself, below are the necessary steps to configure the machine model: 1. Log in to [**Nayax Core**](https://my.nayax.com/core/LoginPage.aspx?ReturnUrl=%2fdcs%2fpublic%2fdefault.aspx&_ga=2.5742451.1172703238.1627224233-738608359.1611493235) using your credentials. <Frame> <img /> </Frame> 2. Go to **Operations > Machines**. <Frame> <img /> </Frame> 3. Create a machine. If you need help, see the [**Create New Machine**](/docs/manage-data-operations/lynx-api/machines/create-new-machine-guides) guide. 4. In the **Machine Model** field, select one of the following options from the dropdown: <ins>For Amit:</ins> * RS232 – PC Machine - Marshall (Amit device) <ins>For VPOST/Onyx/VPOSM:</ins> For PreSelection (Single-Session / Multi-Session)/ if uncertain about the flow: * Marshall - Generic - Marshall - Basic PreSelection Video and manual regarding the configurations relevant to Single Session: [How to for Marshall Configurations | Single Session](https://nayax-u.nayax.com/scenario/how-to-for-marshall-configurations-single-session-54374) Video and manual regarding the configurations relevant to Multi-Session: [How to for Marshall Configurations | Multi-session with Pre-Selection](https://nayax-u.nayax.com/scenario/how-to-for-marshall-configurations-multi-session-with-53447) For Always Idle (PreSelection sub-flow): * Marshall - Generic - Marshall - Always Idle Video and manual regarding the configurations relevant to Always Idle: [How to for Marshall Configurations | Always Idle Pre-Selection](https://nayax-u.nayax.com/scenario/how-to-for-marshall-configurations-always-idle-pre-54427) For PreAuthorization: * Marshall - Generic - Marshall - PreAuthorization Video and manual regarding the configurations relevant to PreAuthorization [How to for Marshall Configurations | Pre-Authorization](https://nayax-u.nayax.com/scenario/how-to-for-marshall-configurations-pre-authorization-54263) 5. Click **Save** to apply the configuration. <Frame> <img /> </Frame> ## Configure session timeout parameter The **Multi-Session Mode** operates only in pre-selection mode but functions similarly to pre-authorization. The transaction flow is akin to a single vending process, with the addition of a **Close Session** command. If your machine works in the **multi-session mode**, set the session timeout parameters as follows: 1. For the configured machine, click the **General** tab. 2. Go to the **VMC** section. 3. Define the **Session Time Out** to specify the session’s duration: * **Maximum for Credit Cards:** 23 hours \*Update: as of 2025 — **71** hours\* * **Maximum for Prepaid Cards:** 72 hours * **Default:** 60 minutes * **Minimum:** 1 minute <Frame> <img /> </Frame> <Note> **Session Expiration and Settlement** Once the session timeout reaches the defined limit, the session expires. In such cases, the settlement amount will correspond to the price sent during the "vend request" command. Once a session has timed out, the device would settle the transaction on its own and send a "Status" command to the peripheral in order to notify it about the settlement taking place. This would let the peripheral know that it no longer needs to settle said transaction (as it has already been settled), and should he try to settle the already-settled transaction he would get "settlement error" (as the device couldn't find said session to settle it). </Note> ## Configure keep alive parameter The Keep Alive signal ensures consistent communication between the Nayax device and the machine by sending a signal every second. Adjust the parameters to enhance the system's tolerance as follows: 1. For the configured machine, click the **General** tab. 2. Go to the **VMC** section. 3. Set the **Keep Alive Intervals** (in seconds) to define the communication timeframe between the device and the machine (maximum: 255 seconds). <Frame> <img /> </Frame> <Note> **Keep Alive Communication Failure** If the device doesn’t receive the Keep Alive command within the time defined, then communication is failed, and the device will launch a Pairing process and send the Reset command again. It is highly recommended to keep it set to 1, and at most not have it above the value of 10- unless you're using VPOSM with Marshall over ETH, and in that case you can use 10 due to LAN limitations. Read more on that in the [Stability/ starvation issues](/docs/integrate-pos-device/marshall/additional-resources/stablity-issues#/) section. </Note> ## Configure cashless address The Cashless Address configuration ensures seamless communication between the machine and the Nayax device for cashless transactions. Follow these steps to set the correct address: 1. For the configured machine, click the **General** tab. 2. Click the **MDB** section. 3. Select the **Cashless MDB address** to **Marshall VMC**. <Frame> <img /> </Frame> ## Configure pre-selection and pre-authorization Pre-selection and Pre-Authorization settings allow flexible transaction flows tailored to different vending scenarios. Pre-selection enables multi-session operations, while Pre-Authorization focuses on card-based transactions with a defined credit limit. Configure these parameters as needed for your machine’s functionality. ### Pre-selection - multi-sessions Pre-selection supports Multi-Session operations, where one device can manage multiple transactions in parallel, each comprising two parts: product selection and authorization, and settlement. To configure this: 1. For the configured machine, click the **General** tab. 2. Click the **MDB** section. 3. Select **MDB Flags** and set **PreSelection Enabled** to **Yes**. <Frame> <img /> </Frame> This allows the system to offer product preselection before making a payment. The **Choose Product Timeout** option is the timeframe that the consumer is required to choose a product. When the transaction flow starts with the machine selection (PreSelection), then the **Choose Product Timeout** option <ins>must be defined as zero</ins>. 4. Click the **Payment** section. 5. Set the Choose Product Timeout to **0** seconds. <Frame> <img /> </Frame> This ensures there are no time restrictions on product selection during payment. ### Pre-selection – always idle Pre-selection in Always Idle mode ensures the machine remains ready for consumers. Use the following steps to configure: 1. For the configured machine, click the **General** tab. 2. Click the **Card Readers** section. * Set the Transaction Start Method to Product. <Frame> <img /> </Frame> 3. Click the **MDB** section. * Set the **MDB flags** to **Preselection Enabled**. <Frame> <img /> </Frame> * Set the **MDB Level 3 Optional Features** to **Enable “Always Idle” state**. <Frame> <img /> </Frame> The **Choose Product Timeout** option is the timeframe that the consumer is required to choose a product. When the transaction flow is “Always Idle”, the **Choose Product Timeout** option <ins>must be defined with a value **greater** than zero</ins>. 4. Click the **Payment** section. 5. Set the **Choose Product Timeout** desired value. <Frame> <img /> </Frame> ### Pre-authorization Pre-Authorization allows the system to secure funds before the vending process begins. Follow these steps to set it up: 1. For the configured machine, click the **General** tab. 2. Click the **MDB** section. 3. Select the **MDB flags** to **Flags Disabled**. <Frame> <img /> </Frame> 4. The **Choose Product Timeout** option is the timeframe that the consumer is required to choose a product. When the transaction flow starts with card authorization, the **Choose Product Timeout** option must be defined with a value greater than zero. 5. Click the **Payment** section. 6. Set the desired **Choose Product Timeout** value. <Frame> <img /> </Frame> The **Default Credit** option needs to be configured for Pre-authorization mode. This is the amount Nayax will charge for card pre-authorization. 7. Click the **Payment** section. 8. Set the desired **Default Credit** value. <Frame> <img /> </Frame> <Note> **Decimal Alignment for Pre-Authorization Value** The pre-authorization amount must be consistent with the Decimal Place configuration in the system settings. Ensuring proper alignment prevents transaction errors and ensures smooth payment processing. </Note> The Payment Flags option needs to be configured for Pre-authorization mode. 9. Click the **Payment** section. 10. Set the **Payment Flags** to **no flags set**. <Frame> <img /> </Frame> ## Configure LCD parameters To optimize the user experience, configure the LCD messages displayed during idle or disabled states. This includes customizing or disabling the **"Cash Only"** or **"Welcome"** messages to suit your machine's requirements. <Frame> <img /> </Frame> ### Cash only message for Amit and VPOS devices By default, the VPOS device displays a **"Cash Only"** message when it is disabled or in idle mode. This occurs when the Transaction Start Method is set to start with the machine. For Marshall devices, this is the normal state. However, to ensure better communication, the "Cash Only" message should be customized. Follow these steps to update the message: 1. Verify that the VPOS device is in idle mode or disabled. 2. Go to the **Machine page**. 3. Click the **LCD** section. 4. Enter an appropriate **Cash Only Message** that suits your needs. ### Cash only/welcome message for touch devices When the Nayax Reader is disabled, the idle screen features animations instructing the consumer to choose a product or service first. Additionally, a "Welcome" message can be customized or disabled as needed. Follow these steps to update the message: 1. Verify that the Nayax Reader is disabled and the idle screen displays the default animations. 2. To disable the Welcome message, send `@@` to the device in the **Welcome message attribute** using the LCD section on the **Machine page**. 3. To customize the Welcome message, click on the **LCD section** and enter an appropriate message (for example, "Swipe card" to start the transaction). 4. Click **Save** to store the customized Welcome message. ## Define the prepaid card(s) in the system Define the Prepaid Test Card(s) sent to the customer under the **Operator/Machine** so the customer can immediately begin their proprietary integration tests. Follow these steps to define the Prepaid Card(s): 1. Go to the **Operator/Machine** section in the system. 2. Define the Prepaid Test Card(s) that were sent to the customer. 3. Ensure the customer can begin their proprietary integration tests immediately. ## Additional configurations relevant for VPOSM5 * Marshall over ETH-\ If working with the ETH port instead of the serial port, you need to have the following configurations: <Frame> <img /> </Frame> Ensure that you have the matching configuration in the SDK. Meaning commented out the serial port line, and uncommented the ETH port line, and set the port in the same line to be 2025: ```csharp C# theme={null} //vmc_instance = marshall_init(new pc_port("COM8", 115200)); vmc_instance = marshall_init(new eth_port("192.168.1.117", 2025)); //ensure to set the IP to be the VPOSM5's IP ``` * Supporting the VPOSM5's QR barcode reader: Should you like to use the device's QR barcode reader, you should set the following Transaction Start Method (include QR in it): <Frame> <img /> </Frame> <Note> **Customer Support Assistance** Should specific help be needed in this matter, please turn to **Customer Support**. </Note> # HW Integration Kit and Setup Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/vpos-touch-installation This section contains different aspects of Nayax Touch Devices installation, including components included in the kit, physical mounting, and configuration on the Nayax Core. ## Available Guides <CardGroup> <Card icon="box-open" title="Marshall Integration Kit" href="/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/sales-kit"> Review the VPOS Touch components included in the installation kit. </Card> <Card icon="list-ol" title="Installation Steps" href="/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/installation-steps"> Mount and connect Nayax Touch and Media devices step by step. </Card> <Card icon="gear" title="Set Up Nayax Core for Marshall Integration" href="/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/set-up-nayax-core-for-marshall-integration"> Configure the Nayax device in Nayax Core to support Marshall functionality. </Card> </CardGroup> # SDK Log Generation Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/log-analysis/log-generation Logging shows you what the SDK is doing and how it's communicating with the peripheral. It's the main tool Nayax uses to diagnose issues in both the SDK's own behavior and its connection to the peripheral. ## Configuration To generate SDK logs, configure two flags in the `main` method. `debug` is a boolean that turns log generation on or off. `dump_packets_level`, in `vmc_configuration`, sets how much detail the SDK logs: | Value | What it logs | | - | - | | `debug_level_dump_none` | Nothing. No log is generated. | | `debug_level_dump_all` | Every message. | | `debug_level_dump_moderate` | Every message except keep-alives and their ACKs. | The example below sets both flags together. <CodeGroup> ```java Java theme={null} public static void main(String[] args) { vmc_config.dump_packets_level = vmc_configuration.debug_level_dump_moderate; vmc_config.debug = true; } ``` ```csharp C# theme={null} public class vend_machine { public static void Main(string[] args) { vmc_config.debug = true; vmc_config.dump_packets_level = vmc_configuration.debug_level_dump_moderate; } } ``` ```c C theme={null} vmc_init() config.dump_packets_level = debug_level_dump_none; ``` </CodeGroup> ## Log file location Where the SDK writes its log file depends on which SDK you use: * On the **C# SDK**, logs save automatically to the `bin\Debug` folder in the directory you run the SDK from. For example: <Frame> <img /> </Frame> * On the **C SDK**, you set the log location by invoking the function below. ```c C theme={null} printk_register_puts(terminal_tx_str); ``` The SDK sends its log output to whatever board or console you configure. It's up to you to decide where to write it: * Command line, as in the x86/Linux example below. * A UART port, as in the STM example below. * Any other destination you choose. ```c C theme={null} static void terminal_tx_str(char *str) { #if defined(__PLATFORM_X86) || defined(__PLATFORM_LINUX) printf("%s", str); #elif defined(__PLATFORM_STM32) drv_usart_tx_data(&terminal_usart, (uint8_t*)str, strlen(str)); #endif } ``` The C SDK's demo app generates the log to the command line by default. * On the **Java SDK**, you set the default log file path in the `FileWriter` initialization, as shown below: ```java Java theme={null} if (vmc_config.debug) { BufferedWriter out = null; try { FileWriter fstream = new FileWriter("c:\\out.txt", true); // true to append data out = new BufferedWriter(fstream); Log.initialize(out); } catch (Exception ex) { // Handle exception } } ``` In the example above, the log file is created at the root of the `C:` drive as `out.txt`. The `true` parameter in the `FileWriter` constructor appends new data to an existing log file instead of overwriting it. ## See also <Card icon="magnifying-glass-chart" title="Log Trace Comparator" href="/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator"> Once you have a log, run it through this tool to check it against known-good reference traces. </Card> # Log Trace Comparator Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator Use this tool to check a Marshall SDK or firmware log against known-good reference traces without reviewing it line by line. You can give it: * A log file (`.txt` or `.log`) * An Excel certification workbook, where each sheet is treated as one test * Log text pasted directly, on the **Paste log text** tab The tool runs it through the same nine checkpoints Nayax uses when reviewing your certification tests: boot handshake, reader state, vend and authorization flow, and session close. The [Checkpoints & Scenario Tags](/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator-guide) page documents each one. <Note> Everything runs locally in your browser. Log files never leave your machine, except for the "Learn more" links, which open Nayax's documentation. </Note> ## Setting the timing threshold The timing anomaly threshold sets how large a gap between two consecutive events in the log the tool flags as unusual. Gaps appear in the log as `+Xms`. The default is 15000 milliseconds, which is 15 seconds. Raise the threshold when a test includes an intentional long wait, such as a 24-hour idle test, a session timeout, or a stress test. For a one-hour wait, set it to 3600000. If you leave the default in place, the tool reports a failure on timing that is really the test working as designed. <MarshallLogTool /> ## Reading the results Each log or sheet gets a verdict badge: * <Badge>ALL CHECKS PASSED</Badge>: every checkpoint passed, no action needed. * <Badge>REVIEW RECOMMENDED</Badge>: at least one checkpoint raised a warning worth a manual look. Not necessarily a bug. * <Badge>FAILED CHECKS FOUND</Badge>: at least one checkpoint failed outright and needs attention. Below the badge, a trace strip shows one dot per checkpoint, in the same colors: * <Badge>Green</Badge>: pass * <Badge>Amber</Badge>: warning * <Badge>Red</Badge>: fail * <Badge>Hollow gray</Badge>: not applicable to that log For any checkpoint that isn't green, a "Suggested fix" box explains the likely cause and links to the relevant documentation. An evidence line shows the exact log line the checkpoint was based on. ## See also <CardGroup> <Card icon="file-lines" title="SDK Log Generation" href="/docs/integrate-pos-device/marshall/log-analysis/log-generation"> How to turn on SDK logging so you have a log to run through this tool. </Card> <Card icon="book-open" title="Checkpoints & Scenario Tags" href="/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator-guide"> The full checkpoint reference, scenario tags, and how to tell a real issue from a false positive. </Card> </CardGroup> # Checkpoints & Scenario Tags Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator-guide This page is the full checkpoint and scenario-tag reference for the Log Trace Comparator tool. Read it if the short legend on the tool page isn't enough, or if you're not sure whether a result is a real issue. ## Anatomy of a result card Each log or sheet gets its own card: * **File / sheet name**: formatted as `filename.xlsx → SheetName`, so it's clear which result came from which file or sheet when several are uploaded together. * **Verdict badge**: <Badge>ALL CHECKS PASSED</Badge>, <Badge>REVIEW RECOMMENDED</Badge>, or <Badge>FAILED CHECKS FOUND</Badge>. See the legend on the main tool page. * **Scenario tags**: automatic detection of the transaction type or scenario, such as Vend denied or Multivend. Full list below. * **Trace strip**: one dot per checkpoint, in the same order the checkpoints are listed below. The color legend is on the tool page. * **Suggested fix box**: appears when a checkpoint gets a warning or a failure, with a concrete recommendation and a "Learn more" link to the relevant documentation page. * **Evidence line**: the exact log line the checkpoint was based on, so you don't have to search for it manually. ## Scenario tags The tool tags each result with the scenario it detected, based on patterns in the log: | Scenario tag | Meaning | | - | - | | `Regular transaction` | A normal transaction, no special scenario detected | | `Multivend` | The tool found a Vend Multi-Request, a multi-product transaction | | `Multisession-capable build` | The build supports multiple parallel sessions (a build capability, not necessarily exercised in this log) | | `Info session (card read only, no vend)` | An information-only session, card details are read but nothing is vended. A "vend denied" outcome here is normal | | `Card rejected — retry requested (unsupported/expired card)` | The card itself was rejected by the reader (status 78/84), usually an unsupported or unreadable card, not an SDK bug | | `Explicit vend failure (no dispense)` | The acquirer approved payment, but the product wasn't dispensed (Vend Failure) | | `Vend denied` | The acquirer or issuer declined the transaction | | `Cancelled / aborted vend` | The user cancelled the transaction (X button or Cancel) | | `Cancelled before card presented` | The user never presented a card before the session closed | | `Session timeout` | The session closed because a timeout expired | | `Settlement failed` | Settlement failed explicitly | | `Communication lost (e.g. SIM removed / no signal)` | No cellular or network connectivity, settlement is stuck | | `eReceipt` | The tool detected a QR or e-receipt in the log | | `Not a recognized Marshall log` | The file or sheet doesn't contain a Marshall log at all, for example source code or a metadata sheet | ## The 9 checkpoints Every result runs through the same 9 checkpoints, grouped into four categories that match the trace-strip order on the tool page. Each row shows what a checkpoint checks and what each verdict means: | Category | Checkpoint | What it checks | What each verdict means | | - | - | - | - | | Initialization | SDK boot handshake | Whether the initial pairing sequence (reset, config, transfer\_data, online) completed in full. | **Pass**: all 4 events found, boot completed normally.<br />**N/A**: this log doesn't include a boot section (a partial capture, which is normal).<br />**Warning**: only 1-3 of 4 found, the capture may start partway through boot. | | Initialization | Reader reaches idle | Whether the device reached Reader Enable and status 20 (available). | **Pass**: both found.<br />**Warning / fail**: the device never reported itself available, usually a communication, wiring, or power issue. | | Transaction | Vend/info request issued | Whether a Vend or Info Session request was sent at all. | **Pass**: a request was found.<br />**N/A**: no vend request in this log (may be a boot-only log, which is fine). | | Transaction | Card read & authorization | Whether card data (`card_type`/`prop_card_uid`) and an MDB (Multi-Drop Bus) approval (code 3 or 5) were both read. | **Pass**: both found.<br />**Warning**: only partial data, or the card was rejected by the reader itself (status 78/84, normal, not always a bug). | | Transaction | Vend outcome resolved | What the vend outcome was: approved, denied, cancelled, or failed to dispense. | **Pass**: full Vend Success.<br />**Warning**: denied, cancelled, or Vend Failure (often expected, depending on the scenario).<br />**Fail**: no outcome was ever received, the flow may have hung. | | Session | Session closed cleanly | Whether end session was received and the device returned to ready/idle. | **Pass**: both found.<br />**Warning / fail**: the session wasn't fully closed, may still be stuck open. | | Session | Settlement result | Whether settlement completed successfully. | **Pass**: settlement done / success.<br />**Fail**: an explicit settlement error.<br />**Warning**: stuck pending, for example due to no cellular connectivity. | | Health | Communication / firmware errors | Count of Mac Send-retry, GUI Task Fail, session timeout, or CPU starvation events. | **Pass**: 0 events, or a low count also seen in known-good logs.<br />**Warning**: higher than usual, an explicit timeout, or explicit starvation. Refer to the stability guide. | | Health | Response timing | Whether there are time gaps (`+Xms`) above the configured threshold (default 15,000ms). | **Pass**: no unusual gaps.<br />**Warning / fail**: gaps found. Sometimes this is an intentional wait (24-hour idle test, session timeout, stress test) rather than a real issue, see the next section. | Before those nine run, the tool checks that the input looks like a Marshall log at all. If it finds none of the expected markers, it stops there and reports a single **File format check** result instead, tagged "Not a recognized Marshall log". That badge means the file was not recognized as a log, not that the log has a problem. Check that you uploaded the right file or sheet, and that it isn't a cover page or a notes sheet. ## Is it a real issue or a false positive? The tool is a fast first-pass filter. It doesn't replace professional judgment. Before you report an issue to your Nayax integrator, check this list: * **Does the sheet or test name suggest intentional behavior, such as timeout, idle, stress, or cancel?** A warning or failure on timing or on the vend outcome may be exactly what that test is meant to demonstrate. * **Is this an info session?** "Vend denied" is correct there, not a bug. The tool already recognizes this and marks it as passed, but it's worth double-checking. * **Is the only failing checkpoint response timing, with everything else passing?** That's very likely a wait, not a real issue. * **Is there a suggested fix box?** Read it and follow the "Learn more" link. It explains whether the behavior is normal for the protocol, or whether it needs a fix in your implementation. * **Was the sheet even recognized as a log?** If you got "Not a recognized Marshall log," check that you uploaded the right sheet and that it isn't a metadata or notes sheet. Whenever in doubt, open the evidence line and read the exact log line in its full context in the original log. Here is what that looks like in practice. A certification file for a multisession, always-idle flow might include a test called "24 hours in idle mode" that fails only on response timing, with 4 gaps above the threshold. That is not a bug: it is the point of the test. The right move is to ignore that failure, or to raise the timing threshold before running the comparison, rather than reporting it as an issue. ## Exporting a report, or starting over Once you've reviewed the results, two actions are available in the footer: * **Download report (.txt)**: downloads a full text summary of all results, including detail and recommendations. Useful for attaching to a support ticket, or for sending to your Nayax integrator. * **Clear all**: clears all files and results to start a fresh check. <Warning> "Clear all" has no undo. Download a report first if you want to keep a copy of the current results. </Warning> ## Known limitations Keep these in mind before treating a result as final: * The tool only detects the first request of each kind, for example the first Vend request. In a log with dozens of back-to-back transactions, such as a stress test, the detail refers to the first transaction only, not each one. * The response timing checkpoint can't distinguish an intentional wait from a real problem; human judgment is required, see the section above. * All the logic is based on text patterns derived from real examples. If the SDK changes existing message wording, a checkpoint might miss it. * The tool never sends data anywhere. All analysis happens locally in the browser. Only the "Learn more" links open a connection to the internet, and only if you click them. ## See also <Card icon="magnifying-glass-chart" title="Log Trace Comparator" href="/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator"> The tool itself, with a short intro and the results legend. </Card> # Log Analysis Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/log-analysis/overview This workflow covers turning on SDK logging, running a log through the comparator tool, and reading what the results mean. Use it before you send a certification test result to your Nayax integrator, or whenever you are debugging a Marshall integration. ## What the Log Trace Comparator is The Marshall Log Trace Comparator is an automated log-comparison tool for the Marshall SDK and firmware protocol. It reads a log file, or an Excel certification workbook, and runs it through the same nine checkpoints Nayax uses when reviewing your certification tests. For every checkpoint that fails or needs a look, it shows a suggested fix and a link to the page that explains it. The checkpoints come from real passing and failing logs, collected across all three SDK languages: C, C#, and Java. Everything runs in your browser, so your log files never leave your machine. ## What it does not do The tool is a fast first pass. It does not replace your own judgment, and it does not decide whether your integration passes certification. Your Nayax integrator does that. A warning is also not the same as a bug. Some tests are designed to produce one: a 24-hour idle test, a session timeout, and a stress test all report timing failures that are the test working as intended. Read the test name before you act on a result. ## Next steps <CardGroup> <Card icon="file-lines" title="SDK Log Generation" href="/docs/integrate-pos-device/marshall/log-analysis/log-generation"> Turn on SDK logging so you have a log file to run through the tool. </Card> <Card icon="magnifying-glass-chart" title="Log Trace Comparator" href="/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator"> Drop in a log file or certification workbook for an instant pass/fail verdict against known-good reference traces. </Card> <Card icon="book-open" title="Checkpoints & Scenario Tags" href="/docs/integrate-pos-device/marshall/log-analysis/log-trace-comparator-guide"> The full checkpoint reference, scenario tags, and how to tell a real issue from a false positive. </Card> </CardGroup> # Marshall C SDK Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-c-release-notes Track Marshall C SDK changes as they ship. Nayax logs Marshall C SDK changes on this page as they ship. Subscribe to the RSS feed using the icon at the top of the page to get notified of new entries. <Update label="C 0.0.2.29 (28.10.2025) (Current)"> Every C SDK version is listed below, from the current version down to the first release. | Version | Date | Summary | | - | - | - | | **0.0.2.29 (Current)** | **October 28, 2025** | **Added site ID and brand name transfer via transfer data and a new technician-mode command to open the door remotely; enhanced error handling with improved validation and more descriptive messages; fixed a bug related to a high `com_id` value** | | 0.0.2.28 | January 30, 2025 | Fixed a crash on cancel after `session_begin` and before `vend_request` | | 0.0.2.27 | December 16, 2024 | Transaction data is now cleared when returning to ready mode after a transaction finishes | | 0.0.2.26 | October 13, 2024 | Fixed a crash when canceling an info session | | 0.0.2.25 | October 13, 2024 | Added e-receipt support; fixed an issue handling consecutive frames received immediately from VPOS | | 0.0.2.24 | September 25, 2024 | Fixed an issue with canceled transactions | | 0.0.2.23 | April 8, 2024 | Added `long_price` support; `cpu_platform_get_time()` now returns a 64-bit value, fixing an overflow after 50 days; fixed the demo app's quit option not actually quitting | | 0.0.2.22 | April 8, 2024 | Added QR-code entry mode and third-party authorization support, a new sample application demonstrating API usage, and out-of-the-box Linux and Windows platform support | | 0.0.2.21 | April 8, 2024 | Added a display control API (`vmc_general.h`) and Keil compiler support | | 0.0.2.16 | April 5, 2023 | Fixed info session to work in always-idle setups | | 0.0.2.15 | April 4, 2023 | Added `card_sub_type` and `card_balance` transfer\_data fields and a check-balance session type | | 0.0.2.14 | January 4, 2023 | Added new transfer data fields; updated discount and final price logic for all payment types | | 0.0.2.13 | January 1, 2023 | Added new transfer data fields | | 0.0.2.12 | December 20, 2022 | `session_status` on the session object is now filled in by the SDK to report the transaction cancellation reason; added the `on_status` event callback, the `vmc_vend_event_on_session_timeout` event, and `vmc_link_get_version()` | | 0.0.2.11 | December 12, 2022 | Fixed segmentation faults printing the "moderate" log level and issuing an info session, a missing `transaction_id_len`, and a vend-cancel bug in always-idle mode | | 0.0.2.10 | December 6, 2022 | Improved rx buffer management to handle concatenated frames | | 0.0.2.9 | October 18, 2022 | Added the ability to dynamically allocate the `vmc_buffer_t` array (behind `VMC_DYNAMIC_ALLOCATION`) and crc/link statistics; fixed a socket-transmit bug so a busy socket now raises a busy event for retransmission | | 0.0.2.8 | August 24, 2022 | Added `vend_status(bool)` for explicit vend success and the total charged (and discount, if any) on the session structure | | 0.0.2.7 | July 25, 2022 | Fixed a pointer-conversion segmentation fault, an opened-sessions query always returning 0, and a `TransferData()` TransactionID length bug (extended from 4 to 8 bytes) | | 0.0.2.6 | April 6, 2022 | Added `unit_of_measure` enums to `vmc_vend`, new vend events (`session_cancled`, `sessions_rsp`, `reader_state_rsp`), QR code (e-receipt) handling, `is_in_middle_of_transaction()`, and new `fw_info` fields; fixed a bug where vend-deny persist mode stayed always-on even after a successful transaction | | 0.0.2.5 | July 20, 2021 | Fixed a multi-vend items bug | | 0.0.2.4 | June 17, 2021 | Fixed a multi-vend crash on an overflowing number of items | | 0.0.2.3 | May 19, 2021 | Added updated status codes, the `on_status` vend event, an alert feature, and support for 8-bit slim micro-controllers, plus various other bug fixes | | 0.0.2.2 | April 28, 2021 | Added updated status codes, the `on_status` vend event, and an alert feature | | 0.0.2.1 | March 17, 2021 | Added compilation flags to reduce flash usage and disable unused modules (socket, general, etc) | | 0.0.2.0 | October 1, 2020 | Added a time-update API, experimental HTTP and FTP client libraries, and native big/little-endian platform support; fixed a `vmc_socket` state-machine stall, a multi-vend bug, and an always-idle bug | | 0.0.1.3 | September 15, 2020 | Added a link events handler | | 0.0.1.2 | September 9, 2020 | Fixed a multi-vend bug | | 0.0.1.1 | August 28, 2020 | Added the Monyx card | | 0.0.1.0 | August 3, 2020 | Added a debug-level packet dump option, a vend-denied policy, and a machine type parameter | | 0.0.0.2 | April 16, 2020 | Updated transfer\_data functionality; added an STM32F0 sample application with UART/DMA support | | 0.0.0.1 | March 12, 2020 | Initial release | </Update> # Create Payments Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-create-payments Once the SDK is running and the connection with the Nayax device is established (`onReady()` has been triggered), the device is ready to handle vending and cashless transactions. This guide shows you how to set up and manage cashless payment transactions from your peripheral's controller using the Nayax Marshall SDK. ## Pre-requisites * Ensure your SDK is running and connected to the Nayax device indicated by the `onReady()` event. <Warning> **Integration** If you have not finished the integration process, check the [Get Started](/docs/integrate-pos-device/marshall/get-started/marshall-get-started) page before continuing. </Warning> ## Create a payment To perform a transaction using the Nayax Marshall SDK, follow the steps below. 1. Start by enabling the device for transactions. <CodeGroup> ```java Java theme={null} m_vmc.vend.session_start(vmc_vend_t.session_type_credit_e); ``` ```csharp C# theme={null} vmc_instance.vend.session_start(vmc_vend_t.session_type_credit_e); ``` ```c C theme={null} vmc_vend_session_start(vmc_vend_session_type_credit_e); ``` </CodeGroup> 2. When a client presents a card and it is approved, the `onSessionBegin()` event is triggered. This is the signal for the peripheral, such as the vending machine, to prepare for payment approval. <CodeGroup> ```java Java theme={null} m_sessions[0] = new vmc_vend_t.vend_session_t((short) 0, 1, (byte) 0, 10); //the fields are (from left to right): produce code (2 bytes long, meaning value up to 65535), quantity (2 bytes), unit of measure (1 byte), price (2 bytes, meaning value up to 65535) ``` ```csharp C# theme={null} List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t> (); list.Add(new vmc_vend_t.vend_item_t(0, 10, 1, 1)); //the fields are (from left to right): produce code (2 bytes long, meaning value up to 65535), price (2 bytes, meaning value up to 65535), quantity (2 bytes), unit of measure (1 byte). session = new vmc_vend_t.vend_session_t(list); ``` ```c C theme={null} session_product.code = 1; session_product .qty = 1; session_product.price = 10; session_product.unit = 1; session->products = &session_product; session->total_products = 1; ``` </CodeGroup> <Warning> **Price field** The price field is set as an integer, meaning it does not take into consideration the Decimal Place: the actual price is calculated by the device based on the Decimal place- meaning if you set a price of 50 in the SDK, the peripheral would send a price of 50 to the device, who would look at its own Decimal Place setting and would multiply the price sent by 10^(-decimal place). Meaning if the device has a Decimal Place of 2, the actual price the device would attempt to charge the consumer would be 0.50.<br />More on that on [Decimal Place](/docs/integrate-pos-device/marshall/marshall-faqs/faq#decimal-place). This means that in case the device is using a Decimal Place of 2, the highest price would be 655.35 (0XFFFF with decimal of 2). </Warning> <Note> **Multi-vend Session** For a multi-vend session, when the consumer is able to select multiple items in one transaction, enable the `multi_vend_support` flag. The session would then include a list of products.<br />You can review an example of it in the demo apps. </Note> Then, inside the onSessionBegin() callback you would send the "Vend Request" for said session (transaction): <Note> <CodeGroup> ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```c C theme={null} vmc_vend_vend_request(session); ``` </CodeGroup> </Note> 3. After the VPOS approves the vending request, the peripheral must notify the SDK that the product has been successfully delivered to the consumer. This is done by implementing the `onVendApproved(...)` API and returning one of the following: * **`True`**: If the vend process is successful, the client's credit card is charged the requested amount. * **`False`**: For a failed vend process. 4. Whether it’s a single session or multi-session, the `onReady()` event will be called upon finishing the vending process, indicating that the device is ready for the next transaction. <Note> **Multi-Session** For multi-session configurations, when the session on the peripheral's end is finished, it is up for the peripheral to close the session in order for the transaction to be settled: <CodeGroup> ```java Java theme={null} m_vmc.vend.session_close(m_session) ``` ```csharp C# theme={null} m_vend_machine.vend.session_close(m_vend_machine.session) ``` ```c C theme={null} vmc_vend_session_close(session) ``` </CodeGroup> </Note> Following these steps ensures that the vending process, from card presentation to product delivery and payment, is handled efficiently and securely using the Nayax Marshall SDK. ## See also <CardGroup> <Card title="Get started" icon="rocket" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Get up and running with the Marshall SDK integration. </Card> <Card title="Methods & functions" icon="code" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> # Marshall C# SDK Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-csharp-release-notes Track Marshall C# SDK changes as they ship. Nayax logs Marshall C# SDK changes on this page as they ship. Subscribe to the RSS feed using the icon at the top of the page to get notified of new entries. <Update label="C# 0.0.5.20 (Current)"> Every C# SDK version is listed below, from the current version down to the first release. | Version | Summary | | - | - | | **0.0.5.20 (Current)** | **Consolidated low-level serial rx handling in `lowlevel_serial_t` (head-only framing, a poll-friendly sleep, and a named reader thread); fixed a `vmc_link` link-down issue where a missed ack left a packet pending forever and stopped keepalive (retransmit is no longer gated on transmit exceeding receive); `vmc_vend_t` now handles `session_end` and `send_transfer_data` globally in any state for a more robust vend flow** | | 0.0.5.19 | Improved link reliability and fixed false retransmissions | | 0.0.5.18 | Fixed a race condition between the rx and tx threads on `m_pending_tx_msg` access | | 0.0.5.17 | Added the `pre_auth_amount_config` (0x8c) vend sub-command, including the message class, decode/encode support, a factory method, event handling, and the public API; added demo menu options to align with the Java SDK (check balance, prepaid pay, pre-auth config, display message, close socket) | | 0.0.5.16 | Multi-vend max products per Marshall message are now calculated from the negotiated max message size; fixed the `session_end` timeout expiring too soon, which caused `reader_always_on` to fire early | | 0.0.5.15 | Aligned the C# SDK with the Java SDK across all modules: fixed transfer\_data bitmap constants and several encode bugs (`msg_time_rsp_t`, `msg_setup_max_min_prices_t`, `msg_remote_selection_t`, `msg_expansion_t`, `msg_reader_state_t`), added missing message classes and factory dispatch for vposm\_ext/ev\_ext messages, added `consumer_id` and other transfer\_data fields, and fixed numerous session, socket, and general-module bugs across `vmc_vend_t`, `vmc_general_t`, `vmc_socket_t`, and `vmc_link` | | 0.0.5.14 | Added real-time price change support for always-idle mode, even after the reader is already enabled, and a sanity check so `vend_request` and `close_session` return a boolean value and reject a price exceeding the permitted amount (65k when `long_price` is disabled); fixed a `session_id` decode issue on `msg_single_vend_t` and updated multi-vend request logging | | 0.0.5.13 | Aligned the C# SDK with the Java SDK; fixed `multi_vend_session_close` encoding | | 0.0.5.12 | Added protection against vend, socket, and general actions being issued when there is no link, preventing unnecessary crashes; optimized `eth_port` logging | | 0.0.5.11 | Removed an unnecessary and alarming "spurious ack" warning; fixed `eth_port` to recover when VPOS restarts but the socket does not close on the VMC side, by closing and reconnecting | | 0.0.5.10 | Fixed multi-vend multi-session packet encoding | | 0.0.5.09 | Fixed a potential packet loss from buffer wraparound that triggered retransmission and a bug where card data was not cleared after a transaction ended; `eth_port` is now functional | | 0.0.5.08 | Added enhanced display control (VPOSM) with legacy support for VPOS Touch devices and updated the sample application to support various display control layouts; stabilized the `eth_port` implementation | | 0.0.5.07 | Fixed frame-size detection with better sanity checks to support varying Marshall message sizes; added a `flush()` call to the port interface | | 0.0.5.06 | Added site ID and brand name transfer to the machine via transfer data and a new technician-mode command to open the door remotely; fixed long price for a single product | | 0.0.5.05 | Added brand selection and custom `transaction_id` generation | | 0.0.5.04 | Fixed an issue receiving `on_begin_session` on the latest SDK | | 0.0.5.03 | Added long price support (VPOSM) and QR third-party authorization support; fixed the negative price display issue | | 0.0.5.02 | Removed a CPU starvation warning that was confusing implementers | | 0.0.5.01 | Removed `lowlevel_serial`; you now inject a `serial_port_i` implementation (a working `pc_port.cs` is provided); fixed the VPOS serial number being returned as raw bytes instead of a correctly arranged string | | 0.0.4.23 | Fixed a re-transmission bug in buffer management that could lose consecutive packets arriving at the same time, an `mdb_rsp` parsing bug (Marshall master), a `lowlevel_serial` buffer management bug, and a string TLV decoding bug affecting transfer\_data parsing | | 0.0.4.22 | Added a `session_id` field to `vend_session_t` for multi-session reference; fixed an error parsing `msg_display_event_t` that skipped the user callback | | 0.0.4.21 | Fixed `card_balance` decoding and possible crashes parsing transfer\_data, including variable-length integer fields; changed the .NET version to 4.6.2 | | 0.0.4.20 | Added a logger API to dump raw data to a log file | | 0.0.4.19 | Fixed an undefined state machine state when `on_begin_session` arrived without a session starting, and deadlock risks from calling the API regardless of link state or stalling a callback while waiting for `end_session`; added the ability to send transfer data throughout the transaction starting at card detection, and added SDK configuration logging | | 0.0.4.17 | Added check-balance session type, card sub type and card balance transfer\_data, vend discount/final price calculation, and support for switching to an info session on always-idle setups; fixed e-receipt not working on multi-session setups, a race condition between rx and tx threads causing retransmission of an already-acked packet, and a possible crash when losing communication while sending `reader_enable` | | 0.0.4.16 | Fixed a multi-instance bug affecting both the sample application and the SDK | | 0.0.4.15 | Added the ability to instantiate multiple Marshall links | | 0.0.4.14 | Fixed the item price and code API type (integer to short) and a crash when cancelling a session after the card is presented but before vend is requested | | 0.0.4.13 | Fixed a transfer\_data parsing error that missed several tags | | 0.0.4.12 | `session_status` on the session object is now filled in by the SDK to report the transaction cancellation reason; fixed session cancel in always-idle mode; optimized `lowlevel_serial` CPU usage | | 0.0.4.11 | Added packet dumps on rx re-arrangement for debugging; improved `lowlevel_serial` handling under stress | | 0.0.4.10 | Added `vend_status(bool)` for explicit vend success, the total charged (and discount, if any) on the session structure, and absolute POSIX timestamps in log lines; renamed `Log.initialize()` to `Log.stream()`; fixed a vend-cancel timing bug and a false CPU warning on SDK initialization | | 0.0.4.9 | Added an extra data parameter to the `onStatus` API and `device_not_available_reason` enums; fixed a faulty transfer\_data parsing issue; the sample application now shows a human-readable status code and extra VPOS info on `onReady` | | 0.0.4.8 | Added `Log.console(boolean)`, new transfer\_data fields (main and POS firmware versions, Monyx ID, default credit), new device status enums, and the `onSessionTimeout(id)` event; reworked the sample application | | 0.0.4.7 | Added `unit_of_measure` enum values to `vmc_vend`; aligned log output between terminal and file | | 0.0.4.6 | Improved `lowlevel_serial` link reliability; fixed the `fw_info` field arrangement, a vend session status request bug, and a `vmc_socket` busy/retransmit timeout bug | | 0.0.4.5 | Added semaphore protection on the `tx_buf` reference critical section | | 0.0.4.4 | Aligned with Marshall 3.0: added session status query, an `fw_info` SDK version string field, reader state retrieval, entry type enum, QR e-receipt, and remote vend; added CPU monitoring, a multi-vend product limit to avoid buffer overflow, and additional VMC info fields to `fw_info`; rewrote the sample application | | 0.0.4.3 | Added the ability to start and stop file logging at runtime | | 0.0.4.2 | Fixed a UI event bug | | 0.0.4.1 | Added protection against disabling the reader in idle mode and display event callbacks | | 0.0.4.0 | Added display control support, extra status codes, and the `onStatus` vend callback (see `marshall_t.status_xxxx`) | | 0.0.3.5 | Fixed MSR card encoding | | 0.0.3.4 | Added serial port access protection to `lowlevel_serial_t` and optimized access; changed the vend `onReady` callback to provide the last session object (null on the first call) | | 0.0.3.3 | Fixed an error calling `start_session` from `onReady()` | | 0.0.3.2 | Added the ability to direct SDK logs to a file and the Monyx card to the `card_type` enum; fixed a multi-vend crash from invalid log string formatting and a `get_transaction_id()` bug returning an invalid date inside `onTransactionInfo` | | 0.0.3.1 | Added serial packet dump-level and vend-denied policy parameters, and a `session_timeout` status type on the session class | | 0.0.3.0 | Updated to the latest Marshall protocol revision: link establishment now reports merchant ID, terminal ID, and machine location; added socket MTU and timeout configuration | | 0.0.2.17 | Clarified that the empty-queue error is a notification, not an error | | 0.0.2.16 | Fixed the always-idle bug | | 0.0.2.15 | Updated the `vmc_general` events interface; fixed `reader_always_on` to apply only when always-idle is explicitly disabled | | 0.0.2.14 | Added the ability to enable or disable log output and an always-idle sample | | 0.0.2.13 | Fixed a "stop" issue preventing restart; added `vmc_framework.get_version()` | | 0.0.2.12 | Fixed a critical link bug | | 0.0.2.11 | Added the paymarket machine type; changed the EV-charger machine type | | 0.0.2.10 | Added machine type to configuration and always-idle mode; improved socket handling; fixed a false mismatch-message-ID warning, a fund-available conversion issue, and a machine serial/version/model string length limit | | 0.0.2.9 | Fixed a link bug that sometimes tried to transmit from an empty queue | | 0.0.2.8 | Added parsing of the transfer\_data structure on vend sessions for detailed, readable information | | 0.0.2.7 | Improved socket logging and changed the low-level interface; the `onReady(...)` callback now transfers VPOS configuration; added a `multi_vend_support` flag to `vmc_configuration` (VPOS must be configured for pre-authorization to use multi-vend sessions); fixed a bug preventing some Marshall APIs from being called from `onReady(...)` | | 0.0.2.6 | Unified the vend request API for single and multi-vend, with products declared on `vend_session_t` | | 0.0.2.5 | Added quantity reporting to DCS (requires VPOS 4.0.1.5 rc9 or newer) and a transaction ID report API; fixed session cancel issues after a card is presented but before vend is requested, and when closing a session while the reader is enabled | | 0.0.2.4 | Fixed model/version reporting to DCS; separated the keep-alive timer from the configured timeout | | 0.0.2.3 | Added a log message and link statistics; fixed a buffer-index parsing bug in the middle of the master buffer | | 0.0.2.2 | Fixed a communications issue | | 0.0.2.1 | Fixed a re-transmit timeout that sometimes fired too fast | | 0.0.2.0 | Improved the `low_level_serial` example; added handling for Marshall piggy-back messages; fixed a re-transmit bug | | 0.0.1.9 | Added a VMC auth sample; improved the `low_level_serial` example | | 0.0.1.8 | Fixed a link issue; added CC last-4-digits transfer data | | 0.0.1.7 | Added reader-always-on mode and cash sale | | 0.0.1.6 | Fixed a session close status bug; added a cash sale notification API | | 0.0.1.5 | Added Mifare/mag auth support | | 0.0.1.4 | Added socket support and info session support | | 0.0.1.3 | Initial version | </Update> # Device Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-faqs/faq ## Device being stuck on "Nayax" screen during power-up- communication issue: This could happen due to multiple reasons: 1. Modem connection issues/bad cellular reception/ connected to ETH, and the connection is poor. Do you happen to use ETH? Or have the devices near something that would block cellular reception? 2. Wrong modem type (for example, a European modem in the US) or a modem that is not too strong. Which modem type are you using? 3. SIM card not installed/supported (for example, a SIM card that you bought outside of Nayax)/all used up. Which SIM are you using? 4. The antenna is not appropriately connected/ wrapped up around itself/pointing downwards/ around a metal box. Can you have a look at it? 5. If the device reaches the Nayax logo and then crashes, do you have a 24V power source with a minimum of 1.5A? The device is connected to the Marshall cable, but the device is in Cash Only mode. Which COM have you connected to your board? Is it COM2 as mentioned in the "Installation Guide"? If you're using a Chipi-X (a specific USB-to-serial adapter, the only one that grants support privileges), does it appear to be connected to a hub? Try connecting it directly to the PC. ## Everything is connected as expected, but things still don't work- what now? 1. Check the parameters in Nayax Core. 2. Check that the physical connection meets the instructions in [Installation Steps](/docs/integrate-pos-device/marshall/hw-integration-kit-and-setup/installation-steps#/). 3. If OK, reboot the device: * Disconnect from power * Wait for the screen to go black * Power the device back on 4. Check that in the SDK code, you changed the COM port to the correct one. 5. Compile and Run the SDK: a. Do you see the peripheral simulator's menu and pairing process displayed in the prompt window? b. Do you see in the log file that the Pairing process ended successfully? ## Using 12V power source (instead of 24V) 12V is on the verge of not being sufficient power for the device to operate (it would make it hard for the device to distinguish between '0' and '1'). It can also cause packets to be sent/received improperly (leading to retries) and result in CRC errors. It can also cause the device to crash during powerup as during the powerup process there is a spike in energy consumption. In addition, if you are using Chipi-x, it also consumes energy, making the 12V even less likely to be sufficient for the device's valid operation. ## VPOSM (4S, 5) - activating the device The first step is to scan the QR code displayed on the device screen with the phone’s camera. <Frame> <img alt="" /> </Frame> Next, you will be redirected to a landing page where you will be required to enter the following details. After submission, a verification code is sent via email, which must be entered on the landing page to complete the device activation. <Frame> <img alt="" /> </Frame> <Note> **Note:** VPOSM 4S is not yet supported (only VPOSM5 as of now). </Note> ## VPOSM (4S, 5): getting the device's details (serial number, IP) You'd tap the top left corner of the screen 7 times, and a menu would appear: <Frame> <img alt="" /> </Frame> Then you'd click on the Device Info, and you'd get the device's serial number as well as information about its communication details, both cellular and Ethernet.<br />In this example, the device has an eSIM (as in this example, it's VPOSM 4S, which will always have an eSIM,) and it's also connected to WIFI, so you can see that it's connected to the WIFI and the device's IP address: <Frame> <img alt="" /> </Frame> Should you like to return to the device's idle screen (to make transactions), click the top-left arrow, then select the Payment APP screen. ### VPOSM- configuring communication (wifi / LAN) VPOSM over Marshall supports either DHCP or Static IP (depends how the client wants to work). DHCP is the default for the device, but it can be changed to Static IP from the device menu:<br />click a couple of times on the top-left corner of the screen and select "Technician Menu": <Frame> <img alt="Image" /> </Frame> And insert the code (by default it's 123123) and scroll down to the "Communication" section:<br /> <Frame> <img alt="Image" /> </Frame> <br />Then go into Wifi or LAN (depending on your connection type):<br /> <Frame> <img alt="Image" /> </Frame> <br />And into the desired network and edit its' settings: go to the "Advanced" section and under it you'd see "IP settings"- which would be DHCP by default, or changed to "Static". #### Configuring Wifi (and IP) Click on the gears icon of the relevant network <Frame> <img alt="Image" /> </Frame> Then on "Advanced": <Frame> <img alt="Image" /> </Frame> And scroll down to IP settings: <Frame> <img alt="Image" /> </Frame> And fill in the IP details. #### Configuring ETH (and IP) On **<u>VPOSM4S</u>** you'd click on the Ethernet option right away, and you'd be prompted to enable the Ethernet connection and edit its settings: <Frame> <img alt="Picture10" /> </Frame> Then, go into the Setting Ethernet and you could enable the static settings: <Frame> <img alt="Picture11" /> </Frame> And fill in the details. On **<u>VPOSM5</u>** On the WiFi settings screen, tap the back arrow at the top-left to return to the device's system settings. <Frame> <img alt="Image" /> </Frame> Tap Network & Internet: <Frame> <img alt="Image" /> </Frame> Tap Ethernet: <Frame> <img alt="Image" /> </Frame> Turn Ethernet on using the toggle, then tap the Ethernet row again to open Ethernet Settings: <Frame> <img alt="Image" /> </Frame> In Ethernet Settings, select Static: <Frame> <img alt="Image" /> </Frame> And fill in the details. ## Changing idle screen/customization of screens/UI control At the moment, only the following modifications are available: * At IDLE state, you can select the pictures/animations to be displayed over our DCS back office. You can also add a customized image, e.g., your company's logo. <Frame> <img alt="" /> </Frame> * Change the "Please select a product" title. <Frame> <img alt="" /> </Frame> * Change the title in idle mode: <Frame> <img alt="" /> </Frame> * Or the product selection message: <Frame> <img alt="" /> </Frame> * Remove the audio of the product selection screen: <Frame> <img alt="" /> </Frame> * Removing any of the following audios: <Frame> <img alt="" /> </Frame> <Frame> <img alt="" /> </Frame> * At the end of the transaction, you can remove the "Thank you and goodbye" message: both the picture and voice message will not be displayed/played. <Frame> <img alt="" /> </Frame> For VPOS Touch- During the transaction process, there is not much to do in terms of UI, and neither messages nor images/animations can be customized. Regarding VPOS Media- this is a new product that is at the final stages of development. There is a possibility of editing the screens and animations, but this section will be updated once it is released. ## Firmware update process **VPOST/ Onyx:** The firmware update is made out of 2 parts- the MAIN update and POS update. For the MAIN update, you'd see "gloader" at the top of the screen, along with a percentage next to it. Once completed, the device would reset itself and start downloading and updating the POS. Please do not touch it until the device resets, as the device's screen will also appear black while the POS is being erased and updated. After completion the VPOST would power itself up and would be in idle mode. This whole process usually takes 30-60 minutes, so keep that in mind. **VPOSM:** The firmware update process is made out of multiple applications being downloaded and later on updated one-by-one. The download process would take place in the background, whereas during the installation the device's screen would switch to an installation screen. The process update timeframe can vary depending on the packages and their versions. ## Device's communication with Nayax's servers- ETH/fallback mechanism We highly recommend that, even if customers plan to use the ETH connection, they leave the SIM card installed and the antenna connected as a fallback, as we've had many customers experience "hiccups"/issues with the ETH connection. In that case, the VPOST/Onyx would try to use the cellular one. ## Decimal place The Decimal place is a parameter in Nayax Core that is forwarded to the device. In Marshall, said value is forwarded to the peripheral via the Marshall command "Config," which is sent as part of the Pairing process. On its end, the machine should calculate the following value: X = 10 ^ "Decimal place" (i.e. 10 power "Decimal place") For each transaction, multiply the price set in the SDK by this value and send the result to the device. For example: Decimal place = 2 Price = 30 Euros Price to be sent to device: 30 *(10 ^ 2) = 30* 100 = 3000 • FYI, Credorax accepts transactions from 10 cents and above only. So, if you send one as a price with a 2 decimal places, we will eventually send to Credorax: 1 / 100 = 0.01 Euro, and the transaction will be declined. ## SIM not working The SIMs' recognition depends on the device's APN addresses. Meaning if the specific SIM does not exist there, it won't work. If you encounter an issue with a SIM (received with your device / bought from Nayax)- please contact the Support team- [support@nayax.com](mailto:support@nayax.com) ## Removing the X button on the device during authorization Removing the X option can be done by changing the "VPOST button function" to "VPOS cancel button during authorization." ## Hardware questions Q: Is it an actual RS232 interface with a level shifter or UART signals with voltage level 5V/3.3V? A: Yes, true RS232 with level shifter. (The RS-232 standard talks about −15 to −3 V and +3 to +15 V. The electric components that we are using are working about ±7V.) Q: Are any HW handshaking signals (RTS/CTC) needed? A: No, only RxD/TxD/GnD is used. Q: What is VPOSM's typical power consumption? A: Idle: around 3-4W, Peak: around 5-7W ## Changing the product selection animation to a Smartfridge one You'd need to send the following file to the device via Machine File: <Frame> <img alt="" /> </Frame> 4010001;devicecoreftp.nayax.net;21;embedded\_support;asdf&^%;./automation/General/1742223843-select\_smartfridge.264;;f7b4;video\select\_smartfridge.264; Then set the following configuration: <Frame> <img alt="" /> </Frame> * Note- this feature is relevant starting version 4.0.25.11 and above # General Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-faqs/faq-general ## Proprietary cards supported Nayax supports both swipe (Magstripe) and RFID cards. The <u>RFID supported</u><ins>RFID supported</ins> are working in frequency 13.56 MHz: Nayax' reader is working in frequency **13.56 MHz and supports ISO 14443 Type A and Type B cards (e.g. MiFare Classic and MiFare Plus) + ISO 15693 (e.g. HID iClass)**. The most popular and simple RFID card supported by Nayax' card reader is of type: MiFare Classic 1K (or 4K). Magstripe cards are supported as well- should they be compatible with a non credit card standard, i.e. do **not** contain any '=' in the card's data and UID is in range 4-40. Should they have any of those features- there is a possibility of supporting those but it may require an additional integration ([Cortina Prepaid](/docs/cortina/prepaid-card/prepaid-card-flows#/)) ## Vend denied — why Nayax doesn't provide a reason to the peripheral As the device is unattended, we wouldn't like to embarrass consumers if their card is blocked etc. ## How to locate which virtual COM port matches the physical connection Go to "Device Manager" -> "Ports": <Frame> <img /> </Frame> ## Marshall over ETH The feature is only supported on VPOSM and for Java and C# SDKs (not supported on C SDK). All you'd need to do is set the eth\_port's configuration instead of the pc\_port, and ensure that the device and machine are located inside the same network. Java: <Frame> <img alt="30" /> </Frame> C#: <Frame> <img alt="31" /> </Frame> ## Marshall over ETH: using the same cable for both Marshall communication as well as the device's with Nayax's servers The supported configuration is to communicate via Ethernet with both the (Marshall) peripheral and Nayax's servers.\ It’s the router’s role to provide access to the external world in parallel to the peripheral.\ Having the device communicate with the peripheral via Ethernet and with the servers via eSIM is not currently supported, as this setup is technically less natural for Android. ## Enabling alerts To be able to see the alerts sent from the SDK in the Nayax Core, you should have the following configuration (even if your machine is not an EV charger) <Frame> <img /> </Frame> In addition to that, you can't make up an alert ID, you should use an ID that exist in our database (and can be configurable). For example, you can use ID number 2, which is a "Door event" (you can change the event data as you desire): • Alert ID of 200 or 810 does nothing. Best practice is to use alert ID 2. <CodeGroup> ```java Java theme={null} m_vmc.general.alert((short) 2, "Back door opened"); ``` ```csharp C# theme={null} vmc_instance.general.alert(2, "alert test"); ``` ```c C theme={null} uint8_t alert_str[32]; sprintf((char*)&alert_str,"Back door opened"); vmc_general_alert((short)2, (char*)&alert_str, strlen((char*)&alert_str)); ``` </CodeGroup> ## Product map This feature allows you to manage products via Nayax Core for your peripherals. This feature is irrelevant for Marshall, as the Product map is not used there. The only relevance is that, if you look in Last Sales/Dynamic Transaction Monitor, you'd see the product name in the transaction details, which appears in the product map for the product code the peripheral has sent. Should managing a product map be relevant for you? Our Support team has sent links for our Nayax U, in which there are guides about that:\ Setting up a Product Map: [https://nayax-u.nayax.com/scenario/how-to-create-a-product-map-template-administration-2349](https://nayax-u.nayax.com/scenario/how-to-create-a-product-map-template-administration-2349)\ Setting up a product in the Product Map:\ [https://nayax-u.nayax.com/scenario/how-to-create-a-product-administration-937](https://nayax-u.nayax.com/scenario/how-to-create-a-product-administration-937) ### Example: The peripheral has sent a "Vend Request" for product code 1 and price of 10.00, and the product map has a row regarding product code 1 which has the name of "Apple" and cost of 20.00- the price that the consumer would be charged for would be 10.00, and in Last Sales/ Dynamic Transaction Monitor you'd see that the transaction is for product code 1 and alongside the product code you'd see "Apple" <br /> ## How to get the eReceipt product name not to be "unknown"? The product names are taken from our product map, so you can create products in it and name them (to match the product codes you send via the SDK). Just keep in mind that Marshall does not use any of the information in the product map, so you can put whatever you want in it. It won't affect the transaction flow, including prices (the only field relevant to you is the product code name, which appears in Last Sales and the eReceipt file). You can add new products to your device's product map by going to the "product map" tab, clicking on "Map"-> "Add BIN", and then add the product code and product group, PA code and MDB code (this is the one which should match the product code in the SDK), and then of course click on "save". ## Static IP There's a requirement to define a static IP for the machine, as when information returns, it would hit a firewall, making the data not know where to be routed. ## Refund request A refund occurs when a transaction is completed and settled, yet a consumer would like to get their money back for some reason. Marshall does not have a refund feature, as it does not relate to communication between the customer's machine and our device, but rather to the payment aspect. You can have a transaction cancelled or a consumer not be charged if you were unable to provide the goods. If there was an issue with dispensing the product, you should respond with "Vend Failure" instead of "Vend Success". If the transaction was completed successfully (the consumer was charged) and you'd want to get a refund for it you can do it through Nayax Core: go to the Dynamic Transactions Monitor page, select the relevant transaction and press right click on it, select Request refund and confirm. Nayax's team will be approving the request, and once approved, you should see the funds back in your account within 1-2 days. ## Unit of measure values | Unit\_of\_measure\_id | Unit\_of\_measure\_name | Unit\_of\_measure\_symbol | | :- | :- | :- | | `1` | units | U | | `2` | centimeter | Cm | | `3` | Gram | G | | `4` | Second | S | | `5` | Celsius | °C | | `6` | Milliliter | Ml | | `7` | Watt hour | Wh | | `8` | Kilowatt hour | kWh | ## Gtrace retrieval Gtrace is a log that provides general information about the device's behavior, unrelated to communication with your machine. It would not show up in the SDK's commands and logs, but on the Gtrace- another type of log file, but this one is generated by Nayax's reader and is sent to Nayax Core.\ Should it be relevant to you, you can retrieve a Gtrace the following way (note that to retrieve it, your device should be on, as you can imagine): Once you've selected your desired machine, you should choose "Actions"-> "Request Gtrace": <Frame> <img /> </Frame> Once you've sent the request, you would see that under the "Dex" tab there would appear a new line/s in the table with the Dex Source of GtraceV2: <Frame> <img /> </Frame> Once you click on the desired log (on a specific line in the table) and on the "View Parsed" button, you'd be able to see the whole log. <Note> **Important note:** The device must be online for the Gtrace to be collected. </Note> ## Last alerts retrieval Last Alerts is a log that appears in Nayax Core under your relevant device's virtual machine. The log provides information on alerts sent between the device and our servers. To retrieve it, you should go to the relevant virtual machine, and then click on Info-> Last Alerts: <Frame> <img /> </Frame> ## Cables SKUs C130011- Regular Marshall cable - VPOST/Onyx C150001- Onyx Marshall cable (with ETH) C140001- VPOST ETH adaptor (RJ11 male to RJ45 female) NX-CB0135- VPOS Media 4S Marshall cable NX-CB0138- VPOS Media 5 Marshall cable NX-CB0156- VPOS Media 4S ETH adaptor (USB-C to RJ45 female) ## Firmware version update process ### VPOST/ Onyx: The firmware update is initiated from Nayax Core.\ The firmware update is made out of 2 parts- the MAIN update and POS update. For the MAIN update, you'd see "gloader" at the top of the screen, along with a percentage next to it. Once completed, the device would reset itself and start downloading and updating the POS. Please do not touch it until the device resets, as the device's screen will also appear black while the POS is being erased and updated. After completion, the VPOST would power up and enter idle mode. This whole process usually takes 30-60 minutes (may take longer if using ETH), so keep that in mind. ### VPOSM 4S: Similar to VPOST and Onyx, the firmware updates are initiated from Nayax Core, but unlike those devices, it is made out of only one part. The download process runs in the background, so consumers can continue using the device during it. Once the download completes, the device will automatically start the installation and display a matching installation screen showing the current installation progress. ### VPOSM5 Unlike VPOST/Onyx/VPOSM 4S, the firmware update is initiated from a separate site, called CasHub. The firmware update process is done by having each of the relevant apps updated manually (not as one package).\ The firmware update for each of the apps is made out of 2 separate parts: the download and the update- meaning once the download process has been completed, your local support would need to send the device a request to initiate the update process for the desired apps. <br /> ## Timeout for getting approval of the transaction from the acquirer The "Authorizing, Please wait" would show until either a response is received from the acquirer or a timeout has reached. Usually, if the VPOST can communicate with our servers (our servers do not have issues getting response from acquirer) the whole process of sending the authorization request and getting a response back is a few seconds long, usually up to 5 seconds, but should there be any (GSM/VPN/MQTT/ETH) communication issues between the VPOST and our servers the request would take some time to arrive to our servers, or take some time to get the response from our servers. I've asked the support about that timeout, and they told me it's configurable with the "MDB RX Timeout" parameter, and the default value is 60 seconds: <Frame> <img /> </Frame> ## "Trick" of starting a transaction at one location and finishing it at another For this explanation, I'd use the example of cart rental: 1. Have a transaction started from Nayax's device at the 1st location (take a cart from there) 2. Have the consumer use the cart 3. Have the consumer return the cart to any rail he desired (not necessarily the 1st location. Let's say it's a 2nd location)- at this stage Nayax's device at the 2nd location would recognize the cart, will send it's ID to a main server which will make a match between the cart ID and the Nayax device in which the transaction started with- and close the transaction over there. But as you can understand, in such a case, there is a need for server management on your side. A couple of requirements: 1. A server to manage which sessions are opened at which location 2. A way to differentiate between different cards 3. Each rail can have up to 60 carts available for rent at a time (should there be more, the consumer won't be able to rent those) ## Dynamic QR channel URL appearing in the SDK (brand selection screen) To have the brand selection screen start with, the device must be configured to Always Idle (since regular Preselection shows animations after a product is selected and cannot display brands). After I've selected a product, then the brand/channel and the QR appeared on the VPOST's screen- it also appeared in the SDK's log. The string appears in Hexa, so there's a need to convert it to ASCII in order to get the URL. For example: [https://www.rapidtables.com/convert/number/hex-to-ascii.html](https://www.rapidtables.com/convert/number/hex-to-ascii.html) <Frame> <img /> </Frame> ## CPU requirements No special requirements for any of the SDKs. **Java and C# SDKs:** The SDK has such low CPU and memory requirements that if your machine can run a JVM, it can run the SDK. Our SDK developer estimates its memory usage to be around 50KB of RAM and almost zero CPU time. (It is based on a 100 code of lines, which are executed every 5ms, and upon serial data received, not much more than that on every packet) **C SDK:** Our SDK developer estimates its memory usage at around 1KB of RAM and every 5ms, timer tick of around 100 lines of code (actual machine code depends on compiler and platform). He ran it on an Atmel AVR with 2KB of RAM, an 8MHz controller, and plenty left for the actual application. <br /> ## Updating an existing implementation's SDK with a newer SDK version **Java:** You'd replace the .JAR file (located inside the SDK's directory, inside the "libs" folder) <Frame> <img /> </Frame> **C#:** You'd replace the .DLL file (located inside the SDK's directory) <Frame> <img /> </Frame> **C:** You'd overwrite the previous SDK with the new one and recompile your implementation ## Android If you're working with Android - you won't use the serial port number Should your board have a serial port you can use the regular lowlevel of the Java SDK. Most Android boards do not have the onboard serial port - in that case you'd use the Android lowlevel file we'd send them. In such case they should use the Java SDK as is with the small change for changing the low-level serial port (as you’re using an Android platform) with the code in the demo called "nayax-android-marshall-demo\_0\_1\_6\_02" The part in the SDK which relates to the serial port is: <Frame> <img /> </Frame> • Note : when working with the lowlevel serial for Android they you wouldn't be able to play with the demo app= but you can use it as a reference as to how to initiate transactions <br /> As for the path when working with Android- you should provide the logger an object of BufferedWriter type. He sent the following example of writing to your SD card: <Frame> <img /> </Frame> ### In case of UART located at /dev/tty: Android can't access "/dev/tty...." meaning you need the vendor serial port library, and implement "serial\_port\_i" around it. ftdi is for USB serial port converted # Flow & Configurations Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-faqs/faq-marshall-flowconfigurations Answers to common questions about Marshall's flow behavior and configuration, including timeouts, status codes, and session handling. ## Vend result timeout (timeout for vend success) This parameter sets how long the device waits for a vend response (`Vend Approved` or `Vend Failure`) from the peripheral after sending it `Vend Approved`. In Nayax Core, the parameter's maximum value is 65535 seconds (18 hours, 12 minutes, and 15 seconds). If you need a longer window, use [Multi-Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session#/), where the timeout is 23 hours for credit cards and 72 hours for proprietary cards. ## Status command Once pairing is complete, the device immediately sends a `Status` command when network communication is lost, so the machine knows. It looks something like this in the Java SDK (the C# and C logs look the same): ```text Java SDK's log theme={null} [1760613771245+( 7476ms)] vmc_link: rx vmc_link :rx :0d:00:01:04:00:36:01:30:0b:15:01:00:08:37:92: [1760613771245+( 0ms)] vmc_link: tx vmc_link :tx :0a:00:00:04:01:30:00:36:00:00:4c:6b: [1760613771245+( 0ms)] vmc_vend_t: received status: 21 [1760613771251+( 6ms)] Main: device not available: in technician mode [1760613771251+( 0ms)] vmc_socket_t: received status: 21 ``` The status is 21 (0x15), which, as the table below shows, means the device is unavailable. The bytes that follow indicate why. | Status ID | Description | | - | - | | 20 | Device in idle mode, available for starting a transaction.<br />Bitmap of extra information (set in the "Status Additional Data" field): bit 0 means an Ethernet connection is available. | | 21 | Device not available.<br />Bitmap of reasons (set in the "Status Additional Data" field): bit 0 means the device has cellular issues, bit 1 means the device has no network communication, bit 2 means the device is busy (for example, a long remote software update), bit 3 means the device is in technician mode, bit 4 means the device has an internal issue. | Once communication resumes and the device returns to idle, the device sends a `Status` command with a value of 20: ```text Java SDK's log theme={null} [1759994336421(+7ms)] : rx: 0d:00:01:02:00:36:01:30:0b:14:01:00:00:34:16: [1759994336424(+3ms)] marshall_t: received status [1759994336426(+2ms)] : tx: 0a:00:00:02:01:30:00:36:00:00:69:ca: [1759994336431(+5ms)] vmc_vend_t: received status: 20 [1759994336431(+0ms)] APP: received status: 20 [1759994336433(+2ms)] APP: device available [1759994336434(+1ms)] vmc_socket_t: received status: 20 ``` The sequence plays out as follows when the device loses communication with the outside world (for example, a SIM issue or a faulty Ethernet connection): 1. The peripheral sends keep-alive commands, and the device responds to each one. 2. The device sends a `Status` command with a value of 21 (0x15). The sequence reverses once communication resumes: 1. The peripheral sends keep-alive commands, and the device responds to each one. 2. The device sends a `Status` command with a value of 20 (0x14). The `Status` command can also provide information during the consumer's card presentation, unrelated to the sequences above: | Status ID | Description | | :- | :- | | `54` | Call your bank | | `56` | Card error (reader not able to read card) | | `61` | Insert card into the contact slot | | `62` | Card not accepted | | `65` | Processing error (card removed before completion of the transaction in contact mode) | | `66` | Remove card from the contact slot | | `67` | Use contact reader | | `68` | Use magnetic stripe reader | | `69` | Try again | | `71` | Present card | | `73` | Card read OK | | `74` | Insert card in contact mode or swipe | | `75` | Present one card only | | `78` | Use another card | | `79` | Insert card in contact mode | | `82` | Look at your mobile (the consumer is completing the transaction on their mobile phone) | | `83` | Present card again | | `84` | Insert or swipe another card | If a consumer has trouble with card reading, the device prompts them to insert the card or use another card. If the card doesn't have enough credit, the device doesn't show that reason on screen or in the SDK logs, since it isn't related to communication between the VPOST and the machine, but rather between the device and the acquirer. You can generally see the reason a transaction was cancelled or a card was rejected in Nayax Core. ## Communication loss The Marshall protocol uses ACK commands in response to each command sent: when your peripheral sends a command to the device, it receives an ACK command in return, and vice versa. The ACK is a response from the receiving side to the sender, confirming the command was received. If no ACK arrives, the command is sent again. If none of the three attempts (the original command plus two retries) receive an ACK, the SDK stops sending keep-alive commands, and the device sends a reset command to re-establish pairing. If no ACKs arrive during a transaction, responsibility depends on timing. If none arrive after `Vend Success`, Nayax is responsible for making the settlement. If none arrive after authorization but before `Vend Success`, or before authorization at all, Nayax cancels the transaction. ## Approval by a 3rd-party server <Warning> Note that for proprietary cards (MiFare, HID and Magstripe) the consumer's card details would be provided 2 times per transactions: One time (via `Transfer Data`) **before** the `Begin Session,` And a second time (via `Transfer Data`) once the card's authorization process has been completed by the 3rd party, meaning would be printed after the Vend Request and right before the `Vend Approved / Vend Denied` </Warning> This section covers how the machine notifies the SDK whether a card is approved. After the `Vend Request` is sent and a consumer presents their card, the `Transfer Data` command is sent, and the peripheral gets the card's details and forwards them (on its own, unrelated to the SDK) to the desired 3rd-party server. Once the server approves or denies the card, the peripheral notifies the SDK, which also informs the device, by calling `client_gateway_auth(bool approved)`: <CodeGroup> ```java Java theme={null} m_vmc.vend.client_gateway_auth(bool approved); ``` ```csharp C# theme={null} vmc_instance.vend.client_gateway_auth(bool approved); ``` ```c C theme={null} vmc_vend_client_gateway_auth(__bool approved) ``` </CodeGroup> In the SDKs' demo apps, this simulates a case where the peripheral returns `true` for approved: <CodeGroup> ```java Java theme={null} public void onSessionBegin(int funds_avail) { // credit card has been detected. stop timer session_timer_stop(); // delayed vend example: send vend request later, and not now inside onBeginSession if (false) vend_timer_start(); else { // vend request m_vmc.vend.vend_request(m_sessions[m_active_session]); // example: approve mifar/mag card externally (vmc authenticates) if (vmc_config.mag_card_approved_by_vmc_support || vmc_config.mifare_approved_by_vmc_support) m_vmc.vend.client_gateway_auth(true); } } ``` ```csharp C# theme={null} public override void onSessionBegin(int funds_avail) { logger.d(TAG, "session began. requesting product vend"); // do vend request vmc_instance.vend.vend_request(session); // todo: check if this is a mifare / mag card // todo: usually you will send this to another thread for async processing if (false) { // acknowledge mifare (note: only when machine is working on mifare/mag mode) if (vmc_config.mifare_approved_by_vmc_support || vmc_config.mag_card_approved_by_vmc_support) vmc_instance.vend.client_gateway_auth(true); } } ``` ```c C theme={null} static void triggered_vend_request(void) { . . . if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support) { vmc_vend_client_gateway_auth(__true); } } ``` </CodeGroup> ## Cancel command If you send `Vend Request` and haven't yet received `Vend Approved` or `Vend Denied`, you can send the `Cancel` command, which causes `Vend Denied` to be sent. If you send `Cancel` before receiving `Vend Approved`, but `Vend Approved` is already on its way to your machine, you won't see `Vend Cancel` in the logs, since a cancel command can't follow `Vend Approved`. In that case, `Vend Failure` is sent from the peripheral's end instead. You can also skip `Cancel` in this situation and respond with `Vend Failure` directly, which produces the same result. You can also cancel a transaction before sending `Vend Request`, if the consumer starts a transaction but backs out before you send it. This can happen either before the consumer presents a card, or right after you receive `Begin Session` but before you send `Vend Request`. In the first case, the SDK's logs show only `Reader Enable`. ## Begin session sent only after card authorization When using prepaid cards, authorization comes first, and `Begin Session` is sent afterward. <Frame> <img alt="Sequence diagram showing authorization before Begin Session for prepaid cards" /> </Frame> Otherwise, `Begin Session` comes first, and authorization happens afterward. <Frame> <img alt="Sequence diagram showing Begin Session before authorization for non-prepaid cards" /> </Frame> You must perform a close session only when the VPOST/Onyx is in idle mode, not in the middle of an active transaction. <Warning> Don't send `Close Session` while a transaction is active. The device processes `Close Session` first, which can get the active transaction stuck. Send `Close Session` only when `onReady` triggers. </Warning> ## Closing a session with a price of 0 To cancel a transaction, send a close session command with a status other than `OK`, such as `Failed to Dispense`. Sending a close session with a price of 0 and a status of `OK` is treated as an error in your machine's price calculation, not as a cancellation. Anyone looking at this device's Last Sales would otherwise assume there's an issue on Nayax's end with settling the transaction, such as a payment or configuration issue. In reality, there's no issue in the transaction process between your peripheral and the device. You didn't want to charge the consumer, for your own reasons. That's why `Vend Failure` exists, along with the close session statuses `Vend Failure` and `Cancel by User`: they indicate the product wasn't provided, so the consumer isn't charged, and the matching reason shows on Last Sales and DTM. Once you change a session's status to anything but `OK`, the price you send becomes irrelevant, since the transaction is cancelled regardless. The possible statuses are: * `0`: Status OK * `1`: User cancel * `2`: Failed to dispense the product * `4`: Vend denied Then you can send the `Close Session` command. ## Multivend: partial vending example Partial vending applies only to Multivend, and means that only some of the selected products could be vended. For example, if the consumer selects five items: <Frame> <img alt="Example showing five items selected in a Multivend transaction" /> </Frame> Say you want to simulate a scenario where only two items are vended. You can add the following to your demo app inside the `onVendApproved` callback: <Frame> <img alt="Example partial vending result showing two of five items vended" /> </Frame> <CodeGroup> ```java Java theme={null} if (vmc_config.multi_vend_support) //example of partial vending { ArrayList<vmc_vend_t.vend_item_t> list = new ArrayList<vmc_vend_t.vend_item_t>(); list.add(new vmc_vend_t.vend_item_t((short) 0, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 1, (short) 100, (short) 1, (byte) 1)); // prepare single session object session.products_list = list; } ``` ```csharp C# theme={null} if (vmc_config.multi_vend_support) //example of partial vending { List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t>(); list.Add(new vmc_vend_t.vend_item_t((ushort)0, (ushort)10, (ushort)1, (byte)1)); list.Add(new vmc_vend_t.vend_item_t((ushort)1, (ushort)10, (ushort)1, (byte)1)); // prepare single session object session = new vmc_vend_t.vend_session_t(list); } ``` ```c C theme={null} session->products = &session_products[0]; session->total_products = 1; ``` </CodeGroup> ## Session timeout delay The device checks its open sessions every minute, so it may settle a transaction up to a minute after the timeout set in Nayax Core. For example: * A 1-minute timeout: the session expires between 1 minute and 1 minute 59 seconds after it starts. * A 5-minute timeout: the session expires between 5 minutes and 5 minutes 59 seconds after it starts. * A 1-hour timeout: the session expires between 1 hour and 1 hour 59 seconds after it starts. # Marshall FAQs Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-faqs/index This FAQ section has technical details, troubleshooting, and configuration guidance for integrating your peripheral with Nayax's Marshall devices (VPOST, Onyx, VPOSM). Browse three core categories to quickly find the information you need: <CardGroup> <Card icon="id-card" title="General" href="/docs/integrate-pos-device/marshall/marshall-faqs/faq-general"> Find essential information on cards, communication (ETH/IP), alerts, logs (Gtrace), refunds, and firmware updates. </Card> <Card icon="microchip" title="Device" href="/docs/integrate-pos-device/marshall/marshall-faqs/faq"> Fix device startup issues, review power supply notes, activation steps, firmware, communication fallback, and hardware specs. </Card> <Card icon="sliders" title="Flow & Configurations" href="/docs/integrate-pos-device/marshall/marshall-faqs/faq-marshall-flowconfigurations"> Configure vend timeouts, Status command logic, communication loss handling, and session flow/status codes. </Card> </CardGroup> <br /> # Marshall Java SDK Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-java-release-notes Track Marshall Java SDK changes as they ship. Nayax logs Marshall Java SDK changes on this page as they ship. Subscribe to the RSS feed using the icon at the top of the page to get notified of new entries. <Note> Some features shipped in the 0.1.6.x patch line require VPOS version 4.0.8.23-RC3 or newer. Check the table below for the patch that introduced the feature you're using. </Note> <Update label="Java 0.1.6.23 (Current)"> Every Java SDK patch is listed below, from the current version down to the first release. | Version | Summary | | - | - | | **0.1.6.23 (Current)** | **Fixed the missed-ack issue.** | | 0.1.6.22 | Fixed a link-down issue where a missed ack stopped keepalive | | 0.1.6.21 | <ul><li>Improved link reliability</li><li>Fixed false retransmissions</li></ul> | | 0.1.6.20 | Fixed a race condition between the rx and tx threads on `m_pending_tx_msg` access | | 0.1.6.19 | **Added**:<ul><li>The `pre_auth_amount_config` (0x8c) vend sub-command, including the message class, decode/encode support, a factory method, and event handling in the public API</li><li>A demo application menu option to test pre-authorization amount configuration</li></ul> | | 0.1.6.18 | Fixed the `session_end` timeout expiring too soon, which caused `reader_always_on` to fire too early | | 0.1.6.17 | **Fixed**:<ul><li>`msg_remote_selection_t` encode was an empty stub; now encodes all fields (funds available, payment media ID, payment type, payment data, item number, item options)</li><li>`msg_setup_max_min_prices_t` encode was missing its sub-command byte and had a currency-code encoding typo</li><li>`msg_expansion_t` now null-checks the body before decode/encode, preventing a crash on the FTL-retry-deny case</li><li>`msg_mdb_rsp_t` decode now correctly instantiates `msg_ftl_retry_deny_t`</li></ul> | | 0.1.6.16 | <ul><li>Added an external reader command</li><li>Fixed the reader state command to also work in always-idle mode</li></ul> | | 0.1.6.15 | Added a sanity check to `vend_request` and `close_session`: both now return a boolean value, and reject a price exceeding the permitted amount (65k when `long_price` is disabled) | | 0.1.6.14 | <ul><li>Added real-time price-change support for always-idle mode, even after the reader is already enabled</li><li>Updated the multi-vend request log</li></ul> | | 0.1.6.13 | Fixed `vend_multi_close_session` encoding | | 0.1.6.12 | <ul><li>Added protection against vend, socket, and general actions being issued when there is no link, preventing unnecessary crashes</li><li>Optimized `eth_port` logging</li></ul> | | 0.1.6.11 | Fixed incorrect session ID encoding in multi-vend multi-session close | | 0.1.6.10 | <ul><li>Added file-system management support, now that VPOS provides those services</li><li>Fixed a bug where card info from a previous session was not cleared once a session completed</li><li>Improved `vmc_link` buffer management, fixing a possible retransmission and frame loss from buffer overflow</li></ul> | | 0.1.6.09 | <ul><li>Added support for extended display control</li><li>The SDK version string now also reports the SDK language</li></ul> | | 0.1.6.08 | <ul><li>Fixed frame-size detection to support varying Marshall message sizes</li><li>Added a `flush()` call to the port interface</li></ul> | | 0.1.6.07 | <ul><li>Added site ID and brand name transfer to the machine via transfer data</li><li>Added a technician-mode command to open the door remotely</li><li>Updated the logger</li></ul> | | 0.1.6.06 | **Fixed**:<ul><li>`fw_info` string copy, which could append garbage to the end of strings</li><li>A `msg_alert` string decode error</li></ul> | | 0.1.6.05 | <ul><li>Machine sub type can now be set explicitly instead of being hard-coded</li><li>Fixed an encoding bug affecting multi-session multi-vend frames</li><li>Updated the `entry_type` enum</li></ul> | | 0.1.6.04 | <ul><li>Added `long_price` support, a 4-byte price capability relevant for VPOS Media, and fixed the display of negative prices</li><li>Added support for the QR-code card type and third-party authorization for QR-code readers</li><li>Fixed the Marshall max message length, relevant for VPOS Media</li><li>`vend_session_data_t` now exposes all nullable fields, so the caller can tell whether a value was assigned</li><li>Added a brands-selection bit for the Japanese market</li><li>Multi-session now works together with multi-vend in the same session</li><li>Added a `final_price` field to `onSessionInfo`</li><li>Added a link-ready check to all vend APIs to prevent crashes when called with no link</li><li>The version string now appends "rc" for unofficial builds</li></ul> | | 0.1.6.03 | Removed a false warning on `vmc_vend_t` when no callback handler was registered, replacing it with a null check shared between `marshall_sdk` and `marshall_master_sdk` | | 0.1.6.02 | **Fixed**:<ul><li>The VPOS serial number is now provided as a correctly arranged string instead of raw bytes</li><li>A typo in `marshall_func_code_transfer_data`</li></ul> | | 0.1.6.01 | <ul><li>The SDK no longer bundles `lowlevel_serial.java` directly; you now inject a `serial_port_i` implementation (a certified FTDI and PC-port implementation is provided)</li><li>The display control API signature now takes a `layout_t` instance directly</li></ul> | | 0.1.5.27 | Fixed a re-transmission bug where two packets arriving at once could be lost, plus fixes in `mdb_rsp` parsing and `lowlevel_serial` buffer management | | 0.1.5.26 | Added `session_id` to `vend_session_t` for multi-session reference, more logging, fixed a `msg_display_event_t` parsing error that skipped the user callback | | 0.1.5.25 | Fixed `card_balance` decoding, transfer\_data parsing crashes, and final\_price parsing; added logs to decoded transfer\_data fields | | 0.1.5.24 | Fixed a stall/deadlock while waiting for `end_session`, added transfer data messages throughout the transaction, added SDK configuration logging | | 0.1.5.23 | Fixed an undefined state machine state when `on_begin_session` arrived without a session actually starting | | 0.1.5.22 | Logs a possible exception in case it occurs | | 0.1.5.20-21 | Fixed a possible crash when losing communication while sending `reader_enable`; cleaned up logs | | 0.1.5.19 | Fixed a race condition between rx/tx threads causing retransmission of an already-acked packet; improved log readability | | 0.1.5.18 | Fixed e-receipt on multi-session setups; can now switch to info session on always-idle setups | | 0.1.5.17 | Added check-balance session type, card sub type and card balance transfer\_data, and vend discount/final price calculation | | 0.1.5.16 | Fixed item price/code API type (integer to short); fixed a crash when cancelling a session after card presented but before vend requested | | 0.1.5.15 | Fixed session cancel on always-idle mode and unfilled `transaction_id_len`; `session_status` is now filled by the SDK; optimized `low_level_serial` CPU usage | | 0.1.5.14 | Dumps packets on rx re-arrangement for debugging; improved `lowlevel_serial` handling under stress | | 0.1.5.13 | Added `vend_status(bool)` for explicit vend success, fixed a vend-cancel timing bug, added total charged/discount on the session, absolute POSIX timestamps in logs, and an aux logging callback | | 0.1.5.12 | `onStatus` gained an extra data parameter, added `device_not_available_reason` enums, fixed faulty transfer\_data parsing, improved sample app status reporting | | 0.1.5.11 | Added `Log.console(boolean)`, new transfer\_data fields (firmware versions), new device status enums, and the `onSessionTimeout(id)` event | | 0.1.5.10 | Fixed vend-deny persist mode staying on after successful transactions; added `unit_of_measure` enum values and new device status enums | | 0.1.5.9 | Fixed `fw_info` field arrangement and a vend session status request bug; improved `low_level_serial` link reliability; added remote vend support | | 0.1.5.8 | Fixed `vmc_socket` busy/retransmit timeout handling | | 0.1.5.7 | Fixed a race condition on user cancel right after a card swipe, a `lowlevel_serial` hang on faulty packet length, and a `vmc_socket` busy-modem retransmit bug | | 0.1.5.6 | Removed the EV extension, fixed minor API bugs and a CPU starvation detection print bug | | 0.1.5.5 | Aligned with Marshall 3.0: session status query, reader state API, entry type enum, QR e-receipt, and a device Marshall-version query | | 0.1.5.4 | Fixed a UI API bug, improved CPU profiling, added VMC info fields to `fw_info`, limited multi-vend products to avoid buffer overflow | | 0.1.5.3 | Added VMC info fields to `fw_info`, limited multi-vend products to avoid buffer overflow | | 0.1.5.2 | Added CPU monitoring for starvation debugging; logs the packet byte stream on CRC error | | 0.1.5.1 | Fixed a UI event callback API bug | | 0.1.5.0 | Added the `onStatus` vend callback and updated close-session status messages | | 0.1.4.8 | Updated to the latest Marshall spec, adding product code and product price TLV fields | | 0.1.4.7 | Enabled multi-instance SDK use, connecting several VPOSes to a single VMC machine | | 0.1.4.6 | Special encoding handling for Mifare card UIDs | | 0.1.4.5 | Improved MSR handling for cards encoded as integer or ASCII string | | 0.1.4.4 | Updated the EV extension; `onReady()` now returns the ended session; renamed `requestTime`/`setDisplayText`; added display control to `vmc_general` | | 0.1.4.2 | Updated the sample application's paymarket demo | | 0.1.4.1 | Added log redirection to a file stream; fixed an invalid date from `get_transaction_id()` in `onTransactionInfo` | | 0.1.4.0 | Added a serial packet dump-level parameter and a vend-denied policy parameter | | 0.1.3.5 | Updated to the latest Marshall protocol; link establishment now reports merchant ID, terminal ID, and machine location; sample app got multi-session/multi-vend demos | | 0.1.3.4 | Fixed an always-idle bug requiring the reader to stay enabled | | 0.1.3.3 | Fixed a crash on the `alert` API; fixed `reader_always_on` to apply only when always-idle is explicitly disabled | | 0.1.3.2 | Added a debug flag to silence log output and always-idle sample code | | 0.1.3.1 | Updated `libjserial` in the demo application | | 0.1.3.0 | Reorganized sample code and added documentation to the folder | | 0.1.2.9 | Fixed the always-on feature, which had been removed by mistake | | 0.1.2.8 | Minor cleanup; added the paymarket machine type; changed the EV-charger machine type | | 0.1.2.7 | Added socket MTU/timeout configuration, Marshall protocol 2.0 support, always-idle MDB mode, a comm-timeout fix, and a fund-available conversion fix | | 0.1.2.6 | Added an SDK version method, a TCP socket sample, machine type configuration, and improved logging | | 0.1.2.5 | Improved socket handling, removed a false mismatch warning, added a lowlevel reset on CRC error for reliability | | 0.1.2.4 | Fixed a link bug transmitting from an empty queue; SDK now ships as a `.JAR` with a demo application | | 0.1.2.3 | Updated the pay API | | 0.1.2.2 | Added transfer\_data structure parsing on vend sessions for readable data; updated the sample application | | 0.1.2.1 | Improved logging, added a multi-vend example, added the `multi_vend_support` flag, fixed an `onReady` API bug | | 0.1.2.0 | Unified the multi-vend API into a single `vend_request` for both single and multi-vend cases | | 0.1.1.6 | Handles async socket-close and session-close requests from VPOS; fixed cancel/close timing bugs | | 0.1.1.5 | Reports quantity to DCS (requires VPOS 4.0.1.5 rc9+); added a transaction ID report API | | 0.1.1.4 | Aligned close session to the new format | | 0.1.1.3 | Fixed model/version reporting to DCS; separated the keep-alive timer from the configured timeout | | 0.1.1.2 | Added link statistics, fixed a tight-timing retransmission issue and a buffer-index parsing bug | | 0.1.1.1 | Fixed issues in the low-level serial template file | | 0.1.1.0 | Fixed a re-transmit index bug | | 0.1.0.9 | Handles piggy-back Marshall messages | | 0.1.0.8 | Improved `lowlevel_serial` and response time during heavy socket work | | 0.1.0.7 | Added multi-vend support, a prepaid `pay` API, and CC last-4-digits transfer data | | 0.1.0.6 | Fixed a rare high-load bug causing out-of-order Marshall messages | | 0.1.0.5 | Added the `reader_always_on` configuration parameter | | 0.1.0.4 | Added a cash sale notification API and link event callbacks; fixed an incorrect session status bug | | 0.1.0.3 | Added socket callbacks for session control and display message/alert/time-request messages | | 0.1.0.2 | Moved `lowlevel_serial` outside the SDK as an application-specific concern; added configuration reporting to the vending client | | 0.1.0.1 | Fixed an FTP socket closing issue; added VPOS configuration notification for the client | </Update> # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/marshall-sdk The Marshall Protocol is a proprietary communication protocol developed by Nayax that operates over RS232. It supports reliable transaction exchange between a machine controller and the VPOST, ONYX, and VPOSM product lines, with a payment API that supports various payment flows, such as: * Pre-Selection * Pre-Authorization * Multi-Session * Multi-Vending The Marshall SDK provides a comprehensive approach to using these flows, eliminating the need to manage the details of the Marshall protocol. *Looking for fuel dispenser or forecourt integration instead? See [Marshall Pro](/docs/integrate-pos-device/marshall-pro/getting-started) for FCC (forecourt controller) integration.* <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> <Note> **Available Languages** For your convenience, we provide the SDK in C, C#, and JAVA. </Note> <br /> <Warning> **Price field/ Decimal Place** The price field in Marshall is an integer that is 2 bytes long, meaning the highest value that can be sent to the device is 65535 (0xFFFF). The actual price the device would attempt to charge a consumer for would be a multiplication of the price sent from the peripheral with 10^(-decimal place): meaning the device would look at its own Decimal Place configurations as set in Nayax Core (its value depends on the country on which the device is installed in) when making the price calculations for the authorization and settlement. This means that in case of Decimal Place of 2, the highest price that the device would be able to authorize or charge the consumer would be 655.35 </Warning> ## System overview The following diagram illustrates the transaction and communication flow of the Nayax system. <Frame> <img /> </Frame> Below is a breakdown of the diagram: * At the core is the Nayax device, which manages transactions. This device communicates with Nayax payment and monitoring servers for transaction processing, which, in turn, interact with banks or payment gateways to finalize payments. * The blue arrows indicate the primary transaction flow between the Nayax device server and banks. * The host machine communicates with the VPOS over the Marshall protocol. ## Guides <Note> **Terms of Service** Before getting started with the Marshall SDK, read the [Terms of Service](/docs/get-started/terms-of-service) of our developer's zone. </Note> To start the Marshall SDK integration, check the following documentation pages: <CardGroup> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Set up the Marshall SDK for Nayax VPOS Touch and VPOS Media devices. </Card> <Card icon="shuffle" title="Payment flows" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows"> Choose the payment flow that matches your machine's operational needs. </Card> <Card icon="credit-card" title="Create payments" href="/docs/integrate-pos-device/marshall/marshall-create-payments"> Set up and manage cashless payment transactions from your peripheral's controller. </Card> </CardGroup> <br /> # Vending Session Management Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/data-structures This page covers the data structures used in the Marshall SDK to handle vending product requests and sessions. Such as: * `vend_item_t` * `vend_session_data_t` * `vend_session_t` These structures define the classes and fields necessary to manage product details, session data, and the overall vending session. ## Product class The `vend_item_t` class represents an individual product request within a vending session. This class includes the product code, price, quantity, and unit of measure. The following code block lists all class parameters: <CodeGroup> ```java Java theme={null} public static class vend_item_t { public short code; public int price; public int qty; public byte unit; } ``` ```csharp C# theme={null} public static class vend_item_t { public short code; public int price; public int qty; public byte unit; } ``` ```c C theme={null} struct vend_item_t uint16_t code; uint16_t/uint32_t price; uint32_t qty; uint32_t unit; ``` </CodeGroup> ### Product parameters The table below provides a more detailed description of the parameters. | Parameter | Type (inferred) | Description | | :- | :- | :- | | `code` | String or Int | The unique identifier for the product, also known as the MDB code. | | `price` | Int | Product price, where the real price is calculated as price / (10 ^ decimal places). | | `qty` | Int | The quantity of the product being vended. | | `unit` | Int | Unit of measure for the product, with `0` indicating a discrete unit (e.g., a single drink bottle). | ## Vending session data class The `vend_session_data_t` class holds detailed information about a vending session, including transaction details and card information. The following code block lists all class parameters: <CodeGroup> ```java Java theme={null} public static class vend_session_data_t { public long transaction_id; public short choose_product_timeout; public int card_type; public int card_entry_mode; public String card_bin; public String card_bin_hash; public String prop_card_uid; public int vmc_auth_status; public int com_status; public String excel_data; public String cc_last_4_digits; } ``` ```csharp C# theme={null} public static class vend_session_data_t { public long transaction_id; public short choose_product_timeout; public int card_type; public int card_entry_mode; public String card_bin; public String card_bin_hash; public String prop_card_uid; public int vmc_auth_status; public int com_status; public String excel_data; public String cc_last_4_digits; } ``` ```c C theme={null} struct vmc_vend_transfer_data_t int encode_bitmap; int transaction_id_len; uint8_t[] transaction_id; uint16_t choose_product_timeout; uint8_t card_type; uint8_t card_sub_type; uint8_t card_entry_mode; int card_bin_len; uint8_t[] card_bin; int card_bin_hash_len; uint8_t[] card_bin_hash; int prop_card_uid_len; uint8_t[] prop_card_uid; uint8_t vmc_auth_status; uint32_t com_status; int ftl_data_len; uint8_t[] ftl_data; char[] cc_last_4_digits; uint16_t product_code; uint32_t product_price; uint32_t default_credit; uint8_t[] main_fw_ver; uint8_t[] pos_fw_ver uint8_t[] monyx_id; uint32_t final_price; sint32_t card_balance; ``` </CodeGroup> ### Class parameters The table below provides a more detailed description of the parameters. | Parameter | Type (inferred) | Description | | :- | :- | :- | | `transaction_id` | String or Int | Transaction unique identifier. | | `choose_product_timeout` | Int | Timeout duration for choosing a product. | | `card_type` | String | Card type used in the transaction. | | `card_entry_mode` | String | Card entry mode (e.g., swipe, insert). | | `card_bin` | String or Int | The Bank Identification Number (BIN) of the card. | | `card_bin_hash` | String | The hashed BIN of the card for security purposes. | | `prop_card_uid` | String | The UID of the proprietary card. | | `vmc_auth_status` | String or Int | Authorization status from the VMC. | | `com_status` | String or Int | Communication status. | | `excel_data` | String | Additional data in Excel format. | | `cc_last_4_digits` | String | The last four digits of the credit card. | ## Vending session handle class The `vend_session_t` class represents a vending session, encapsulating session-specific data, product lists, and session status. The following code block lists all class parameters: ```java Java theme={null} public static class vend_session_t { public int funds_avail; public int session_status; public vend_session_data_t data; public ArrayList<vend_item_t> products_list; } ``` ```csharp C# theme={null} public static class vend_session_t { public int funds_avail; public int session_status; public vend_session_data_t data; public ArrayList<vend_item_t> products_list; } ``` ```c C theme={null} struct vend_session_t int funds_avail; int total_amount; int vend_amount; int discount; uint16_t session_id; vmc_vend_transfer_data_t* data; vend_item_t* products; int total_products; ``` ### Vending session class parameters The table below provides a more detailed description of the parameters. | Parameter | Type (inferred) | Description | | :- | :- | :- | | `funds_avail` | int | Available funds for the session. | | `session_status` | String or Enum | The user sets the session's status, especially in cases of cancellation or failed dispensing. | | `vend_session_data_t data` | Object | An instance of `vend_session_data_t` containing detailed session data. | | `products_list` | ArrayList\<vend\_item\_t> | A list of `vend_item_t` objects representing the products involved in the session. Note that only a single product is allowed in multi-session mode. | # Framework Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/framework The `vmc_framework` is the core component of the Marshall SDK, acting as the primary interface between your application and the vending machine controller (VMC). It handles all the essential operations, from initiating and managing sessions to processing transactions and communicating with various peripherals. ## Function To begin using the `vmc_framework`, you need to obtain its singleton instance. This ensures that only one instance of the framework is active, providing a consistent and controlled interaction point for all SDK operations. To initiate the framework instance, you can use the following command: <CodeGroup> ```java Java theme={null} vmc_framework m_vmc = vmc_framework.getInstance(); ``` ```csharp C# theme={null} vmc_framework vmc_instance = vmc_framework.getInstance(); ``` </CodeGroup> ### Parameters The table below provides a detailed description of the command. | Parameter | Description | | :- | :- | | `vmc_framework` | Main class of the Marshall SDK that manages the interaction with the vending machine controller (VMC). | | `m_vmc` or `vmc_instance` | Variable that holds the instance of the `vmc_framework`. | | `getInstance()` | This method returns the singleton instance of the `vmc_framework`. The Singleton pattern ensures that only one instance of the framework runs in the application. | ## Lifecycle methods The primary methods to control the lifecycle of the SDK are: | Parameter | Description | | :- | :- | | `start()` | Initializes and starts the SDK thread, enabling the framework to handle vending operations and device communication. | | `stop()` | Terminates the SDK thread, halting all operations and safely shutting down the framework. | Refer to [SDK Flags Descriptions](/docs/integrate-pos-device/marshall/get-started/sdk-flags-descriptions) to learn about other flags that can be initiated to control specific configurations. # General Marshall Events Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/general-marshall-events This page outlines the general facilities provided by the Marshall SDK. It includes event handling through the `GeneralEvents` interface and APIs for registering callbacks, sending alerts, and requesting time updates. ## Events interface The `GeneralEvents` interface defines various events related to the general operations of the Marshall SDK. Implementing this interface allows your application to respond to specific events triggered during the SDK's operation. The following code block presents all available event methods: <CodeGroup> ```java Java theme={null} public interface GeneralEvents void onDCSParamChange(int dcs_param, byte[] data); void onDisplayEventButtonPressed(byte button_id); void onDisplayEventTextInput(string input); void onTransferData(byte[] data); void onTimeUpdate( byte year, byte month, byte day, byte hours, byte minutes, byte seconds); ``` ```csharp C# theme={null} public interface GeneralEvents void onDCSParamChange(int dcs_param, byte[] data); void onTransferData(byte[] data); void onTimeUpdate( byte year, byte month, byte day, byte hours, byte minutes, byte seconds); ``` </CodeGroup> ### Events methods The table below outlines all the methods available through the interface. <table> <thead> <tr> <th> Parameter </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `onDCSParamChange(int dcs_param, byte[] data)` </td> <td> When a Nayax Core parameter changes, the parameter identifier and the new data are provided. </td> </tr> <tr> <td> `onDisplayEventButtonPressed(byte button_id)` </td> <td> Triggered when a button on the display is pressed, providing the button identifier. </td> </tr> <tr> <td> `onDisplayEventTextInput(string input)` </td> <td> Called when text input is received from the display, providing the input text. </td> </tr> <tr> <td> `onTransferData(byte[] data)` </td> <td> This function is invoked when data is transferred between the Device and the Peripheral. The transferred data is provided as a byte array: `(byte[] data)`, which contains information structured in TLV (Tag-Length-Value) format. See [onTransferData](/docs/integrate-pos-device/marshall/additional-resources/marshall-ontransferdata) for more details. </td> </tr> <tr> <td> `onTimeUpdate(byte year, byte month, byte day, byte hours, byte minutes, byte seconds)` </td> <td> It is called when a time update occurs, providing the updated time value. </td> </tr> </tbody> </table> ## General methods The following methods are available to interact with the general facilities of the Marshall SDK: | Parameter | Type | Description | | :- | :- | :- | | `register_callbacks(GeneralEvents events)` | void | Registers the callback events for the peripheral general module. This method allows your application to handle the events defined in the GeneralEvents interface. | | `alert(short id, String msg)` | void | Sends an alert to Nayax Core, shown under **Last Alerts**. | | `requestTime()` | void | Makes a time request from the VPOS. The response will arrive as an event (`onTimeUpdate`). | # Link and Events Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/link-and-events-configuration This page will explore the essential components and configurations needed to establish and manage the connection between your application and Nayax's payment devices using the Marshall SDK. This includes: * Handling events through the `vmc_link_events_t` interface. * Understanding the structure of `vpos_config_t` class. Refer to the following sections for more information. ## Link events interface The `vmc_link_events_t` Interface defines the events related to the communication link between the vending machine controller (VMC) and Nayax devices. Implementing this interface enables your application to respond to critical events that occur during the device's operation. The following code block presents how to add the interface: <CodeGroup> ```java Java theme={null} public interface vmc_link_events_t void onReady(vmc_link.vpos_config_t config); void onCommError(); ``` ```csharp C# theme={null} public interface vmc_link_events_t void onReady(vpos_config_t config); void onCommError(); ``` </CodeGroup> ### Interface methods The table below describes the available methods of the interface. | Method | Description | | :- | :- | | `onReady()` | This method is called when the link with the VPOS (Vend Point of Sale) is successfully established and the device is ready for vending operations. It provides the VPOS's configuration details. | | `onCommError()` | This method is invoked when a communication error occurs between the VMC and the VPOS, allowing your application to handle such errors appropriately. | ## VPOS configuration class The `vpos_config_t` class encapsulates the configuration settings for the VPOS, which are communicated between the VMC and the device. The following code block lists all available configurations: <CodeGroup> ```java Java theme={null} public static class vpos_config_t public byte prot_ver_major; public byte prot_ver_minor; public byte language; public byte[] country_code; public byte[] currency_code; public byte decimal_place; public byte[] vpos_serial; public int machine_type; public byte[] merchant_id; public byte[] acquirer_terminal_id; public byte[] machine_location; ``` ```csharp C# theme={null} public static class vpos_config_t public byte prot_ver_major; public byte prot_ver_minor; public byte language; public byte[] country_code; public byte[] currency_code; public byte decimal_place; public byte[] vpos_serial; public int machine_type; public byte[] merchant_id; public byte[] acquirer_terminal_id; public byte[] machine_location; ``` ```c C theme={null} vpos_config_t uint8_t language; uint8_t[] country_code; uint8_t[] currency_code; uint8_t decimal_place; uint8_t[] vpos_serial; uint8_t[] merchant_id; uint8_t[] acquirer_terminal_id; uint8_t[] machine_location; ``` </CodeGroup> ### Class parameters The table below provides a detailed description of the parameters. | Parameter | Type (inferred) | Description | | :- | :- | :- | | `prot_ver_major` | int | The major version of the Marshall protocol. | | `prot_ver_minor` | int | The minor version of the Marshall protocol. | | `language` | String | The language setting of the VPOS. | | `country_code` | String | The country code in ISO format. | | `currency_code` | String | The currency code in ISO format. | | `decimal_place` | int | The price is represented as 10 exponents. For example, if the decimal place is 2 and the requested price is 100, then the actual cost is 1.00 (with 2 decimal places). | | `vpos_serial` | String | The serial number of the VPOS. | | `machine_type` | String | The type of machine connected to the VPOS. | | `merchant_id` | String | The merchant ID. | | `acquirer_terminal_id` | String | The acquirer terminal ID. | | `machine_location` | String | The location of the machine. | ## Callback function To register the callback events for link operations, use the following method: <CodeGroup> ```java Java theme={null} public vmc_link set_events(vmc_link_events_t events); ``` ```csharp C# theme={null} public vmc_link set_events(vmc_link_events_t events); ``` ```c C theme={null} void vmc_link_register_callback(vmc_vend_event_handler_cb_t cb) ``` </CodeGroup> By understanding and implementing these configurations and methods, you can effectively manage the communication link and event handling for Nayax payment devices, ensuring reliable and efficient vending operations. # Methods & Functions Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions This section provides detailed reference documentation for all methods and functions available in the Marshall SDK integration. Use this reference when building or maintaining your integration with Marshall. ## Available Guides <CardGroup> <Card icon="cube" title="Framework" href="/docs/integrate-pos-device/marshall/methods-functions/framework"> Use the vmcframework component to interface between your application and the vending machine. </Card> <Card icon="plug" title="Link and Events Configuration" href="/docs/integrate-pos-device/marshall/methods-functions/link-and-events-configuration"> Set up and manage the connection between your application and Nayax's servers. </Card> <Card icon="bell" title="Vending Events" href="/docs/integrate-pos-device/marshall/methods-functions/vending-events"> Handle events for each stage of the vending process. </Card> <Card icon="table-list" title="Vending Session Management" href="/docs/integrate-pos-device/marshall/methods-functions/data-structures"> Work with the data structures Marshall uses for vending product requests and sessions. </Card> <Card icon="toolbox" title="General Marshall Methods" href="/docs/integrate-pos-device/marshall/methods-functions/general-marshall-events"> Register callbacks, send alerts, and use other general SDK facilities. </Card> </CardGroup> # Vending Events Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/methods-functions/vending-events Vending events are a crucial aspect of the Marshall SDK, enabling your application to handle various stages of the vending process. * For **Java** and the **C#** SDKs the `vend_callbacks_t` interface defines the set of callback methods that your application must implement to respond to these events. * In the **C** SDK the `vmc_vend_event_e` enumeration performs the same. The sections below provide an overview of these events and their respective callback methods. ## Vending callbacks interface <Warning> **Java and C# SDKs Only** The interface described on this section is relevant for the **Java** and **C#** SDKs only. </Warning> The `vend_callbacks_t` interface is designed to handle events related to vending operations. <CodeGroup> ```java Java theme={null} public abstract static interface vend_callbacks_t ``` ```csharp C# theme={null} public abstract static interface vend_callbacks_t ``` </CodeGroup> Implementing this interface allows your application to manage the lifecycle of a vending session, from initiation to settlement, and handle various statuses and commands received from Nayax's devices. Below is a list of methods available when using the `vend_callbacks_t` interface: ### Interface methods The table below provides a more detailed description of the Methods. | Method | Description | | :- | :- | | `onReady(vmc_link.vpos_config_t config)` | This method is called when the link with the VPOS (Vend Point of Sale) is successfully established and the device is ready for vending operations. It provides the configuration details of the VPOS. | | `onSessionBegin(int funds_avail)` | Triggered when a client presents a credit card, indicating that a new session has begun and funds are available for the transaction. | | `onTransactionInfo(vend_session_data_t data)` | Called on receipt of transaction data, providing detailed information about the current transaction. | | `onVendApproved(vend_session_t session)` | Invoked when a vending request is approved. This method should return `true` if the vendor process was successful, indicating that the client’s credit card will be charged, or `false` if the vendor process failed. | | `onVendDenied(vend_session_t session)` | Called when a vending request is denied, allowing the application to handle the denial accordingly. | | `onSettlement(boolean success)` | Triggered when a transaction settlement occurs, indicating whether the settlement was successful. | | `onStatus(int status)` | Called when the peripheral receives a `Status` command from Nayax's device, providing the current status of the session as defined in the Marshall Protocol section 8.11. | | `onOpenedSessions(ushort[] sessions)` | This is invoked when the peripheral receives a `Get Session Status` command from Nayax's device. It helps identify which sessions are open, especially in multi-session mode. (See Marshall Protocol section 8.27.5) | | `onReaderState(boolean enabled)` | Provides the status of the reader, indicating whether it is enabled or disabled. (See Marshall Protocol section 8.27.9) | | `onRemoteVend(int avail_funds, int product_code, int options)` | Triggered when the device receives a remote vend command, providing the available funds, product code, and options for dispensing the product. | | `onReceipt(int ereceipt_type, String data)` | Called when a QR code receipt is generated, passing the QR code data to the peripheral to display for the consumer. (See Marshall Protocol section 8.12) | ## Vending events enumeration <Warning> **C SDK Only** The enumeration described in this section is relevant for the **C** SDK only. </Warning> The `vmc_vend_event_e` enumeration is designed to handle events related to vending operations in the C SDK. ```c C theme={null} Enum vmc_vend_event_e ``` ### Enumeration methods Below is a list of methods available when using the `vend_callbacks_t` interface: | Method | Description | | :- | :- | | `onReady(vend_session_t session)` | Called when the peripheral framework is ready to start a session. This occurs after a link has been established or a previous session has ended. | | `onSessionBegin(int fundsAvail)` | Called when a client presents a credit card, providing the available funds for the transaction. | | `onTransactionInfo(vend_session_data_t data)` | Triggered when transaction data is received, passing detailed information about the current session. | | `onVendApproved(vend_session_t session)` | Called when a vending request is approved, providing session details for further processing. | | `onVendDenied(vend_session_t session)` | Called when a vending request is denied, passing relevant session details. | | `onSessionCanceled(vend_session_t session)` | Triggered when a transaction is canceled, providing information about the canceled session. | | `onSettlement(uint32_t success)` | Indicates the settlement status of a transaction. The success parameter indicates whether the settlement was successful (non-zero for success). | | `onStatus(uint32_t status)` | Called when the peripheral receives a `Status` command from Nayax's device. (See Marshall Protocol section 8.11) | | `onSessionsResponse(mdb_msg_sessions_status_t sessions)` | Triggered when the "Get Session Status" command is received from Nayax's device. Provides details about open sessions, helpful in multi-session mode or after a software restart. | | `onReaderStateResponse(mdb_msg_reader_status_t state)` | Responds to the "Get Reader Status" command, indicating whether the card reader is enabled or disabled. (See Marshall Protocol section 8.27.9) | | `onReceipt(int ereceiptType, String data)` | Called when a QR code receipt is generated. Passes the QR code data to the peripheral to display for the consumer. (See Marshall Protocol section 8.12) | | `onSessionTimeout(uint32_t sessionId)` | Triggered when a transaction times out, providing the `sessionId` of the timed-out session. | # Single Session Pre-Authorization with External Settlement Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/external-settlement-marshall The Marshall implementation of [ExternalSettlement](/reference/spark/transactions/externalsettlement) separates the authorization and settlement phases of a transaction. While the Marshall peripheral and Nayax device manage the initial interaction with the consumer and the payment card, the final financial settlement is performed by a 3rd Party Server that sends the settlement request to Nayax's servers. <Warning> **Prerequisite** For this flow to function, the [ExternalSettlement](/reference/spark/transactions/externalsettlement) setting must be enabled by Nayax. </Warning> ## Configuration & device behavior Once enabled, the Nayax Engine changes how the physical device handles transactions: * The device will not send its own settlement command after a successful authorization. * The transaction remains unsettled until an external request is received. * The only way to settle a transaction is via the [ExternalSettlement](/reference/spark/transactions/externalsettlement) command. * For Multi-session flows, the "Close Session" command is no longer relevant; use [ExternalSettlement](/reference/spark/transactions/externalsettlement) instead. * To allow the settlement price to differ from the authorized amount (settlement price ≤ authorized price), enable the `price not final` flag in the Marshall SDK. This gives you the flexibility to trigger the settlement stage externally according to your own business logic, supporting all flow types (Pre-Selection/Pre-Authorization). | Feature | Requirement | | :- | :- | | **Settlement Window** | Transactions must be settled within **48 hours** of initiation. | | **Expiry** | Settlement attempts performed after the 48-hour window will fail. | | **Auto-Cleanup** | Transactions unsettled for >48 hours are automatically canceled via card scheme regulations (this should not be relied upon). | | **Incremental Auth** | The final settlement price must not exceed the Maximum Default Credit set for the operator/machine. | <Note> **Incremental Authorization** External Settlement supports Incremental Authorization. Ensure your logic adheres to the Maximum Default Credit limits to avoid settlement failure. More on this in the [Incremental Authorization documentation](/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features#incremental-authorization). </Note> ## Managing unsettled transactions When no product or service is provided, you must proactively manage the transaction to maintain a good user experience. * **External Cancel:** If you know no settlement will occur, you must send an **External Cancel** immediately. * **Consumer Impact:** If a transaction remains authorized without being canceled or settled, the consumer's funds will stay captured on their payment method, leading to potential disputes. ## External settlement flow The flow consists of two phases: payment authorization handled by the Marshall peripheral and Nayax device, and settlement or cancellation triggered by your 3rd-party server. ### Payment authorization The steps below cover the authorization phase, from card tap through session completion. <Frame> <img alt="" /> </Frame> 1. The consumer initiates a transaction with the peripheral. 2. The Peripheral enables the Nayax's device card reader. 3. The consumer is prompted to present their card. 4. The consumer presents the card to the Nayax Device. 5. The consumer is notified about the authorization process taking place. 6. The Nayax Device sends an authorization request to the Nayax Server. 7. The Nayax Server performs authorization with the Billing Provider. 8. The Billing Provider sends an authorization response (approved) to the Nayax Server. 9. The Nayax Server sends the authorization response back to the Nayax Device. 10. The peripheral's SDK triggers the "session begin" event: <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onBeginSession(funds_avail)) ``` ```csharp C# theme={null} vend_callbacks(onBeginSession(funds_avail)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_session_begin) ``` </CodeGroup> This is the signal for the peripheral, such as the vending machine, to prepare for payment approval. <CodeGroup> ```java Java theme={null} m_sessions[0] = new vmc_vend_t.vend_session_t((short) 0, 1, (byte) 0, 10); //the fields are (from left to right): produce code (2 bytes long,meaning value up to 65535), quantity (2 byte), unit of measure (1 byte), price (2 bytes, meaning value up to 65535) ``` ```csharp C# theme={null} List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t> (); list.Add(new vmc_vend_t.vend_item_t(0, 10, 1, 1)); //the fields are (from left to right): produce code (2 bytes long,meaning value up to 65535), price (2 bytes, meaning value up to 65535), quantity (2 bytes), unit of measure (1 byte), . session = new vmc_vend_t.vend_session_t(list); ``` ```c C theme={null} session_product.code = 1; session_product .qty = 1; session_product.price = 10; session_product.unit = 1; session->products = &session_product; session->total_products = 1; ``` </CodeGroup> 11. The machine display shows: "Please Select a Product." and the consumer selects a product, prompting the peripheral's SDK to send a "vend request" to the Nayax Device. <CodeGroup> ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```c C theme={null} vmc_vend_vend_request(session); ``` </CodeGroup> <Frame> <img alt="" /> </Frame> 12. The peripheral's SDK handles transaction data received via Transfer Data command (includes Nayax Transaction ID and card details): <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` </CodeGroup> At this point, the peripheral must retain the (Nayax's) Transaction ID and Site ID received for later use in the External Settlement/External Cancel. 13. **Optional:** The peripheral's SDK can respond to Nayax's device with its own Transaction number (this information won't be used anywhere, just in case the peripheral would like to have its own Transaction ID appearing in the SDK's logs). 14. Nayax's device sends "Vend Approved", triggering the peripheral's SDK "vend approved" event: <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` ```csharp C# theme={null} vend_callbacks(via onVendApproved(session)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` </CodeGroup> 15. The peripheral dispenses the product or provides the service to the consumer, and the SDK reports success and completes the local session: <CodeGroup> ```java Java theme={null} onVendApproved(session) ``` ```csharp C# theme={null} onVendApproved(session) ``` ```c C theme={null} vmc_vend_vend_status(&session, __true)` and `vmc_vend_vend_session_complete_lowlevel() ``` </CodeGroup> 16. The peripheral sends `Session Complete` to indicate completion of the ongoing transaction process (not yet settling it). 17. Nayax's device sends `End Session` to the peripheral. 18. The peripheral sends `Reader Disable` to put the reader in standby. ### Settling the transaction After session close, a 3rd-party server handles either settlement or cancellation depending on whether the service was provided. If the service was provided: 19. The 3rd Party Server initiates communication by calling the `StartAuthentication` method with an encrypted cipher to authenticate. 20. The Nayax Server decrypts the cipher, validates the credentials and timestamps to confirm authenticity. <Frame> <img alt="" /> </Frame> 21. The 3rd Party Server sends an [ExternalSettlement](/reference/spark/transactions/externalsettlement) request. It must contain: `NayaxTransactionId`, `SiteId` (information retrieved from the transaction's Transfer Data's command) and be sent within 48 hours of the authorization of the consumer's card. * To allow the settlement price to differ from the authorized amount (settlement price ≤ authorized price), enable the `price not final` flag in the Marshall SDK. 22. The peripheral notifies the server of the transaction's completion. 23. The 3rd party server starts the authentication process. 24. Nayax Server sends a response. 25. Nayax's servers send an [ExternalSettlement](/reference/spark/transactions/externalsettlement) response to the 3rd-party server. 26. Nayax's servers notify the device of the settlement. 27. Nayax's device notifies the consumer that the transaction has been settled for the final amount they were charged. 28. Nayax Server sends an external settlement response. If the service was not provided: <Frame> <img alt="" /> </Frame> 24. The 3rd Party Server starts the authentication process. 25. Nayax Server sends a response. 26. The 3rd Party Server sends an [ExternalCancel](/reference/spark/transactions/externalcancel) request. It must contain: `NayaxTransactionId`, `SiteId` (information retrieved from the transaction's Transfer Data's command) and be sent within 48 hours of the authorization of the consumer's card. 27. The Nayax Server initiates the cancellation process with the payment provider. 28. Nayax's servers receive the response from the payment provider. 29. Nayax's servers send an [ExternalCancel](/reference/spark/transactions/externalcancel) response to the 3rd Party Server. ## Next steps <CardGroup> <Card title="External settlement API" icon="link" href="/reference/spark/transactions/externalsettlement"> API reference for the ExternalSettlement endpoint used to settle authorized transactions from a 3rd-party server. </Card> <Card title="External cancel API" icon="link" href="/reference/spark/transactions/externalcancel"> API reference for the ExternalCancel endpoint used to cancel authorized transactions when no service is provided. </Card> <Card title="Incremental authorization" icon="link" href="/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features#incremental-authorization"> Details on Incremental Authorization and Maximum Default Credit limits that apply to External Settlement. </Card> </CardGroup> # Multi-Session Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session The **Multi-Session** payment flow separates the consumer interaction into two distinct parts: 1. **Product selection.** 2. **Authorization and settlement** of the consumer’s card. This differs from the Single-Session flow, in which settlement is performed immediately after product selection and authorization. ## Settlement timeout <Note> Settlement should occur anywhere between **1 minute and 71 hours** (the exact value depends on a parameter called **"Session timeout"** in Nayax Core) after authorization process was completed. Note that in case of the machine not sending a settlement command within a timeframe set in **"Session timeout"** parameter in Nayax Core- the device would settle the transaction on its own and notify the peripheral about it via "Status" command. For VPOSM- it's possible to have the transaction be cancelled instead of settled in case of timeout- but that would be possible via additional configuration on Nayax Core (unrelated to the Marshall flow- meaning from Marshall's POV, the device would always try and settle the transaction at session timeout). </Note> <Danger> It's important that peripherals do not count on the Session Timeout mechanism as it's strictly a fallback mechanism from the device's end.\ Meaning the peripheral should always send a settlement command, and in case of not wanting to charge the consumer he can change one of the settlements fields, called "status" (unrelated to the "Status" command) to a status of "Vend failure" for example- more on that in [Multisession- not charging a consumer at settlement stage](/docs/integrate-pos-device/marshall/marshall-faqs/faq-marshall-flowconfigurations#not-charging-consumers-close-session-with-price-of-0--what-is-the-issue) </Danger> ## Why use multi-session The Multi-Session flow enables you to manage **multiple concurrent transactions** on a single device. It is ideal for peripherals with longer transaction times or those that serve several consumers simultaneously. ### Concurrent transactions This flow is applicable in environments such as **EV chargers**, where multiple consumers may use the same station simultaneously but require independent payment processing. ### Longer transaction times Multi-Session is also helpful when the vending process is longer than the standard **4 minutes and 15 seconds**. The flow allows the peripheral to notify the Nayax Device that vending can begin immediately after the card is authorized. The Nayax Device then waits for a later update from the peripheral regarding the final vend status or service stop, which enables settlement. ### Quicker credit release The Multi-Session flow functions technically as a **Pre-Selection flow**. For some acquirers, this architecture can lead to a **quicker release of captured credit** than the Single-Session flow with Pre-Authorization. If you use Single-Session with Pre-Authorization, the authorized credit amount may take days or weeks to be released, which can confuse consumers who may think they were charged the full Pre-Authorization amount. Multi-Session helps mitigate this issue. ## Payment flow The diagrams below illustrate the sequence of events within the Multi-Session payment flow. <Note> In this flow there are two parts to the transaction process, therefore there are two separate diagrams, one for each step. </Note> <Frame> <img /> </Frame> <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. The Nayax Device sends a message to the consumer: "Please Select a Product." 2. The consumer selects a product from the vending machine. 3. The peripheral's SDK sends a vending request to the Nayax Device: <CodeGroup> ```c C theme={null} vmc_vend_vend_request(vend_session_t *session) ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` </CodeGroup> 4. The Nayax Device sends a message to the consumer: "Please Present Card." 5. The consumer presents their payment card. 6. The Nayax Device sends an authorization request to the Nayax Server. 7. The Nayax Server forwards the authorization request to the Billing Provider. 8. The Billing Provider sends an authorization response (approved) to the Nayax Server. 9. The Nayax Server sends the authorization response (approved) back to the Nayax Device. 10. The peripheral's SDK handles transaction data received from the Nayax Device via Transfer Data (said data includes information about the Nayax transaction ID and the consumer's card details): <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 11. The SDK triggers "Vend Approved" events: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` ```csharp C# theme={null} vend_callbacks() (via onVendApproved(session)) ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` </CodeGroup> 12. The peripheral starts dispensing the product/ providing the service to the consumer. 13. The SDK reports "vend success": <CodeGroup> ```c C theme={null} vmc_vend_vend_status(&session, __true) ``` ```csharp C# theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` </CodeGroup> and completes the vend session: <CodeGroup> ```c C theme={null} vmc_vend_vend_session_complete_lowlevel() ``` ```csharp C# theme={null} no such function in C# or Java due to the nature of the languages ``` ```java Java theme={null} no such function in C# or Java due to the nature of the languages ``` </CodeGroup> 14. The first part of the transaction **ends**. <Frame> <img /> </Frame> 15. The machine finishes dispensing the product/providing the service. 16. Vending machine SDK settles the transaction (session): <CodeGroup> ```c C theme={null} vmc_vend_session_close(session) ``` ```csharp C# theme={null} vmc_instance.vend.session_close(session) ``` ```java Java theme={null} m_vmc.vend.session_close(session) ``` </CodeGroup> 17. The Nayax Server forwards the settlement request to the Billing Provider. 18. The Billing Provider sends a settlement response (OK) to the Nayax Server. 19. Nayax Server returns the settlement response (OK) to the Nayax Device. 20. The peripheral's SDK receives a status command regarding the settlement (whether the device was able to settle it or not) and triggers a "settlement" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_settlement) ``` ```csharp C# theme={null} vmc_vend_events() (via onSettlement(success) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onSettlement(success) -which would return "true") ``` </CodeGroup> 21. Vending machine SDK transfers data and triggers a "transaction info" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 22. Message to the consumer: "Thank you & Goodbye." ## See also <CardGroup> <Card icon="diagram-project" title="Payment flows" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows"> Explore the full range of payment flows available in the Marshall SDK. </Card> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Get up and running with the Marshall SDK integration. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> <br /> # Multi-Vending with Pre-Authorization Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-vend-with-pre-auth This guide explains the **Multi-Vending with Pre-Authorization** flow. This method allows a customer to purchase multiple products in one session after a single initial payment approval. This streamlines the transaction by consolidating authorization into one initial step. ## Payment flow The diagram below illustrates the complete sequence of events for a Multi-Vending with Pre-Authorization transaction. <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. The consumer presents the card to the Nayax Device. 2. The Nayax Device sends an authorization request to the Nayax Server. 3. The Nayax Server forwards the authorization request to the Billing Provider. 4. The Billing Provider sends an authorization response (approved) to the Nayax Server. 5. Nayax Server sends the authorization response (approved) back to the Nayax Device. 6. The peripheral's SDK begins the session and triggers the "session begin" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_session_begin) ``` ```csharp C# theme={null} vend_callbacks(onBeginSession(funds_avail)) ``` ```java Java theme={null} vmc_vend_events() (via onBeginSession(funds_avail)) ``` </CodeGroup> 7. Message to the consumer: "Please Select a Product." 8. The consumer selects the desired product/s from the vending machine. Said products are being added to a list called "session": <CodeGroup> ```c C theme={null} session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } ``` ```csharp C# theme={null} List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t>(); list.Add(new vmc_vend_t.vend_item_t((ushort)1, (ushort)10, (ushort)1, (byte)1)); list.Add(new vmc_vend_t.vend_item_t((ushort)2, (ushort)20, (ushort)2, (byte)1)); list.Add(new vmc_vend_t.vend_item_t((ushort)3, (ushort)30, (ushort)3, (byte)1)); // prepare single session object session = new vmc_vend_t.vend_session_t(list); ``` ```java Java theme={null} ArrayList<vmc_vend_t.vend_item_t> list = new ArrayList<vmc_vend_t.vend_item_t>(); list.add(new vmc_vend_t.vend_item_t((short) 0, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 1, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 2, (short) 200, (short) 2, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 3, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 4, (short) 200, (short) 2, (byte) 1)); // in this sample we can have up to 2 sessions (in case of multi-session) m_sessions = new vmc_vend_t.vend_session_t[1]; // prepare single session object m_sessions[0] = new vmc_vend_t.vend_session_t(3, list); ``` </CodeGroup> 9. The peripheral's SDK sends a "Multi Vend Request" to the Nayax Device: <CodeGroup> ```c C theme={null} vmc_vend_vend_request(vend_session_t *session) ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` </CodeGroup> 10. The peripheral's SDK handles transaction data received from the Nayax Device via Transfer Data (said data includes information about the Nayax transaction ID and the consumer's card details): <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 11. The peripheral's SDK triggers the "vend approved" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` ```csharp C# theme={null} vend_callbacks() (via onVendApproved(session)) ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` </CodeGroup> 12. The peripheral dispenses the product/ provides the service to the consumer 13. The SDK reports "vend success": <CodeGroup> ```c C theme={null} vmc_vend_vend_status(&session, __true) ``` ```csharp C# theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` </CodeGroup> <br /> <Note> **Note:** in case of partial dispensing (meaning not all of the selected items were actually vended) you can create a new list with only the items which were actually vended prior to responding with "true": </Note> <Frame> <img /> </Frame> And completes the vending session: ```c C theme={null} vmc_vend_vend_session_complete_lowlevel() ``` ```csharp C# theme={null} no such function in C# or Java due to the nature of the languages ``` ```java Java theme={null} no such function in C# or Java due to the nature of the languages ``` 14. Message to the consumer: "Please Take Product." 15. Nayax Device sends a settlement request to the Nayax Server. 16. Nayax Server forwards the settlement request to the Billing Provider. 17. The Billing Provider sends a settlement response (OK) to the Nayax Server. 18. Nayax Server sends the settlement response (OK) back to the Nayax Device. ## See also <CardGroup> <Card icon="diagram-project" title="Payment flows" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows"> Explore the full range of payment flows available in the Marshall SDK. </Card> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Get up and running with the Marshall SDK integration. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> <br /> # Multi-Vending with Pre-Selection Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-vend-with-pre-sel With the **Multi-Vending** flow, your machine can dispense multiple products (up to 20, as of 4.0.25.9 and above, up to 40) in a single transaction and provide differentiation for each product in the SDK. Customers first select all of their desired products, then present their payment card. Upon authorization, the vending machine dispenses the selected products, and the session is settled and completed with an appropriate message. ## Payment flow The diagram below illustrates the complete sequence of events for a Multi-Vending transaction. <Frame> <img /> </Frame> Here's a breakdown of the diagram: 1. The Nayax Device sends a message to the consumer: "Please Select a Product." 2. The consumer selects the desired product/s from the vending machine. Said products are being added to a list called "session": <CodeGroup> ```c C theme={null} session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } ``` ```csharp C# theme={null} List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t>(); list.Add(new vmc_vend_t.vend_item_t((ushort)1, (ushort)10, (ushort)1, (byte)1)); list.Add(new vmc_vend_t.vend_item_t((ushort)2, (ushort)20, (ushort)2, (byte)1)); list.Add(new vmc_vend_t.vend_item_t((ushort)3, (ushort)30, (ushort)3, (byte)1)); // prepare single session object session = new vmc_vend_t.vend_session_t(list); ``` ```java Java theme={null} ArrayList<vmc_vend_t.vend_item_t> list = new ArrayList<vmc_vend_t.vend_item_t>(); list.add(new vmc_vend_t.vend_item_t((short) 0, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 1, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 2, (short) 200, (short) 2, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 3, (short) 100, (short) 1, (byte) 1)); list.add(new vmc_vend_t.vend_item_t((short) 4, (short) 200, (short) 2, (byte) 1)); // in this sample we can have up to 2 sessions (in case of multi-session) m_sessions = new vmc_vend_t.vend_session_t[1]; // prepare single session object m_sessions[0] = new vmc_vend_t.vend_session_t(3, list); ``` </CodeGroup> 3. The peripheral's SDK sends a vending request to the Nayax Device: <CodeGroup> ```c C theme={null} vmc_vend_vend_request(vend_session_t *session) ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` </CodeGroup> 4. The Nayax Device sends a message to the consumer: "Please Present Card." 5. The consumer presents their payment card. 6. The Nayax Device sends an authorization request to the Nayax Server. 7. The Nayax Server forwards the authorization request to the Billing Provider. 8. The Billing Provider sends an authorization response (approved) to the Nayax Server. 9. The Nayax Server sends the authorization response (approved) back to the Nayax Device. 10. The peripheral's SDK handles transaction data received from the Nayax Device via Transfer Data (said data includes information about the Nayax transaction ID and the consumer's card details): <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 11. The SDK triggers "Vend Approved" events: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` ```csharp C# theme={null} vend_callbacks() (via onVendApproved(session)) ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` </CodeGroup> 12. The peripheral dispenses the product/s to the consumer. 13. The SDK reports "vend success": <CodeGroup> ```c C theme={null} vmc_vend_vend_status(&session, __true) ``` ```csharp C# theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` </CodeGroup> <Note> **Note:** In case of partial dispensing (meaning not all of the selected items were actually vended) you can create a new list with only the items which were actually vended prior to responding with "true": </Note> <Frame> <img /> </Frame> And completes the vending session: <CodeGroup> ```c C theme={null} vmc_vend_vend_session_complete_lowlevel() ``` ```csharp C# theme={null} no such function in C# or Java due to the nature of the languages ``` ```java Java theme={null} no such function in C# or Java due to the nature of the languages ``` </CodeGroup> 14. Message to the consumer: "Please Take Product." 15. The Nayax Device sends a settlement request to the Nayax Server. 16. The Nayax Server forwards the settlement request to the Billing Provider. 17. The Billing Provider sends a settlement response (OK) to the Nayax Server. 18. The Nayax Server returns the settlement response (OK) to the Nayax Device. ## See also <CardGroup> <Card icon="diagram-project" title="Payment flows" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows"> Explore the full range of payment flows available in the Marshall SDK. </Card> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Get up and running with the Marshall SDK integration. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> # Payment Flows Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows The Nayax Marshall SDK offers a diverse range of payment flows, each designed to meet specific operational needs and dictate precisely how your system handles vending sessions, payment authorizations, and transaction processing. The following pages provide a more detailed description of each one: ## Single Session Flows <CardGroup> <Card icon="hand-pointer" title="Single Session with Pre-Selection" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel"> Separate product selection from payment authorization in a single transaction. </Card> <Card icon="shield-check" title="Single Session with Pre-Authorization" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-auth"> Approve payment before the consumer selects a product to minimize risk. </Card> <Card icon="server" title="Single Session Pre-Authorization with External Settlement" href="/docs/integrate-pos-device/marshall/payment-flows/external-settlement-marshall"> Let a third-party server trigger final settlement or cancellation. </Card> </CardGroup> ## Multi-Vend Flows <CardGroup> <Card icon="cart-shopping" title="Multi-Vending with Pre-Selection" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-vend-with-pre-sel"> Dispense multiple selected products after the consumer completes one payment. </Card> <Card icon="layer-group" title="Multi-Vending with Pre-Authorization" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-vend-with-pre-auth"> Let customers buy multiple products after a single upfront authorization. </Card> </CardGroup> ## Multi-Session Flows <CardGroup> <Card icon="users" title="Multi-Session" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session"> Separate product selection from authorization and settlement across sessions. </Card> <Card icon="network-wired" title="Multi-Session Pre-Authorization with External Settlement" href="/docs/integrate-pos-device/marshall/payment-flows/multi-session-pre-authorization-with-external-settlement"> Manage multiple parallel transactions with an external settlement server. </Card> </CardGroup> ## Additional Flows & Features <CardGroup> <Card icon="puzzle-piece" title="Sub Flows & Features" href="/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features"> Start a transaction from product selection when full pre-selection isn't available. </Card> </CardGroup> ## Recommended Flows If you are unsure which flow is ideal for your machine type, the following table shows the recommended flow and configuration. | Machine Type | Recommended Flow | Recommended Configuration | | - | - | - | | Vending Machine | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | Coin Exchanger | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | Cotton Candy | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle + Explicit Vend Success | | Photo Booth | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | Coffee Machine | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | Massage Chair | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | Car Washing Machine | [Single Session + Pre-Selection](/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel) | Always Idle | | EV Charger 1 | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final | | EV Charger 2 | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final + Mifare approved by VMC | | EV Charger 3 | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final + Mifare approved by VMC + Info Session | | EV Charger 4 | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final + Mifare approved by VMC + Info Session + Always On | | Smart Fridge | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session)+ [Sub flows / features](/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features#/) | Price not final + Always On | | Power Bank | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session)+ [Sub flows / features](/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features#/) | Price not final + Always On | | Locker | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final | | Racket Rental Machine | [Multi Session](/docs/integrate-pos-device/marshall/payment-flows/marshall-multi-session) | Price not final + Always Idle | <br /> # Single Session with Pre-Authorization Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-auth This guide explains the **Pre-Authorization** vending flow. This process is key to minimizing risk because it approves payment before the consumer selects a product. ## Payment flow Visualize the Pre-Authorization process with the diagram below, which illustrates each step of the single vending session flow, from product selection to payment authorization and dispensing. <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. The consumer presents the card to the Nayax Device. 2. The Nayax Device sends an authorization request to the Nayax Server. 3. The Nayax Server forwards the authorization request to the Billing Provider. 4. The Billing Provider sends an authorization response (approved) to the Nayax Server. 5. Nayax Server sends the authorization response (approved) back to the Nayax Device. 6. The peripheral's SDK begins the session and triggers the "session begin" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_session_begin) ``` ```csharp C# theme={null} vend_callbacks(onBeginSession(funds_avail)) ``` ```java Java theme={null} vmc_vend_events() (via onBeginSession(funds_avail)) ``` </CodeGroup> 7. Message to the consumer: "Please Select a Product." 8. The consumer selects a product. 9. The peripheral's SDK sends a "vend request" to the Nayax Device: 10. The peripheral's SDK handles transaction data received from the Nayax Device via Transfer Data command (said data includes information about the Nayax transaction ID and the consumer's card details): <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 11. The peripheral's SDK triggers the "vend approved" event: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` ```csharp C# theme={null} vend_callbacks() (via onVendApproved(session)) ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` </CodeGroup> 12. The peripheral dispenses the product/ provides the service to the consumer 13. The SDK reports vend success: <CodeGroup> ```c C theme={null} vmc_vend_vend_status(&session, __true) ``` ```csharp C# theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` </CodeGroup> And completes the vend session: <CodeGroup> ```c C theme={null} vmc_vend_vend_session_complete_lowlevel() ``` ```csharp C# theme={null} no such function in C# or Java due to the nature of the languages ``` ```java Java theme={null} no such function in C# or Java due to the nature of the languages ``` </CodeGroup> 14. Message to the consumer: "Please Take Product." 15. Nayax Device sends a settlement request to the Nayax Server. 16. Nayax Server forwards the settlement request to the Billing Provider. 17. The Billing Provider sends a settlement response (OK) to the Nayax Server. 18. Nayax Server sends the settlement response (OK) back to the Nayax Device. ## See also <CardGroup> <Card icon="diagram-project" title="Payment flows" href="/docs/integrate-pos-device/marshall/payment-flows/marshall-payment-flows"> Explore the full range of payment flows available in the Marshall SDK. </Card> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/marshall/get-started/marshall-get-started"> Get up and running with the Marshall SDK integration. </Card> <Card icon="code" title="Methods & functions" href="/docs/integrate-pos-device/marshall/methods-functions/marshall-methods-and-functions"> Find reference documentation for all methods and functions in the Marshall SDK. </Card> </CardGroup> <br /> # Single Session with Pre-Selection Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/marshall-single-session-with-pre-sel This guide walks through the **Pre-Selection** vending flow. You'll understand the sequence of events that separate product selection from payment authorization within a single transaction, ensuring a smooth and secure vending session. ## Payment flow Visualize the Pre-Selection process with the diagram below, which illustrates each step of the single vending session flow, from product selection to payment authorization and dispensing. <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. The Nayax Device sends a message to the consumer: "Please Select a Product." 2. The consumer selects a product from the vending machine. 3. The peripheral's SDK sends a vending request to the Nayax Device. <CodeGroup> ```c C theme={null} vmc_vend_vend_request(vend_session_t *session) ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` </CodeGroup> 4. The Nayax Device sends a message to the consumer: "Please Present Card." 5. The consumer presents their payment card. 6. The Nayax Device sends an authorization request to the Nayax Server. 7. The Nayax Server forwards the authorization request to the Billing Provider. 8. The Billing Provider sends an authorization response (approved) to the Nayax Server. 9. The Nayax Server sends the authorization response (approved) back to the Nayax Device. 10. The peripheral's SDK handles transaction data received from the Nayax Device via the Transfer Data command (said data includes information about the Nayax transaction ID and the consumer's card details): <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` </CodeGroup> 11. The SDK triggers "Vend Approved" events: <CodeGroup> ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` ```csharp C# theme={null} vend_callbacks() (via onVendApproved(session)) ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` </CodeGroup> 12. The peripheral dispenses the product/ provides the service to the consumer. 13. The SDK reports "vend success": <CodeGroup> ```c C theme={null} vmc_vend_vend_status(&session, __true) ``` ```csharp C# theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` ```java Java theme={null} vmc_vend_events() (via onVendApproved(session) -which would return "true") ``` </CodeGroup> And completes the vend session: <CodeGroup> ```c C theme={null} vmc_vend_vend_session_complete_lowlevel() ``` ```csharp C# theme={null} no such function in C# or Java due to the nature of the languages ``` ```java Java theme={null} no such function in C# or Java due to the nature of the languages ``` </CodeGroup> 14. Message to the consumer: "Please Take Product." 15. The Nayax Device sends a settlement request to the Nayax Server. 16. The Nayax Server forwards the settlement request to the Billing Provider. 17. The Billing Provider sends a settlement response (OK) to the Nayax Server. 18. The Nayax Server returns the settlement response (OK) to the Nayax Device. ## Next steps <NextSteps> <NextStepCard icon="sample" title="Implement this flow in C" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/single-session"> Copy the single-session sample and adapt it to your VMC. </NextStepCard> <NextStepCard icon="payment" title="Create your first payment" href="/docs/integrate-pos-device/marshall/marshall-create-payments"> Send a vend request and settle the transaction from your controller. </NextStepCard> </NextSteps> # Multi-Session Pre-Authorization with External Settlement Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/multi-session-pre-authorization-with-external-settlement This guide explains the **Multi-Session Pre-Authorization with External Settlement** flow. This method allows for multiple transactions to be managed in parallel with an external server who manages the settlement process for each of the transactions (decides when the settlement would take place and for what final price). <Note> ****Prerequisite**** For this flow to function, the [ExternalSettlement](/reference/spark/transactions/externalsettlement) setting must be enabled by Nayax. </Note> ## Configuration & device behavior Once enabled, the Nayax Engine changes how the physical device handles transactions: * The device will not send its own settlement command after a successful authorization. * The transaction remains unsettled until an external request is received. * The only way to settle a transaction is via the [ExternalSettlement](/reference/spark/transactions/externalsettlement) command. * For Multi-session flows, the "Close Session" command is no longer relevant; use [ExternalSettlement](/reference/spark/transactions/externalsettlement) instead. This provides integrators the flexibility to trigger the settlement stage externally according to their own business logic, supporting all flow types (Pre-Selection/Pre-Authorization). The following table has the technical requirements based on the feature: | Feature | Requirement | | :- | :- | | **Settlement Window** | Transactions must be settled within **48 hours** of initiation. | | **Expiry** | Settlement attempts performed after the 48-hour window will fail. | | **Auto-Cleanup** | Transactions unsettled for >48 hours are automatically canceled via card scheme regulations (this should not be relied upon). | | **Incremental Auth** | The final settlement price must not exceed the Maximum Default Credit set for the operator/machine. | <Note> ****Incremental Authorization**** External Settlement supports Incremental Authorization. Ensure your logic adheres to the Maximum Default Credit limits to avoid settlement failure. More on this in the [Incremental Authorization documentation](/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features#incremental-authorization). </Note> ## Managing unsettled transactions When no product or service is provided, proactive management of the transaction is required to maintain a good user experience. * **External Cancel:** If it is known that no settlement will occur, you must send an **External Cancel** immediately. * **Consumer Impact:** If a transaction remains authorized without being canceled or settled, the consumer’s funds will stay captured on their payment method, leading to potential disputes. ### **Multi-session payment flow** The following sequence illustrates the complete journey for a multi-session transaction: #### Initiation of transaction <Frame> <img alt="" /> </Frame> 1. Cardholder selects an item on the peripheral. 2. Peripheral sends `Reader Enable` to VPOS Touch. 3. Nayax's device displays "Present Card" animations to the consumer. 4. Cardholder presents payment. 5. Nayax's device sends `Begin Session` to the peripheral and the peripheral's SDK triggers the "session begin" event: <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onBeginSession(funds_avail)) ``` ```csharp C# theme={null} vend_callbacks(onBeginSession(funds_avail)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_session_begin) ``` </CodeGroup> This is the signal for the peripheral, such as the vending machine, to prepare for payment approval. <CodeGroup> ```java Java theme={null} m_sessions[0] = new vmc_vend_t.vend_session_t((short) 0, 1, (byte) 0, 10); //the fields are (from left to right): produce code (2 bytes long,meaning value up to 65535), quantity (2 byte), unit of measure (1 byte), price (2 bytes, meaning value up to 65535) ``` ```csharp C# theme={null} List<vmc_vend_t.vend_item_t> list = new List<vmc_vend_t.vend_item_t> (); list.Add(new vmc_vend_t.vend_item_t(0, 10, 1, 1)); //the fields are (from left to right): produce code (2 bytes long,meaning value up to 65535), price (2 bytes, meaning value up to 65535), quantity (2 bytes), unit of measure (1 byte), . session = new vmc_vend_t.vend_session_t(list); ``` ```c C theme={null} session_product.code = 1; session_product .qty = 1; session_product.price = 10; session_product.unit = 1; session->products = &session_product; session->total_products = 1; ``` </CodeGroup> 6. The machine display shows: "Please Select a Product." and the consumer selects a product- prompting the peripheral's SDK to send a `Vend Request` to the Nayax Device. <CodeGroup> ```java Java theme={null} m_vmc.vend.vend_request(m_sessions[m_active_session]); ``` ```csharp C# theme={null} vmc_instance.vend.vend_request(session); ``` ```c C theme={null} vmc_vend_vend_request(session); ``` </CodeGroup> 7. The device displays "Please Wait For Authorization". 8. The device contacts Nayax’ Server. 9. Nayax’ Server forwards request to the Bank/Gateway. 10. Bank/Gateway returns approval/decline. 11. Nayax’ Server sends an authorization response. <Frame> <img alt="" /> </Frame> 12. The peripheral's SDK handles transaction data received via `Transfer Data` command (includes Nayax Transaction ID and card details): <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onTransactionInfo(data)) ``` ```csharp C# theme={null} vend_callbacks(onTransactionInfo(data)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_transaction_info) ``` </CodeGroup> At this point, the peripheral must retain the (Nayax's) Transaction ID and Site ID received for later use in the External Settlement/External Cancel. 13. **Optional:** The peripheral's SDK can respond to Nayax's device with its own Transaction number (this information won't be used anywhere, just in case the peripheral would like to have its own Transaction ID appearing in the SDK's logs). 14. Nayax's device sends `Vend Approved`, triggering the peripheral's SDK "vend approved" event: <CodeGroup> ```java Java theme={null} vmc_vend_events() (via onVendApproved(session)) ``` ```csharp C# theme={null} vend_callbacks(via onVendApproved(session)) ``` ```c C theme={null} vmc_vend_event_handler_cb(vm_vend_event_on_vend_approved) ``` </CodeGroup> 15. The peripheral dispenses the product or provides the service to the consumer, and the SDK reports `Vend Success` and completes the local session: <CodeGroup> ```java Java theme={null} onVendApproved(session) ``` ```csharp C# theme={null} onVendApproved(session) ``` ```c C theme={null} vmc_vend_vend_status(&session, __true)` and `vmc_vend_vend_session_complete_lowlevel() ``` </CodeGroup> 16. The peripheral sends `Session Complete` to indicate completion of the ongoing transaction process (not yet settling it). 17. Nayax's device sends `End Session` to the peripheral. 18. The peripheral sends `Reader Disable` to put the reader in standby. <br /> #### Settling the transaction (External Settlement) <Danger> ****Important Note**** If External Settlement is enabled, the terminal's standard "Close Session" behavior is altered. You must rely exclusively on the **External Settlement** or **External Cancel** APIs to manage the financial lifecycle of the transaction. </Danger> <Frame> <img alt="" /> </Frame> If the service was provided: 19. Cardholder finishes interaction or returns the product. 20. Peripheral notifies Nayax’ Server the process is complete. 21. 3rd Party Server initiates auth with Nayax’ Server. 22. Nayax’ Server confirms authentication status. 23. 3rd Party Server requests final settlement. 24. Nayax’ Server sends the capture request to the Bank/Gateway. 25. Bank/Gateway confirms the funds transfer. 26. Nayax’ Server confirms status to the 3rd Party Server. <Frame> <img alt="" /> </Frame> If the service was not provided: 19. 3rd Party Server requests auth from Nayax’ Server. 20. Nayax’ Server confirms. 21. The 3rd Party Server triggers a settlement or state change. 22. Nayax’ Server requests a void from the Bank/Gateway. 23. Bank/Gateway confirms the cancellation. 24. Nayax’s Server notifies the 3rd Party Server of success. # Sub Flows & Features Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/payment-flows/sub-flows-features Reference for Marshall's payment sub-flows and features, including Transfer Data, Display Control, eReceipt, and Incremental Authorization. Marshall supports two sub-flows, Reader Always On and Always Idle, plus five related features: Transfer Data, Display Control, eReceipt, Info Session, and Incremental Authorization. ## Reader always on This configuration is relevant for peripherals that want to start the transaction with product selection (PreSelection flow) but don't have a way to start a transaction from the peripheral. It means the transaction process is initiated from a consumer selecting a product on Nayax's device screen, which then triggers the peripheral to send the product's details. In rare cases, a consumer's card presentation can trigger the peripheral to send the product selection, but this option isn't common. ## Always idle The transaction starts with the consumer selecting a product (PreSelection flow) on the peripheral, which then sends `Vend Request` without waiting for a `Begin Session` trigger. This flow is very commonly used in the Far East. ## Transfer data Transfer Data provides information during the transaction process about the transaction details: Nayax's transaction ID and the consumer's card details. For credit cards, this means the BIN, the PAN hash, and the last four digits. For proprietary cards, it means the UID (the card's full number). The card details are sent automatically once a consumer presents their card and the authorization result arrives. Transfer Data also lets the peripheral send its own transaction ID, so it appears in the SDK's logs. Nayax doesn't use that information for anything else. For more detail, see [Transfer Data](/docs/integrate-pos-device/marshall/additional-resources/marshall-ontransferdata). ## Display control Display Control is a feature for peripherals that need the Marshall master to define different selection screens on the device before sending a request for a specific price. This way, product selection comes from Nayax's device instead of the peripheral. It helps when the peripheral has no screen, or no way for consumers to select a product on its own end. For more detail, see [Display Control](/docs/integrate-pos-device/marshall/additional-resources/marshall-display#/). ## eReceipt eReceipt generates a digital receipt file on the device once the transaction settles, and sends the file's link to the peripheral via the SDK using a QR code. To enable it, set the following configurations in Nayax Core: * **Payment** tab > **Transaction Options** > **Enable eReceipt on Transaction End**: enabled * **Receipt Button Display Duration**: 20 * **Receipt QR Display Duration**: 40 * **Vend Flow Options**: Dynamic Receipt In older SDK versions, the URL is stored in hex. Convert it to ASCII to parse it, using a tool such as [this hex-to-ASCII converter](https://www.rapidtables.com/convert/number/hex-to-ascii.html). In newer versions, it looks something like this: ```c C theme={null} marshall-c-sdk-demo: received ereceipt: https://ereceipt.nayax.com/qr/2470412964/0123456478901234/2 ``` ### Fixing an unrecognized eReceipt product name Product names come from your product map. You can create products in it and name them to match the product codes you send via the SDK. Marshall doesn't use any other information in the product map, so it doesn't affect the transaction flow, including prices. The only field that matters is the product code name, which appears in Last Sales and the eReceipt file. To add new products to your device's product map, go to the Product Map tab and click **Map** > **Add BIN**. Add the product code, product group, PA code, and MDB code (the MDB code must match the product code in the SDK), then click **Save**. ## Info session Info Session is an informative, non-vending session that provides the peripheral with the consumer's card details when they present their card. The consumer isn't charged, and receives a `Card Read Successfully` notification. The transaction ends with `Vend Denied`, since there's no authorization and no need to proceed to vending. Info Session is used chiefly for consumer re-identification, by having the consumer present the same card they used to start the transaction. It's most relevant for rentals and EV chargers. <Note> **Important note:** This feature requires the peripheral to have a screen, or another way to distinguish between a vending session and an info session, since the peripheral decides which type of session to start. </Note> ## Incremental authorization Incremental authorizations increase the total amount authorized when the estimated or initial authorization isn't enough. An incremental authorization request can also be based on a revised estimate of the consumer's spending. Incremental authorizations don't replace the original approval: they're additional to previously authorized amounts. The sum of all linked estimated and incremental authorizations is the total amount permitted for a given transaction. <Warning> **Supported billing providers** As of February 2026, only these billing providers support this feature: Heartland (US), Chase (US), Credorax (Europe), First Data (Australia), and Adyen (US and Europe). If your devices use any other billing provider, Incremental Authorization doesn't work. </Warning> ### How incremental authorization works The incremental feature uses two Default Credit parameters: the regular one, and Maximum Default Credit. The consumer is initially authorized for the regular Default Credit amount, as in any PreAuthorization transaction. If there isn't enough credit for the Default Credit amount, the transaction is cancelled at this step. If the consumer takes items worth less than the Default Credit amount, they're only charged for those items, as usual. **Example:** With a Default Credit of \$10.00 (or, in a Multisession with price not final flow, the price of Vend Request instead of Default Credit) and a Maximum Default Credit of \$50.00: If the consumer takes items worth more than the Default Credit amount but less than the Maximum Default Credit amount (for example, \$17.00), the device runs a second authorization for the difference between the final price and the Default Credit amount (\$7.00): * If the second authorization is approved, the consumer is charged the full amount (\$17.00). Last Sales shows this as one line record, with a settlement amount higher than the authorization amount: <Frame> <img alt="Last Sales record showing a settlement amount higher than the authorization amount" /> </Frame> * If the second authorization fails, the consumer is only charged the first authorization amount, the Default Credit (\$10.00). In this case, the loss from the failed second authorization is the machine operator's risk. If the consumer takes items worth more than the Maximum Default Credit (for example, \$60.00), the machine must send the Maximum Default Credit as the final price, or the transaction is cancelled. In this case too, the risk is on the machine operator if the second authorization fails, or if the machine can't charge the consumer more than the Maximum Default Credit (a loss of at least \$10.00). # C SDK Simulator Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/c-sdk-simulator The Nayax Marshall SDK includes a simulator to help developers test and debug their device integration with the Nayax payment system. The simulator replicates the behavior of the actual hardware and software interactions, allowing you to validate the vending process without needing physical hardware. ## Simulator When the C SDK simulator is started on a terminal, its menu will look like this: <TerminalBlock> \[0]: start session 0 \[1]: close session 0 \[2]: info session \[3]: cancel session \[4]: query sessions \[5]: reader state \[6]: link stats \[7]: quit </TerminalBlock> The table below describes each option on the simulator terminal. | Command | Description | | :- | :- | | `Start session 0` | Starts a session (a transaction) with product code 0. | | `Close Session 0` | Only relevant in multisession. Closes the session (settles it) at the end of a transaction. | | `Cancel Session` | Cancels the transaction from the peripheral's end. Can be sent up until the consumer's card has been approved. | | `Query sessions` | Gives information about which sessions are currently open. *This option is relevant from 4.0.0.22 and above*. | | `Reader state` | Gives information about whether the reader is `enabled (1)/disabled (0)`. *This option is relevant from 4.0.0.22 and above*. | | `Link stats` | Provides information about the number of CRC errors, packet retransmissions, and communication losses. | | `Quit` | Quits the simulator program. | ## Transaction flow examples Below are examples of the flow for each transaction type: 1. **Regular Transaction** (Single Session): 1. Start a session: with `[0]: Start session`. 2. Present card, wait for authorization and "Thank you" screen. 2. **Multi-Session Transaction**: 1. Start a session with `[0]: Start session 0`. 2. Present card, wait for authorization and "Thank you" screen. 3. Close the relevant session- in this case, use `[1]: Close Session 0`. ## See also <CardGroup> <Card icon="hashtag" title="C# SDK simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/csharp-sdk-simulator"> Test and debug your C# SDK integration without physical hardware. </Card> <Card icon="mug-hot" title="Java SDK simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/java-sdk-simulator"> Test and debug your Java SDK integration without physical hardware. </Card> </CardGroup> # C# SDK Simulator Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/csharp-sdk-simulator The Nayax Marshall SDK includes a simulator to help developers test and debug their device integration with the Nayax payment system. The simulator replicates the behavior of the actual hardware and software interactions, allowing you to validate the vending process without needing physical hardware. ## Simulator When the C# SDK simulator is started on a terminal, its menu will look like this: <TerminalBlock> \[0]: start session 0 \[1]: close session 0 \[2]: info session \[3]: cancel session \[4]: query sessions \[5]: reader state \[6]: cash sale \[7]: alert \[8]: transfer custom transaction\_id \[9]: brand config \[10]: ftp socket test \[11]: screen control \[12]: link stats \[13]: quit </TerminalBlock> Where: <table> <thead> <tr> <th> Command </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `Start session 0` </td> <td> Starts a session (a transaction) with product code 0. </td> </tr> <tr> <td> `Close Session 0` </td> <td> Only relevant in multisession. Closes the session (settles it) at the end of a transaction. </td> </tr> <tr> <td> `Info Session` </td> <td> Retrieves card details (BIN, PAN-HASH, 4 digits) without charging the consumer or vending a product </td> </tr> <tr> <td> `Cancel Session` </td> <td> Cancels the transaction from the peripheral's end. Can be sent up until the consumer's card has been approved. </td> </tr> <tr> <td> `Query sessions` </td> <td> Gives information about which sessions are currently open. *This option is relevant from 4.0.0.22 and above*. </td> </tr> <tr> <td> `Reader state` </td> <td> Gives information about whether the reader is `enabled (1)/disabled (0)`. *This option is relevant from 4.0.0.22 and above*. </td> </tr> <tr> <td> `Cash sale` </td> <td> Simulates cash sale. </td> </tr> <tr> <td> `Alert` </td> <td> Sends an alert to the DCS. It can be seen in **Last Alerts**. </td> </tr> <tr> <td> `transfer custom transaction_id` </td> <td> Allows the customer to send a custom transaction ID. Needs to be sent during an ongoing transaction process (before or after the authorization) </td> </tr> <tr> <td> `brand config` </td> <td> Relevant only for the Japanese market and firmware version. When selected prior to starting a transaction and then selecting a product, the desired brand selection would take place (without going into the brand selection screen). In order for the peripheral to know which brands are set on the device's end, the devices sends the brands information during the pairing process </td> </tr> <tr> <td> `FTP socket test` </td> <td> Allows the peripheral to use Nayax's modem for its own needs. </td> </tr> <tr> <td> `Screen control` </td> <td> Tests the Display Control feature. Needs configurations in the DCS. </td> </tr> <tr> <td> `Link stats` </td> <td> Provides information about the number of CRC errors, packet retransmissions, and communication losses. </td> </tr> <tr> <td> `Quit` </td> <td> Quits the simulator program. </td> </tr> </tbody> </table> ## Transaction flow examples Below are examples of the flow for each transaction type: 1. **Regular Transaction** (Single Session): 1. Start a session: with `[0]: Start session`. 2. Present card, wait for authorization and "Thank you" screen. 2. **Multi-Session Transaction**: 1. Start a session with `[0]: Start session 0`. 2. Present card, wait for authorization and "Thank you" screen. 3. Close the relevant session- in this case, use `[1]: Close Session 0`. ## See also <SeeAlso> <SeeAlsoCard title="Java SDK Simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/java-sdk-simulator"> The same menu and transaction flows, for the Java SDK. </SeeAlsoCard> <SeeAlsoCard title="C SDK Simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/c-sdk-simulator"> The same menu and transaction flows, for the C SDK. </SeeAlsoCard> </SeeAlso> # Java SDK Simulator Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/java-sdk-simulator The Nayax Marshall SDK includes a simulator to help developers test and debug their implementation with the Nayax payment system. The simulator replicates the behavior of the actual hardware and software interactions, allowing you to validate the vending process without needing physical hardware. ## Simulator When the Java SDK simulator is started on a terminal, its menu will look like this: <TerminalBlock> \[0]: Start Vend Session 0 \[1]: Cancel Session \[2]: Close Session 0 \[3]: Info Session \[4]: Check balance \[5]: query opened sessions \[6]: query reader state \[7]: cash sale \[8]: alert \[9]: select brand \[10]: transfer custom transaction\_id \[11]: display message \[12]: open socket \[13]: close socket \[14]: UI control \[15]: marshall parser \[q]: quit </TerminalBlock> <TerminalBlock> \[0]: Start Vend Session 0 \[1]: Cancel Session \[2]: Close Session 0 \[3]: query opened sessions \[4]: query reader state \[5]: cash sale \[6]: alert \[7]: display message \[8]: open socket \[9]: close socket \[10]: UI control \[q]: quit </TerminalBlock> The following table describes each option: <table> <thead> <tr> <th> Command </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> Start Vend Session 0 </td> <td> Starts a session (a transaction) with product code 0. </td> </tr> <tr> <td> Cancel Session </td> <td> Cancels the transaction from the peripheral's end. Can be sent up until the consumer's card has been approved. </td> </tr> <tr> <td> Close Session 0 </td> <td> Only relevant in multisession. Closes the session (settles it) at the end of a transaction. </td> </tr> <tr> <td> Info Session </td> <td> Retrieves card details (BIN, PAN-HASH, 4 digits) without charging the consumer or vending a product </td> </tr> <tr> <td> Check balance </td> <td> Relevant only for the Japanese market (TMN) </td> </tr> <tr> <td> Query opened sessions </td> <td> Gives information about which sessions are currently open. *This option is relevant from 4.0.0.22 and above*. </td> </tr> <tr> <td> Query reader state </td> <td> Gives information about whether the reader is `enabled (1)/ disabled (0)`. *This option is Relevant from 4.0.0.22 and above*. </td> </tr> <tr> <td> Cash sale </td> <td> Simulates cash sale. </td> </tr> <tr> <td> Alert </td> <td> Sends an alert to the DCS. It can be seen in Last Alerts. </td> </tr> <tr> <td> Select brand </td> <td> Relevant only for the Japanese market and firmware version. When selected prior to starting a transaction and then selecting a product, the desired brand selection would take place (without going into the brand selection screen). In order for the peripheral to know which brands are set on the device's end, the devices sends the brands information during the pairing process </td> </tr> <tr> <td> transfer custom transaction\_id </td> <td> Allows the customer to send a custom transaction ID. Needs to be sent during an ongoing transaction process (before or after the authorization) </td> </tr> <tr> <td> Display message </td> <td> Currently, this option is not available. </td> </tr> <tr> <td> Open socket </td> <td> For the peripheral, use Nayax's modem for its own needs. </td> </tr> <tr> <td> Close socket </td> <td> Closes the socket which was opened for the peripheral. </td> </tr> <tr> <td> UI control </td> <td> Tests the Display Control feature. Needs configurations in Nayax Core. </td> </tr> <tr> <td> Marshall parser </td> <td> Irrelevant, an internal testing tool </td> </tr> <tr> <td> Quit </td> <td> Quits the simulator program. </td> </tr> </tbody> </table> ## Transaction flow examples Below are examples of the flow for each transaction type: 1. **Regular Transaction** (Single Session): 1. Start a session: with `[0]: Start session`. 2. Present card, wait for authorization and "Thank you" screen. 2. **Multi-Session Transaction**: 1. Start a session with `[0]: Start session 0`. 2. Present card, wait for authorization and "Thank you" screen. 3. Close the relevant session- in this case, use `[2]: Close Session 0`. ## See also <CardGroup> <Card icon="hashtag" title="C# SDK simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/csharp-sdk-simulator"> Test and debug your C# SDK integration without physical hardware. </Card> <Card icon="terminal" title="C SDK simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/c-sdk-simulator"> Test and debug your C SDK integration without physical hardware. </Card> </CardGroup> # C SDK Always Idle Mode Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/marshall-c-always-idle The SDK can also configure the peripheral to remain idle, meaning the transaction process would begin from the peripheral's end by sending the "Vend Request" with the relevant product (instead of having the peripheral enable the device's reader upon a product selection, then having the device respond with "Begin Session" to the consumer's card presentation and only then have the peripheral send the "Vend Request"). This page will guide you on implementing an always idle state in C SDK in more detail. To better explain this process, the code implementation is divided into the following steps: 1. Include Libraries 2. Set Up Macro and Global Variables 3. Set Up Private Functions 4. Add Initialization Functions 5. Implement the Main Function See the sections below for more details on each step. ## Step 1: include libraries Start by including the necessary libraries for the SDK. See the code block below: ```c C theme={null} #include <string.h> #include "types.h" #include "macros.h" #include "cli/cli.h" #include "msg_queue/msg_queue.h" #include "vsnprintf/printk.h" #include "cpu_platform.h" #include "board/board.h" #include "menu.h" #include "vpos/vmc_link.h" #include "vpos/vmc_vend.h" /* Drivers */ #include "drv_usart.h" ``` ## Step 2: setup macro and global variables The code below defines a macro for the module name used in logging/debugging and sets up the global variables that store configuration and session-related data. ```c C theme={null} #define __MODULE__ "marshall-c-sdk-demo" static vmc_config_t config; static vend_item_t session_product; static vend_session_t session; static menu_t menu; static int com_id = -1; ``` Where: * `config`: Stores vending machine configuration. * `session_product`: Represents a single vending item. * `session`: Stores the session details. * `menu`: Stores menu-related settings. * `com_id`: Represents a communication ID. ## Step 3: set up private functions Implement helper functions for debugging, handling events, and processing transactions. The following sections provide more details. ### Debug output function This function determines the output stream for debug information, supporting different platforms: * Linux/X8: Uses `printf()`. * STM32 microcontroller: Uses `drv_usart_tx_data()`. See the code below. ```c C theme={null} static void terminal_tx_str(char *str) { #if defined(__PLATFORM_X86) || defined(__PLATFORM_LINUX) printf("%s", str); #elif defined(__PLATFORM_STM32) drv_usart_tx_data(&terminal_usart, (uint8_t*)str, strlen(str)); #endif } ``` Where: * `str`: String that contains the debug information. ### CPU timer tick This function is called periodically (every 5-10ms) by the platform timer. ```c C theme={null} static __bool cpu_timer_tick(void *p) { vmc_link_background(); return __false; } ``` Where: * `p`: Pointer to optional parameter (unused in this function). ### VMC link events handler This function handles link events and logs relevant information. ```c C theme={null} static __bool vmc_link_event_handler_cb(int event_id, void *data) { __bool result = __false; __log("link event_id: %d", event_id); switch (event_id) { case vmc_link_event_on_ready: if (__true) { vpos_config_t *config = (vpos_config_t*)data; __log("link ok! decimal places: %d", config->decimal_place); } break; case vmc_link_event_on_comm_error: if (__true) { __log("lost comm"); } break; default: break; } return result; } ``` Where: * `event_id`: Type of link event. * `data`: Pointer to optional parameter (varies based on event type). The function will always return the boolean value `__false` as no success/failure is determined. ### Vend requests handler This function handles the session and the included items. See the code block below: ```c C theme={null} static void triggered_vend_request(void) { if (config.reader_always_on) current_session = 2; if (current_session != -1) { vend_session_t *session = &sessions[current_session]; /* a card has been detected. now we can ask the vpos to take money */ memset(session, 0, sizeof(vend_session_t)); session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } else { session->products = &session_products[current_session]; session->total_products = 1; } vmc_vend_vend_request(session); if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support) { vmc_vend_client_gateway_auth(__true); } } } ``` ### Vending events handler This function handles vend events and logs relevant information. ```c C theme={null} static __bool vmc_vend_event_handler_cb(int event_id, void *data) { __bool result = __false; static __bool vend_sent = __false; __log("vend event_id: %d", event_id); switch (event_id) { case vmc_vend_event_on_ready: break; case vmc_vend_event_on_vend_approved: /* the vpos approved the payment */ result = __true; break; case vmc_vend_event_on_vend_denied: /* the vpos declined the payment */ break; case vmc_vend_event_on_settlement: break; case vmc_vend_event_on_session_canceled: if (__true) { __log("received cancel session"); } break; case vmc_vend_event_on_transaction_info: if (__true) { __log("received transaction info"); vmc_vend_transfer_data_t *info = (vmc_vend_transfer_data_t*)data; if (info->encode_bitmap & transfer_data_encode_transaction_id) __log("transaction id: %lu", __ptr2uint64_t(info->transaction_id)); if (info->encode_bitmap & transfer_data_encode_card_bin) __log("card bin: %.6s", info->card_bin); if (info->encode_bitmap & transfer_data_encode_prop_card_uid) __log("prop card uid: %lu", __ptr2uint64_t(info->prop_card_uid)); if (info->encode_bitmap & transfer_data_encode_card_last_4_digits) __log("cc last 4 digits: %.4s", info->cc_last_4_digits); } break; case vmc_vend_event_on_status: if (__true) { uint32_t status = (uint32_t)data; __log("received status: %d", status); } break; case vmc_vend_event_on_sessions_rsp: if (__true) { mdb_msg_sessions_status_t *sessions = (mdb_msg_sessions_status_t*)data; __log("open sessions: %d\n", sessions->num_opened_sessions); } break; case vmc_vend_event_on_reader_state_rsp: if (__true) { mdb_msg_reader_status_t *state = (mdb_msg_reader_status_t*)data; __log("reader state: %d\n", state); } break; case vmc_vend_event_on_qr_code: if (__true) { ereceipt_t *receipt = (ereceipt_t*)data; __log("received ereceipt: %s\n", receipt->qr_data); } break; case vmc_vend_event_on_session_timeout: if (__true) { uint32_t *session_id = (uint32_t*)data; __log("session timeout: %d\n", session_id); } break; default: break; } return result; } ``` Where: * `event_id`: Type of vend event. * `data`: Pointer to optional parameter. Varies based on event type. This function will return a boolean value: * `__false` in most cases. * `__true` for `vmc_vend_event_on_vend_approved` to indicate a successful vend approval. ## Step 4: setup initialization functions After adding the helper functions, you need to implement the functions to initialize the VMC configuration and the Menu Handler. See the sections below for more details. ### Initialize VMC This function initializes the VMC configuration and registers the event handlers. See the code below: ```c C theme={null} static void vmc_init(void) { /* initialize sdk */ vmc_link_init(); /* configuring the sdk */ memset(&config, 0, sizeof(config)); __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, "01234567"); __strcpy(config.vmc_manuf_code, "manuf"); config.multi_vend_support = __false; config.multi_session_support = __false; config.price_not_final_support = __false; config.reader_always_on = __false; config.always_idle = __true; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; /* register to the link and vend events */ vmc_link_register_callback((vmc_link_event_handler_cb_t)vmc_link_event_handler_cb); vmc_vend_register_callback((vmc_vend_event_handler_cb_t)vmc_vend_event_handler_cb); } ``` Since you want to leave the status in the always idle, set `config.always_idle` to `__true`. ### Initialize menu Before initializing the menu, add the necessary handler functions. See the code below: ```c C theme={null} static void handler_start_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_credit_e); triggered_vend_request(); } static void handler_cancel_session(void *aux_data) { vmc_vend_session_cancel(); } static void handler_quit(void *aux_data) { menu_stop(&menu); exit(0); } static void handler_link_stats(void *aux_data) { vmc_stats_t* stats = vmc_link_get_link_stats(); char buffer[50]; sprintf(buffer, "\n ------ Stats ------ \n"); menu_output(buffer); sprintf(buffer, " crc error: %d\n", stats->crc_errors); menu_output(buffer); sprintf(buffer, " re-trans: %d\n", stats->retrans); menu_output(buffer); sprintf(buffer, " link loss: %d\n", stats->resets); menu_output(buffer); sprintf(buffer, " ------ Stats ------ \n"); menu_output(buffer); } static void handler_info_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_info_e); } static void handler_query_sessions(void *aux_data) { vmc_vend_get_session_status(); } static void handler_reader_state(void *aux_data) { vmc_vend_get_reader_state(); } ``` Now, you can initialize the menu, calling the handlers created before. See the code below. ```c C theme={null} static void menu_init(void) { menu.total_items = 0; menu_add_item(&menu, "start session 0", &handler_start_session, 0); menu_add_item(&menu, "close session 0", &handler_close_session, 0); if (config.multi_session_support == __true) { menu_add_item(&menu, "start session 1", &handler_start_session, 1); menu_add_item(&menu, "close session 1", &handler_close_session, 1); } menu_add_item(&menu, "info session", &handler_info_session, __null); menu_add_item(&menu, "cancel session", &handler_cancel_session, __null); menu_add_item(&menu, "query sessions", &handler_query_sessions, __null); menu_add_item(&menu, "reader state", &handler_reader_state, __null); menu_add_item(&menu, "link stats", &handler_link_stats, __null); menu_add_item(&menu, "display control", &handler_display_control, __null); menu_add_item(&menu, "quit", &handler_quit, __null); menu.menu_running = __true; menu_show(&menu); } ``` ## Step 5: implement the main function Once all other parts are implemented, you can add the program's main entry point, which initializes the link to the peripheral and the menu, then starts an infinite loop that runs the menu. See the code below: ```c C theme={null} int mymain(int argc, char *argv[]) { printk_register_puts(terminal_tx_str); /* Modules initialization */ vmc_init(); set_command_line_arguments(argc, argv, &config, &com_id); /* Board initialization */ board_init(com_id); /* Register the timer tick handler */ cpu_platform_register_timer_tick_cb(2, (platform_timer_tick_cb_t)cpu_timer_tick); /* Modules initialization */ #if UTILITIES_CLI_MODE==1 cli_init(); cli_register_io(terminal_tx_str); printk("welcome to %s, version: %s, build: %s\n\r", __stringify(APP_NAME), __stringify(APP_VER), __stringify(APP_BUILD)); printk("build data: "__DATE__ " "__TIME__"\n\r"); /* Start modules and application */ cli_start(); #endif vmc_link_start(&vmc_usart, &config); menu_init(); while (1) { #if UTILITIES_CLI_MODE==1 if (drv_usart_is_rx_pending(&terminal_usart)) { cli_process_char(drv_usart_rx_byte(&terminal_usart)); } #endif menu_run(&menu); } } ``` # Simulators & Sample Codes Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/marshall-sdk-simulators This section provides simulators (demo apps) in the SDK in order to help developers test and debug their implementation with the Nayax payment system, along with sample codes for implementing different Payment flows in the C SDK. ## Simulators <CardGroup> <Card icon="display" title="C# SDK Simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/csharp-sdk-simulator"> Test and debug a C# SDK device integration without physical hardware. </Card> <Card icon="display" title="C SDK Simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/c-sdk-simulator"> Test and debug a C SDK device integration without physical hardware. </Card> <Card icon="display" title="Java SDK Simulator" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/java-sdk-simulator"> Test and debug a Java SDK implementation without physical hardware. </Card> </CardGroup> ## Sample Codes <CardGroup> <Card icon="user" title="C SDK Single Session" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/single-session"> Process a single transaction before the system resets. </Card> <Card icon="users" title="C SDK Multi-Session" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-session"> Run multiple independent transactions in self-service environments. </Card> <Card icon="layer-group" title="C SDK Multi-Vend" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-vend"> Let consumers buy multiple differentiated items in one payment session. </Card> <Card icon="hourglass" title="C SDK Always Idle Mode" href="/docs/integrate-pos-device/marshall/simulators-sample-codes/marshall-c-always-idle"> Configure the peripheral to start the transaction with a Vend Request. </Card> </CardGroup> # C SDK Multi-Session Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-session Multi-session payment allows multiple transactions to be processed independently, ensuring a seamless user experience in self-service environments. This page will guide you through implementing a multi-session payment in C SDK in more detail. To better explain this process, the code implementation is divided into the following steps: 1. Include Libraries 2. Set Up Macro and Global Variables 3. Set Up Private Functions 4. Add Initialization Functions 5. Implement the Main Function See the section below for more details on each step. ## Step 1: include libraries Start by including the necessary libraries for the SDK. See the code block below: ```c C theme={null} #include <string.h> #include "types.h" #include "macros.h" #include "cli/cli.h" #include "msg_queue/msg_queue.h" #include "vsnprintf/printk.h" #include "cpu_platform.h" #include "board/board.h" #include "menu.h" #include "vpos/vmc_link.h" #include "vpos/vmc_vend.h" /* Drivers */ #include "drv_usart.h" ``` ## Step 2: setup macro and global variables The code below defines a macro for the module name used in logging/debugging and sets up the global variables that store configuration and session-related data. ```c C theme={null} #define __MODULE__ "marshall-c-sdk-demo" static vmc_config_t config; static vend_item_t session_products[2]; static vend_session_t sessions[2]; static int current_session = -1; static menu_t menu; static int com_id = -1; ``` Where: * `config`: Stores vending machine configuration. * `session_products`: Array representing two products, one per session. * The first is for session 0. * The second is for session 1. * `sessions`: Array representing two active sessions. * `current_session`: Keeps track of the active session. * `menu`: Stores menu-related settings. * `com_id`: Represents a communication ID. ## Step 3: setup private functions Implement helper functions for debugging, event handling, and transaction processing. The following sections provide more details. ### Debug output function This function determines the output stream for debug information. ```c C theme={null} static void terminal_tx_str(char *str) { #if defined(__PLATFORM_X86) || defined(__PLATFORM_LINUX) printf("%s", str); #elif defined(__PLATFORM_STM32) drv_usart_tx_data(&terminal_usart, (uint8_t*)str, strlen(str)); #endif } ``` Where: * `str`: String that contains the debug information. ### CPU timer tick This function is called periodically (every 5-10ms) by the platform timer. ```c C theme={null} static __bool cpu_timer_tick(void *p) { vmc_link_background(); return __false; } ``` Where: * `p`: Pointer to optional parameter (unused in this function). ### VMC link events handler This function handles link events and logs relevant information. ```c C theme={null} static __bool vmc_link_event_handler_cb(int event_id, void *data) { __bool result = __false; __log("link event_id: %d", event_id); switch (event_id) { case vmc_link_event_on_ready: if (__true) { vpos_config_t *config = (vpos_config_t*)data; __log("link ok! decimal places: %d", config->decimal_place); } break; case vmc_link_event_on_comm_error: if (__true) { __log("lost comm"); } break; default: break; } return result; } ``` Where: * `event_id`: Type of link event. * `data`: Pointer to optional parameter (varies based on event type). The function will always return the boolean value `__false` as no success/failure is determined. ### Multi-session vend request handler This function manages the session and its included items, then sends a vending request to the Nayax Device. See the code block below: ```c C theme={null} static void triggered_vend_request(void) { if (config.reader_always_on) current_session = 2; if (current_session != -1) { vend_session_t *session = &sessions[current_session]; /* a card has been detected. now we can ask the vpos to take money */ memset(session, 0, sizeof(vend_session_t)); session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } else { session->products = &session_products[current_session]; session->total_products = 1; } vmc_vend_vend_request(session); if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support) { vmc_vend_client_gateway_auth(__true); } } } ``` It initializes `session_products` 0 and 1, each with a different product code and price. Each of those would be a separate session (transaction). This is, of course, a demo app, meaning you can (and should) manage your own products and prices to match your peripherals. ### Multi-session vending events handler This function handles vend events for multi-session and logs relevant information. ```c C theme={null} static __bool vmc_vend_event_handler_cb(int event_id, void *data) { __bool result = __false; static __bool vend_sent = __false; __log("vend event_id: %d", event_id); switch (event_id) { case vmc_vend_event_on_ready: break; case vmc_vend_event_on_session_begin: if (__true) { triggered_vend_request(); } break; case vmc_vend_event_on_vend_approved: /* the vpos approved the payment */ result = __true; break; case vmc_vend_event_on_vend_denied: /* the vpos declined the payment */ break; case vmc_vend_event_on_settlement: break; case vmc_vend_event_on_session_canceled: if (__true) { __log("received cancel session"); } break; case vmc_vend_event_on_transaction_info: if (__true) { __log("received transaction info"); vmc_vend_transfer_data_t *info = (vmc_vend_transfer_data_t*)data; if (info->encode_bitmap & transfer_data_encode_transaction_id) __log("transaction id: %lu", __ptr2uint64_t(info->transaction_id)); if (info->encode_bitmap & transfer_data_encode_card_bin) __log("card bin: %.6s", info->card_bin); if (info->encode_bitmap & transfer_data_encode_prop_card_uid) __log("prop card uid: %lu", __ptr2uint64_t(info->prop_card_uid)); if (info->encode_bitmap & transfer_data_encode_card_last_4_digits) __log("cc last 4 digits: %.4s", info->cc_last_4_digits); } break; case vmc_vend_event_on_status: if (__true) { uint32_t status = (uint32_t)data; __log("received status: %d", status); } break; case vmc_vend_event_on_sessions_rsp: if (__true) { mdb_msg_sessions_status_t *sessions = (mdb_msg_sessions_status_t*)data; __log("open sessions: %d\n", sessions->num_opened_sessions); } break; case vmc_vend_event_on_reader_state_rsp: if (__true) { mdb_msg_reader_status_t *state = (mdb_msg_reader_status_t*)data; __log("reader state: %d\n", state); } break; case vmc_vend_event_on_qr_code: if (__true) { ereceipt_t *receipt = (ereceipt_t*)data; __log("received ereceipt: %s\n", receipt->qr_data); } break; case vmc_vend_event_on_session_timeout: if (__true) { uint32_t *session_id = (uint32_t*)data; __log("session timeout: %d\n", session_id); } break; default: break; } return result; } ``` Where: * `event_id`: Type of vend event. * `data`: Pointer to optional parameter. Varies based on event type. This function will return a Boolean value: * `__false` in most cases. * `__true` for `vmc_vend_event_on_vend_approved` to indicate a successful vend approval. ## Step 4: setup initialization functions After adding the helper functions, you need to implement the functions to initialize the VMC configuration and the Menu Handler. See the sections below for more details. ### Initialize VMC This function initializes the VMC configuration and registers the event handlers. See the code below: ```c C theme={null} static void vmc_init(void) { /* initialize sdk */ vmc_link_init(); /* configuring the sdk */ memset(&config, 0, sizeof(config)); __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, "01234567"); __strcpy(config.vmc_manuf_code, "manuf"); config.multi_vend_support = __false; config.multi_session_support = __true; config.price_not_final_support = __true; config.reader_always_on = __false; config.always_idle = __false; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; /* Register to the link and vend events */ vmc_link_register_callback((vmc_link_event_handler_cb_t)vmc_link_event_handler_cb); vmc_vend_register_callback((vmc_vend_event_handler_cb_t)vmc_vend_event_handler_cb); } ``` Since this is a multi-session payment ` config.multi_session_support` is set to`__true`. ### Initialize menu Before initializing the menu, add the necessary handler functions. See the code below: ```c C theme={null} static void handler_start_session(void *aux_data) { current_session = (int)aux_data; vmc_vend_session_start(vmc_vend_session_type_credit_e); } static void handler_close_session(void *aux_data) { current_session = (int)aux_data; if (current_session != -1) { vend_session_t *session = &sessions[current_session]; /* The settlement price can be updated: */ session_products[current_session].price /= 2; /* Can also notify vpos on session status, for example: */ if (__false) session->session_status = vmc_vend_session_status_fail_to_dispense_e; vmc_vend_session_close(session); } } static void handler_cancel_session(void *aux_data) { vmc_vend_session_cancel(); } static void handler_quit(void *aux_data) { menu_stop(&menu); exit(0); }; static void handler_link_stats(void *aux_data) { vmc_stats_t* stats = vmc_link_get_link_stats(); char buffer[50]; sprintf(buffer, "\n ------ Stats ------ \n"); menu_output(buffer); sprintf(buffer, " crc error: %d\n", stats->crc_errors); menu_output(buffer); sprintf(buffer, " re-trans: %d\n", stats->retrans); menu_output(buffer); sprintf(buffer, " link loss: %d\n", stats->resets); menu_output(buffer); sprintf(buffer, " ------ Stats ------ \n"); menu_output(buffer); } static void handler_info_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_info_e); } static void handler_query_sessions(void *aux_data) { vmc_vend_get_session_status(); } static void handler_reader_state(void *aux_data) { vmc_vend_get_reader_state(); } ``` Now, you can initialize the menu linking the handlers created before. See the code below. ```c C theme={null} static void menu_init(void) { menu.total_items = 0; menu_add_item(&menu, "start session 0", &handler_start_session, 0); menu_add_item(&menu, "close session 0", &handler_close_session, 0); if (config.multi_session_support == __true) { menu_add_item(&menu, "start session 1", &handler_start_session, 1); menu_add_item(&menu, "close session 1", &handler_close_session, 1); } menu_add_item(&menu, "info session", &handler_info_session, __null); menu_add_item(&menu, "cancel session", &handler_cancel_session, __null); menu_add_item(&menu, "query sessions", &handler_query_sessions, __null); menu_add_item(&menu, "reader state", &handler_reader_state, __null); menu_add_item(&menu, "link stats", &handler_link_stats, __null); menu_add_item(&menu, "display control", &handler_display_control, __null); menu_add_item(&menu, "quit", &handler_quit, __null); menu.menu_running = __true; menu_show(&menu); } ``` ## Step 5: implement the main function Once all other parts are implemented, you can add the program's main entry point, which initializes the link to the peripheral and the menu, then starts an infinite loop that runs the menu. See the code below: ```c C theme={null} int mymain(int argc, char *argv[]) { printk_register_puts(terminal_tx_str); /* Modules initialization */ vmc_init(); set_command_line_arguments(argc, argv, &config, &com_id); /* Board initialization */ board_init(com_id); /* Register the timer tick handler */ cpu_platform_register_timer_tick_cb(2, (platform_timer_tick_cb_t)cpu_timer_tick); /* Modules initialization */ #if UTILITIES_CLI_MODE==1 cli_init(); cli_register_io(terminal_tx_str); printk("welcome to %s, version: %s, build: %s\n\r", __stringify(APP_NAME), __stringify(APP_VER), __stringify(APP_BUILD)); printk("build data: "__DATE__ " "__TIME__"\n\r"); /* Start modules and application */ cli_start(); #endif vmc_link_start(&vmc_usart, &config); menu_init(); while (1) { #if UTILITIES_CLI_MODE==1 if (drv_usart_is_rx_pending(&terminal_usart)) { cli_process_char(drv_usart_rx_byte(&terminal_usart)); } #endif menu_run(&menu); } } ``` # C SDK Multi-Vend Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/multi-vend The multi-vend flow in Nayax allows consumers to purchase multiple items within a single payment session and for the peripheral to have differentiation between said products. This is useful in vending machines and self-service kiosks where customers may want to select various products before completing a payment. This page will guide you through implementing a multi-vend session in C SDK in more detail. To better explain this process, the code implementation is divided into the following steps: 1. Include Libraries 2. Set Up Macro and Global Variables 3. Set Up Private Functions 4. Add Initialization Functions 5. Implement the Main Function See the sections below for more details on each step. ## Step 1: include libraries Start by including the necessary libraries for the SDK. See the code block below: ```c C theme={null} #include <string.h> #include "types.h" #include "macros.h" #include "cli/cli.h" #include "msg_queue/msg_queue.h" #include "vsnprintf/printk.h" #include "cpu_platform.h" #include "board/board.h" #include "menu.h" #include "vpos/vmc_link.h" #include "vpos/vmc_vend.h" /* Drivers */ #include "drv_usart.h" ``` ## Step 2: setup macro and global variables The code below defines a macro for the module name used in logging/debugging and sets up the global variables that store configuration and session-related data. ```c C theme={null} #define __MODULE__ "marshall-c-sdk-demo" static vmc_config_t config; static vend_item_t session_products[2]; static vend_session_t session; static int current_session = -1; static menu_t menu; static int com_id = -1; ``` Where: * `config`: Stores vending machine configuration. * `session_products`: Array holding two different items for vending. * `session`: Stores the session details. * `menu`: Stores menu-related settings. * `com_id`: Represents a communication ID. ## Step 3: setup private functions Implement helper functions for debugging, event handling, and transaction processing. The following sections provide more details. ### Debug output function This function determines the output stream for debug information. ```c C theme={null} static void terminal_tx_str(char *str) { #if defined(__PLATFORM_X86) || defined(__PLATFORM_LINUX) printf("%s", str); #elif defined(__PLATFORM_STM32) drv_usart_tx_data(&terminal_usart, (uint8_t*)str, strlen(str)); #endif } ``` Where: * `str`: String that contains the debug information. ### CPU timer tick This function is called periodically (every 5-10ms) by the platform timer. ```c C theme={null} static __bool cpu_timer_tick(void *p) { vmc_link_background(); return __false; } ``` Where: * `p`: Pointer to optional parameter (unused in this function). ### VMC link events handler This function handles link events and logs relevant information. ```c C theme={null} static __bool vmc_link_event_handler_cb(int event_id, void *data) { __bool result = __false; __log("link event_id: %d", event_id); switch (event_id) { case vmc_link_event_on_ready: if (__true) { vpos_config_t *config = (vpos_config_t*)data; __log("link ok! decimal places: %d", config->decimal_place); } break; case vmc_link_event_on_comm_error: if (__true) { __log("lost comm"); } break; default: break; } return result; } ``` Where: * `event_id`: Type of link event. * `data`: Pointer to optional parameter (varies based on event type). The function will always return the boolean value `__false` as no success/failure is determined. ### Multi-vend requests handler This function handles the session and the included items. See the code block below: ```c C theme={null} static void triggered_vend_request(void) { if (config.reader_always_on) current_session = 2; if (current_session != -1) { vend_session_t *session = &sessions[current_session]; /* a card has been detected. now we can ask the vpos to take money */ memset(session, 0, sizeof(vend_session_t)); session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } else { session->products = &session_products[current_session]; session->total_products = 1; } vmc_vend_vend_request(session); if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support) { vmc_vend_client_gateway_auth(__true); } } } ``` It initializes `session_products` 0 and 1, each with a different product code and price and adds them to the "session" object. ### Multi-session vending events handler This function handles vend events and logs relevant information. ```c C theme={null} static __bool vmc_vend_event_handler_cb(int event_id, void *data) { __bool result = __false; static __bool vend_sent = __false; __log("vend event_id: %d", event_id); switch (event_id) { case vmc_vend_event_on_ready: break; case vmc_vend_event_on_session_begin: if (__true) { triggered_vend_request(); } break; case vmc_vend_event_on_vend_approved: /* the vpos approved the payment */ result = __true; break; case vmc_vend_event_on_vend_denied: /* the vpos declined the payment */ break; case vmc_vend_event_on_settlement: break; case vmc_vend_event_on_session_canceled: if (__true) { __log("received cancel session"); } break; case vmc_vend_event_on_transaction_info: if (__true) { __log("received transaction info"); vmc_vend_transfer_data_t *info = (vmc_vend_transfer_data_t*)data; if (info->encode_bitmap & transfer_data_encode_transaction_id) __log("transaction id: %lu", __ptr2uint64_t(info->transaction_id)); if (info->encode_bitmap & transfer_data_encode_card_bin) __log("card bin: %.6s", info->card_bin); if (info->encode_bitmap & transfer_data_encode_prop_card_uid) __log("prop card uid: %lu", __ptr2uint64_t(info->prop_card_uid)); if (info->encode_bitmap & transfer_data_encode_card_last_4_digits) __log("cc last 4 digits: %.4s", info->cc_last_4_digits); } break; case vmc_vend_event_on_status: if (__true) { uint32_t status = (uint32_t)data; __log("received status: %d", status); } break; case vmc_vend_event_on_sessions_rsp: if (__true) { mdb_msg_sessions_status_t *sessions = (mdb_msg_sessions_status_t*)data; __log("open sessions: %d\n", sessions->num_opened_sessions); } break; case vmc_vend_event_on_reader_state_rsp: if (__true) { mdb_msg_reader_status_t *state = (mdb_msg_reader_status_t*)data; __log("reader state: %d\n", state); } break; case vmc_vend_event_on_qr_code: if (__true) { ereceipt_t *receipt = (ereceipt_t*)data; __log("received ereceipt: %s\n", receipt->qr_data); } break; case vmc_vend_event_on_session_timeout: if (__true) { uint32_t *session_id = (uint32_t*)data; __log("session timeout: %d\n", session_id); } break; default: break; } return result; } ``` Where: * `event_id`: Type of vend event. * `data`: Pointer to optional parameter. Varies based on event type. This function will return a boolean value: * `__false` in most cases. * `__true` for `vmc_vend_event_on_vend_approved` to indicate a successful vend approval. ## Step 4: setup initialization functions After adding the helper functions, you need to implement the functions to initialize the VMC configuration and the Menu Handler. See the sections below for more details. ### Initialize VMC This function initializes the VMC configuration and registers the event handlers. See the code below: ```c C theme={null} static void vmc_init(void) { /* initialize sdk */ vmc_link_init(); /* configuring the sdk */ memset(&config, 0, sizeof(config)); __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, "01234567"); __strcpy(config.vmc_manuf_code, "manuf"); config.multi_vend_support = __true; config.multi_session_support = __false; config.price_not_final_support = __false; config.reader_always_on = __false; config.always_idle = __false; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; /* register to the link and vend events */ vmc_link_register_callback((vmc_link_event_handler_cb_t)vmc_link_event_handler_cb); vmc_vend_register_callback((vmc_vend_event_handler_cb_t)vmc_vend_event_handler_cb); } ``` Since this is a multi-vend session ` config.multi_vend_support` is set to `__true`. ### Initialize menu Before initializing the menu, add the necessary handler functions. See the code below: ```c C theme={null} static void handler_start_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_credit_e); } static void handler_cancel_session(void *aux_data) { vmc_vend_session_cancel(); } static void handler_quit(void *aux_data) { menu_stop(&menu); exit(0); } static void handler_link_stats(void *aux_data) { vmc_stats_t* stats = vmc_link_get_link_stats(); char buffer[50]; sprintf(buffer, "\n ------ Stats ------ \n"); menu_output(buffer); sprintf(buffer, " crc error: %d\n", stats->crc_errors); menu_output(buffer); sprintf(buffer, " re-trans: %d\n", stats->retrans); menu_output(buffer); sprintf(buffer, " link loss: %d\n", stats->resets); menu_output(buffer); sprintf(buffer, " ------ Stats ------ \n"); menu_output(buffer); } static void handler_info_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_info_e); } static void handler_query_sessions(void *aux_data) { vmc_vend_get_session_status(); } static void handler_reader_state(void *aux_data) { vmc_vend_get_reader_state(); } ``` Now you can initialize the menu by linking the handlers you created earlier. See the code below. ```c C theme={null} static void menu_init(void) { menu.total_items = 0; menu_add_item(&menu, "start session 0", &handler_start_session, 0); menu_add_item(&menu, "close session 0", &handler_close_session, 0); if (config.multi_session_support == __true) { menu_add_item(&menu, "start session 1", &handler_start_session, 1); menu_add_item(&menu, "close session 1", &handler_close_session, 1); } menu_add_item(&menu, "info session", &handler_info_session, __null); menu_add_item(&menu, "cancel session", &handler_cancel_session, __null); menu_add_item(&menu, "query sessions", &handler_query_sessions, __null); menu_add_item(&menu, "reader state", &handler_reader_state, __null); menu_add_item(&menu, "link stats", &handler_link_stats, __null); menu_add_item(&menu, "display control", &handler_display_control, __null); menu_add_item(&menu, "quit", &handler_quit, __null); menu.menu_running = __true; menu_show(&menu); } ``` ## Step 5: implement the main function Once all other parts are implemented, you can add the program's main entry point, which initializes the link to the peripheral and the menu, then starts an infinite loop that runs the menu. See the code below: ```c C theme={null} int mymain(int argc, char *argv[]) { printk_register_puts(terminal_tx_str); /* Modules initialization */ vmc_init(); set_command_line_arguments(argc, argv, &config, &com_id); /* Board initialization */ board_init(com_id); /* Register the timer tick handler */ cpu_platform_register_timer_tick_cb(2, (platform_timer_tick_cb_t)cpu_timer_tick); /* Modules initialization */ #if UTILITIES_CLI_MODE==1 cli_init(); cli_register_io(terminal_tx_str); printk("welcome to %s, version: %s, build: %s\n\r", __stringify(APP_NAME), __stringify(APP_VER), __stringify(APP_BUILD)); printk("build data: "__DATE__ " "__TIME__"\n\r"); /* Start modules and application */ cli_start(); #endif vmc_link_start(&vmc_usart, &config); menu_init(); while (1) { #if UTILITIES_CLI_MODE==1 if (drv_usart_is_rx_pending(&terminal_usart)) { cli_process_char(drv_usart_rx_byte(&terminal_usart)); } #endif menu_run(&menu); } } ``` # C SDK Single Session Source: https://devzone.nayax.com/docs/integrate-pos-device/marshall/simulators-sample-codes/single-session The single-session payment in Nayax allows only one transaction to be processed. Unlike multi-session, where multiple transactions can run concurrently, the system handles a single-user payment session before resetting. This page will guide you through implementing a single session in C SDK in more detail. To better explain this process, the code implementation is divided into the following steps: 1. Include Libraries 2. Set Up Macro and Global Variables 3. Set Up Private Functions 4. Add Initialization Functions 5. Implement the Main Function See the section below for more details on each step. ## Step 1: include libraries Start by including the necessary libraries for the SDK. See the code block below: ```c C theme={null} #include <string.h> #include "types.h" #include "macros.h" #include "cli/cli.h" #include "msg_queue/msg_queue.h" #include "vsnprintf/printk.h" #include "cpu_platform.h" #include "board/board.h" #include "menu.h" #include "vpos/vmc_link.h" #include "vpos/vmc_vend.h" /* Drivers */ #include "drv_usart.h" ``` ## Step 2: setup macro and global variables The code below defines a macro for the module's logging/debugging name and sets up global variables to store configuration and session-related data. ```c C theme={null} #define __MODULE__ "marshall-c-sdk-demo" static vmc_config_t config; static vend_item_t session_product; static vend_session_t session; static menu_t menu; static int com_id = -1; ``` Where: * `config`: Stores vending machine configuration. * `session_product`: Represents a product in a vending session. * `session`: Represents an ongoing vending session. * `menu`: Stores menu-related settings. * `com_id`: Represents a communication ID (-1 as default). ## Step 3: setup private functions Implement helper functions for debugging, event handling, and transaction processing. The following sections provide more details. ### Debug output function This function determines the output stream for debug information. ```c C theme={null} static void terminal_tx_str(char *str) { #if defined(__PLATFORM_X86) || defined(__PLATFORM_LINUX) printf("%s", str); #elif defined(__PLATFORM_STM32) drv_usart_tx_data(&terminal_usart, (uint8_t*)str, strlen(str)); #endif } ``` Where: * `str`: String that contains the debug information. ### CPU timer tick This function is called periodically (every 5-10ms) by the platform timer. ```c C theme={null} static __bool cpu_timer_tick(void *p) { vmc_link_background(); return __false; } ``` Where: * `p`: Pointer to optional parameter (unused in this function). ### VMC link events handler This function handles link events and logs relevant information. ```c C theme={null} static __bool vmc_link_event_handler_cb(int event_id, void *data) { __bool result = __false; __log("link event_id: %d", event_id); switch (event_id) { case vmc_link_event_on_ready: if (__true) { vpos_config_t *config = (vpos_config_t*)data; __log("link ok! decimal places: %d", config->decimal_place); } break; case vmc_link_event_on_comm_error: if (__true) { __log("lost comm"); } break; default: break; } return result; } ``` Where: * `event_id`: Type of link event. * `data`: Pointer to optional parameter (varies based on event type). The function will return a boolean value (`__false` always, as no success/failure is determined). ### Vend request handler This function manages the session and its included items, then sends a vending request to the VPOS. ```c C theme={null} static void triggered_vend_request(void) { if (config.reader_always_on) current_session = 2; if (current_session != -1) { vend_session_t *session = &sessions[current_session]; /* a card has been detected. now we can ask the vpos to take money */ memset(session, 0, sizeof(vend_session_t)); session_products[0].code = 1; session_products[0] .qty = 1; session_products[0].price = 10; session_products[0].unit = 1; session_products[1].code = 2; session_products[1].qty = 1; session_products[1].price = 20; session_products[1].unit = 1; if (config.multi_vend_support) { session->products = session_products; session->total_products = 2; } else { session->products = &session_products[current_session]; session->total_products = 1; } vmc_vend_vend_request(session); if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support) { vmc_vend_client_gateway_auth(__true); } } } ``` ### VMC vend events handler Handles vend events and logs relevant information. ```c C theme={null} static __bool vmc_vend_event_handler_cb(int event_id, void *data) { __bool result = __false; static __bool vend_sent = __false; __log("vend event_id: %d", event_id); switch (event_id) { case vmc_vend_event_on_ready: break; case vmc_vend_event_on_session_begin: if (__true) { triggered_vend_request(); } break; case vmc_vend_event_on_vend_approved: /* the vpos approved the payment */ result = __true; break; case vmc_vend_event_on_vend_denied: /* the vpos declined the payment */ break; case vmc_vend_event_on_settlement: break; case vmc_vend_event_on_session_canceled: if (__true) { __log("received cancel session"); } break; case vmc_vend_event_on_transaction_info: if (__true) { __log("received transaction info"); vmc_vend_transfer_data_t *info = (vmc_vend_transfer_data_t*)data; if (info->encode_bitmap & transfer_data_encode_transaction_id) __log("transaction id: %lu", __ptr2uint64_t(info->transaction_id)); if (info->encode_bitmap & transfer_data_encode_card_bin) __log("card bin: %.6s", info->card_bin); if (info->encode_bitmap & transfer_data_encode_prop_card_uid) __log("prop card uid: %lu", __ptr2uint64_t(info->prop_card_uid)); if (info->encode_bitmap & transfer_data_encode_card_last_4_digits) __log("cc last 4 digits: %.4s", info->cc_last_4_digits); } break; case vmc_vend_event_on_status: if (__true) { uint32_t status = (uint32_t)data; __log("received status: %d", status); } break; case vmc_vend_event_on_sessions_rsp: if (__true) { mdb_msg_sessions_status_t *sessions = (mdb_msg_sessions_status_t*)data; __log("open sessions: %d\n", sessions->num_opened_sessions); } break; case vmc_vend_event_on_reader_state_rsp: if (__true) { mdb_msg_reader_status_t *state = (mdb_msg_reader_status_t*)data; __log("reader state: %d\n", state); } break; case vmc_vend_event_on_qr_code: if (__true) { ereceipt_t *receipt = (ereceipt_t*)data; __log("received ereceipt: %s\n", receipt->qr_data); } break; case vmc_vend_event_on_session_timeout: if (__true) { uint32_t *session_id = (uint32_t*)data; __log("session timeout: %d\n", session_id); } break; default: break; } return result; } ``` Where: * `event_id`: Type of vend event. * `data`: Pointer to optional parameter (varies based on event type). This function will return a Boolean value: * `__false` in most cases. * `__true` for `vmc_vend_event_on_vend_approved` to indicate a successful vend approval. ## Step 4: setup initialization functions After adding the helper functions, you need to implement the functions to initialize the VMC configuration and the Menu Handler. See the sections below for more details. ### Initialize VMC This function initializes the VMC configuration and registers the event handlers. ```c C theme={null} static void vmc_init(void) { /* Initialize SDK */ vmc_link_init(); /* Configuring the SDK */ memset(&config, 0, sizeof(config)); __strcpy(config.model, "marshall-c-sdk-demo"); __strcpy(config.serial, "01234567"); __strcpy(config.sw_ver, "vmc app version"); __strcpy(config.vmc_hw_ver, "01234567"); __strcpy(config.vmc_manuf_code, "manuf"); config.multi_vend_support = __false; config.multi_session_support = __false; config.price_not_final_support = __false; config.reader_always_on = __false; config.always_idle = __false; config.explicit_vend_success = __false; config.vend_denied_policy = vend_denied_policy_persist_e; config.mifare_approved_by_vmc_support = __false; config.mag_card_approved_by_vmc_support = __false; config.qr_approved_by_vmc_support = __false; config.dump_packets_level = debug_level_dump_moderate; config.debug = __true; /* Register to the link and vend events */ vmc_link_register_callback((vmc_link_event_handler_cb_t)vmc_link_event_handler_cb); vmc_vend_register_callback((vmc_vend_event_handler_cb_t)vmc_vend_event_handler_cb); } ``` ### Initialize menu Before initializing the menu, add the necessary handler functions. See the code below: ```c C theme={null} static void handler_start_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_credit_e); } static void handler_cancel_session(void *aux_data) { vmc_vend_session_cancel(); } static void handler_quit(void *aux_data) { menu_stop(&menu); exit(0); } static void handler_link_stats(void *aux_data) { vmc_stats_t* stats = vmc_link_get_link_stats(); char buffer[50]; sprintf(buffer, "\n ------ Stats ------ \n"); menu_output(buffer); sprintf(buffer, " crc error: %d\n", stats->crc_errors); menu_output(buffer); sprintf(buffer, " re-trans: %d\n", stats->retrans); menu_output(buffer); sprintf(buffer, " link loss: %d\n", stats->resets); menu_output(buffer); sprintf(buffer, " ------ Stats ------ \n"); menu_output(buffer); } static void handler_info_session(void *aux_data) { vmc_vend_session_start(vmc_vend_session_type_info_e); } static void handler_query_sessions(void *aux_data) { vmc_vend_get_session_status(); } static void handler_reader_state(void *aux_data) { vmc_vend_get_reader_state(); } ``` ## Step 5: implement main function Once all other parts are implemented, you can add the program's main entry point, which initializes the link to the peripheral and the menu, then starts an infinite loop that runs the menu. See the code below: ```c C theme={null} int mymain(int argc, char *argv[]) { printk_register_puts(terminal_tx_str); /* Modules initialization */ vmc_init(); set_command_line_arguments(argc, argv, &config, &com_id); /* Board initialization */ board_init(com_id); /* Register the timer tick handler */ cpu_platform_register_timer_tick_cb(2, (platform_timer_tick_cb_t)cpu_timer_tick); /* Modules initialization */ #if UTILITIES_CLI_MODE==1 cli_init(); cli_register_io(terminal_tx_str); printk("welcome to %s, version: %s, build: %s\n\r", __stringify(APP_NAME), __stringify(APP_VER), __stringify(APP_BUILD)); printk("build data: "__DATE__ " "__TIME__"\n\r"); /* Start modules and application */ cli_start(); #endif vmc_link_start(&vmc_usart, &config); menu_init(); while (1) { #if UTILITIES_CLI_MODE==1 if (drv_usart_is_rx_pending(&terminal_usart)) { cli_process_char(drv_usart_rx_byte(&terminal_usart)); } #endif menu_run(&menu); } } ``` # Global Payment Flows Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-flows/payment-flows-copy-1 TweezerComm follows structured payment flows to ensure secure and efficient transaction processing. These flows define how different transaction types, such as regular payments, pre-authorizations, and deferred payments, are handled within the system. Understanding these flows enables client applications to integrate appropriately with the Nayax Gateway and optimize payment processing capabilities. The pages below provide a more detailed description of each one: <CardGroup> <Card icon="list-check" title="Pre-Selection" href="/docs/integrate-pos-device/tweezercomm/global-payment-flows/tweezercomm-engine-preselection-flow"> Process, authorize, and settle a payment request before completing the transaction. </Card> <Card icon="hourglass-half" title="Pre-Authorization" href="/docs/integrate-pos-device/tweezercomm/global-payment-flows/tweezercomm-engine-preauth-flow"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> </CardGroup> # Pre-Authorization Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-flows/tweezercomm-engine-preauth-flow Tweezercomm's pre-authorization transactions are processed, authorized, and either settled or canceled based on the response from the payment server. This process also includes a resilience mechanism for handling errors. ## Transaction flow To understand the pre-authorization flow, see the diagram below: <Frame> <img alt="" /> </Frame> Here's a breakdown of each step: 1. After the cardholder selects the product or service, the ECR/POS sends a [`doTransaction()`](/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction) Request to the Nayax Device (Agamento App) through TweezerComm. 2. The device then displays a prompt for the cardholder, requesting him to insert or swipe a card. 3. The cardholder inserts, swipes, or taps their card on the ECR/POS. 4. The Nayax Device communicates with the Nayax Server for payment authorization. 5. The Nayax Server responds with the authorization result, which is then returned to the ECR/POS. 6. Depending on the outcome of the approval, the ECR/POS sends a `doTransaction(tranType=6/7)` Request to the Nayax Device to settle or cancel the transaction. 7. The settlement or cancellation request is sent to the Nayax Server, which responds with the final transaction status. 8. The Nayax Device then relays this status back to the ECR/POS, completing the process. <Warning> **Resilience Mechanism** If the `statusCode != 0` (indicating an issue) is returned, the system refers to the [Resilience Mechanism](/docs/integrate-pos-device/tweezercomm/resilience-mechanism-copy) to understand how TweezerComm handles errors or retry mechanisms. </Warning> ## See also <CardGroup> <Card icon="play" title="doTransaction" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction"> Start and process a payment transaction over the TweezerComm protocol. </Card> <Card icon="shield-halved" title="Resilience mechanism" href="/docs/integrate-pos-device/tweezercomm/resilience-mechanism-copy"> Handle transaction completion or cancellation when errors or failures occur. </Card> </CardGroup> # Pre-Selection Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-flows/tweezercomm-engine-preselection-flow The pre-selection transaction flow processes, authorizes, and settles a payment request before completing the transaction. This streamlined approach ensures that all payment stages are finalized in a single, continuous sequence. ## Transaction flow To understand the pre-selection transaction flow, consider the following sequence of events: <Frame> <img /> </Frame> Here's a breakdown of each step: 1. After the cardholder selects the product or service, the ECR/POS sends a [`doTransaction`](/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction) Request to the Nayax Device (Agamento App). 2. The application then displays a prompt for the cardholder, requesting him to insert or swipe a card. 3. The cardholder inserts, swipes, or taps their card on the ECR/POS. 4. The Nayax Device communicates with the Nayax Server to request payment authorization and settlement. 5. The Nayax Server responds with the transaction status (approved or declined). The Nayax Device then relays this status back to the ECR/POS, completing the process. ## See also <CardGroup> <Card icon="play" title="doTransaction" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction"> Start and process a payment transaction over the TweezerComm protocol. </Card> <Card icon="hourglass-half" title="Pre-authorization" href="/docs/integrate-pos-device/tweezercomm/global-payment-flows/tweezercomm-engine-preauth-flow"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> </CardGroup> # abortTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/abort-transaction The `abortTransaction` method cancels an ongoing transaction before it is registered in the database, meaning before a doTransaction Response is received (= prior to a consumer's card presentation / prior to a transaction timeout taking place).\ This ensures that transactions in progress but not yet finalized can be safely terminated without affecting the merchant's records. This method is beneficial when a user initiates a transaction but cancels before completion or when an issue is detected during processing that requires stopping the transaction. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `abortTransaction`. As in the example request below: ```json theme={null} { "jsonrpc":"2.0", "method":"abortTransaction", "id":"123454352", "params": [ "engine",{ "vuid": "cb740169-7758-4f55-b685-b90652b9aba6" } ] } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | - | - | - | | `vuid` | string | Vendor (client) unique transaction identifier. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "ok" } } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | - | - | - | | `statusCode` | integer | The operation status (0 = success) | | `statusMessage` | string | Operation message | # doPinpadTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/dopinpadtransaction The `doPinpadTransaction` method is used in the PinPad flow to continue an ongoing EMV transaction after the initial card capture. This is primarily done to prompt the cardholder to enter a PIN or to exchange additional EMV data (tags) with the payment terminal, advancing the EMV state machine. <Warning> **Contact Transactions Only** This method is relevant to contact transactions (inserted cards), which require a controlled multi-step EMV dialogue involving the terminal and the PIN pad. </Warning> ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `doPinpadTransaction`. * The `service` must be set to `engine` in the params. The request includes the service name and a dictionary of EMV tags that the host system must return to the terminal/card to proceed with the transaction dialogue. ```json theme={null} {    "jsonrpc": "2.0",    "method": "doPinpadTransaction",    "id": "123454352",    "params": [        "engine",        {            "tags": {                "95": "tag value",                "9F02": "tag value"            }        }    ] } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `tags` | JSON of strings | A dictionary containing the required EMV Tag-Value pairs that the host system must return to the card/terminal to continue the EMV dialogue. | ## Response A successful response indicates that the PinPad transaction state has advanced, either by successfully collecting the PIN from the cardholder or by completing an EMV data exchange round. ```json theme={null} {    "jsonrpc": "2.0",    "id": "123454352",    "result": {        "statusCode": 0,        "statusMessage": "ok",        "pem": EMVMANAGER_CONTACT,        "tags": {            "95": "tag value",            "9F02": "tag value",            "5A": "tag value",            "5F34": "tag value",            "5F2A": "tag value",            "9F02": "tag value",            "9F03": "tag value",            "9A": "tag value",            "9C": "tag value",            "9F1A": "tag value",            "9F21": "tag value",            "9F37": "tag value",            "9F36": "tag value",            "9F26": "tag value",            "9F27": "tag value"        }    } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The PinPad transaction status. A value of `0` indicates success. | | `statusMessage` | string | The transaction message (e.g., `ok`). | | `pem` | integer | POS Entry Mode, indicating the method of card entry (e.g., `EMVMANAGER_CONTACT`). | | `tags` | JSON of strings | A dictionary containing updated or new EMV Tag-Value pairs from the card/terminal, including information like the masked PAN (`5A`) or updated cryptograms. | <br /> # doTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction The `doTransaction` method initiates and processes payment transactions within the TweezerComm protocol. It enables client applications, such as point-of-sale (POS) systems or electronic cash registers (ECRs), to interact with the Agamento payment terminal for secure transaction execution. This method supports multiple transaction types, including: * **Regular Transactions (PreSelection)**: Standard payments using credit cards or closed-loop payment methods. * **Pre-Authorization (initiation)**: Reserve a specified amount on a customer’s card for later confirmation. * **Pre-Authorization Completion and Cancellation**: Completing or voiding previously authorized transactions. * **MOTO (Mail Order/Telephone Order) Transactions**: Processing card-not-present transactions securely. * [Refunds](/docs/integrate-pos-device/tweezercomm/global-payment-methods/refunds-dotransaction): Partial or full refunds of previous transactions. * **Deferred Payments**: Approving transactions even in cases where there is no immediate network connectivity. The sections below will describe the request parameters in more detail: ## Requests <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `doTransaction`. The transaction is defined by the `tranCode` parameter. Check the example request for each transaction type on the tabs below: <Warning> **Mandatory Fields** `vuid`, `amount` and `tranType` are mandatory for all requests. All others depend on the type of transaction made. </Warning> <Tabs> <Tab title="Regular Transaction"> For a regular transaction, set the `tranType` parameter to `1`. The code block shows a request example for a regular transaction: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "123454352", "params": [ "engine", { "vuid": "44d96006", "amount": 100, "tranType": 1 } ] } ``` ### Parameter Definitions The table below describes all parameters available in this request: | Name | Type | Description | | | :- | :- | :- | - | | `vuid` | string | Vendor (client) unique transaction identifier. | | | `amount` | integer | Amount in cents. | | | `tranType` | integer | The transaction type code. **1**: Single Step Transaction. | | </Tab> <Tab title="Pre-Authorization"> For initiating a Pre-Authorization transaction, set the `tranType` parameter to `3`. The code block shows a request example for initiating a Pre-Authorization transaction: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "1696161997899", "params": [ "engine", { "vuid": "80b458684", "tranType": 3, "amount": 100, } ] } ``` ### Parameter Definitions The table below describes all parameters available in this request: | Name | Type | Description | | :- | :- | :- | | `vuid` | string | Vendor (client) unique transaction identifier. | | `tranType` | integer | Transaction type. **3**: Pre-Authorization. | | `amount` | integer | Amount in cents. | </Tab> <Tab title="Complete Pre-Authorization"> For completing a Pre-Authorization transaction, set the `tranType` parameter to `6`. The code block shows a request example for completing a Pre-Authorization transaction: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "1696161997899", "params": [ "engine", { "vuid": "80b458654", "tranType": 6, "amount": 100, "originalTransactionId":"2022052432" } ] } ``` ### Parameter Definitions The table below describes all parameters available in this request: | Name | Type | Description | | :- | :- | :- | | `vuid` | string | Vendor (client) unique transaction identifier. | | `tranType` | integer | Transaction type. **6**: Complete Pre-Authorization. | | `amount` | integer | Amount in cents. | | `originalTransactionId` | string | The ID of the original pre-authorization transaction. | </Tab> <Tab title="Cancel Pre-Authorization"> For canceling a Pre-Authorization transaction which has been initiated, set the `tranType` parameter to `7`. The code block shows a request example for such cancellation: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "1696161997899", "params": [ "engine", { "vuid": "80b458654", "tranType": 7, "amount": 100, "originalTransactionId":"2022052432" } ] } ``` ### Parameter Definitions The table below describes all parameters available in this request: | Name | Type | Description | | :- | :- | :- | | `vuid` | string | Vendor (client) unique transaction identifier. | | `tranType` | integer | Transaction type. **7**: Cancel Pre-Authorization. | | `amount` | integer | Amount in cents. | | `originalTransactionId` | string | The ID of the original pre-authorization transaction. | </Tab> <Tab title="MOTO"> For a MOTO transaction, set the `tranCode` parameter to `5`. The code block shows a request example for a MOTO transaction: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "1696161997899", "params": [ "engine", { "vuid": "80b458654", "tranType": 5, "amount": 100, "pan": "1234567812345678", "exp": "0927", "cvv": "987" } ] } ``` ### Parameter Definitions The table below describes all parameters available in this request: | Name | Type | Description | | :- | :- | :- | | `vuid` | string | Vendor (client) unique transaction identifier. | | `tranType` | integer | Transaction type. **5**: MOTO. | | `amount` | integer | Amount in cents. | | `pan` | string | **Required**: The 16-digit card number. | | `exp` | string | **Required**: Card expiration date (MMYY). | | `cvv` | string | **Required**: 3-digit security code. | </Tab> </Tabs> ## Responses The service will return a response structured similarly to the examples provided in the code blocks below: <Tabs> <Tab title="Regular Transaction"> ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.62", "vuid": "12354", "amount": 100, "transactionId": "2038584332", "entryMode": 4, "transactionOriginalRequestId": "6439809e-619f-414b-8c3e-f1a9f3c3bc49", "transactionOriginalTime": "2025-03-05 23:08:06.597", "transactionOriginalAmount": 100, "serverResultMessage": "Sale is Approved", "tranType": 1, "dtId": "1741244869236399011", "rrn": "250306070806", "maskedPan": "541333******4111", "currencyCode": "USD", "currencyISOCode": "840", "originalSiteId": 1, "mainBoardSerial": "000177234933444", "hwSerial": "0900044624102737" } } ``` ### Response Parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Result of the request (**0** for success). | | `statusMessage` | string | Text description of the status. | | `appVersion` | string | Version of the payment application. | | `vuid` | string | Vendor unique transaction identifier. | | `amount` | integer | Final transaction amount in cents. | | `transactionId` | string | Unique gateway transaction ID. | | `entryMode` | integer | Method used to read the card (e.g., Chip, Contactless). | | `transactionOriginalRequestId` | string | ID of the original request. | | `transactionOriginalTime` | string | Timestamp of the original transaction. | | `transactionOriginalAmount` | integer | Original amount requested. | | `serverResultMessage` | string | Detailed message from the processing server. | | `tranType` | integer | Transaction type code (**1** for Regular). | | `dtId` | string | Device Transaction Identifier. | | `rrn` | string | Retrieval Reference Number. | | `maskedPan` | string | The masked card number used for the transaction. | | `currencyCode` | string | Alphanumeric currency code (e.g., USD). | | `currencyISOCode` | string | Numeric ISO currency code (e.g., 840). | | `originalSiteId` | integer | Identifier of the originating site. | | `mainBoardSerial` | string | Serial number of the device main board. | | `hwSerial` | string | Hardware serial number. | </Tab> <Tab title="Pre-Authorization"> ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.38", "vuid": "80b45894", "tranType": 3, "amount": 100, "currencyCode": "GBP", "currencyISOCode": "826", "transactionId": "2022052432", "dtId": "1721134022667243531", "rrn": "240716123742", "maskedPan": "374245*****1007" } } ``` ### Response Parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Result of the request (**0** for success). | | `statusMessage` | string | Text description of the status. | | `appVersion` | string | Version of the payment application. | | `vuid` | string | Vendor unique transaction identifier. | | `tranType` | integer | Transaction type code (**3** for Pre-Auth). | | `amount` | integer | Reserved amount in cents. | | `currencyCode` | string | Alphanumeric currency code. | | `currencyISOCode` | string | Numeric ISO currency code. | | `transactionId` | string | Unique gateway transaction ID. | | `dtId` | string | Device Transaction Identifier. | | `rrn` | string | Retrieval Reference Number. | | `maskedPan` | string | Masked card number used for reservation. | </Tab> <Tab title="Complete Pre-Authorization"> ```json theme={null} { "jsonrpc": "2.0", "id": "1696161997899", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.64", "vuid": "80b458654", "amount": 100, "transactionId": "2022052432", "entryMode": 4096, "transactionOriginalAmount": 128, "tranType": 6, "dtId": "1743763936600399011", "currencyCode": "USD", "currencyISOCode": "840" } } ``` ### Response Parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Result of the request. | | `statusMessage` | string | Text description of the status. | | `appVersion` | string | Version of the payment application. | | `vuid` | string | Vendor unique transaction identifier. | | `amount` | integer | Final captured amount in cents. | | `transactionId` | string | Unique gateway transaction ID. | | `entryMode` | integer | Method used for the capture. | | `transactionOriginalAmount` | integer | Amount reserved in the initial pre-auth. | | `tranType` | integer | Transaction type code (**6** for Completion). | | `dtId` | string | Device Transaction Identifier. | | `currencyCode` | string | Alphanumeric currency code. | | `currencyISOCode` | string | Numeric ISO currency code. | </Tab> <Tab title="Cancel Pre-Authorization"> ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.38", "vuid": "80b45894", "tranType": 7, "amount": 100, "currencyCode": "GBP", "currencyISOCode": "826", "transactionId": "2022052432", "dtId": "1721134022667243531", "rrn": "240716123742", "maskedPan": "374245*****1007" } } ``` ### Response Parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Result of the request. | | `statusMessage` | string | Text description of the status. | | `appVersion` | string | Version of the payment application. | | `vuid` | string | Vendor unique transaction identifier. | | `tranType` | integer | Transaction type code (**7** for Cancellation). | | `amount` | integer | Amount released in cents. | | `currencyCode` | string | Alphanumeric currency code. | | `currencyISOCode` | string | Numeric ISO currency code. | | `transactionId` | string | Unique gateway transaction ID. | | `dtId` | string | Device Transaction Identifier. | | `rrn` | string | Retrieval Reference Number. | | `maskedPan` | string | Masked card number associated with the void. | </Tab> <Tab title="MOTO"> ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.38", "vuid": "80b45894", "tranType": 5, "amount": 100, "currencyCode": "GBP", "currencyISOCode": "826", "transactionId": "2022052432", "dtId": "1721134022667243531", "rrn": "240716123742", "maskedPan": "374245*****1007" } } ``` ### Response Parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Result of the request (**0** for success). | | `statusMessage` | string | Text description of the status. | | `appVersion` | string | Version of the payment application. | | `vuid` | string | Vendor unique transaction identifier. | | `tranType` | integer | Transaction type code (**5** for MOTO). | | `amount` | integer | Transaction amount in cents. | | `currencyCode` | string | Alphanumeric currency code (e.g., GBP). | | `currencyISOCode` | string | Numeric ISO currency code (e.g., 826). | | `transactionId` | string | Unique gateway transaction ID. | | `dtId` | string | Device Transaction Identifier. | | `rrn` | string | Retrieval Reference Number. | | `maskedPan` | string | The masked card number entered manually. | </Tab> </Tabs> <br /> # endPinpadTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/endpinpadtransaction The `endPinpadTransaction` method is used to terminate the PinPad mode session on the payment terminal. This is the final step in the card/PIN capture process and should be called regardless of whether the transaction was successful, cancelled, or failed the PinPad steps. Successfully ending the session ensures the terminal is reset and ready for the next operation. <Warning> **Contact Transactions Only** This method is relevant to contact transactions (inserted cards), which require a controlled multi-step EMV dialogue involving the terminal and the PIN pad. </Warning> ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `endPinpadTransaction`. * The `service` must be set to `engine` in the params. The request takes a fixed format with no specific parameters in the second object. ```json theme={null} {    "jsonrpc": "2.0",    "method": "endPinpadTransaction",    "id": "123454353",    "params": [        "engine",        {}    ] } ``` ## Response A successful response indicates that the PinPad mode on the terminal has been successfully exited and the device has returned to its idle state. ```json theme={null} {    "jsonrpc": "2.0",    "id": "123454353",    "result": {        "statusCode": 0,        "statusMessage": "ok"    } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The status of the command. A value of `0` indicates the terminal successfully ended the PinPad session. | | `statusMessage` | string | The message confirming the status (e.g., `ok`). | # getInternalStatus Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/getinternalstatus The `getInternalStatus` method returns the internal status of the AEA (Agamento Engine Application).\ This method is typically called infrequently to determine the internal state of the engine's service logic, particularly during transaction flows. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getInternalStatus`, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getInternalStatus", "id": "123454352", "params": [ "engine" ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `engine` | string | The fixed service name | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "status": "idle" } } ``` ### Response parameters The table below lists the possible values of the `status` field: | Value | Description | | - | - | | `IDLE` | The engine is in idle mode and ready | | `BUSY` | The engine is currently busy and cannot handle new requests | | `PHASE2_READY` | The engine is ready for phase 2 of a transaction | | `AUTH_READY` | The engine is ready to perform an authorization | # getReport Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/getreport The `getReport` method is used to retrieve service transaction reports. It provides a way to query various transaction records, including mini-settlement transactions, pre-authorization transactions, and deferred authorization transactions. This allows client applications to access transaction summaries based on their processing stage. * This method is less relevant for the Global payment method due to the nature of how transactions are processed: Globally, each completed transaction that is saved on the payment terminal is sent immediately to the Engine and gets the final settlement. Whereas in Israel, each completed transaction that is saved on the payment terminal and is kept until the end of day and only then there's a bulk transmission (doPeriodic) of all of the transactions done that day to Ashrait and only then they are finally settled. getReport is used in order to query the information that is saved on the payment terminal- so globally there wouldn't be any transactions saved there (that have not already reached the Engine) ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getReport`, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getReport", "id": "123454352", "params": [ "engine", "miniSettlementTransactions" ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `action` </td> <td> string </td> <td> The type of transaction report to retrieve. Available values: * `miniSettlementTransactions`: Mini settlement transactions report * `queryPreAuthTransactions`: Query pre-auth transactions report * `queryDeferredAuthTransactions`: Query deferred auth transactions report </td> </tr> </tbody> </table> ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "queriedTransactions": [ "414d5aca-3df9-46aa-8c20-86d1685da885", "526ecaca-3df9-46aa-8c20-8456185da885" ] } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `statusCode` | integer | The operation status (0 = success) | | `statusMessage` | string | Operation message | | `queriedTransactions` | array | A list of queried transaction identifiers. | # getRetailerInfo Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/getretailerinfo The `getRetailerInfo` method allows you to verify the merchant's name and ID. This is useful for confirming that a terminal was configured correctly after installation or setup. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To call this method, the `method` field should be set to `getRetailerInfo`, and the params array must include the fixed service name `engine`. ```json theme={null} { "jsonrpc": "2.0", "method": "getRetailerInfo", "id": "136bdaa3", "params": [ "engine" ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `engine` | string | The fixed service name | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "136bdaa3", "result": { "id": "12970568", "name": "MACHINE_TEST" } } ``` ### Response parameters The table below lists the possible values of the `result` object: | Name | Type | Description | | - | - | - | | `id` | string | The unique retailer (machine) ID | | `name` | string | The name of the retailer | # getStatus Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/getstatus The `getStatus` method returns the current AEA (Agamento Engine Application) service status and informs the client whether the payment engine is ready to process transactions (as opposed to getInternalStatus which provides information about the payment terminal's readiness to do the first part of processing a new transaction).\ It is intended to be called infrequently (e.g., a few times per day) to check the operational state of the engine. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getStatus`, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getStatus", "params": [ "engine" ], "id": 1 } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `engine` | string | The fixed service name | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "result": "engineReady", "id": 1 } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Value | Description | | - | - | | `engineReady` | Engine is ready to process transactions | | `engineNotEstablished` | No established setup exists (engine not initialized). | | `engineReadyOnline` | Engine is ready, but all transactions are processed online due to the old DB. | | `engineError` | General engine error (e.g., corrupted database). | # getTransactionByVuid Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/gettransactionbyvuid The `getTransactionByVuid` method retrieves a transaction using its vendor-unique identifier (vuid). This allows client applications to fetch transaction details, including status, amount, and processing details. This method helps track transactions, confirm their status, and retrieve essential metadata, such as entry mode, timestamps, and deposit status. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getTransactionByVuid`, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getTransactionByVuid", "id": "123454352", "params": [ "engine", { "vuid": "48a70a44-a919-4587-901e-bafb073aef0e" } ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | - | - | - | | `vuid` | string | Vendor (client) unique transaction identifier. | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.62", "vuid": "48a70a44-a919-4587-901e-bafb073aef0e", "amount": 100, "transactionId": "2038587830", "entryMode": 4, "transactionOriginalRequestId": "fa19cf10-2294-441e-9739-9c8521801cff", "transactionOriginalTime": "2025-03-05 23:41:32.963", "transactionOriginalAmount": 100, "isFinalAmount": 1, "transactionDeposited": 1, "tranType": 1, "currencyCode": "840", "originalSiteId": 1, "mainBoardSerial": "000177234933444", "hwSerial": "0900044624102737" } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `id` | string | Request identifier | | `statusCode` | integer | Status code of the transaction | | `statusMessage` | string | Status message of the transaction | | `appVersion` | string | Application version | | `vuid` | string | Vendor-unique transaction identifier | | `amount` | integer | Transaction amount | | `transactionId` | string | Transaction identifier | | `entryMode` | integer | Entry mode of the transaction (Swipe, Contact, NFC) | | `transactionOriginalRequestId` | string | Original transaction request ID | | `transactionOriginalTime` | string | Original transaction timestamp | | `transactionOriginalAmount` | integer | Original transaction amount | | `isFinalAmount` | integer | Indicator if the amount is final | | `transactionDeposited` | integer | Deposit status of the transaction | | `mainBoardSerial` | string | Main board serial of the device | | `hwSerial` | string | Hardware serial of the device | # Global Payment Methods Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/payment-services-methods-copy-1 This section describes the API methods for handling payment transactions for transactions globally with the `engine` payment service. You can: * Start different types of transactions. * Cancel transactions that are in progress but not yet finished. * Look up details of past transactions using a unique ID. * Get reports about various transaction records. These tools give you complete control over your payment processes, making it easy to manage, track, and report on all your transactions. ## Transaction Processing <CardGroup> <Card icon="play" title="doTransaction" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction"> Start and process a payment transaction over the TweezerComm protocol. </Card> <Card icon="ban" title="abortTransaction" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/abort-transaction"> Cancel an ongoing transaction before it registers in the database. </Card> </CardGroup> ## Reporting & Status <CardGroup> <Card icon="chart-column" title="getReport" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/getreport"> Query transaction reports, including mini-settlement records. </Card> <Card icon="gauge" title="getStatus" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/getstatus"> Check whether the AEA payment engine is ready to process transactions. </Card> <Card icon="microchip" title="getInternalStatus" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/getinternalstatus"> Check the internal status of the AEA engine. </Card> </CardGroup> ## Transaction Lookup & Retailer Info <CardGroup> <Card icon="fingerprint" title="getTransactionByVuid" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/gettransactionbyvuid"> Look up a transaction by its vendor-unique identifier (vuid). </Card> <Card icon="circle-info" title="getRetailerInfo" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/getretailerinfo"> Verify the merchant name and ID configured on the terminal. </Card> </CardGroup> <Note> **Send Requests** See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how to structure and send requests. </Note> # Refunds Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/refunds-dotransaction The `doTransaction` method allows you to process refunds. There are two primary scenarios for this operation: * **Standard Refund**: Done on the same terminal where the original sale occurred. * **External Refund**: Done on a different terminal, requiring additional metadata for server-side validation. <Note> To perform a Refund transaction, save the `originalTransactionId` from the original transaction. </Note> ## Standard refund A Standard Refund is utilized when a transaction needs to be reversed or partially returned using the same terminal that processed the original sale. ### Request The following example shows a typical request body for a standard refund: ```json JSON theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "123454352", "params": [ "engine", { "vuid": "80b45894", "amount": 100, "originalTransactionId": "2022052432", "tranType": 2 } ] } ``` ## External refund \[from other device] To refund a transaction initiated on a different terminal, the system requires the following metadata from the original transaction to ensure security and validity: * `transactionOriginalTime` * `transactionOriginalAmount` * `transactionOriginalRequestId` * `mainBoardSerial` * `hwSerial` ### Request The following example shows a typical request body for an external refund: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "123454352", "params": [ "engine", { "vuid": "$guid", "amount": 13, "originalTransactionId": "2037037300", "originalSiteId": 1, "transactionOriginalTime": "2025-02-17 03:04:40.760", "transactionOriginalAmount": 13, "transactionOriginalRequestId": "afbae618-678f-45a9-ad87-5073c36419a2", "mainBoardSerial": "543654645", "hwSerial": "1231412", "tranType": 2 } ] } ``` ### Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.62", "vuid": "123454", "amount": 100, "transactionId": "2022052432", "entryMode": 1, "transactionOriginalRequestId": "6439809e-619f-414b-8c3e-f1a9f3c3bc49", "transactionOriginalTime": "0001-01-01 00:00:00.000", "transactionOriginalAmount": 100, "serverResultMessage": "Refund is Approved", "tranType": 2, "dtId": "1741246498022399011", "currencyCode": "USD", "currencyISOCode": "840", "mainBoardSerial": "000177234933444", "hwSerial": "0900044624102737" } } ``` ### Refund request parameters To perform a refund, you must include the following parameters within the `params` object of the `doTransaction` method. | Name | Type | Description | | :- | :- | :- | | `jsonrpc` | string | JSON-RPC protocol version (e.g., "2.0"). | | `method` | string | The API method to call: `doTransaction`. | | `vuid` | string | Vendor unique identifier. | | `amount` | integer | The refund amount (in the smallest currency unit, e.g., cents). | | `originalTransactionId` | string | **Mandatory.** The ID of the transaction to be refunded. | | `tranType` | integer | **Mandatory.** Set to `2` for Refund transactions. | | `originalSiteId` | integer | **Conditional.** Required for external refunds to identify the source site. | | `transactionOriginalTime` | string | **Conditional.** Original timestamp in `YYYY-MM-DD HH:MM:SS.mmm` format. | | `transactionOriginalAmount` | integer | **Conditional.** The original amount of the initial transaction. | | `transactionOriginalRequestId` | string | **Conditional.** The original request GUID/ID. | | `mainBoardSerial` | string | **Conditional.** Mainboard serial of the original device. | | `hwSerial` | string | **Conditional.** Hardware serial of the original device. | ### Refund response parameters Below are the parameters returned in the `result` object following a refund request: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | `0` for success; non-zero for errors or declines. | | `statusMessage` | string | High-level status text (e.g., "TRANSACTION APPROVED"). | | `appVersion` | string | The current version of the application. | | `vuid` | string | Vendor unique identifier for the transaction. | | `amount` | integer | The amount processed for the refund. | | `transactionId` | string | The unique ID assigned to this refund attempt. | | `entryMode` | integer | Method used to enter the card data. | | `transactionOriginalRequestId` | string | Matches the request ID of the original transaction. | | `transactionOriginalTime` | string | The timestamp recorded for the original transaction. | | `transactionOriginalAmount` | integer | The total amount of the original transaction. | | `serverResultMessage` | string | Detailed message from the processor (e.g., "Refund is Approved"). | | `tranType` | integer | Transaction type identifier (e.g., `2`). | | `dtId` | string | Device-specific transaction identifier. | | `currencyCode` | string | Alphanumeric currency code (e.g., "USD"). | | `currencyISOCode` | string | Numeric ISO currency code (e.g., "840"). | | `mainBoardSerial` | string | Serial number of the processing device's main board. | | `hwSerial` | string | Hardware serial number of the processing device. | <br /> # startPinpadTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/global-payment-methods/startpinpadtransaction The `startPinpadTransaction` method initiates the PinPad process on the payment terminal, instructing it to get ready to receive card information via Magnetic Stripe Read (MSR) or Contactless (Tap) or Contact. In case of Contact transaction- the transaction would proceed to doPinPadTransaction, otherwise will not- more on that in [Pinpad Mode](/docs/integrate-pos-device/tweezercomm/pinpad-mode).\ The response will provide the method of payment used through the `panEntryMode` parameter. This method captures raw card data (Track 2 or EMV tags) from the physical device, preparing the system for subsequent authorization steps. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `startPinpadTransaction`. * The service must be set to `engine` in the `params`. The request includes a list of parameters, with the first being the service name, which is currently fixed as `engine`, and the second being a dictionary containing all other transaction-specific details. ```json theme={null} { "jsonrpc":"2.0", "method":"startPinpadTransaction", "id":"123454352", "params": [ "engine",{ "vuid": "{{$guid}}", "amount":100, "tranType":1 } ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | :- | :- | :- | | `vuid` | string | Vendor (client) unique transaction identifier. | | `amount` | integer | Amount of the transaction in cents. | | `tranType` | float | Transaction type code. For example, `1` for a standard transaction. | ## Response A successful request will return a response containing the captured card data, which varies depending on whether the card was read via magnetic stripe or contactless (EMV). ### Magnetic stripe read response This response is returned when the card is successfully swiped via the magnetic stripe reader. ```json theme={null} {    "jsonrpc": "2.0",    "id": "123454352",    "result": {        "statusCode": 0,        "statusMessage": "ok",        "panEntryMode": 0, "track2": "65458643975398",    } } ``` #### Response Parameters The table below describes the response parameters for this method when a Magnetic Stripe Read occurs. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> The PinPad transaction status. A value of `0` indicates success. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> The transaction message (e.g., `ok`). </td> </tr> <tr> <td> `panEntryMode` </td> <td> integer </td> <td> POS Entry Mode, indicating the method of card entry. * `0` indicates a Magnetic Stripe read. * `1` indicates a Contact read. * `3` indicates a Contactless read. </td> </tr> <tr> <td> `track2` </td> <td> string </td> <td> The raw Track 2 card data captured from the magnetic stripe. </td> </tr> </tbody> </table> ### contactless read response This response is returned when the card is successfully read via the contactless reader. ```json theme={null} {    "jsonrpc": "2.0",    "id": "123454352",    "result": {        "statusCode": 0,        "statusMessage": "ok",        "panEntryMode": 3,        "tags": {            "95": "tag value",            "9F02": "tag value",            "5A": "tag value",            "5F34": "tag value",            "5F2A": "tag value",            "9F02": "tag value",            "9F03": "tag value",            "9A": "tag value",            "9C": "tag value",            "9F1A": "tag value",            "9F21": "tag value",            "9F37": "tag value",            "9F36": "tag value",            "9F26": "tag value",            "9F27": "tag value"        }    } } ``` #### Response Parameters The table below describes the response parameters for this method when a Contactless Read occurs. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> The PinPad transaction status. A value of `0` indicates success. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> The transaction message (e.g., `ok`). </td> </tr> <tr> <td> `panEntryMode` </td> <td> integer </td> <td> POS Entry Mode, indicating the method of card entry. * `0` indicates a Magnetic Stripe read. * `1` indicates a Contact read. * `3` indicates a Contactless read. </td> </tr> <tr> <td> `tags` </td> <td> json of strings </td> <td> A dictionary containing raw **EMV Tag-Value pairs** captured from the contactless chip. </td> </tr> </tbody> </table> # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/overview-tweezer TweezerComm is a secure and efficient payment communication protocol that enables seamless integration between client applications and Nayax attended payment devices. It allows point-of-sale (POS) systems, electronic cash registers (ECRs), and other payment-enabled applications to process transactions securely over a structured JSON-RPC interface. It enables client applications to communicate with the Agamento payment application (which runs on a Nayax attended terminal), the central unit for transaction processing. Communication should be over a **local network** such as **HTTPS** (the best practice), **HTTP**, **BT** or **USB** connection, allowing you to: * Initiate and manage transactions. * Retrieve and process transaction data. * Handle settlements, refunds, and pre-authorizations. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> ## Payment services Nayax's TweezerComm protocol supports two primary payment services, one for global users and one exclusive to Israel. * **Global Payments**: The `Engine` Service is the primary service for processing credit card and closed-loop transactions with the Nayax Gateway. The Nayax Gateway is responsible for setting device parameters and processing transactions according to the settings configured in Nayax Core. This service is widely used, supporting many payment providers in numerous countries. Before a transaction can be executed, the device must complete an "establishment" process (managed by Nayax's team). * **Israel Payments**: The `Ashrait` Service is a specialized service for performing AshraitEMV transactions. The client application communicates with the AshraitEMV Application (AEA), which can run on a stand-alone terminal or a central server. All approved transactions are written to the AEA's database. A key part of this service is the batch process, where the AEA transmits approved transactions to the ABS (SHVA) server. The sections below list the relevant guides for each payment service. ## Global TweezerComm guides This section provides guides to assist you in using TweezerComm with the Nayax global payment service, outlining the integration process and available API methods. See the pages below to learn more: <CardGroup> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started"> See how TweezerComm structures and sends requests using JSON-RPC 2.0. </Card> <Card icon="route" title="Global payment flows" href="/docs/integrate-pos-device/tweezercomm/global-payment-flows/payment-flows-copy-1"> Follow the structured payment flows for global transaction processing. </Card> <Card icon="code" title="Global payment methods" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/payment-services-methods-copy-1"> Browse the API methods for the global engine payment service. </Card> </CardGroup> ## Israel TweezerComm guides This section provides guides to assist you in using TweezerComm with the Nayax Israel payment service, outlining the integration process and available API methods. See the pages below to learn more: <CardGroup> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started"> See how TweezerComm structures and sends requests using JSON-RPC 2.0. </Card> <Card icon="route" title="Israel payment flows" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-israel-payment-flows"> Follow the structured payment flows for Israel transaction processing. </Card> <Card icon="code" title="Israel payment methods" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/tweezercomm-israel-payment-methods"> Browse the API methods for the Israel ashrait payment service. </Card> </CardGroup> ## General guides This section provides general guides that are relevant to TweezerComm's payment services. See the pages below to learn more: <CardGroup> <Card icon="mobile-screen-button" title="Device methods" href="/docs/integrate-pos-device/tweezercomm/device-methods/index"> Manage payment terminals: device info, card reads, configuration, and diagnostics. </Card> <Card icon="server" title="TC service" href="/docs/integrate-pos-device/tweezercomm/tc-service"> Run the Agamento app as a background service for your own Android app. </Card> <Card icon="shield-halved" title="Resilience mechanism" href="/docs/integrate-pos-device/tweezercomm/resilience-mechanism-copy"> Handle transaction completion or cancellation when errors or failures occur. </Card> <Card icon="book" title="Additional resources" href="/docs/integrate-pos-device/tweezercomm/additional-resources/tweezercomm-additional-resources"> Find certification files, error codes, and other supporting materials. </Card> </CardGroup> # Get Started Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started TweezerComm follows the [JSON-RPC 2.0](http://www.jsonrpc.org/specification) specification to standardize transaction processing between the POS/ECR and Agamento payment application (that runs on Nayax attended devices). JSON-RPC is a lightweight, remote procedure call (RPC) protocol encoded in JSON. It allows client and server communication using structured requests and responses. Refer to the sections below to learn how to submit requests on TweezerComm. ## Server endpoint TweezerComm operates over HTTPS using a standard REST API convention. The SPICy Server acts as the entry point for processing JSON-RPC messages. The server endpoint is structured as follows: ```text theme={null} https://device_ip:8080/SPICy ``` * The POS/ECR and Agamento payment application needs to be connected to the same local network All requests are processed at this endpoint using a **POST** method. Remember to replace `device_ip` with the actual IP address of your device. <Note> **Agamento Port** Agamento listens on port **8080** for TC Lan integration and **9090** for Bonjour integration, allowing communication between the client application and the payment device. </Note> ## Enter the Agamento app on Nayax's device <Frame> <img alt="Picture123" /> </Frame> ## Perform a request To request TweezerComm via the SPICy server, the client application must send an adequately formatted JSON-RPC request to the specified endpoint. Below is an example of how to initiate a basic transaction: ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "id": "123454352", "params": [ "engine", { "vuid": "44d96006", "amount": 100, "tranType": 1 } ] } ``` In this request, you need to configure the following parameters: * `jsonrpc`: Defines the JSON-RPC version. In this case, always set it to `2.0`. * `method`: Specifies the method to be used. See [Global Payment Methods](/docs/integrate-pos-device/tweezercomm/global-payment-methods/payment-services-methods-copy-1), [Israel Payment Methods](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/tweezercomm-israel-payment-methods), and [Device Methods](/docs/integrate-pos-device/tweezercomm/device-methods/index) for a list and description of available methods. * `id`: A unique identifier for tracking the request. * `params`: This is an array divided into two parts. * The first specifies the payment service to be used: * `engine` for global transactions. See [Global Payment Flows](/docs/integrate-pos-device/tweezercomm/global-payment-flows/payment-flows-copy-1) for more details. * `ashrait` for Israel transactions. See [Israel Payment Flows](/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-israel-payment-flows) for more details. * The second part contains the parameters specific to the requested method. By following this structure, client applications can reliably interact with TweezerComm for secure and efficient payment processing. # Integration Process Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/tweezercomm-integration-process A step-by-step guide to integrating with Nayax The Nayax integration process ensures a seamless and efficient implementation, providing technical support at every stage. From initial setup to production deployment, Nayax teams work closely with partners or customer developers to meet all technical and operational requirements. ## Stages of the process The integration process is divided into five main stages: 1. Kickoff Meeting 2. Integration Setup 3. Development Phase 4. Testing & Certification 5. Production Setup <Frame> <img /> </Frame> Each stage is structured to provide technical support and essential resources, ensuring smooth and efficient implementation. ### Kickoff Meeting The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator’s project, the technical teams, and the Nayax Integration Engineer. ### Integration Setup This initial stage establishes the technical foundation for the integration. 1. **Assignment of Integration Engineer:** A Nayax integration engineer is assigned as the primary focal point for the partner or customer developer. 2. **Configuration:** The engineer configures the Nayax Core (backend) and sets up the device with the relevant transaction flow in the integration environment. 3. **Welcome Email:** At the end of this phase, the engineer sends a welcome email with all necessary resources, including the URL, SDK, documentation, tokens, and other required development tools. ### Development Phase This stage focuses on the partner or customer developing their solution. 1. **Partner/Customer Development:** The partner or customer developer creates their solution using the Nayax API/SDK. 2. **Support:** During this phase, the integration engineer provides assistance for any issues or "how-to" queries to ensure progress. <Note> **Support for OCPP/OCPI Integrations** For integrations based on **OCPP/OCPI** standards, this step is not relevant, as these integrations follow predefined flows according to the standard protocol. </Note> ### Testing & Certification This stage verifies that the integration meets Nayax’s standards: 1. **Certification Test Requirements:** Nayax shares specific requirements for certification tailored to the integration type and transaction flow. 2. **Testing:** The partner or customer developer performs a series of tests (typically 9–15, depending on the integration type and flow). 3. **Review:** The Nayax integration engineer reviews the results of these tests to ensure all criteria are met. 4. **Certification:** Upon successfully completing all tests, Nayax issues a certification letter confirming the integration is ready for deployment. ### Production Setup The final stage ensures a smooth deployment in a live environment: 1. **Production Environment Configuration:** Nayax configures the integration in the production environment, including the machine model setup. 2. **Support for Testing:** The integration engineer provides support during production lab or field tests to confirm successful deployment. The Nayax integration process provides a structured, step-by-step approach that ensures reliable and efficient implementation. By collaborating closely with partners and customers, Nayax delivers high-quality solutions that meet industry standards and support successful deployments in the market. # Home Source: https://devzone.nayax.com/index <Header /> <McpPromo /> <IntegratePOS /> <ManageData /> <AcceptPayments /> # Android App Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/demo-applications/android-demo-application The SDK provides a demo application with source code that enables you to test the integration from day one. This demo provides a fully functional application that uses the Nayax SDK APIs to communicate with the EMV Core. You can use the source application as a foundation for developing your own system. <Warning> Before starting, ensure your Reader is registered with the Nayax Core system. Without registration, payment transactions cannot be completed. </Warning> ## Installation The SDK includes the following files: | File Name | Description | | - | - | | `com.nayax.emvCore-release-v.v-bbb.apk` | The EMV Core service package. | | `com.nayax.emv_core_android_test-release-v.v-bbb.apk` | The SDK sample application. | | `emv-core-test-v.v-bbb.zip` | Android Studio project with library and sample application source code in Java. | To install the demo application, follow the steps below: 1. Install the EMV Core Service `com.nayax.emvCore-release-x.x-xxx.apk` on your Android device. 2. Install the Test application `com.nayax.emv_core_android_test-release-x.x.x.apk`. <Note> If you experience communication issues between the EMV Core service and the application or Reader, restart the EMV Core service. </Note> ## Using the demo application To start using the test application, you can follow the steps below: 1. Connect your UNO reader to your Android device. If you get a system message saying, “Allow EmvCore Service to access Saturn 8700,” press **OK**. <Frame> <img /> </Frame> <Warning> If this message appears frequently, you can configure your device to reduce prompts: * Whitelist the Nayax Reader in your Android OS settings. * On your mobile device, check the **Always open EmvCore service when Saturn 8700 is connected** option and press **OK**. * It’s also recommended to allow the **Stop optimizing battery usage** option when prompted. </Warning> 2. The application will automatically attempt to connect to the EMV Core service and the UNO Reader. Once the connection is successful, the status line at the top of the screen will display **Ready**. ### Navigating the application The demo application includes multiple pages for performing specific actions. ### Maintenance page <Frame> <img /> </Frame> On the **Maintenance** page, you can perform the following actions: * **Get Data:** Retrieves the version information and status from the EMV Core service and Reader. * **Show Message (UNO-PLUS readers only):** Allows you to edit and send two lines of text to the Reader's display. ### Settings page <Frame> <img /> </Frame> On the **Settings** page, you can configure the following options: * **Currency Code:** Enter the currency code (e.g., `840` for USD or `978` for Euro). * **Product ID:** Optionally, assign an identifier for the product to track it in transaction logs and reports. * **Timeout:** Set a timeout duration (in seconds) for transactions. The maximal time is `60` seconds, for unlimited polling use 'continuous=true'. * **Continuous:** Automatically renew the transaction polling when a timeout occurs, allowing unlimited polling. It can be stopped with the `CancelTransaction` command. ### Payment page Run a payment transaction: 1. Select **Authorize** for a two-step transaction or **Pay** for a single-step transaction. 2. Enter the transaction **Amount**. 3. Press **START** to initiate the transaction. The virtual display will show **Present card**, and the status line will display **Payment transaction**. <Frame> <img /> </Frame> 4. Present the EMV card to the Reader. 5. Once the transaction response arrives, it will appear on the screen, allowing you to proceed to the settlement page. <Frame> <img /> </Frame> 6. You can also continue to run another authorization. The previous transaction may be kept open (Authorized). ### Config page <Frame> <img /> </Frame> On the Config page, you can test the `GetAttribute` command: 1. Insert the Attribute name, such as `CONFIG_VERSION`. 2. Press `GET ATTRIBUTE` to get the attribute value from the Config file. ### External settlement example settings To simulate [External Settlement](/docs/integrate-pos-device/emv-core/payment-flows/pre-authorization-with-external-settlement) from the demo application, get the following parameters from Nayax support and set them in the sample app's `settings.java` file: * `externalSettlementTokenId` * `externalSettlementToken` * `externalSettlementIntegratorId` * `externalSettlementSignKey` # Demo Applications Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/demo-applications/emv-core-demo-applications This article provides a centralized jumping-off point for testing the Nayax EMV Core demo applications. Nayax provides a demo app to help you validate hardware communication and transaction flows from day one of your integration, ensuring your environment is correctly configured before you begin custom development. ### Why Start with Demo Apps? * **Immediate Validation:** Confirm that your card reader and host system are communicating correctly without writing new code. * **Reference Code:** Use the demo source code as a blueprint for implementing your own payment logic. * **Gateway Testing:** Verify connectivity to the Nayax gateway and process test transactions in a controlled environment. To access the repository, documentation, and setup instructions for your specific platform, select one of the following links: <CardGroup> <Card icon="mobile-screen-button" title="Android App" href="/docs/integrate-pos-device/emv-core/demo-applications/android-demo-application"> Test the EMV Core integration on Android with a fully functional demo application and source code. </Card> <Card icon="terminal" title="Linux App" href="/docs/integrate-pos-device/emv-core/demo-applications/linux-demo-application"> Test the EMV Core integration on Linux with a fully functional demo application and source code. </Card> </CardGroup> # Linux App Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/demo-applications/linux-demo-application The SDK provides a demo application with source code that enables you to test the integration from day one. This demo provides a fully functional application that uses the Nayax SDK APIs to communicate with the EMV Core. You can use the source application as a foundation for developing your own Linux-based system. <Note> Before starting, ensure your Reader is registered with the Nayax Core system. Without registration, payment transactions cannot be completed. To register your device, provide its Serial Number (SN) to your Nayax account manager. </Note> ## Installation The SDK includes the following files: | File Name | Description | | :- | :- | | `otiKiosk` | The EMV Core service executable. | | `otiKioskDemo` | The client Test application executable. | | `kiosk-client-library-xxx.zip` | Source code (C) and project files for the library and sample app. | | `otikiosk-xxx-vvv.zip` | Package for TMS remote updates (using `CON_PROG` command). | To install the SDK, follow these steps: 1. Copy the `otiKiosk` binary file to the target device using your preferred transfer method. <Warning> The file must remain named `otiKiosk`. Do not rename the binary. </Warning> 2. Configure the target system to automatically start the EMV Core binary upon boot or as a managed service. 3. Grant the application read and write access to the reader hardware. This typically involves configuring the device management system, such as adding udev rules for: * **USB Reader:** USB HID * **RS232 Reader:** TTY interface 4. Update the permissions of the directory containing the application binary to ensure the process has full read, write, and execute (RWX) access. 5. If environment variables are used to specify folder paths for the application: * Manually create these directories if they do not exist. * Set the folder permissions to allow the EMV Core application full read, write, and execute access. ## Using the demo application The zip contains a project with makefiles, a library, and a sample application with C source code: * The library `libotikiosk` converts the Socket JSON API to C functions. * `otiKioskDemo` supports two operating modes: Single API flow and Auto Mode. ### Single API flow 1. The application starts in an idle state and presents a simple menu allowing the user to select the required command using the keyboard. 2. After selecting the command, it runs the command and returns to step 1. 3. When selecting `Confirm Transaction` or `Void Transaction` after `Authorize Transaction`, the application will use the last transaction ID. <Frame> <img /> </Frame> ### Auto mode flow 1. Run the sample application with the command option: `--auto` : `$ ./otiKioskDemo --auto` 2. The application starts in the Idle state and shows a welcome message. 3. The device calls the `AuthorizeTransaction` and shows the price and tells the user to present their card. 4. After presenting the card, it sends the card data to the server and shows a waiting message. 5. The device shows the transaction result and returns to Idle. <Frame> <img /> </Frame> ### Build the sample application from source code Follow these steps to compile the demo from source: 1. Get the sources to your target system. On Ubuntu, unzip the following file: ```text theme={null} `EMV-Core Linux SDK v1.4\Linux\x86_64\Sources\Emv-Core-client-x86_64-1.4-97.zip` ``` This will extract a folder named `Emv-Core-client` containing the application sources and makefiles. 2. Install the required build dependencies (Ubuntu Linux): ```shell theme={null} sudo apt-get update sudo apt-get install build-essential automake ``` 3. Build the SDK and demo. The provided sources are pre-configured for Ubuntu Linux x86\_64 using GCC and automake: ```shell theme={null} autoreconf -fi ./configure make ``` 4. The build process will generate static libraries and the demo binary under the following directory: `Emv-Core-client/demo/otiKioskDemo`. 5. To run your newly generated application, ensure the binary has the appropriate execution permissions and follow the environment-specific execution steps. ### Run the sample application To run the test application executable on Ubuntu: 1. Start the **EMV Core (otiKiosk)** as explained in the previous section. 2. Run the **otiKioskDemo** sample application from the same folder as the EMV Core binary (do not navigate into the demo application folder itself). 3. For example, if your folder structure is as follows: ```text theme={null} sdk/ ├── nayax-emb ├── otiKiosk <-- File provided with SDK ├── otiKioskDemo <-- File provided with SDK ├── Emv-Core-client/ │ ├── libotikiosk/ │ ├── demo/ │ │ ├── otiKioskDemo <-- Sample application from build │ │ ├── otiKioskDemo.c │ │ ├── Makefile.am │ │ └── .deps/ │ ├── [Additional client files] │ ├── .vscode/ │ └── m4/ └── [Root level files] ``` You should execute the applications using these commands: <Tabs> <Tab title="Terminal 1 (Start EMV Core)"> ```bash theme={null} cd sdk sudo ./otiKiosk ``` </Tab> <Tab title="Terminal 2 (Start Sample Application)"> ```bash theme={null} cd sdk sudo ./Emv-Core-client/demo/otiKioskDemo ``` </Tab> <Tab title="Run Automatically"> ```bash theme={null} sudo ./Emv-Core-client/demo/otiKioskDemo --auto ``` </Tab> </Tabs> # EMV Core Android & Linux SDK Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/emv-core-android-linux-release-notes Track EMV Core Android & Linux SDK changes as they ship. Nayax logs EMV Core Android & Linux SDK changes on this page as they ship. Subscribe to the RSS feed to get notified of new entries. To find the feed, add `/rss.xml` to the end of this page's URL. Release notes are organized into three categories to help you evaluate the impact of each update: * **Improvements**: New API commands, expanded platform and card support, and performance enhancements. * **Fixes**: Resolved bugs and reliability improvements. * **Known Issues**: Current limitations or pending features, with recommended workarounds. <Note> **Platform-Specific Features** While most updates are universal, platform-specific improvements or fixes are marked with **(Android Only)** or **(Linux Only)** in the section titles. </Note> <Update label="SDK Version 1.5 (Latest)"> This version includes the following improvements, fixes, and known issues for the SDK: <Accordion title="Improvements" icon="rocket"> ### **1-Step Incremental Authorization (Android Only) (#7462)** Settling a transaction for more than its pre-authorized amount now automatically triggers an incremental authorization for the difference. See [Single-step incremental authorization](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#single-step-incremental-authorization). This release also adds the [`IncrementalAuthorization`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#incrementalauthorization) method and [`IncrementalAuthorizationResponse`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks#incrementalauthorizationresponse) callback, reserved for a future multi-step flow and not required for the single-step behavior above. *** ### **Deferred Transaction (#7486)** The terminal can now keep accepting payments while offline and send them for approval once communication is restored. Set `isDeferred` and `isFinalAmount` in `PreAuthorize` to use it. This replaces the deprecated `PMT_ACCEPT_OFFLINE` configuration attribute. See [Deferred Transaction](/docs/integrate-pos-device/emv-core/payment-flows/deferred-transaction) for details. *** ### **Offline by Default Mode (#7604)** EMV Core's defaults changed so it behaves as a simple, offline-capable RFID reader out of the box: [`CLP_MIFARE_ENABLED`](/docs/integrate-pos-device/emv-core/emv-core-configuration#managing-settings) now defaults to `2` (local Closed-Loop Mifare) and [`OPEN_LOOP_ENABLED`](/docs/integrate-pos-device/emv-core/emv-core-configuration#managing-settings) now defaults to `0` (disabled). In this default configuration, `GetStatus` reports `Ready` and `PreAuthorize`/`GetCardToken` keep working even without network. The device only requires network, and reports `NoNetwork` when it's down, if you explicitly enable Open Loop or set `CLP_MIFARE_ENABLED=1`. *** ### **External Settlement Support in the Client Library (#7430)** The client library now parses and exposes the fields required for server-to-server settlement. *** ### **Push Notifications via MQTT (#6817)** EMV Core now supports MQTT push notifications. To use this feature, configure the MQTT Primary Address (`oti-broker.nayax.com:1883`) and Ping Interval (default 600 seconds) machine attributes in Nayax Core. *** ### **Currency Fallback from the Reader (#7654)** If `CURRENCY_CODE` is missing from the configuration, EMV Core now falls back to the reader's kernel currency tag (`9F3C`) before defaulting to USD. *** ### **AUDIO\_PERCENTAGE Configuration (#7609)** Added the `AUDIO_PERCENTAGE` configuration attribute to control the reader's audio volume. *** ### **Terminal Authentication over TLS (#6719, #7305)** Terminal Authentication (DSS) `GET /challenge` requests are now sent over TLS. *** ### **additionalReceiptData in PreAuthorize and ConfirmTransaction (#7377)** You can now pass `additionalReceiptData` directly in `PreAuthorize` and `ConfirmTransaction` to include extra data in the eReceipt. *** ### **Local Firmware and Configuration Update Utility (#7372)** Added a utility to update reader firmware and configuration locally without a TMS connection. This is intended for production-line use only. Remove it before deployment. *** ### **Advanced Closed Loop Card Support (#7639)** EMV Core can now read Mifare blocks using the `CLP_MIFARE_READ` attribute. *** ### **SendToReader (Android Only) (#6898)** Host applications can now send commands directly to the reader with the new [`SendToReader`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/remote-management#sendtoreader) method. *** ### **Reader Configuration Management from Nayax Core (#7250)** Reader configuration can now be managed from Nayax Core machine attributes. *** ### **Process Info in UPLOAD\_LOG (#7300)** `UPLOAD_LOG` now includes process information: CPU, memory, and uptime. *** ### **Felica IDm as CLP UID (#7496)** FeliCa's IDm is now returned as the CLP UID. *** ### **Unconditional Confirmation (#7594)** Removed the `CONFIRM_IF_UNSURE` flag. Confirmation behavior is now unconditional. *** ### **Client Library Version Reporting (#7673)** The client library version is now reported to TMS via `GetVersions`. *** ### **Nayax TLS CA Support (#7703)** Added support for the Nayax TLS certificate authority. *** ### **Hardcoded External Settlement Defaults (#7705)** External Settlement properties are now hardcoded defaults, removing the dependency on `local.properties`. *** ### **Foreground Service (#7712)** The EMV Core service now runs in the foreground, preventing the OS from killing it. *** ### **New UNO-mini Firmware (EMVSC\_v071749)** Adds Type B card reading support (for Autel). This firmware is valid for the Linux, Android, and RTOS v1.5 SDKs. RTOS v1.0 should continue using firmware `EMVSC_v071652.oef`. </Accordion> <Accordion title="Fixes" icon="wrench"> ### **ReaderMessageEvent Index Correction (#7088)** Messages that previously used index `255` now use the correct assigned indexes in the `201`-`220` range. *** ### **Reader Communication Recovery (#6819)** Improved reader communication recovery, including handling of reader power cycles. *** ### **External Settlement Response Missing hwSerial (#7515)** The External Settlement response was missing the `hwSerial` field. *** ### **Push Notifications on TMS-C (#7537)** Fixed push notifications not working when the device is managed by TMS-C (Nayax Core). *** ### **CLP Card ID Response Fields (#7425)** Fixed the CLP Card ID being sent in the wrong response fields. *** ### **Local CLP Transaction and Card ID (#7512)** Fixed the Transaction ID and Card ID (`CardToken`) being identical on Local CLP transactions. *** ### **Transaction Fee Reporting (#7478)** Fixed transaction fees not being sent correctly to the Bridge. *** ### **PMT\_DUKPT\_KEY\_VARIANT Fallback (#6772)** `PMT_DUKPT_KEY_VARIANT` now falls back to `0x11` when the configured value is invalid. *** ### **Automatic Restart with No Reader (#7183)** EMV Core now restarts automatically if it doesn't find a reader within 1 hour. *** ### **IncrementalAuthorization URL (Android Only) (#7662)** Fixed an incorrect URL used by `IncrementalAuthorization`. *** ### **Configuration Preserved Across APK Upgrades (#7491)** Configuration was previously deleted when the APK was updated. It's now preserved across upgrades. *** ### **hwSerial Truncation (#7710)** Fixed `hwSerial` being truncated in `NayaxTransactionIdInfo`. *** ### **Large Receipt Data Buffer Overflow (#7763)** Fixed a buffer overflow that could crash or reset the device when large receipt or terminal data combined with transaction result data. *** ### **Truncated Server Responses (#7783)** Fixed truncated or rejected server responses that could report a valid approval as declined, or drop a TMS-pushed command. *** ### **Continuous Polling Interruption (#7217)** Fixed polling stopping in the middle of a `continuous=true` transaction. *** ### **CON\_CONFIG and Service Restart (#7452, #7701)** Fixed the `CON_CONFIG` command failing, and the Android service sometimes not restarting after that command. *** ### **GetStatus Stuck at Update (#7740)** Fixed `GetStatus` remaining stuck at `Update` for 5 or more minutes after a firmware flash. *** ### **Duplicate Authorize Requests** Reduced duplicate `Authorize` requests sent after a timeout or cancellation. </Accordion> <Accordion title="Known issues" icon="exclamation-triangle"> ### **Reader Swap Terminal ID (#7211, #7030)** Always stop EMV Core before moving a reader to a different machine. Swapping a reader without resetting EMV Core doesn't update the Terminal ID, and payment may complete against the previous terminal. Moving a reader to a different machine without first stopping EMV Core on the original machine may also cause unpredictable behavior on the new machine. *** ### **Android OS Service Restarts (#7714)** The Android OS may stop the EMV Core service, causing multiple restarts during operation. *** ### **IsTransactionApproved on Cancelled Transactions (#7743)** A cancelled transaction incorrectly returns `IsTransactionApproved` as `true`. *** ### **Cancellation After CannotCancel (#7742)** A transaction may still be cancelled after receiving a `CannotCancel` response. *** ### **GetStatus with Ethernet Disabled (#7741)** `GetStatus` returns `Ready` even when Ethernet is disabled. </Accordion> </Update> ### Version history Every earlier Android & Linux SDK version, condensed to one line. See the current version above for full detail and links. | Version | Summary | | - | - | | SDK Version 1.4 | **Added** (#7473, #7474, #7308):<ul><li>Automated currency code management</li><li>Nayax Core/OTI TMS server failover</li><li>Local serial port management (Linux)</li></ul>**Fixed** (#7443, #7497):<ul><li>Reader message event delivery and reader reconnection</li><li>Sample app token reporting and sample app resources</li></ul> | | SDK Version 1.2 | **Added** (#6782, #7139, #7346, #7269, #6888):<ul><li>eReceipt/Remote Settlement support</li><li>Nayax Core-managed attribute/limit control and CLP cards</li><li>Enhanced logging</li></ul>**Fixed** (#7385, #7371, #7199, #7272):<ul><li>Offline display sync and reader-boot/core-invocation issues</li><li>Deprecated `PayTransaction` in favor of `PreAuthorize`/`ConfirmTransaction`</li></ul> | | SDK Version 1.1 (Linux Only) | **Shipped** (#6813, #7165, #7157):<ul><li>Official UNO-8 firmware v54227</li><li>Beta UNO-mini firmware v071514</li></ul>**Fixed** (#7144, #7331):<ul><li>Serial reader stability</li><li>TMS independence</li><li>A socket resource leak</li></ul> | | SDK Version 1.0 | **Added** (#71156, #7129, #7117):<ul><li>`GetAttribute`</li><li>Enhanced Android logging and config reporting</li><li>Linux sample app improvements</li></ul>**Fixed** (#6960, #7136, #7091, #7169, #7180, #6658, #7200, #7204, #7130, #7210):<ul><li>Log truncation</li><li>CLP card mapping</li><li>Timing/sync issues</li><li>Android diagnostics/UI bugs</li></ul> | | SDK Version 0.9 | **Added** (#6550, #6838, #6978):<ul><li>Mifare UID support to `GetCardToken`</li><li>Automatic EMV Core startup/recovery</li><li>`GetCardToken` continuous mode on Android</li></ul>**Fixed** (#6980, #6987, #7001, #6961, #6658):<ul><li>Closed-loop UID reporting</li><li>UI/input stability</li><li>UNO-mini firmware events</li><li>Pre-authorization logic</li></ul> | | SDK Version 0.8 | **Added**:<ul><li>`GetCardToken` with continuous polling</li><li>Expanded CLP/Vicinity card support</li><li>Offline CLP UID retrieval</li></ul>**Fixed** (#6550, #6919, #6938, #6862):<ul><li>A crash with no internet connection</li><li>A `Void`-after-`PreAuthorize` bug</li><li>TMS/reader connectivity</li><li>A Linux serial-port config bug</li></ul> | | SDK Version 0.7 | First official Android SDK release.<br />**Added**:<ul><li>Linux configuration attributes (`OPEN_LOOP_ENABLED`, `PRE_AUTH_AMOUNT`, `KIOSK_TCP_LOCALHOST`)</li><li>`GetAttribute()` retrieval</li></ul><ul><li>Switched Linux to internal sockets by default</li><li>Fixed TMS production-info retrieval (#6705)</li></ul> | | SDK Version 0.6.03 (Linux Only) | **Improved**:<ul><li>UART stability</li><li>Closed-loop Mifare support (Ultralight, 7-byte UIDs)</li></ul><ul><li>Fixed a config-parsing crash on empty lines</li><li>Confirmed sequential `PreAuthorize` rejection is intentional</li></ul> (#6560, #6576) | | SDK Version 0.6.00 (Linux Only) | Introduced foundational Closed Loop Mifare support | | SDK Version 0.1 (Linux Only) | First Lite SDK release for Linux, built in C for low-resource embedded environments | # Configuration Parameters Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/emv-core-configuration The EMV Core configuration determines how your terminal functions, handles transactions, and interacts with external systems. Settings use a standard `<Parameter Name>=<Value>` format (e.g., `TMS_SVC_URL=tms.otiglobal.com`). ## Managing settings Configuration is handled centrally through the **Nayax Core** server. To adjust these settings: 1. Navigate to **Operations** > **Machines**. 2. Locate the **Embedded** and **Embedded Advanced** sections. 3. Click the **?** next to specific fields to identify which configuration parameters correspond to the options on the page. <Frame> <img /> </Frame> Once saved, the server generates a configuration file and automatically pushes it to the device. <Warning> Nayax Core manages this configuration file. Do not manually edit or delete it on the device: doing so can prevent the device from working correctly. If it happens by mistake, use **Actions** > **Reload Configuration** in Nayax Core to push the configuration from the server again. </Warning> The table below lists the primary configuration keys available for both platforms: | Category | Parameter Name | Description | Type | Default Value | Platform Notes | | :- | :- | :- | :- | :- | :- | | **Network & System** | `ETH_INTERFACE` | Network interface for reporting; autodetects if empty. | String | empty | Fallback to eth0. | | | `KIOSK_USE_TCP_SOCKETS` | Set to 1 to use TCP ports 10000 (cmd) and 10001 (events). | Bool (1/0) | 0 | Disables domain sockets if set. | | | `DAILY_RESTART_HOUR` | Automatic daily reboot hour (0-23); 0 is disabled. | U8 | 0 | Reboot occurs within 30 minutes of the set hour. | | | `KIOSK_TCP_LOCALHOST` | Limits EMV Core sockets to the localhost interface. | Bool (1/0) | 0 | Introduced in SDK v0.7. | | | `DNS_ENTRY_1` … `DNS_ENTRY_5` | Static hostname-to-IP mapping entries; injected into `/etc/hosts` at startup (e.g., `192.168.1.10 myserver.local`). | String | none | Introduced in SDK v1.5. | | | `SOCKET_OPEN_MAX_TIMEOUT` | Maximum socket connection timeout, in seconds. | Int (sec) | none | Introduced in SDK v1.5. | | | `TEST_COMMANDS_ENABLED` | Unlocks `TEST_*` JSON-RPC commands for test automation. | Bool (1/0) | 0 | Introduced in SDK v1.5. Do not enable in production. | | | `NO_READER_RESTART_TIMEOUT` | How long to wait for the reader to respond before rebooting. | Int (sec) | 3600 | Introduced in SDK v1.5. Minimum 60 seconds. | | **TMS & Payment** | `TMS_SVC_URL` | URL for Terminal Management System. | URL String | tms.otiglobal.com | Use tms-c.otiglobal.com for Nayax Core. | | | `PAYMENT_SVC_URL` | URL for payment processing server. | URL String | payment-nayax-p.otiglobal.com | Max 256 characters. | | | `SERVER_POLL_INTERVAL` | Seconds between calls to the server for updates. | U16 | 600 | Low values increase data usage. | | **Reader Settings** | `READER_IS_SERIAL` | 0=USB, 1=Serial, 2=Auto-detect. | 0/1/2 | 2 | Removed in SDK v1.4; use `READER_SERIAL_PORT`. | | | `READER_SERIAL_PORT` | Sets the actual port device (e.g., /dev/ttyS0). | String | None (USB) | Not supported in Android SDK. | | | `AUDIO_PERCENTAGE` | Sets the reader's audio volume (UNO-8/PLUS only). | U8 | unset | Introduced in SDK v1.5. | | **Open Loop Payment** | `OPEN_LOOP_ENABLED` | Enables/Disables open-loop payment. | Bool (1/0) | 0 | Introduced in SDK v0.7. Default changed from `1` to `0` in SDK v1.5. | | | `PMT_ACCEPT_OFFLINE` | Automatically approves auth when network is down (Store & Forward). | Bool (1/0) | 0 | 0=Disabled, 1=No comm, 2=Always. Deprecated in SDK v1.5; use the [`deferred`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize) parameter in `PreAuthorize` instead. | | | `PRE_AUTH_AMOUNT` | Default pre-authorization amount if not provided by API. | Int | 0 | Provided in cents. | | | `PAYMENT_SVC_SYNCHRONOUS` | Waits for the current transaction to close on the server before starting a new one. | Bool (1/0) | 0 | `PMT_KIOSK_AUTOCONFIRM` has no effect on this platform since SDK v1.5. | | | `CURRENCY_CODE` | ISO 4217 code (e.g., 840 for USD). | String | 840 | v1.4 takes this from Nayax Core automatically. SDK v1.5 adds a further fallback to the reader's kernel currency tag (9F3C) on the first transaction before defaulting to 840. | | **Closed Loop (CLP)** | `CLP_MIFARE_ENABLED` | Enables Mifare detection as a closed loop. | Int | 2 | 0=Off, 1=Server approval, 2=Local Host API. | | | `CLP_MIFARE_READ` | Format: `K[A`\|`B][key_num]B[block_num]...` (for example, `KA01B10B14,KB05B20B30` reads blocks 10 and 14 with key A number 1, and blocks 20 and 30 with key B number 5). | String | unset | Read blocks are returned in `TransactionComplete`'s `mifare_read` field. | | **Logging** | `LOG_FILE_SIZE` | Max size in KB for each log file. | Int | 1024 | Default was 256 KB before SDK v1.2. | | | `LOG_NO_OF_FILES` | Number of log files kept before rotation. | Int | 10 | Default was 6 before SDK v1.2. | # EMV Core RTOS SDK Release Notes Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/emv-core-rtos-release-notes Track EMV Core RTOS SDK changes as they ship. Nayax logs EMV Core RTOS SDK changes on this page as they ship. Subscribe to the RSS feed to get notified of new entries. To find the feed, add `/rss.xml` to the end of this page's URL. Release notes are organized into three categories to help you evaluate the impact of each update: * **Improvements**: New API commands, expanded platform and card support, and performance enhancements. * **Fixes**: Resolved bugs and reliability improvements. * **Known Issues**: Current limitations or pending features, with recommended workarounds. <Update label="SDK Version 1.0"> *Released: 11 February 2026* This version includes the following improvements, fixes, and known issues for the RTOS SDK: <Accordion title="Improvements" icon="rocket"> ### **Linux Sample Application (Portable C Sources)** SDK callback architecture refactored for better compiler compatibility (RM7434). JSON-RPC messages are now logged by default in the sample application (RM7471). *** ### **TLS Support** Secure server communication via TLS for both TMS and payment service connections (RM7021). *** ### **External Settlement (Remote Settlement)** `TransactionComplete` now returns an `Additional_Parameters` field with the data required for Nayax server-to-server External Settlement (RM7549): * `SiteId`: unique identifier of the transaction site * `EntryMode`: transaction entry mode (Swipe, Contact, NFC) * `MachineAuTime`: machine authorization time * `NayaxTransactionId`: transaction ID *** ### **e-Receipt Support** `TransactionComplete` now returns the data required for the Nayax e-Receipt. *** ### **CLP Card Type Detection** `TransactionComplete` now returns the closed-loop card type. *** ### **Reserved for Future Use** The following features are included but not yet fully tested and should not be used: * `UpdateMachineAttributes` API * Enhanced `SendToReader` functionality with TLS-based permissions * Push service integration </Accordion> <Accordion title="Fixes" icon="wrench"> ### **libecodsdk Library** * Network Status Notifications * Threading Model: Dual-Thread Architecture * New configuration options in `ecod_sdk_configs.h`: * `EC_ACK_TIMEOUT_MS`: timeout for ACK responses (default: 1000 ms) * `EC_ACK_MAX_RETRIES`: maximum retries for unacknowledged frames (default: 0) * `EC_SUPPORT_LONG_LIVED_SOCKETS`: enable persistent socket connections * New status value: `EC_DISABLED`, indicates EMV Core is in a disabled state *** ### **Platform Layer** * Added `ecod_platform_init()` for platform-specific initialization * Serial port data flushing on port open * Linux: SIGPIPE signal handling to prevent crashes on socket disconnections *** ### **Logging** * Log files limited to 336 KB total to protect critical operations (RM7534) * Fix: Log upload now includes the most recent entries (issue #7357) * Auto-cleanup of excess log files on configuration change (RM7539) * New log level: `EC_LOG_LEVEL_TRACE` for detailed debugging * File logging support added * Improved log formatting with module prefixes *** ### **Configuration & Storage** * Periodic file system cleanup for long-term reliability (RM7527) * Reader file-system cleanup to prevent storage exhaustion (RM7531) * Fix: Configuration file corruption during updates (RM7533) *** ### **Payment Parameters (`emvCorePaymentParameters`)** * Removed: `fee_cents` and `currency_code` * Added: `additional_receipt_data`, `is_final_amount`, `is_deferred` (RFU) *** ### **Reader Communication** * Backwards compatibility with ECOD v0.9 * Device auto-recovers when reader misses configuration files (RM7573) * Reader configuration update reliability improved with retry mechanism (RM7575) * Socket response timeout handling improved (RM7578) * ACK/NAK handling with automatic retransmission * Better handling of fragmented serial messages * Frame size validation *** ### **Network Bridge (Socket API)** * Nagle's algorithm disabled for reduced latency on small packets * Optimized socket data arrival notifications * Automatic network connectivity monitoring (Linux) *** ### **User Interface** * Fix: `ReaderMessage` events now include correct message index (RM7470) * Fix: "Present card" message displays immediately after `PreAuthorize` (RM7553) * Fix: LED blinking behavior corrected during Poll EMV (RM7585) *** ### **Reader Firmware** * Safe dual-mode operation (TLV and JSON-RPC) (RM7571, RM7572, RM7584) * Firmware update package size reduced </Accordion> <Accordion title="Known issues" icon="exclamation-triangle"> ### **Intermittent TLV Messages (RM7586)** Device may intermittently send TLV format messages instead of JSON-RPC. *** ### **Slow First Response After Reset (RM7592)** Serial communication: the first response after reset may be slow. *** ### **Virtual Machine Device Discovery** On virtual Linux machines (e.g., WSL or VirtualBox), the host sample application cannot find the device after it restarts: ``` SERIAL [ERROR] failed to open HID port /dev/hidraw0: No such file or directory ``` This occurs because the virtual OS attaches the reader with a different name (e.g., `hidraw1`). Not relevant for physical operating systems. </Accordion> </Update> ### Version history Every earlier RTOS SDK version, condensed to one line. See the current version above for full detail and links. | Version | Date | Summary | | - | - | - | | SDK Version 0.9 | July 31, 2025 | **Added**:<ul><li>A portable Linux sample app</li><li>A framed Datalink layer</li><li>`GetCardToken`/`CardTokenReceived`/`GetAttribute` commands</li></ul>**Fixed** (#7052, #7054, #7056, #7072, #7233):<ul><li>LED bugs</li><li>Core-version bugs</li><li>Present Card display bugs</li></ul> | | SDK Version 0.2 | March 24, 2025 | **Added**:<ul><li>UART TTL communication</li><li>UNO-8 Manager v4.0.0</li></ul>**Fixed** (#7077, #7043, #7051):<ul><li>Safe-Mode startup</li><li>Parallel TMS transfers during transactions</li><li>Millisecond log timestamps</li></ul> | | SDK Version 0.1 | December 30, 2024 | First RTOS SDK release | # Android SDK Installation Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/get-started/emv-core-android-installation Integrating the EMV Core SDK into an Android environment allows for pre-certified EMV payment processing within a Kiosk or POS application. ### System requirements and SDK files Before beginning, ensure the host hardware meets the following criteria: * **Android OS**: Version 7 or above. * **Network**: Stable internet communication with TLS v1.2 or above. * **Permissions**: The application must have permission to read `/sys/class`. * **SDK Package Components**: 1. `com.nayax.emvCore-release-v.v-bbb.apk`: The mandatory EMV Core service package. 2. `com.nayax.emv_core_android_test-release-v.v-bbb.apk`: The sample application used for testing. 3. `emv-core-test-v.v-bbb.zip`: An Android Studio project containing a library and sample source code in Java. ### Installation steps 1. **Deploy APKs**: Install the EMV Core Service package followed by the Test application on the target Android device. 2. **Hardware Connection**: Connect the UNO reader to the Android device. 3. **System Prompts**: * When the system prompts you to "Allow EmvCore Service to access Saturn 8700," check the "Always open..." box and press **OK** to whitelist the reader. * Select **Allow** on the "Stop optimizing battery usage" prompt to keep the service running in the background. 4. **Restarting**: If communication issues occur between the reader and the application, restart the service. ### Verification Once the applications are running and the reader is connected, the status line at the top of the test application screen should display **"Ready"**. You can then navigate to the **'Maintenance'** page and press **'Get Data'** to retrieve software versions and hardware status. # Obtain Your Device ID Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/get-started/emv-core-device-id The Device ID is required to register your hardware with the Nayax Core system. This unique identifier is derived from the reader's Serial Number (SN) and is necessary to enable payment clearing and remote management. The most direct way to find the ID is to look at the hardware and locate the Serial Number (SN) label on the back of the EMV reader. <Warning> Scan the barcode to prevent manual entry errors. </Warning> If the reader is already connected to your host system, you can retrieve the ID programmatically using the provided test applications: <Tabs> <Tab title="Linux"> 1. Navigate to your SDK directory and start the demo application. 2. From the main menu, select the option for Kiosk ID or EMV Core ID (typically menu option 9 on Linux or 8 on RTOS). 3. The application will query the reader and display a 16-digit numeric string (e.g., 4207012624000149). <Frame> <img alt="" /> </Frame> </Tab> <Tab title="Android"> 1. Open the SDK Sample Application. 2. Navigate to the **Maintenance** page. 3. Press the **Get Data** button. 4. The **Kiosk ID** field will populate with the reader's unique identifier. <Frame> <img /> </Frame> </Tab> </Tabs> Once you have retrieved the 16-digit Device ID, provide it to your Nayax Account Manager. They will register the terminal in the Nayax Core system, which is a prerequisite for completing any payment transactions. # Get Started Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/get-started/emv-core-get-started-1 The Nayax OEM POS Solution provides a pre-certified EMV module that simplifies the development of card-present kiosks. By integrating the EMV Core, you can focus on your application's UI and business logic while we handle the complexities of transaction processing. <Note> **Version Compatibility** This documentation applies to EMV Core v1.5, which is the current version. </Note> ## Installation Select your platform to begin the SDK installation: <CardGroup> <Card icon="mobile-screen-button" title="Android SDK installation" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-android-installation"> Integrate the EMV Core SDK into an Android environment for pre-certified EMV payment processing. </Card> <Card icon="terminal" title="Linux SDK installation" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-linux-installation"> Install the EMV Core SDK on Linux-based platforms using optimized binaries for your CPU architecture. </Card> </CardGroup> ## Identify your device After installation, you must [Obtain Your Device ID](/docs/integrate-pos-device/emv-core/get-started/emv-core-device-id). This unique identifier is required to communicate with the Nayax gateway, initialize the EMV Core, and begin processing test transactions. # Integration Process Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/get-started/emv-core-integration-process A step-by-step guide to integrating with Nayax The Nayax integration process ensures a seamless and efficient implementation, providing technical support at every stage. From initial setup to production deployment, Nayax teams work closely with partners or customer developers to meet all technical and operational requirements. ## Stages of the process The integration process is divided into five main stages: 1. Kickoff Meeting 2. Integration Setup 3. Development Phase 4. Testing & Certification 5. Production Setup <Frame> <img /> </Frame> Each stage is structured to provide technical support and essential resources, ensuring smooth and efficient implementation. ### Kickoff Meeting The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator’s project, the technical teams, and the Nayax Integration Engineer. ### Integration Setup This initial stage establishes the technical foundation for the integration. 1. **Assignment of Integration Engineer:** A Nayax integration engineer is assigned as the primary focal point for the partner or customer developer. 2. **Configuration:** The engineer configures the Nayax Core (backend) and sets up the device with the relevant transaction flow in the integration environment. 3. **Welcome Email:** At the end of this phase, the engineer sends a welcome email with all necessary resources, including the URL, SDK, documentation, tokens, and other required development tools. ### Development Phase This stage focuses on the partner or customer developing their solution. 1. **Partner/Customer Development:** The partner or customer developer creates their solution using the Nayax API/SDK. 2. **Support:** During this phase, the integration engineer provides assistance for any issues or "how-to" queries to ensure progress. <Note> **Support for OCPP/OCPI Integrations** For integrations based on **OCPP/OCPI** standards, this step is not relevant, as these integrations follow predefined flows according to the standard protocol. </Note> ### Testing & Certification This stage verifies that the integration meets Nayax’s standards: 1. **Certification Test Requirements:** Nayax shares specific requirements for certification tailored to the integration type and transaction flow. 2. **Testing:** The partner or customer developer performs a series of tests (typically 9–15, depending on the integration type and flow). 3. **Review:** The Nayax integration engineer reviews the results of these tests to ensure all criteria are met. 4. **Certification:** Upon successfully completing all tests, Nayax issues a certification letter confirming the integration is ready for deployment. ### Production Setup The final stage ensures a smooth deployment in a live environment: 1. **Production Environment Configuration:** Nayax configures the integration in the production environment, including the machine model setup. 2. **Support for Testing:** The integration engineer provides support during production lab or field tests to confirm successful deployment. The Nayax integration process provides a structured, step-by-step approach that ensures reliable and efficient implementation. By collaborating closely with partners and customers, Nayax delivers high-quality solutions that meet industry standards and support successful deployments in the market. # Linux SDK Installation Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/get-started/emv-core-linux-installation The Nayax EMV Core SDK supports a wide range of Linux-based platforms. Each delivery includes optimized binaries for specific CPU architectures and library versions. <Accordion title="Supported platforms" icon="info-circle"> The following table has all supported Linux platforms: | Target Name | Description | Bits | PIE | CPU ABI | Min Kernel | GLIBC | libCurl | | :- | :- | :- | :- | :- | :- | :- | :- | | **x86\_64** | X86 64-bit (Ubuntu) | 64 | Yes | AMD64 | 3.2.0 | 2.34 | 7.81.0 | | **armhf** | ARM32 GCC "hard float" | 32 | Yes | ARM v7-A | 3.2.0 | 2.34 | 7.81.0 | | **armhf\_7.5** | ARM32 GCC "hard float" (Linaro 7.5) | 32 | No | ARM v7-A | 3.2.0 | 2.17 | 7.86.0 | | **armv8a** | ARM64 Poky Linux (Yocto) | 64 | Yes | ARM AArch64 | 5.15.0 | 2.38 | 8.4.0 | | **aarch64-nuvoton** | ARM64 for Nuvoton (Buildroot) | 64 | No | ARM AArch64 | 5.10.0 | 2.28 | 7.79.1 | | **arm-inj** | ARM32 (Buildroot) | 32 | Yes | ARM v7-A VE | - | - | 7.83.1 | | **ql\_oe\_mdm9607** | Quectel MDM9607 OpenEmbedded | 32 | No | ARM v7-A | 2.6.32 | 2.17 | 7.44.0 | | **cortexa53-poky-linux** | ARM64 based on Poky Linux | 64 | Yes | ARM AArch64 | 3.14.0 | 2.34 | 7.82.0 | | **cortexa53-hardknott** | ARM64 using Hardknott build | 64 | Yes | ARM AArch64 | 3.14.0 | 2.33 | 7.75.0 | | **openwrt** | Open-source firmware for embedded MIPS | 32 | No | MIPS | - | - | 8.0.1 | | **nuvoton\_NUC970** | ARM32 for Nuvoton NUC970 | 32 | - | ARM | - | - | 7.52.1 | | **openwrt-arm** | Open-source firmware for embedded ARM32 | 32 | - | ARM | - | - | 7.82.0 | | **aarch64-ndk23** | ARM64 using Android NDK | 64 | Yes | ARM AArch64 | - | - | 7.86.0 | | **aarch64-13.2** | ARM64 using GNU toolchain 13.2 | 64 | - | ARM AArch64 | 3.7.0 | 2.34 | 8.9.0 | | **aarch64-musl** | ARM64 OpenWRT MUSL | 64 | - | ARM AArch64 | - | - | 8.15.0 | </Accordion> ### Package contents Each platform folder contains four primary components: * **`otiKiosk`**: The primary EMV Core service executable. * **`otiKioskDemo`**: The client Test Application executable. * **`kiosk-client-library-xxx.zip`**: Eclipse project containing the C source code and sample app. * **`otikiosk-xxx.zip`**: Package for remote updates via TMS (using the `CON_PROG` command). The package is organized as follows: ```text theme={null} Linux/ └── x86_64/ ├── otiKiosk/ # EMV Core Service ├── otiKioskDemo/ # Test App ├── Sources/ # Client library & source code └── TMS Update/ # Remote update package ``` ## Installation The EMV Core SDK for Linux provides a set of APIs to control payment processes over Unix domain sockets or TCP. It supports multiple architectures, including x86\_64 and various ARM platforms. ### Prerequisites and environment Verify these requirements before deploying the SDK: * **System Dependencies**: Requires `libcurl` for secured internet access with TLS 1.2 or higher. * **Permissions**: The user running the service must have read/write access to the executable folder and the reader device (e.g., `/dev/hidrawX` for USB or `/dev/ttyXXX` for Serial). * **Architecture**: Ensure you are using the correct binary for your target platform (e.g., Ubuntu x86\_64, armhf, or armv8a). ### Installation steps 1. Copy the EMV Core binary (`otiKiosk`) to the target device. Note that the file must not be renamed. 2. Build the sample application: * Install build essentials: `sudo apt-get install build-essential automake`. * Extract the source code zip file (e.g., `Emv-Core-client-x86_64-1.4-97.zip`). * Run the following commands in the source folder: ```bash theme={null} autoreconf -fi ./configure make ``` 3. Run the applications: * **Terminal 1**: Start the EMV Core service with `sudo ./otiKiosk`. * **Terminal 2**: Start the test application with `sudo ./otiKioskDemo`. <Note> **Communication Configuration** By default, the SDK uses Internal (Unix domain) sockets, creating `socket_cmd` and `socket_events` in the application's `/var` folder. If you prefer TCP communication, set the configuration option `KIOSK_USE_TCP_SOCKETS=1`. This will use ports **10000** for commands and **10001** for events. </Note> # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/overview Nayax Embedded Solution enables OEM manufacturers to integrate secure, affordable, and global payment capabilities into their machines. This solution includes a robust hardware reader, flexible software SDK, and powerful payment processing services. Whether you're developing Android or Linux applications or building on an MCU or RTOS embedded platform, Nayax provides the tools to streamline integration and ensure smooth transactions. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> ## Key benefits * **Global Payment Acceptance**: Support for debit, credit, prepaid cards, and mobile payments. * **Developer-Friendly Integration**: JSON and Java APIs with sample code for quick setup. * **Reliable and Scalable**: Redundant PCI-certified servers and 24/7 tier-1 support in 50+ countries. ## Solution components The Nayax Embedded solution is composed of the following components: <Columns> <Card title="Nayax EMV reader"> A low-cost, EMV-certified reader that securely reads card data and communicates exclusively with the EMV Core for processing. </Card> <Card title="Nayax EMV Core"> An SDK installed on the host machine (Android, Linux, or RTOS embedded platform) that handles communication between the EMV Reader and Nayax servers. </Card> <Card title="Host application"> Developed by OEM manufacturers to manage the entire payment system, it connects to the Nayax EMV Core for transaction processing and management. </Card> </Columns> <Frame> <img /> </Frame> ## What Nayax provides When you choose to use the Nayax Embedded solution, Nayax will provide the following: * **Hardware**: * **UNO-8/mini**: EMV-certified reader with L1, L2, TQM certifications. * **Software**: * Nayax EMV Core SDK with sample code for Android, Linux, and RTOS embedded platforms. * Support for EMV payments, prepaid payments, and remote firmware updates. * **Gateway Services**: * Secure processing for all major card brands and mobile payments. * Redundant PCI-certified servers with 99.9% uptime. * Remote management with customizable alerts and reporting tools. ## Choose your SDK Select your integration path based on your target platform: <Columns> <Card title="Android & linux SDK" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-get-started-1"> Java and native binary SDK for Android and Linux applications. Includes pre-built payment flows, a full Java API, and demo applications. </Card> <Card title="RTOS SDK" href="/docs/integrate-pos-device/emv-core/rtos/rtos-overview"> Portable C library (C99) for MCU and RTOS embedded platforms. Communicates with the UNO-mini reader over UART or USB HID. </Card> </Columns> # Closed Loop Transaction Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/closed-loop-transaction Closed-loop transactions use MIFARE cards. The merchant reads the card UID and processes the transaction on their own application server, without involving bank networks. Since no bank operations are required, closed-loop transactions do not use the Nayax servers. Instead, your host machine uses the EMV reader to read the card and EMV Core to interact with it. <Warning> Your application does not know whether the consumer will present an open-loop (credit or debit) or closed-loop (MIFARE) card until the reader scans it. Your application must be prepared to handle both. </Warning> ## Transaction flow The following diagram shows the transaction flow for a closed-loop transaction: <Frame> <img /> </Frame> Where: 1. The host machine calls the [`PreAuthorize`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize) method using the EMV Core API. This is the only action performed by the host machine. 2. The EMV Core sends the amount to the Reader. 3. Your application prompts the consumer to tap their card. 4. The shopper taps the card into the EMV reader. 5. The Nayax EMV Reader pulls the Response with the encrypted card data to the Nayax EMV Core. 6. Nayax EMV Core identifies it as a MIFARE card (closed-loop transaction) and informs the host application that the transaction is complete, returning the card UID and optional card data. <Note> By default, MIFARE card data is shared locally with your host machine. You can also configure the SDK to send the data to Nayax servers for processing through Nayax Prepaid. </Note> 7. Your application uses the card UID to authorize the transaction with your application server. 8. Once approved, the transaction is complete. 9. The product is successfully delivered to the consumer. 10. EMV Core allows transactions to be reported to the Nayax server, which sends the proprietary payment amount and UUID. # Deferred Transaction Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/deferred-transaction Deferred transaction, also known as "offline transaction" or "store & forward," lets the terminal keep providing service even when it has no communication with the server. ## How it works The terminal keeps the transaction data in persistent memory and sends it for online approval once communication is restored. EMV Core performs basic card authentication first. If that authentication passes, EMV Core returns the `TransactionComplete` event to the host before it goes on to request online authorization. To use deferred transaction on Android, set `isDeferred=true` in [`PreAuthorize`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize). The same parameter is called `deferred` in the JSON API. This parameter, introduced in SDK v1.5, replaces the [`PMT_ACCEPT_OFFLINE`](/docs/integrate-pos-device/emv-core/emv-core-configuration#managing-settings) configuration attribute. `PMT_ACCEPT_OFFLINE` is deprecated and no longer affects EMV Core's behavior. ## Final amount requirement In SDK v1.5, deferred authorization is only supported when `isFinalAmount=true`. Under this condition: * EMV Core stores the transaction data in memory and sends it to the server when possible. * The transaction is authorized and settled for the same amount. * You don't need to call `ConfirmTransaction` afterward. <Warning> Activating this feature risks some transactions not being approved. Use it only when preventing service is impossible, for example parking, lockers, or transit. The operator bears the risk and responsibility; Nayax is not responsible for any transaction that isn't approved. </Warning> ## Next steps <CardGroup> <Card title="PreAuthorize API" icon="code" href="/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize"> API reference for PreAuthorize, including the isDeferred and isFinalAmount parameters used to trigger a deferred transaction. </Card> <Card title="Configuration parameters" icon="gear" href="/docs/integrate-pos-device/emv-core/emv-core-configuration#managing-settings"> Configuration reference. Look for the deprecated PMT\_ACCEPT\_OFFLINE parameter in the parameter table further down the page. </Card> </CardGroup> # Payment with Pre-Authorization Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/payment-with-authorization Nayax recommends the pre-authorization approach. It splits payment into two steps: 1. Pre-authorization 2. Settlement <Note> If you prefer, you can perform the authorization and settlement in just one step. To learn more about this process, visit the [Single Step Payment](/docs/integrate-pos-device/emv-core/payment-flows/single-step-payment) page. </Note> ## Pre-authorization In the first step, the host machine uses the EMV Core to authorize a specified amount for the payment operation with the consumer's card. The following diagram shows the transaction flow for a **pre-authorization**: <Frame> <img /> </Frame> Where: 1. The host machine calls the [`PreAuthorize`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize) method using the EMV Core API. This is the only action performed by the host machine. 2. EMV Core polls the reader. Your application should prompt the consumer to tap their card. 3. The reader prompts the consumer to present their card. 4. The consumer taps their card. 5. The reader sends the encrypted card data to EMV Core. 6. EMV Core sends the data to the Nayax servers to authorize the amount from step 1. 7. The Nayax servers return the authorization response with the transaction ID and data. 8. EMV Core triggers the `TransactionComplete` event with the transaction ID and result. <Note> The `TransactionComplete` callback fires regardless of the result — approved, declined, or timed out. Check the transaction data to determine the result and decide how to proceed. </Note> After the transaction is approved, proceed with your selling flow: deliver the product, start charging, or perform any other operation. You can also store the transaction ID and data on your server. ## Settlement Settlement defines the final amount and charges it to the consumer's card. It starts after the product is delivered or the operation (such as EV charging) is complete. <Frame> <img /> </Frame> 1. The selling operation completes. For example, the product is delivered to the consumer. 2. Your application reports the sale to your application server. 3. The application server closes the session. 4. Your application calls [`ConfirmTransaction`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#confirmtransaction) with the transaction ID and the final amount to charge. <Note> The final amount can differ from the pre-authorized amount. To avoid problems, use the maximum expected amount at authorization if the final amount may vary. </Note> 5. EMV Core confirms the amount and initiates settlement with the Nayax servers. Settlement is not yet complete at this point. 6. EMV Core sends the transaction ID and amount to the Nayax servers. 7. The Nayax servers return an acknowledgment so EMV Core does not need to resend the confirmation. Nayax processes the settlement and transfers the funds. <Note> To cancel a pre-authorized transaction, send a void operation instead of a confirm. </Note> # Pre-Authorization with External Settlement Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/pre-authorization-with-external-settlement The EMV Core implementation of [ExternalSettlement](/reference/spark/transactions/externalsettlement) separates the authorization and settlement phases of a transaction. While EMV Core manages the initial interaction with the consumer and the payment card, the final financial settlement is performed by a 3rd-party server that sends the settlement request to Nayax's servers. <Warning> **Prerequisite** For this flow to function, the [ExternalSettlement](/reference/spark/transactions/externalsettlement) setting must be enabled by Nayax. </Warning> ## Configuration & device behavior Once enabled, settlement is handled externally rather than by the host application: * The only way to settle a transaction is via the [ExternalSettlement](/reference/spark/transactions/externalsettlement) command. * The settlement amount can be less than or equal to the authorized amount. This gives you the flexibility to trigger the settlement stage externally according to your own business logic. | Feature | Requirement | | :- | :- | | **Settlement Window** | Transactions must be settled within **60 hours** of initiation by default. This window can be adjusted for specific cases by Nayax support. | | **Expiry** | Settlement attempts performed after the settlement window will fail. | | **Auto-Cleanup** | Transactions unsettled past the settlement window are automatically canceled via card scheme regulations (this should not be relied upon). | | **Settlement Amount** | The final settlement price must not exceed the authorized amount. | ## Managing unsettled transactions When no product or service is provided, you must proactively manage the transaction to maintain a good user experience. * **External Cancel:** If no settlement will occur, you must send an **External Cancel** immediately. * **Consumer Impact:** If a transaction remains authorized without being canceled or settled, the consumer's funds will stay captured on their payment method, leading to potential disputes. ## External settlement flow The flow consists of two phases: payment authorization handled by EMV Core, and settlement or cancellation triggered by your 3rd-party server. ### Payment authorization The steps below cover the authorization phase, from card tap through session completion. <Frame> <img alt="Sequence diagram of the payment authorization phase, from the PreAuthorize call through the TransactionComplete event and service delivery" /> </Frame> 1. The host machine calls the [`PreAuthorize`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#preauthorize) method using the EMV Core SDK. 2. EMV Core begins polling the reader. The host application should prompt the consumer to tap their card. 3. The consumer taps their card on the reader. 4. EMV Core reads the card data and sends an authorization request to the Nayax servers. 5. Nayax servers perform authorization with the Billing Provider. 6. The Billing Provider sends an authorization response to the Nayax servers. 7. Nayax servers return the authorization response to EMV Core. 8. EMV Core sends a `TransactionComplete` event to the host application. The event contains the transaction ID and transaction data, including `NayaxTransactionId` and `SiteId` in the `authorizationDetails.Additional_Parameters` field. At this point, the host application must retain the `NayaxTransactionId` and `SiteId` for later use in the External Settlement or External Cancel request. 9. The host application proceeds with providing the service (for example, starts an EV charging session or dispenses a product). ### Settling the transaction After service delivery, a 3rd-party server handles either settlement or cancellation depending on the outcome. If the service was provided: <Frame> <img alt="Sequence diagram of the external settlement flow, from StartAuthentication through the ExternalSettlement response" /> </Frame> 10. The 3rd-party server initiates communication by calling the `StartAuthentication` method with an encrypted cipher to authenticate. 11. The Nayax Server decrypts the cipher and validates the credentials to confirm authenticity. 12. The 3rd-party server sends an [ExternalSettlement](/reference/spark/transactions/externalsettlement) request. It must contain the `NayaxTransactionId` and `SiteId` retrieved from the `TransactionComplete` event, and must be sent within the settlement window. 13. Nayax servers process the settlement with the Billing Provider. 14. Nayax servers send an [ExternalSettlement](/reference/spark/transactions/externalsettlement) response to the 3rd-party server confirming the settlement outcome. If the service was not provided: <Frame> <img alt="Sequence diagram of the external cancel flow, from StartAuthentication through the ExternalCancel response" /> </Frame> 10. The 3rd-party server initiates communication by calling the `StartAuthentication` method. 11. The Nayax Server validates the credentials. 12. The 3rd-party server sends an [ExternalCancel](/reference/spark/transactions/externalcancel) request. It must contain the `NayaxTransactionId` and `SiteId` retrieved from the `TransactionComplete` event, and must be sent within the settlement window. 13. Nayax servers initiate the cancellation process with the Billing Provider. 14. Nayax servers receive the response from the Billing Provider. 15. Nayax servers send an [ExternalCancel](/reference/spark/transactions/externalcancel) response to the 3rd-party server. ## Next steps <CardGroup> <Card title="External settlement API" icon="link" href="/reference/spark/transactions/externalsettlement"> API reference for the ExternalSettlement endpoint used to settle authorized transactions from a 3rd-party server. </Card> <Card title="External cancel API" icon="link" href="/reference/spark/transactions/externalcancel"> API reference for the ExternalCancel endpoint used to cancel authorized transactions when no service is provided. </Card> </CardGroup> # Single Step Payment Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/single-step-payment The single-step payment flow enables immediate authorization and settlement in a single operation, streamlining the payment process for use cases that require fast, straightforward transactions. While less robust than the two-step process (`PreAuthorize` and `ConfirmTransaction`), it is suitable for low-risk environments such as vending machines or self-service kiosks. <Warning> Nayax recommends the [Payment with Pre-Authorization](/docs/integrate-pos-device/emv-core/payment-flows/payment-with-authorization) approach because it handles communication failures more reliably. </Warning> ## Transaction flow The following diagram shows the transaction flow for a single-step payment: <Frame> <img /> </Frame> Where: 1. The host application initiates a payment transaction by calling the [`PayTransaction`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#paytransaction) method. The total transaction amount, currency, and other parameters are specified to EMV Core upfront. 2. EMV Core polls the card reader to determine whether a card is present. 3. The consumer taps or inserts their card. 4. EMV Core captures the card's encrypted data. 5. The encrypted card data is sent to the EMV Core. 6. EMV Core confirms the transaction and sends the details to the Nayax Server. 7. The server receives the transaction data and performs the settlement, confirming it to EMV Core. 8. EMV Core receives the transaction result from the server and triggers the [`TransactionComplete`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks#transactioncomplete) event, sending the transaction's data. 9. The vending is finalized, and the product is delivered to the consumer. 10. The transaction report is sent to the Kiosk Application server. # Payment Flows Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/payment-flows/transaction-flow The SDK supports multiple transaction flows to accommodate diverse use cases, from single-step payments to multi-step preauthorization and confirmation processes. This flexibility allows developers to choose the flow that best suits their application's requirements while maintaining security and reliability. The available transaction flows are: <CardGroup> <Card icon="shield-halved" title="Payment with Pre-Authorization" href="/docs/integrate-pos-device/emv-core/payment-flows/payment-with-authorization"> Preauthorize a transaction amount, then confirm it for settlement in a second step. Ideal for scenarios where the exact final amount is unknown (such as EV charging). </Card> <Card icon="repeat" title="Closed Loop Transaction" href="/docs/integrate-pos-device/emv-core/payment-flows/closed-loop-transaction"> Process MIFARE card operations on your own application server using the card UID, without involving bank transactions. </Card> <Card icon="bolt" title="Single Step Payment" href="/docs/integrate-pos-device/emv-core/payment-flows/single-step-payment"> Authorize and settle a transaction immediately in one operation, streamlining the payment process for fast, straightforward use cases. </Card> <Card icon="money-bill-transfer" title="Pre-Authorization with External Settlement" href="/docs/integrate-pos-device/emv-core/payment-flows/pre-authorization-with-external-settlement"> Separate the authorization and settlement phases, letting a 3rd-party server handle final settlement through the Nayax API. Ideal for EV charging and similar variable-amount use cases. </Card> <Card icon="wifi-slash" title="Deferred Transaction" href="/docs/integrate-pos-device/emv-core/payment-flows/deferred-transaction"> Keep accepting payments while the terminal has no connection to Nayax's servers, and settle once communication is restored. Ideal for transit, parking, and lockers. </Card> </CardGroup> # C API Reference Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-c-api ## Overview The EMV Core provides the POS application with two API layers: 1. **C functions** implemented in `libecodsdk`. See `ecod_sdk.h` and `ecod_sdk_types.h` in the SDK. 2. **JSON-RPC messages** with Datalink wrapper over Serial or USB. See [JSON-RPC API](/docs/integrate-pos-device/emv-core/rtos/rtos-json-rpc-api). The POS application manages the user interface, using reader state events from EMV Core to keep the display in sync with the current payment status (idle, authorizing, declined, approved, etc.). ## Supported functionality The SDK supports the following payment and device management operations: * **Credit / Debit / Pre-paid Cards Sale:** * EMV Contactless (NO CVM only) * Two-step transaction (Authorize → Confirm) * Closed-loop (pre-paid) cards * Synchronous (single session) and Asynchronous (multi-session) flows * **Cancel and Void Transaction:** * `CancelTransaction` cancels an active poll before a card is captured. * `VoidTransaction` reverses a transaction that was already approved. * **User Interface (UI):** Managed by the POS application using Reader state events. * **Terminal Management:** Firmware and configuration updates, status and version queries, Device ID. * **Network API:** The host must implement the Network API to enable EMV Core communication with Nayax servers. ## API reference ### Initialization and lifecycle ### Get SDK version string Returns the SDK version as a null-terminated string: ```c theme={null} const char* EcodSdk_GetSdkVersion(void); ``` ### Initialize SDK Call once at startup: ```c theme={null} bool EcodSdk_Init(void); ``` ### Maintenance loop Call continuously from a dedicated thread: ```c theme={null} void EcodSdk_Maintain(void); ``` ### Process JSON-RPC messages Call from a second thread when `EC_USE_DATALINK_PROTOCOL=1`: ```c theme={null} int EcodSdk_ProcessMessages(uint32_t timeout_ms); ``` When `EC_USE_DATALINK_PROTOCOL` is enabled, a second thread is required to process JSON-RPC messages. Call `EcodSdk_Maintain()` for datalink operations and `EcodSdk_ProcessMessages()` for message processing. ### Set logging verbosity Call to control the detail level of SDK log output: ```c theme={null} EC_RET EcodSdk_SetLogLevel(EC_LOG_LEVEL max_level); ``` *** ### Device status ### Get current device status Call to query the current device state: ```c theme={null} EC_RET EcodSdk_GetStatus(EC_STATUS* out_status); ``` ### Get device identification (serial number) and versions Call to retrieve the device serial number and firmware version strings: ```c theme={null} EC_RET EcodSdk_GetKioskId(char* out_id, int max_out_size); EC_RET EcodSdk_GetEmvCoreVersion(char* out_version, int max_out_size); EC_RET EcodSdk_GetReaderVersion(char* out_version, int max_out_size); ``` ### Read configuration attribute Returns the value of a named key from the active configuration file: ```c theme={null} EC_RET EcodSdk_GetAttribute(char* attribute_name, char* out_value, int max_out_size); ``` *** ### Transaction operations ### Start pre-authorization Reserves the amount; must be confirmed or voided later: ```c theme={null} EC_RET EcodSdk_PreAuthorize(emvCorePaymentParameters* params); ``` ### Request card token without charging Starts card polling without initiating a payment: ```c theme={null} EC_RET EcodSdk_GetCardToken(emvCorePaymentParameters* params); ``` ### Confirm a pre-authorized transaction Call after the product or service has been delivered: ```c theme={null} EC_RET EcodSdk_ConfirmTransaction(uint32_t amount_cents, uint32_t product_id, char* transaction_reference); ``` ### Void a pre-authorized transaction Call to release a pre-authorized hold without charging the card: ```c theme={null} EC_RET EcodSdk_VoidTransaction(char* transaction_reference); ``` ### Cancel ongoing payment process Call to stop an active card poll before authorization completes: ```c theme={null} EC_RET EcodSdk_CancelTransaction(void); ``` *** ### Network notifications These functions are called by the platform layer to notify the SDK of network events: ### Notify EmvCore of socket data arrival Call from the platform layer when data is available on a socket: ```c theme={null} EC_RET EcodSdk_NotifySocketDataReceived(int socket_id, int available_bytes); ``` ### Notify EmvCore that socket was closed Call from the platform layer when a socket connection has been closed: ```c theme={null} EC_RET EcodSdk_NotifySocketClosed(int socket_id); ``` ### Notify EmvCore of network connectivity change Call from the platform layer when the network becomes available or unavailable: ```c theme={null} EC_RET EcodSdk_NotifyNetworkStatusChanged(bool available); ``` *** ### Callback registration ### Transaction completion (success, decline, error, cancel, timeout) Register a handler to receive the result of every `PreAuthorize` call: ```c theme={null} void EcodSdk_Register_TransactionComplete_Callback(TransactionCompleteCb_t cb); ``` ### Reader display events (customer prompts) Register a handler to receive the current message displayed on the reader: ```c theme={null} void EcodSdk_Register_ReaderEvent_Callback(RdrEventCb_t cb); ``` *** ## Key data types ### Payment parameters Pass this struct to `EcodSdk_PreAuthorize` and `EcodSdk_GetCardToken`: ```c theme={null} typedef struct { uint32_t amount_cents; // Amount in cents (1500 = $15.00) uint32_t product_id; // Product identifier unsigned int timeout_sec; // Timeout for card presentation bool continuous; // Wait continuously until cancelled char* additional_receipt_data; // Optional JSON string (can be NULL) bool is_deferred; // Deferred authorization (charge later) — RFU bool is_final_amount; // Amount won't change (no incremental auth) } emvCorePaymentParameters; ``` ### Transaction response This struct is passed to the `TransactionComplete` callback: ```c theme={null} typedef struct { emvCoreTransStatus status; // OK, Declined, Error, Timeout, Cancelled, etc. int error_code; // Error code if status is Error char error_message[100]; // Human-readable error double amount_requested; // Amount that was requested double amount_authorized; // Amount actually authorized char transaction_reference[128]; // Use for confirm/void/incremental char partial_PAN[20]; // Masked card number (****1234) char card_type[32]; // VISA, MASTERCARD, etc. char card_id[64]; // Unique card identifier char card_token[128]; // Tokenized card data char authorization_code[128]; // Auth code from processor char rrn[128]; // Retrieval reference number bool is_transaction_approved; // True if approved // ... additional fields for receipt, balance, Nayax info } emvCorePaymentResponse; ``` ### Status codes **Device status** (from `EcodSdk_GetStatus`): ```c theme={null} typedef enum { EC_READY, // Ready for transactions EC_TRANSACTION, // Transaction in progress EC_UNCONFIRMED, // Pending transaction needs confirm/void EC_UPDATE, // Device updating EC_NOT_READY, // Initializing EC_NO_EMVCORE, // Cannot communicate with device EC_NO_READER, // Reader not connected EC_NO_TERMINAL_ID, // Terminal ID not configured EC_DISABLED, // Device disabled EC_ERROR // Error state } EC_STATUS; ``` **API return codes:** ```c theme={null} typedef enum { EC_RET_OK, // Success EC_RET_GENERAL_ERROR, // General error EC_RET_MEMORY_ERROR, // Memory allocation failed EC_RET_PARSING_ERROR, // Response parsing failed EC_RET_COMM_ERROR, // Communication error EC_RET_NEGATIVE_RESP // Device returned error } EC_RET; ``` **Transaction status:** ```c theme={null} typedef enum { emvCoreTransStatus_OK, // Success emvCoreTransStatus_Declined, // Declined by processor emvCoreTransStatus_Error, // Error occurred emvCoreTransStatus_Timeout, // Card presentation timeout emvCoreTransStatus_Cancelled, // Cancelled by application emvCoreTransStatus_Voided, // Transaction voided emvCoreTransStatus_LocalCLP // Local closed-loop payment } emvCoreTransStatus; ``` ## Amount field details Amount fields use different units depending on the API method: * **C API:** `amount_cents` in `emvCorePaymentParameters` and the amount argument in `EcodSdk_ConfirmTransaction` are always in **cents** (e.g., 450 = \$4.50). * **JSON-RPC `PreAuthorize`:** amount is in **major units** (e.g., 4.50 = \$4.50). * **JSON-RPC `ConfirmTransaction`:** amount is in **cents** (e.g., 450 = \$4.50). * The `amount` fields in the `TransactionComplete` event are returned in **major units** (e.g., 4.50 USD) as received from the PSP. * The `fee` parameter is **deprecated**. Set it to `0`. It will be removed in the next SDK version. ## Currency code management The SDK resolves the currency code from multiple sources in priority order: * From SDK v1.0 onward, the currency code is taken from the `CURRENCY_CODE` attribute in the EMV Core configuration. * If `CURRENCY_CODE` is missing from the configuration, the `currency` parameter sent by the host in `PreAuthorize` is used (backward compatibility). * If neither is provided, the EMV Core software default (840 / USD) is used and an alert is sent to the Nayax Core server. * When the device is managed from Nayax Core, the currency code is automatically taken from the machine settings. # Configuration File Reference Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-configuration Configuration parameters are managed centrally from Nayax Core and may vary by customer and machine. ## Location Configuration files are saved on the reader file system in the `E:\ETC` folder. <Frame> <img /> </Frame> ## Format ``` <Parameter Name>=<Value> ``` **Example:** `TMS_SVC_URL=tms.otiglobal.com` ## Managing settings Configuration is managed centrally through **Nayax Core**. To adjust settings: 1. Navigate to **Operations** > **Machines**. 2. Locate the **Embedded** and **Embedded Advanced** sections. 3. Update the relevant attributes and press **Save**. The server generates a configuration file and pushes it to the device automatically. *** ## Network & system settings These parameters control network interface selection and system-level behavior: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `ETH_INTERFACE` | Network interface; empty = autodetect with fallback to eth0 | String | empty | — | | `KIOSK_USE_TCP_SOCKETS` | Use TCP ports 10000 (commands) and 10001 (events) instead of domain sockets | Bool (1/0) | 0 | — | | `DAILY_RESTART_HOUR` | Hour for automatic daily reboot (0–23, 0 = disabled). Actual reboot within 30 min of set hour. | U8 | 0 | — | | `CONFIG_VERSION` | Version of the config file; sent to TMS, not used by the device | String | — | — | | `KIOSK_TCP_LOCALHOST` | Limit EMV Core sockets to localhost interface | Bool (1/0) | 0 | 0.7 | ## TMS & payment service settings These parameters configure the URLs and polling behavior for the TMS and payment server: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `TMS_SVC_URL` | URL of TMS service. Use `tms.otiglobal.com` for OTI TMS or `tms-c.otiglobal.com` for Nayax Core. | URL String | tms.otiglobal.com | 0.7 / 1.0 | | `PAYMENT_SVC_URL` | Payment server URL, name only (e.g., `payment-nayax-p.otiglobal.com`) | URL String (max 256) | empty | — | | `SERVER_POLL_INTERVAL` | Seconds between server calls for updates. Lower value = better responsiveness but more data usage. | U16 | 600 | — | ## Reader settings These parameters control initialization commands, button behavior, and reader display messages: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `INIT_CMD` | Commands to send to the Saturn Reader on initialization. Hex strings of TLV tags, separated by `\|`. Example: `DF0A0100\|DF7A0100` | Hex strings | empty | — | | `STOP_BUTTON_ID` | ID of the STOP/CANCEL button: 1 = Right, 2 = Left | U8 | 1 | — | | `STOP_BUTTON_LED_PRESENT` | 0 = disable button blinking (if LED is not on the STOP button) | Bool (1/0) | 1 | — | | `R_COUNTRY_CODE` | Sets the Terminal Country Code value in the reader. v1.0 takes it from Nayax Core machine country. | String (4 chars) | N/A | 0.7 / 1.0 | | `R_DO` | Sends DO commands to the reader on device start. Executed only once, unlike `INIT_CMD`. Multiple `R_DO` lines are all executed. | Hex string | N/A | — | | `R_MSG_X_Y` | Sets reader message (index X, line Y) when the device starts | ASCII string | N/A | — | ## Security settings These parameters control SSL and encryption settings for server connections: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `TMS_USE_SSL` | Switch SSL for TMS service on or off | Bool (1/0) | 0 | — | | `PMT_DUKPT_KEY_VARIANT` | DUKPT key variant depending on PSP. Use decimal format (e.g., 17 decimal = 0x11). Set to 0 to disable DUKPT (testing only). | U8 | 17 | — | | `PAYMENT_SVC_USE_SSL` | Switch SSL for payment service on or off | Bool (1/0) | — | — | ## Open loop payment settings These parameters control open-loop (credit/debit) payment behavior, timeouts, and authorization flow: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `PMT_ACCEPT_OFFLINE` | Store & Forward: automatically approve when network is unavailable. **Note:** Risk of unapproved transactions; operator responsibility. | Bool (1/0) | 0 | — | | `PMT_KIOSK_AUTOCONFIRM` | Automatically confirms with pre-auth amount if session is interrupted. Supports long sessions with possible resets (e.g., EV chargers). | Bool (1/0) | 1 | — | | `PMT_CONFIRMATION_INTERVAL` | Seconds between attempts to execute pending Confirm or Void operations | U32 | 5 | — | | `PAYMENT_SVC_SERVER_RETRIES` | How many times online authorization will be retried on error | Int | 3 | — | | `PAYMENT_SVC_SERVER_TIMEOUT` | HTTP timeout for payment server requests (seconds) | Int | 20 | — | | `PAYMENT_SVC_CONFIRM_TIMEOUT` | Server timeout when sending Confirm or Void requests (seconds) | U32 | 60 | — | | `PAYMENT_SVC_USER_WAITING_MAX_TIME` | Max waiting time for online authorization (seconds) | U16 | 30 | — | | `MAESTRO_LIMIT_CENTS` | Transactions above this limit with Maestro card will be declined without fallback | U32 | 2500 | — | | `PAYMENT_SVC_SYNCHRONOUS` | Wait for the current transaction to close on the server before starting a new one. Note: for asynchronous mode after an unexpected reset, also set `PMT_KIOSK_AUTOCONFIRM=0`. | Bool (1/0) | 0 | — | | `OPEN_LOOP_ENABLED` | Enable/disable open-loop payment | Bool (1/0) | 1 | 0.7 | | `PRE_AUTH_AMOUNT` | Default pre-authorization amount in cents if no amount is provided by the API | Int | 0 | 0.7 | | `CURRENCY_CODE` | ISO 4217 code (e.g., 840 = USD). v1.0 takes it from Nayax Core automatically after any machine attribute change or 'Reload configuration' action. | String | 840 | 0.7 / 1.0 | ## Closed-loop payment settings These parameters enable and configure closed-loop (prepaid) card support, including Mifare: | Parameter | Description | Type | Default | Since Ver. | | | :- | :- | :- | :- | :- | - | | `CLP_PROPRIATARY_TRACKS_ENABLED` | Enable detection of proprietary tracks as Closed Loop during EMV payment. Requires proper reader configuration. | Bool (1/0) | 0 | — | | | `CLP_MIFARE_READ` | Specify Mifare blocks to read. Format: \`K\[A | B]\[key\_num]B\[block\_num],...`Example:`KA01B10B14,KB05B20B30\` | String | — | — | | `CLP_MIFARE_ENABLED` | Enable Mifare cards as Closed Loop during payment. 0 = disabled; 1 = enabled via server; 2 = enabled via local host API (UID returned immediately in `TransactionComplete`). | Int | 0 | 0.7 | | ## Logging settings These parameters control log file size, retention, and per-module verbosity: | Parameter | Description | Type | Default | Since Ver. | | :- | :- | :- | :- | :- | | `LOG_HOURS_TO_UPLOAD` | Hours of logs to include in UPLOAD\_LOG command | U16 | 10 | — | | `LOG_NO_OF_FILES` | Number of log files kept. Oldest file is overridden when all reach `LOG_FILE_SIZE`. | Int | 6 | — | | `LOG_FILE_SIZE` | Max size in KB of each log file | Int | 256 | — | | `LOG_GLOBAL` | Default log level for all modules (1–5) | 1–5 | 3 | — | | `LOG_READER` | Log level for Reader | 1–5 | 3 | — | | `LOG_ETH` | Log level for Ethernet (errors only; use LOG\_NET for data) | 1–5 | 3 | — | | `LOG_NET` | Log level for oT\_Net (network) | 1–5 | 3 | — | | `LOG_SYSTEM` | Log level for SYSTEM or common functions | 1–5 | 3 | — | | `LOG_APP_3` | Log level for Open Loop | 1–5 | 3 | — | | `LOG_APP_4` | Log level for TMS | 1–5 | 3 | — | | `LOG_USBH2` | Log level for USB Host | 1–5 | 3 | — | ## Reader message customization These parameters customize the text displayed on the Saturn Reader for various states: | Parameter | Description | Type | Default | | :- | :- | :- | :- | | `SAT_MSG_DECLINED1` | Line 1 of "Declined" message | String (16) | — | | `SAT_MSG_DECLINED2` | Line 2 of "Declined" message | String (16) | — | | `SAT_MSG_ERROR1` | Line 1 of "Error" message | String (16) | — | | `SAT_MSG_ERROR2` | Line 2 of "Error" message | String (16) | — | | `SAT_MSG_CARD_NOT_RECOGNIZED1` | Line 1, used by Closed-Loop Payment | String (16) | Card not | | `SAT_MSG_CARD_NOT_RECOGNIZED2` | Line 2, used by Closed-Loop Payment | String (16) | recognized | | `SAT_MSG_CLP_AUTHORIZING1` | Line 1, used by Closed-Loop Payment | String (16) | Authorizing... | | `SAT_MSG_CLP_APPROVED1` | Line 1, used by Closed-Loop Payment | String (16) | Approved | | `SAT_MSG_CLP_APPROVED2` | Line 2, used by Closed-Loop Payment | String (16) | Balance: | | `SAT_MSG_SWIPE_ALL1` | Message for retrying transaction in all channels | String (16) | Insert or Swipe | | `SAT_MSG_SWIPE_ALL2` | — | String (16) | Or Change Card | | `SAT_MSG_DEFAULT_MSGSWIPE1` | Message for retrying transaction via Mag Stripe | String (16) | Please Swipe | | `SAT_MSG_DEFAULT_MSGSWIPE2` | — | String (16) | Card | # Datalink Layer Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-datalink-layer The channel between EMV Core and Host is either a serial or USB channel. **In USB:** * The device uses the HID Protocol Class with 64-byte blocks (Reports in HID terminology). * The first byte of every 64-byte block is a length byte, indicating how many of the following 63 bytes are actually used. * If the length byte is less than 63, the remaining bytes should be discarded. * If it is 63 or more, all following 63 bytes are used. ## Datalink protocol ### Command sequence example (GetKioskId) The following exchange shows the full ACK/NAK flow for a `GetKioskID` command: ``` → Host sends data: <A0|0065{"jsonrpc":"2.0","method":"GetKioskID","params":{},"id":7}5C> ← EMV Core sends ACK: <+0> ← EMV Core sends data response: <A1|0054{"jsonrpc":"2.0","result":"1234567890123456","id":7}6D> → Host sends NAK (e.g., LRC error): <-1|8> ← EMV Core sends data response (retry): <A1|0054{"jsonrpc":"2.0","result":"1234567890123456","id":7}6D> → Host sends ACK: <+1> ``` *** ## Data frame **Example:** ``` <A1|0065{"jsonrpc":"2.0","method":"GetKioskID","params":{},"id":7}5C> ``` **Structure:** `<A[Frame-ID]|[Length][Data][LRC]>` | Field | Description | | :- | :- | | `<` | Start of frame | | `>` | End of frame | | `A` | Protocol version A; fixed value | | `[Frame-ID]` | ID of the frame: `0` or `1`, toggled by the sender on every new frame. On retry (after NAK or timeout), Frame-ID stays the same. ACK/NAK use the same Frame-ID. | | `[Length]` | 4 decimal digits: length of the `[Data]` field in bytes | | `[Data]` | Higher-level data being transported, typically a JSON-RPC message | | `[LRC]` | 2-character hex LRC (XOR of all bytes from `<` through the last byte of `[Data]`) | ### LRC and length calculation example ``` Message: <A1|0065{"jsonrpc":"2.0","result":"4207012624000108","id":6}63> Part for LRC: <A1|0065{"jsonrpc":"2.0","result":"4207012624000108","id":6} Hex: 3C 41 31 7C 30 30 36 35 7B 22 6A 73 6F 6E 72 70 63 22 3A 22 32 2E 30 22 2C 20 22 72 65 73 75 6C 74 22 3A 22 34 32 30 37 30 31 32 36 32 34 30 30 30 31 30 38 22 2C 20 22 69 64 22 3A 36 7D LRC: 63 Length: 65 bytes → encoded as "0065" ``` *** ## ACK frame Sent to acknowledge a successfully received and validated Data Frame. **Examples:** `<+0>`, `<+1>` **Structure:** `<+[Frame-ID]>` The `[Frame-ID]` matches the Data Frame being acknowledged. *** ## NAK frame Sent when the receiving side fails to parse a Data Frame. **Examples:** `<-0|1>`, `<-1|7>` **Structure:** `<-[Frame-ID]|[Err]>` | Error Code | Meaning | | :- | :- | | `0` | Unspecified | | `1` | Unsupported protocol (first byte after `<` is not `A`) | | `2` | Length field invalid (contains non-digits) | | `3` | Length field too large | | `4` | Data field invalid (not JSON-RPC) | | `5` | LRC field invalid (characters not hex A-F, 0-9) | | `6` | LRC wrong | | `7` | ETX invalid | | `8` | Timeout: frame not fully received after timeout expired | The transmitting party does not change its behavior based on the error codes; they are for debugging only. *** ## Protocol rules The datalink layer follows these timing and sequencing rules: * ACK/NAK are expected within **30 milliseconds**. * If ACK is not received, or if a NAK is received, the sending party may resend the frame with the same Frame-ID. * While waiting for ACK/NAK, the sending party must not send another frame. * When receiving a frame: if the first bytes are not `<A0` or `<A1`, do not send a NAK. Instead, keep reading until receiving a valid start of frame. # Firmware & Configuration Updates Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-firmware-updates You can update the cashless reader firmware and configuration: * **Remotely:** via Nayax Core or OTI Terminal Management System (TMS) * **Locally:** from a Windows PC using the UNO-8 Manager ## Remote update from Nayax Core ### Update reader (POS) firmware <Steps> <Step title="Select the required machine" /> <Step title="Select actions | update device version" /> <Step title="Select the main requested FW version"> Select **EMV Core v1.x**. </Step> <Step title="Select the POS requested FW version"> Select the required firmware: * **For UNO-mini:** * RTOS SDK firmware starts with `EMVSC_` (e.g., `EMVSC_v071652`) * The first RTOS SDK version is named `EMVS_v071558_ec` * Linux or Android SDK firmware starts with `EMVS_` * If more than one firmware is available for your device, take the latest one. <Warning> RTOS SDK v1.0 should stay on firmware `EMVSC_v071652.oef`. Don't upgrade it to `EMVSC_v071749`, the firmware released for SDK v1.5. </Warning> <Frame> <img /> </Frame> </Step> <Step title="Select apply"> This adds the action to the Queue. </Step> </Steps> ### Reader (POS) kernel configuration The kernel configuration is automatically selected by Nayax Core based on Country, Billing Provider, and Device type. Follow these steps to trigger the update: 1. Ensure the correct **Country** is set in the machine's General settings. 2. Ensure the correct **Billing Provider** is set in the machine's Payment settings. 3. Select **Actions | Reboot device** to initiate a device power-up. 4. Wait 5 to 10 minutes for the device to receive its kernel configuration, then verify in the **Embedded Advanced** section under **POS Configuration Version Name**. Expected configuration names: | Country | Billing Provider | POS Config Version Prefix | Example | | :- | :- | :- | :- | | USA | Heartland Nayax EMV | `HTL_` | HTL\_29 | | Canada | CityCardPayment (Nuvei) | `NUV_` | NUV\_16 | | Europe, UK | Credorax (Finaro/Shift4) | `FIN_` | FIN\_18 | | Other countries | Stubb billing (test only) | `FIN_` | FIN\_18 | ### Machine configuration To push a new configuration to the device: <Steps> <Step title="Update a machine attribute"> Open the **Embedded** or **Embedded Advanced** section and update the relevant attribute. <Frame> <img /> </Frame> </Step> <Step title="Press save"> This adds the changed attributes to the Queue. <Note> Any attribute change causes a complete update of all machine attributes. </Note> </Step> </Steps> *** ## Remote update from the TMS ### Update reader firmware 1. Log in to OTI TMS and select the **Terminals** tab. 2. Select the terminals you wish to update. 3. Open the **Command builder**. 4. Select the **SAT\_PROG** command. 5. Select the firmware file (`*.Oef`), found in `.\Firmware and Configuration`. 6. Press **Send** and wait for the process to complete, or use **Add Command to batch** for additional commands. <Frame> <img /> </Frame> ### Update reader configuration Follow the process above, but use: * Command: **SAT\_CONFIG** * Configuration file: For UNO-8/PLUS, use a `*.zip` configuration pack (e.g., `EVO_UNO8_135.zip`). * SDK configuration files are in `.\Firmware and Configuration`. After updates are complete, send the **GET\_VERSIONS** command so all changes are reflected in the TMS. *** ## Local update from a Windows PC ### UNO-8 and UNO-mini 1. Install **UNO-8 Manager v4.0** or above from the SDK: `.\Utilities\UNO-8 Manager` folder. 2. Connect your reader to the PC. ### Update firmware 1. Open UNO-8 Manager and select the **Upgrade FW** tab. 2. Select the firmware file (`.\Firmware and Configuration`). 3. Press **Upgrade** and wait for the process to complete. ### Update configuration <Steps> <Step title="Open UNO-8 manager"> Select the **File System** tab. <Frame> <img /> </Frame> </Step> <Step title="Navigate to the CONFIG folder"> Open Windows File Explorer and navigate to the Reader `CONFIG` folder (e.g., `.\Firmware and Configuration\Reader Configuration\USA\CONFIG`). </Step> <Step title="Drag the configuration files"> Drag the 3 configuration files from File Explorer into the `S:\CONFIG` folder in UNO-8 Manager. <Frame> <img /> </Frame> </Step> <Step title="Delete the previous configuration file"> Right-click the old file and select **Delete file**. <Frame> <img /> </Frame> </Step> <Step title="Reset the device"> <Frame> <img /> </Frame> </Step> </Steps> # Get Started Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-get-started Verify your hardware and build requirements, install the reader firmware, and obtain the Device ID needed for terminal registration. ## Requirements ### Hardware Your setup requires the following hardware: | Requirement | Details | | :- | :- | | **Device connection** | USB HID or UART TTL | | **Memory** | Minimum 64 KB RAM (configurable for smaller systems) | | **Reader power** | 5–12 VDC; 0.7 W idle, 3 W peak | ### Network requirements The host platform must support IPv4 TCP networking with the following characteristics: * IPv4 TCP sockets only * Up to 3 sockets in parallel * DNS resolution * Network status indication * Client only (no server functionality needed) * Low latency of sending and receiving packets (up to 10 ms) * **Socket usage:** * 1 constantly open socket exchanging small amounts of data (Keep-alive) every 2–30 minutes. May receive data at any moment. * 2 short-lived sockets (few seconds, one or more request/response cycles), which may work in parallel. * Download of 1.5 MB at a time; upload of \~1 MB at a time, through a single socket in chunks of 1.5 KB. #### Transport Layer * The channel between EMV Core and Host is either a Serial or a USB channel. * Messages should be sent without breaks between the bytes (RS-232/TTL) or blocks (USB). * A break in the sequence indicates message completion. A break is defined as 11 ETU on RS-232/TTL: * 1.15 ms at 9600 BAUD * 0.1 ms at 115200 BAUD ### Build system The host sample code requires: | Requirement | Details | | :- | :- | | **Compiler** | GCC 4.8+ or Clang 3.5+ with C99 support | | **Build Tools** | GNU Autotools (`autoconf`, `automake`, `libtool`) | | **Operating System** | Linux (primary), or other systems with platform layer implementation | | **Dependencies** | POSIX threads (`pthread`) for the Linux reference platform implementation | <Note> Use the sample host implementation included with the SDK rather than writing one from scratch. </Note> ## SDK delivery The SDK package is organized into three top-level folders: ```text theme={null} SDK Package/ ├── Linux Sample Application/ Portable C sources and demo application │ ├── ecod_sdk/ Core SDK headers and sources │ │ ├── platform/ Platform abstraction layer │ │ ├── src/ SDK implementation │ │ └── include/ Internal and public headers │ └── demo/ Example demo application ├── Firmware and Configuration/ Reader firmware and config files │ ├── Reader Firmware/ EMV Core FW file (EMVSC_v0xxxxx.oef) │ └── Reader Configuration/ Regional configuration files └── Utilities/ └── UNO-8 Manager/ Tool for local firmware and configuration updates ``` ### EMV Core communication protocols The EMV Core FW running on the UNO Reader automatically adapts to two protocols based on the host application: | Protocol | Used By | | :- | :- | | JSON with Datalink wrapper | Linux Sample Application (Portable C code) | | Low-level TLV reader protocol | UNO-8 Manager tool | <Warning> When switching from one protocol to another, you must restart the UNO Reader. </Warning> ## Firmware installation on UNO-mini ### EMV Core installation The EMV Core module is provided with the UNO Reader firmware. * **First-time installation** is performed using the **UNO-8 Manager**. * **Future updates** may be done remotely using the Nayax Terminal Management System (TMS). The firmware file (`EMVSC_v0xxxxx.oef`) can be found in the SDK `Firmware and Configuration\Reader Firmware` folder. <Warning> The Reader must be registered to the Nayax Core system. If it is not registered, you will not be able to complete payment transactions. To register your device, provide its Device ID (Reader serial number) to your Nayax account manager. </Warning> ## Getting a device ID The Kiosk ID is the Reader Serial Number (SN). Obtain it by: **a) Reading the SN from the back of the reader:** scan the barcode to prevent errors. **b) Using the EMV Core Test application on Linux:** 1. Run the Linux test application. 2. Select option **8** and press **Enter** to display the Device ID. <Note> Keep a record of your Device ID. You will need to provide it to your Nayax account manager for terminal registration before processing live transactions. </Note> # Integration Guide Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-integration-guide Use this page to configure serial communication, set up threads and callbacks, handle errors, and tune SDK settings for the EMV Core RTOS SDK. <Note> Check device status regularly, even when not performing transactions, to keep the UI in sync and surface error states. You cannot call any SDK API from within a callback. </Note> ## Serial interface configuration The SDK supports two serial communication modes. Select the one that matches your hardware connection. ### UART mode (default) Connect the UNO-mini via RS-232/TTL serial. Configure the device path and baud rate in the platform layer to match your hardware. ```c theme={null} // In platform/linux/ecod_platform_linux.c // Comment out USE_HID_INTERFACE to enable UART mode // #define USE_HID_INTERFACE // Linux reference implementation settings: // Device: /dev/ttyUSB0 // Baud: 115200 // Data bits: 8, Stop bits: 1, Parity: None ``` ### HID mode Connect the UNO-mini via USB HID. Each 64-byte report uses the first byte as a length indicator; remaining bytes carry the actual data. ```c theme={null} // In platform/linux/ecod_platform_linux.c #define USE_HID_INTERFACE // Linux reference implementation settings: // Device: /dev/hidraw0 // Report size: 64 bytes // First byte contains actual data length ``` ## Threading requirements The SDK requires dedicated background threads for communication. When `EC_USE_DATALINK_PROTOCOL=1`, two threads are required: ```c theme={null} #include <pthread.h> #include <unistd.h> volatile int keep_running = 1; // Thread 1: Datalink layer maintenance (serial I/O, framing, ACK/NAK) void* maintenance_thread(void* arg) { while (keep_running) { EcodSdk_Maintain(); usleep(1000); // 1ms sleep recommended } return NULL; } // Thread 2: JSON-RPC message processing (when EC_USE_DATALINK_PROTOCOL enabled) void* message_thread(void* arg) { while (keep_running) { // Process one message, wait up to 100ms if queue empty EcodSdk_ProcessMessages(100); } return NULL; } int main() { if (!EcodSdk_Init()) { printf("Failed to initialize SDK\n"); return 1; } // Register callbacks before starting threads EcodSdk_Register_TransactionComplete_Callback(on_transaction_complete); EcodSdk_Register_ReaderEvent_Callback(on_reader_event); // Start maintenance thread (required) pthread_t maintain_tid; pthread_create(&maintain_tid, NULL, maintenance_thread, NULL); // Start message processing thread (required when EC_USE_DATALINK_PROTOCOL=1) pthread_t message_tid; pthread_create(&message_tid, NULL, message_thread, NULL); // Your application logic here keep_running = 0; pthread_join(maintain_tid, NULL); pthread_join(message_tid, NULL); return 0; } ``` <Note> When `EC_USE_DATALINK_PROTOCOL` is disabled, only the maintenance thread is needed. </Note> ## Callback registration All SDK operations are asynchronous. Register callbacks before initiating operations: ```c theme={null} // Transaction completion callback — called when payment finishes void on_transaction_complete(emvCorePaymentResponse* resp) { printf("Transaction %s: %s\n", resp->is_transaction_approved ? "approved" : "declined", resp->transaction_reference); // Copy any data you need — resp is only valid during callback } // Reader display events (prompts shown to customer) void on_reader_event(uint8_t msg_index, char* line1, char* line2) { printf("Reader: %s / %s\n", line1, line2); } // Token operation completion void on_token_response(emvCoreGetTokenResponse* resp) { if (resp->status == emvCoreTransStatus_OK) { printf("Token: %s\n", resp->card_token); } } // Incremental authorization response (for variable-amount sessions, e.g. EV chargers) void on_incremental_auth(emvCorePaymentResponse* resp) { printf("Incremental auth: %s\n", resp->is_transaction_approved ? "approved" : "declined"); } // Register all callbacks EcodSdk_Register_TransactionComplete_Callback(on_transaction_complete); EcodSdk_Register_ReaderEvent_Callback(on_reader_event); EcodSdk_Register_GetTokenResponse_Callback(on_token_response); EcodSdk_Register_IncrementalAuthorizationResponse_Callback(on_incremental_auth); ``` ## Error handling Check return values and implement proper error handling: ```c theme={null} EC_RET result = EcodSdk_PreAuthorize(¶ms); if (result != EC_RET_OK) { switch (result) { case EC_RET_GENERAL_ERROR: printf("General error\n"); break; case EC_RET_MEMORY_ERROR: printf("Memory allocation failed\n"); break; case EC_RET_PARSING_ERROR: printf("Failed to parse response\n"); break; case EC_RET_COMM_ERROR: printf("Communication error with device\n"); break; case EC_RET_NEGATIVE_RESP: printf("Device returned error response\n"); break; default: printf("Unknown error: %d\n", result); } } // Also check device status before operations EC_STATUS status; if (EcodSdk_GetStatus(&status) == EC_RET_OK) { switch (status) { case EC_READY: /* Ready for transactions */ break; case EC_TRANSACTION: /* Transaction in progress */ break; case EC_UNCONFIRMED: /* Pending confirmation */ break; case EC_NO_EMVCORE: /* Device not connected */ break; case EC_NO_READER: /* Reader not connected */ break; case EC_DISABLED: /* Device disabled */ break; default: break; } } ``` ## Configuration ### Memory management Configure the memory allocation strategy in `ecod_sdk_configs.h`: ```c theme={null} // Heap allocation (recommended for desktop/server applications) #define EC_USE_HEAP 1 // Static allocation (recommended for embedded systems) #define EC_USE_HEAP 0 ``` ### Buffer sizes Buffer sizes are defined in `ecod_sdk_setup.h`: ```c theme={null} // JSON-RPC communication buffer (default: 2048) // Affects maximum message size; socket data uses hex encoding (2x expansion) #define EC_MAX_BUFFER_SIZE 2048 // Per-socket receive buffer (default: 4096) #define EC_SOCKET_BUFFER_SIZE 4096 // Maximum concurrent socket connections (default: 10) #define EC_MAX_SOCKETS 10 ``` <Note> JSON-RPC overhead reduces usable payload by \~64 bytes. Socket data is hex-encoded, so effective throughput is halved. </Note> ### Timeouts and timing Configure communication timeouts in `ecod_sdk_configs.h`: ```c theme={null} // Incomplete frame timeout (default: 500ms) #define EC_INCOMPLETE_FRAME_TIMEOUT_MS 500 // ACK timeout (default: 1000ms) #define EC_ACK_TIMEOUT_MS 1000 // Socket idle timeout (default: 10 seconds) #define EC_SOCKET_IDLE_TIMEOUT_MS 10000 ``` ### Logging Enable debug logging during development: ```c theme={null} // Set log level (default is EC_LOG_LEVEL_INFO) EcodSdk_SetLogLevel(EC_LOG_LEVEL_DEBUG); // Available log levels: // EC_LOG_LEVEL_ERROR (1) — Only errors // EC_LOG_LEVEL_INFO (3) — Errors + informational messages // EC_LOG_LEVEL_DEBUG (5) — Errors + info + debug details // EC_LOG_LEVEL_TRACE (7) — All messages including protocol traces // Log modules in debug output: // "SERIAL" — Serial communication and framing // "JRPC" — JSON-RPC protocol messages // "NET" — Network bridge operations // "SOCK" — Socket management ``` ## Integration troubleshooting ### Device not detected Use these commands to check device visibility and permissions: ```bash theme={null} # Check if device is connected ls -la /dev/ttyUSB* /dev/hidraw* # Check permissions sudo chmod 666 /dev/ttyUSB0 # or /dev/hidraw0 # Add user to dialout group (requires logout/login) sudo usermod -a -G dialout $USER ``` ### Serial communication failures Check the following common causes: * Verify correct device path (`/dev/ttyUSB0` vs `/dev/hidraw0`) * Check if another process is using the serial port * Ensure proper HID/UART mode selection in platform code * Verify baud rate settings match device configuration ### Threading issues Check the following when threads are not behaving as expected: * Ensure the maintenance thread is running continuously * Check for mutex deadlocks in callback functions * Avoid blocking operations in callback handlers * Verify proper thread cleanup on application exit ### Memory issues Check the following when experiencing memory-related failures: * Monitor buffer overflow with `EC_MAX_BUFFER_SIZE` * Check for memory leaks if using heap allocation * Ensure proper cleanup of SDK resources * Consider static allocation for embedded systems ### Debug logging Enable comprehensive logging to diagnose issues: ```c theme={null} EcodSdk_SetLogLevel(EC_LOG_LEVEL_DEBUG); // Example debug output: // [DEBUG] SERIAL: Opening /dev/ttyUSB0 // [DEBUG] JRPC: Sending frame: <A0|0042{"method":"preauth",...}E3> // [DEBUG] NET: Socket 1 connected to 192.168.1.100:8080 // [DEBUG] SOCK: Received 1024 bytes on socket 1 ``` ### Performance tuning Apply these adjustments to improve SDK responsiveness: * Keep maintenance thread sleep interval at 1 ms * Use static allocation for memory-constrained environments * Minimize callback processing time * Configure appropriate buffer sizes for your use case * Consider network bridge settings for socket-heavy applications ## Migration checklist (from SDK v0.9) If upgrading from SDK v0.9, apply the following changes to your integration: 1. **Update `emvCorePaymentParameters` usage:** * Remove `fee_cents` and `currency_code` fields. * Add `is_final_amount` and `additional_receipt_data` as needed. `is_deferred` is reserved for future use (RFU). 2. **Handle new Status code:** Check for `EC_DISABLED` in status handling. 3. **Dual-thread mode:** If using datalink protocol, implement a second thread calling `EcodSdk_ProcessMessages()`. 4. **Update response handling:** Take advantage of new fields in `emvCorePaymentResponse`. # JSON-RPC API Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-json-rpc-api While integrators should use the [C API](/docs/integrate-pos-device/emv-core/rtos/rtos-c-api) provided by `libecodsdk`, the JSON-RPC API is used by the EMV Core logs and is very useful during integration debugging. ## Protocol rules ### Syntax rules All commands follow these formatting conventions: * All commands and events use the **JSON-RPC 2.0** protocol with named parameters. * All commands and events require a response, **except** `log()` and `ReaderMessageEvent()`, which have no `id`. * Message format: ```json theme={null} {"jsonrpc":"2.0", "method":"CommandName", "params": {"param1":value1, "param2":value2}, "id":idNumber} ``` * Use a different `id` for each command (e.g., a running counter) to aid synchronization. * An illegal command returns a `"Not existing command"` response from the EMV Core. ### Send & receive **Sending a message:** 1. Send the JSON-RPC message. 2. Wait for the JSON-RPC response. 3. Once data starts arriving, wait for a complete JSON (all parentheses closed), or a 1-second timeout. **Receiving a message (loop):** 1. Wait for incoming data. 2. Once data starts arriving, wait for complete JSON, or a 1-second timeout. 3. Parse and process the message as JSON-RPC. 4. Send a JSON-RPC response (no response needed for `ReaderMessageEvent`; no response is sent for `socket_data_received`). ## Payment flow A typical payment session follows this sequence: 1. POS sends `PreAuthorize`. 2. EMV Core responds (after card tap and authorization) with `TransactionComplete`. 3. POS sends either `ConfirmTransaction` (product delivered) or `VoidTransaction` (otherwise). 4. POS may send `CancelTransaction` at any time; `TransactionComplete` will return with status `Cancelled`. **Important notes:** * Always close a `PreAuthorize` session with Confirm or Void/Cancel. An unclosed session will be reversed by the processor after some time, which may incur higher fees. * Once `ConfirmTransaction` has been acknowledged by the EMV Core, do not re-send it. * To force synchronous processing, set `PAYMENT_SVC_SYNCHRONOUS=1`. <Frame> <img /> </Frame> <Frame> <img /> </Frame> ### Closed loop (CLP) flow For pre-paid cards, EMV Core immediately returns the card UID to the host application via `TransactionComplete` without sending to the Nayax server. <Frame> <img /> </Frame> ## Commands ### PreAuthorize Pre-authorize a card with the payment processor. The EMV Core waits for a card, reads it, processes it, then sends `TransactionComplete`. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"PreAuthorize", "params": {"amount":150, "currency":840, "productid":5, "continuous":false, "timeout":60}, "id":801} << {"jsonrpc": "2.0", "result": true, "id": 801} ``` **Parameters:** | Parameter | Description | | :- | :- | | `amount` | Amount to charge in full units (dollars, not cents) | | `currency` | ISO 4217 code (e.g., 840 = USD) | | `productID` | Optional: product ID selected by consumer, saved in server for reports | | `continuous` | If `true`, poll for card restarts immediately after timeout; `TransactionComplete` returns `PollContinuous` | | `timeout` | Maximum seconds to wait for a card. Returns `Timeout` status if no card arrives. | *** ### ConfirmTransaction Confirms the pre-authorization so the payment can settle. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"ConfirmTransaction", "params": {"amount":150, "productID":1, "transaction_Reference":"8453F02DFD33413EBA7733"}, "id":616386422} << {"jsonrpc":"2.0", "result":true, "id":616386422} ``` **Parameters:** | Parameter | Description | | :- | :- | | `Amount` | Actual amount to charge in minor units (cents) | | `transactionReference` | `TransactionDbID` from the `TransactionComplete` event | | `productID` | Optional: product ID, saved in server for reports | | `terminal_data` | Optional: `terminal_data=(key1=value1,key2=value2)`; passed to PSP in online requests | *** ### VoidTransaction Void a transaction in two cases: * Transaction was pre-authorized but not confirmed, to release reserved funds. * Transaction was completed but needs to be canceled (e.g., product not vended). **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"VoidTransaction", "params": {"transaction_Reference":"8453F02DFD33413EBA77334B696D5991"}, "id":803} << {"jsonrpc":"2.0", "result":true, "id":803} ``` | Parameter | Description | | :- | :- | | `transactionReference` | Transaction reference from the `TransactionComplete` event | `VoidTransaction` does not return an event. Check voided transaction status in TMS by searching for `Cancel` and `Cancel Declined` statuses. *** ### CancelTransaction Cancels the last transaction started by `PreAuthorize`: * **Card not yet presented:** Stops the reader poll sequence. The display shows "Cancelling"; the host application must update the display. * **Card already presented but not completed:** Returns `CannotCancel`. `TransactionComplete` arrives after the online authorization result. * **Transaction already completed:** Returns `NoTransaction`. * For `CannotCancel` or `NoTransaction`, use `VoidTransaction` to undo a successful transaction. * If `TransactionComplete` returns `Decline`, no `VoidTransaction` is needed. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"CancelTransaction", "id":802} << {"jsonrpc":"2.0", "result":true, "id":802} ``` *** ### GetCardToken Returns a card token without performing a payment transaction. Returns `CardTokenReceived` event. * For payment cards: returns a base64 card token. * For CLP (e.g., Mifare) cards: returns the card UID. **Example:** ```json theme={null} >> {"jsonrpc":"2.0","method":"GetCardToken","params":{"continuous":false,"timeout":60},"id":5820} << {"jsonrpc":"2.0", "result":true, "id":5820} ``` | Parameter | Description | | :- | :- | | `timeoutSeconds` | Maximum seconds to wait. Maximum value: 60 seconds. | **Notes:** * Requires tag `DFA155` added to the reader's Clear results tag list. * CLP card UID is returned only when `CLP_MIFARE_ENABLED=2`. *** ### GetStatus Returns the current EMV Core status. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"GetStatus", "id":805} << {"jsonrpc":"2.0", "result":"Ready", "id":805} ``` **Result values:** `{NotReady, Ready, PaymentTransaction, Update, NoReader, NoTerminalId}` *** ### ShowMessage Shows a message on the OTI Saturn Reader display. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"ShowMessage", "params": {"line1":"Please Select", "line2":"Your Product"}, "id":901} << {"jsonrpc":"2.0", "result":true, "id":901} ``` | Parameter | Description | | :- | :- | | `line1` | Text for line 1 of the reader display (max 16 characters) | | `line2` | Text for line 2 of the reader display (max 16 characters) | *** ### GetVersion Returns the version of components in the system. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"GetVersion", "params":{"component":"Reader"}, "id":902} << {"jsonrpc":"2.0", "result":"S8_v054105", "id":902} ``` | Parameter | Values | | :- | :- | | `component` | `otiKiosk` (for EMV Core version) or `Reader` | *** ### GetKioskID Returns the Kiosk identification number. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"GetKioskID", "params":{}, "id":902} << {"jsonrpc":"2.0", "result":"00130226001C9C69", "id":902} ``` *** ### GetAttribute Returns the value of an EMV Core configuration attribute. **Example:** ```json theme={null} >> {"jsonrpc":"2.0","method":"GetAttribute", "params": {"Key":"PRE_AUTH_AMOUNT"}, "id":12} << {"jsonrpc":"2.0", "result":"150", "id":12} // If attribute not found: << {"jsonrpc":"2.0", "error":{"code":-1, "message":"Get attribute key not found"}, "id":12} ``` *** ## Events ### TransactionComplete Sent by the EMV Core when a transaction completes (success or failure). Contains all data needed for receipts and dispute resolution. **Note:** If no acknowledgment is received, the EMV Core resends up to 2 times (3 total). If still no answer, it assumes the message was received and does not cancel the transaction. **Example (open loop):** ```json theme={null} << {"jsonrpc":"2.0", "method":"TransactionComplete", "params": { "status":"OK", "errorCode":0, "errorDescription":"", "transactionId":"6856770806", "authorizationDetails": { "AmountAuthorized":4.50, "AmountRequested":4.50, "AuthorizationCode":"AuthOK", "PartialPan":"453997******4280", "CardType":"Visa Credit", "IsTransactionApproved":true, "eReceipt":"https://wee.ai/tr/...", "Card_ID":"2026-02-10 10:15:32.057|6|3", "Card_Balance":0.00, "RRN":"260210081532", "TransactionDbID":"6856770806", "Transaction_Referance":"6856770806", "CardToken":"kC7WxiEKKUMw/lNddlT5MiMGX/uvea4/aEtjOljLNlY=", "Additional_Parameters": { "hwSerial":"4207012624000108","SiteId":"6","EntryMode":"4", "MachineAuTime":"2026-02-10T10:15:32.057", "NayaxTransactionId":"6856770806" }}}, "id":701} >> {"jsonrpc":"2.0", "result":true, "id":701} ``` **Parameters:** | Field | Description | | :- | :- | | `status` | `OK`, `Declined`, `Error`, `Timeout`, `Cancelled`, `LocalCLP` | | `errorCode` | Numeric error code (0 = no error; positive = PSP errors; negative = OTI system errors) | | `errorDescription` | Technical error description for developers; do not display to users | | `transactionId` | Use for `ConfirmTransaction` or `VoidTransaction` | **Authorization Details fields:** | Field | Description | | :- | :- | | `AmountAuthorized` | Amount approved in major units (may be lower for prepaid cards) | | `AmountRequested` | Amount requested in major units | | `Authorization_Code` | PSP transaction identifier for approved transactions | | `PartialPan` | Masked PAN (first 6 and last 4 digits) | | `CardType` | Card scheme (MasterCard, Visa, Amex, etc.) or closed-loop card technology | | `IsTransactionApproved` | Boolean approval status | | `eReceipt` | URL for Nayax eReceipt | | `Card_ID` | Mifare UID when `CLP_MIFARE_ENABLED=2` | | `RRN` | Processor reference number for approved transactions | | `CardToken` | Base64 token for payment cards; card UID for closed-loop cards | | `Additional_Parameters` | Optional fields for Nayax External Settlement: `SiteId`, `EntryMode`, `MachineAuTime`, `NayaxTransactionId` | **Closed-loop card types:** | Card Type | Description | | :- | :- | | `Type A` | ISO/IEC 14443 Type A | | `Type B` | ISO/IEC 14443 Type B | | `Mifare` | Mifare | | `Mifare-U` | Mifare Ultralight | | `DesFire` | Mifare DESFire | | `Mifare-P` | Mifare Plus | | `Vicinity` | ISO/IEC 15693 | | `Vicinity-P` | ISO/IEC 15693 HID iClass | | `Felica` | FeliCa JIS X 6319-4 | | `CLP` | Unknown closed loop | *** ### CardTokenReceived Sent when `GetCardToken` is completed. **Example:** ```json theme={null} >> {"jsonrpc":"2.0", "method":"CardTokenReceived", "params": { "status":"OK", "errorCode":0, "errorDescription":"", "CardToken":"WSAr79nKPywW3INXrWvr6IL3vgTgSJlwZBgseKDmMHM=", "PartialPan":""}, "id":702} ``` *** ### ReaderMessageEvent Sent when the display message on the Saturn Reader changes. Use this to synchronize the kiosk application with reader state. **Note:** Requires the reader to be configured to send External Display message events (Tag DF 46 with index 04). This event does **not** require acknowledgment. **Example:** ```json theme={null} << {"jsonrpc":"2.0", "method":"ReaderMessageEvent", "params": {"index":36, "line1":"Authorizing", "line2":"Please wait"}} ``` **Message Index:** | Hex | Decimal | Message | LED | | :- | :- | :- | :- | | 0x01 | 1 | Present card | LED1 On | | 0x11 | 17 | Welcome | LED1 Blink | | 0x05 | 5 | Please present one card only | — | | 0x33 | 39 | Read error — Please try again | — | | 0x24 | 36 | Authorizing — Please wait | Chasing LEDs | | 0x06 | 6 | Approved | — | | 0x09 | 9 | Not Approved | — | | 0x30 | 30 | Timeout — No Card | — | | 0x26 | 38 | Insert Card | — | | 0x0A | 10 | Terminated | — | | 0x0B | 11 | Contactless fail — PIN required | — | | 0x0C | 12 | See Phone | — | | — | 255 | Declined | — | *** ## Network protocol ### Socket API #### socket\_connect Opens a TCP socket to a remote host. ```json theme={null} >> {"jsonrpc":"2.0", "method":"socket_connect", "params": {"address":"tms.otiglobal.com", "port":80, "timeout_sec":10}, "id":1426} << {"jsonrpc":"2.0", "result":2, "id":1426} ``` Returns a positive socket ID on success, or a negative error number on failure. #### socket\_send Sends data in binary form. Blocks until data is sent. `hex_data` is a hex-encoded string (2 ASCII characters per byte). ```json theme={null} >> {"jsonrpc":"2.0", "method":"socket_send", "params": {"socket_id":2, "hex_data":"474554202F..."}, "id":813} << {"jsonrpc":"2.0", "result":165, "id":813} ``` #### socket\_recv Receives data from a socket. Returns hex-encoded data. ```json theme={null} >> {"jsonrpc":"2.0", "method":"socket_recv", "params": {"socket_id":16, "max_bytes":99}, "id":1644} << {"jsonrpc":"2.0", "result":"7B2243757272656E74...", "id":1644} ``` #### socket\_close ```json theme={null} >> {"jsonrpc":"2.0","method":"socket_close","params":{"socket_id":2}, "id":815} << {"jsonrpc":"2.0", "result":0, "id":815} ``` #### socket\_data\_received (event) Sent by the host when data is available on an open socket. The device does not respond. ```json theme={null} << {"jsonrpc":"2.0","method":"socket_data_received", "params":{"socket_id":2, "number_of_bytes":458}} >> [no response] ``` *** ### Network management APIs #### network\_get\_status Returns `"on"` if network is available. ```json theme={null} >> {"jsonrpc":"2.0", "method":"network_get_status", "id":811} << {"jsonrpc":"2.0", "result":"on", "id":811} ``` #### network\_get\_info Returns network channel, operator, technology (3G/4G), signal strength, and BER. #### resolve\_host\_name DNS resolution: returns list of IP addresses and TTL. ```json theme={null} >> {"jsonrpc":"2.0", "method":"resolve_host_name", "params": {"host_name":"httpbin.org"}, "id":812} << {"jsonrpc":"2.0", "result": {"addresses":"44.217.225.103, 107.23.72.23", "TTL":10}, "id":812} ``` # Linux Sample Application Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-linux-sample-app The Linux Sample Application ships with the RTOS SDK as portable C (C99) source code. It provides a working reference implementation for the platform abstraction layer and a demo application for testing the SDK. The sample code was developed and tested on Ubuntu (x86\_64). When porting to other operating systems, you must adapt the Platform Abstraction Layer. See [Platform Porting](/docs/integrate-pos-device/emv-core/rtos/rtos-platform-porting). **Notes:** * All source code is in standard C (C99). * Platform-specific code is under `platform/`. * It is highly recommended **not** to modify code outside the `platform/` folder. ## Directory structure The sample application sources are organized as follows: ``` ecod_sdk/ # Core SDK headers and sources platform/ # Platform abstraction layer src/ # SDK implementation include/ # Internal and public headers demo/ # Example / demo application ``` ## Build ### Get the sources Obtain the SDK package from your Nayax account manager and extract the `Linux Sample Application` folder. ### Install build dependencies (ubuntu linux) Run these commands to install the required tools: ```bash theme={null} sudo apt-get update sudo apt-get install build-essential automake ``` ### Build the SDK and demo The provided sources and demo are ready to build on Ubuntu Linux x86\_64 with GCC and automake: ```bash theme={null} autoreconf -fi # Generate autotools configuration ./configure # Configure build (respects CONFIGURE_FLAGS) make # Build SDK library and demo ``` The build generates static libraries and the demo binary. ### Clean build artifacts Use these targets to remove compiled output: ```bash theme={null} make clean # Remove build objects make maintainer-clean # Remove all generated files ``` ## Configuration options The SDK supports various build-time configurations through `ecod_sdk_configs.h`: ```c theme={null} // Memory allocation strategy #define EC_USE_HEAP 1 // Use malloc/free (0 = static allocation) // Protocol settings #define EC_USE_DATALINK_PROTOCOL 1 // Enable datalink framing with ACK/NAK #define EC_INCOMPLETE_FRAME_TIMEOUT_MS 500 // Timeout for incomplete frames #define EC_ACK_TIMEOUT_MS 1000 // Timeout waiting for ACK #define EC_ACK_MAX_RETRIES 0 // Max retransmissions on missing ACK // Network bridge settings #define EC_SUPPORT_LONG_LIVED_SOCKETS 1 // Support persistent connections ``` <Note> Computed defaults are in `ecod_sdk_setup.h`. Do not modify that file directly. </Note> ## Run the demo After building, run the included demo application to test the SDK: **Manual mode:** user selects operations using the keyboard: ```bash theme={null} ./demo/ecodSdkDemo ``` **Automatic mode:** performs a payment transaction in a loop: ```bash theme={null} ./demo/ecodSdkDemo --auto ``` In `--auto` mode, transactions run in a loop. If authorized, one out of two is confirmed and the other is voided, demonstrating both use cases. Review `demo/main.c` for example code and usage patterns. # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-overview The EMV Core RTOS SDK is a portable C99 library for adding EMV payment to MCU and RTOS-based hardware. Your application calls the SDK APIs; the SDK handles card reading, authorization, and server communication. <Note> This documentation covers SDK v1.0 for MCU and RTOS platforms. For the Android or Linux SDK, see [Android Installation](/docs/integrate-pos-device/emv-core/get-started/emv-core-android-installation) or [Linux Installation](/docs/integrate-pos-device/emv-core/get-started/emv-core-linux-installation). </Note> ## SDK highlights * **C99 source code** designed for embedded systems * **Complete EMV transaction processing**, including command handling and authorization * **Platform abstraction layer** to run on any RTOS without code changes * **Linux reference implementation** included with the SDK * **Example application** to test your setup quickly ## System overview The Nayax Embedded solution includes three elements: <Columns> <Card title="Cashless reader hardware"> The UNO-mini reader running EMV Core firmware, exposing a JSON Payment API and network socket interface. </Card> <Card title="SDK sample code"> C99 sample code implementing the network socket and payment API calls. </Card> <Card title="Nayax servers (Nayax Core)"> Cloud service for remote terminal management and transaction clearing. </Card> </Columns> <Frame> <img /> </Frame> ## Hardware and software architecture The UNO-mini reader running EMV Core connects to the Host platform (MCU/RTOS) via UART TTL or USB HID. <Frame> <img /> </Frame> <Frame> <img /> </Frame> ### Application layers Communication flows through the following layers: | Layer | Description | | :- | :- | | **Application Layer** | Your code calls SDK APIs (e.g., `EcodSdk_PreAuthorize()`) | | **JSON-RPC Layer** | Converts API calls to JSON-RPC messages with datalink framing | | **Serial Transport** | Sends framed messages via UART (`/dev/ttyUSB0`) or HID (`/dev/hidraw0`) | | **EMV Core Device** | Processes payment requests and returns responses | | **Callback System** | Async responses delivered via registered callbacks | ## Requirements summary | Requirement | Details | | :- | :- | | **Device connection** | USB HID or UART TTL | | **Minimum RAM** | 64 KB (configurable for smaller systems) | | **Reader power** | 5–12 VDC, 0.7 W idle / 3 W peak | | **Network** | IPv4 TCP sockets, DNS resolution, client-only | | **Compiler** | GCC 4.8+ or Clang 3.5+ with C99 support | ## Next steps <Columns> <Card icon="link" title="Get started" href="/docs/integrate-pos-device/emv-core/rtos/rtos-get-started"> SDK delivery, firmware installation, and obtaining your Device ID. </Card> <Card icon="link" title="Integration guide" href="/docs/integrate-pos-device/emv-core/rtos/rtos-integration-guide"> Threading, callbacks, error handling, and configuration. </Card> <Card icon="link" title="C API reference" href="/docs/integrate-pos-device/emv-core/rtos/rtos-c-api"> Complete C API function reference and key data types. </Card> </Columns> # Platform Porting Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-platform-porting The SDK is designed for portability across embedded platforms and operating systems. To port the SDK to a new platform, follow these steps. <Tip> Use the Linux reference implementation in `platform/linux/` as a working starting point. For RTOS-based platforms, map mutexes and events to your RTOS primitives (e.g., FreeRTOS `SemaphoreHandle_t`, Zephyr `k_mutex`). </Tip> ## Implement the platform layer ### Create the platform directory Create a new directory under `platform/` (e.g., `platform/my_platform/`) with two files: ### Platform types (`ecod_platform_types.h`) Define the platform-specific types used by the SDK: ```c theme={null} typedef /* platform-specific */ ecod_socket_t; // Socket handle typedef /* platform-specific */ ecod_mutex_t; // Mutex primitive typedef struct { /* platform-specific fields for a waitable event */ } ecod_event_t; ``` The Linux reference uses `pthread_mutex_t` for mutexes and a struct wrapping `pthread_mutex_t` + `pthread_cond_t` + `bool` flag for events. Adapt these to your platform's RTOS or OS primitives. ### Platform implementation (`ecod_platform_<name>.c`) Implement all functions declared in `ecod_sdk_platform.h`. They are grouped into these categories: ### Initialization Implement the startup function to allocate platform resources: ```c theme={null} // Called once at startup. Initialize platform resources (e.g., signal handling, log files). EC_SDK_STATUS ecod_platform_init(void); ``` ### Clock & timing Implement these functions to provide the SDK with a monotonic clock and blocking delay: ```c theme={null} // Return current time in milliseconds (must be monotonic / always increasing) u32 ecod_platform_get_tick_ms(void); // Blocking delay for the given number of milliseconds void ecod_platform_delay(u32 delay_ms); ``` ### Logging Implement these functions to route SDK log output to your platform's logging system: ```c theme={null} // printf-style log output, filtered by level and tagged with module name void ecod_log(EC_LOG_LEVEL level, const char* module, const char* format, ...); // Set the maximum log level that will be output void ecod_set_log_level(EC_LOG_LEVEL max_level); // Log a data buffer as hex (useful for protocol debugging) void ecod_log_buf(EC_LOG_LEVEL level, const char* module, const char* msg, u8* data, u32 data_len); ``` ### Memory (only when `EC_USE_HEAP` is enabled) Implement `malloc` and `free` wrappers when heap allocation is enabled: ```c theme={null} void* ecod_malloc(u32 size); void ecod_free(void* ptr); ``` ### Mutex Implement these functions using your platform's mutual-exclusion primitives: ```c theme={null} EC_SDK_STATUS ecod_mutex_init(ecod_mutex_t* out_mutex); void ecod_mutex_lock(ecod_mutex_t* p_mutex); void ecod_mutex_unlock(ecod_mutex_t* p_mutex); ``` ### Event Waitable signal used for inter-thread synchronization: ```c theme={null} EC_SDK_STATUS ecod_event_init(ecod_event_t* out_event); EC_SDK_STATUS ecod_event_clear(ecod_event_t* p_event); EC_SDK_STATUS ecod_event_wait(ecod_event_t* p_event, u32 timeout_ms); // 0xFFFFFFFF = infinite EC_SDK_STATUS ecod_event_signal(ecod_event_t* p_event); ``` ### Serial communication Implement these functions to handle raw serial or USB HID I/O: ```c theme={null} // Open and configure the serial port (UART or HID). Called once. bool ecod_serial_init(void); // Synchronous send. Returns number of bytes actually sent. u32 ecod_serial_send(u8* data, u32 length); // Receive up to max_length bytes, waiting up to timeout_ms. Returns bytes received. u32 ecod_serial_receive(u8* data, u32 max_length, u32 timeout_ms); ``` ### Network (only if using the network bridge) Implement these functions to give the SDK access to TCP sockets: ```c theme={null} EC_SDK_STATUS ecod_network_init(void); void ecod_network_cleanup(void); bool ecod_network_is_ready(void); EC_SDK_STATUS ecod_socket_connect(char* host, u16 port, u16 timeout_sec, ecod_socket_t* out_socket); EC_SDK_STATUS ecod_socket_close(ecod_socket_t socket); EC_SDK_STATUS ecod_socket_send(ecod_socket_t socket, u8* data, u32 data_len, bool last_part, u32* out_sent_data_len); EC_SDK_STATUS ecod_socket_recv(ecod_socket_t socket, u8* out_data, u32 max_size, u32* out_received_size); ``` ## Update the build system Modify `configure.ac` and `Makefile.am` to include your platform: ```makefile theme={null} # In ecod_sdk/Makefile.am if TARGET_MY_PLATFORM libecodsdk_a_SOURCES += platform/my_platform/ecod_platform_my_platform.c endif ``` ## Test the integration Use the demo application to verify functionality on your target platform: ```bash theme={null} ./demo/ecodSdkDemo ``` For detailed porting guidance, see `platform/ecod_sdk_platform.h`. # Error Handling & Troubleshooting Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/rtos/rtos-troubleshooting This page covers system-level issues: terminal registration, configuration, and log collection. For SDK-level integration issues (serial setup, threading, callbacks, memory), see [Integration Guide](/docs/integrate-pos-device/emv-core/rtos/rtos-integration-guide#integration-troubleshooting). When encountering errors or unexpected behavior, provide the following to Nayax support: 1. **Device ID** (Reader Serial Number) 2. **EMV Core FW version** in use 3. **EMV Core configuration file** 4. **EMV Core log files** 5. **Transaction data** (if applicable): date/time, amount, transaction ID, error received 6. **Reader configuration** (retrievable with the Saturn Management Utility) ## Log files The EMV Core saves information in log files for debugging purposes. Log files can be obtained by: 1. **Nayax Core**: Use the **Request Gtrace** action. 2. **TMS**: Send the `UPLOAD_LOGS` command. 3. **Locally via UNO-8 Manager**: * Select the **File System** tab. * Navigate to the `E:\LOG` folder. * Right-click the `*.log` files and select **Save As...** to save to your PC. <Frame> <img /> </Frame> ## Troubleshooting sequence When encountering an issue, work through these steps in order: 1. **Check SDK version**: Uninstall old versions and install the latest. 2. **Check and update configuration**: * EMV Core configuration * Reader configuration 3. **Verify correct registration**: * OTI TMS * Nayax Core * Note: Test terminals and live terminals require different registration. 4. **Try a transaction with a valid test card.** 5. **Ensure communication is not blocked by a firewall** or similar mechanism. ## Common problems ### Error code overview Error codes fall into two categories depending on their source: * **Positive error codes** (e.g., `99`): From the PSP system. * **Negative error codes** (e.g., `-997`): From the OTI system. Note: Negative error codes such as `-995 declined by reader` can also indicate an online decline from the PSP. *** ### Terminal registration issues **Symptom 1:** * Status = `Not ready` (visible in the test application "Get Status" button) * Error: `"Failed getting terminal operator …code: -997"` **Possible cause:** Terminal is not registered properly in TMS. **Suggested steps:** * Confirm your terminal ID appears in TMS under the correct operator; consult Nayax support if needed. * Check the EMV Core configuration file for: * `TMS_SVC_URL=tms.otiglobal.com` (for management from TMS) * `TMS_SVC_URL=tms-c.otiglobal.com` (for management from Nayax Core) *** **Symptom 2:** * Transaction ends with error: ``` Method TransactionComplete arrived with parameters: Declined '1' Invalid Device' {...} ``` **Suggested steps:** * Check the kiosk configuration file. Most common settings: ``` PAYMENT_SVC_URL=payment-nayax-p.otiglobal.com ``` * Verify the terminal ID is properly registered at Nayax backend; consult the Nayax support team. # SDK Methods & Functions Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/sdk-methods-functions/emv-core-apis The EMV Core SDK provides pre-certified EMV payment APIs for kiosk and point-of-sale (POS) developers. The SDK handles card reading, authorization, and server communication so you can focus on your application’s UI and business logic. This section guides you through using the SDK features. See the following pages for more information: <CardGroup> <Card icon="credit-card" title="Payment" href="/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1"> Integrate and manage payment functionality, including pre-authorization, transaction confirmation, and voids. </Card> <Card icon="server" title="Remote Management" href="/docs/integrate-pos-device/emv-core/sdk-methods-functions/remote-management"> Manage firmware updates, device configuration, and diagnostics to keep devices running smoothly. </Card> <Card icon="bell" title="Event Callbacks" href="/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks"> Get real-time updates on transaction status through the SDK's event callbacks. </Card> <Card icon="comment-dots" title="Reader Messages" href="/docs/integrate-pos-device/emv-core/sdk-methods-functions/reader-messages"> Handle and display the user-facing prompts and instructions the payment terminal sends. </Card> </CardGroup> # Event Callbacks Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks The SDK triggers event callbacks in the EMV Core SDK to notify the application of specific events during the transaction lifecycle. They enable developers to respond dynamically to changes in transaction status and system events. These callbacks provide real-time updates, keeping the SDK and the application in sync. These are the available callbacks. * [CardTokenReceived](#cardtokenreceived) * [IncrementalAuthorizationResponse](#incrementalauthorizationresponse) * [ReaderMessageEvent](#readermessageevent) * [SystemStatusChanged](#systemstatuschanged) * [TransactionComplete](#transactioncomplete) You can read a more detailed description of each Callback event in the sections below. *** ## `CardTokenReceived` This event is triggered after a card token is successfully retrieved. <Tabs> <Tab title="JSON"> Open loop example: ```json theme={null} {"jsonrpc":"2.0", "method": "CardTokenReceived", "params": {"status": "OK", "errorCode": 0, "errorDescription": "", "CardToken": "WSAr79nKPywW3INXrWvr6IL3vgTgSJlwZBgseKDmMHM=", "PartialPan": "", "CardType": "EMV"}, "id": 702} ``` Closed loop example: ```json theme={null} {"jsonrpc":"2.0", "method": "CardTokenReceived", "params": {"status": "LocalCLP", "errorCode": 0, "errorDescription": "", "CardToken": "73D0D1C5", "PartialPan": "", "CardType": "Type A"}, "id": 702} ``` **Parameters:** | Parameter | Description | | :- | :- | | `status` | Transaction result: `OK`, `Declined`, `Error`, `Timeout`, `Cancelled`, or `LocalCLP`. | | `errorCode` | Numerical error code. `0` when there is no error. | | `CardToken` | Card token. Base64 string for payment cards, or the card UID for closed loop (Mifare) cards. | | `PartialPan` | Masked PAN with the card account number's first six and last four digits. Empty for closed loop cards. | | `CardType` | Card scheme (for example, EMV, MasterCard, Visa). For closed loop cards, the card technology (for example, Type A, Mifare). | </Tab> <Tab title="Android"> ```java Java theme={null} void CardTokenReceived(TokenDetails tokenDetails); ``` Where `tokenDetails` has two fields: | Parameter | Description | | :- | :- | | `CardToken` | Base64 string for payment cards, or the card UID for closed loop (Mifare) cards. | | `CardType` | Card scheme (for example, EMV, MasterCard, Visa). For closed loop cards, the card technology (for example, Type A, Mifare). | </Tab> <Tab title="Linux"> ```c Linux theme={null} void LibOtiKiosk_Register_GetTokenResponse_Callback(GetTokenCb_t cb); ``` **Parameters:** **`cb`**: A callback function of type `void (*)(otiKioskGetTokenResponse* resp)`. This function is triggered automatically when a card token operation completes. The callback receives a pointer to an `otiKioskGetTokenResponse` struct with the token result: ```c C theme={null} typedef struct { otiTransactionStatus status; // Operation status int error_code; // Error code if failed char error_message[100]; // Error description char card_token[128]; // Generated card token char card_type[32]; // Card scheme (e.g., EMV, Visa, Mifare) } otiKioskGetTokenResponse; ``` **Struct fields:** | Field | Description | | :- | :- | | `status` | Status of the token operation. Same values as the JSON `status` field. | | `error_code` | Numerical error code. `0` when there is no error. | | `error_message` | Short technical description of the error, for developer and support use. Do not display to users. | | `card_token` | Generated card token. Base64 string for payment cards, or the card UID for closed loop cards. | | `card_type` | Card scheme (for example, EMV, Visa) for payment cards, or card technology (for example, Type A, Mifare) for closed loop cards. | </Tab> </Tabs> *** ## `IncrementalAuthorizationResponse` <Warning> This event is only available for the Android operating system. </Warning> The `IncrementalAuthorizationResponse` event triggers when an [`IncrementalAuthorization`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#incrementalauthorization) call completes, whether it succeeds or fails. It's reserved for a future multi-step flow and isn't required today: for the current single-step behavior, see [Single-step incremental authorization](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1#single-step-incremental-authorization). <Note> Nayax doesn't yet support the multi-step flow server-side. `IncrementalAuthorizationResponse` won't fire beyond what's described above. </Note> ```java Java theme={null} void IncrementalAuthorizationResponse(IncrementalAuthorizationDetails details); ``` | Parameter | Description | | - | - | | `Status` | `OK` or `Error`. | | `Amount` | The incremental amount, in major units (for example, 1.50 for \$1.50). | | `TransactionReference` | Transaction reference from the original `IncrementalAuthorization` call. | *** ## `ReaderMessageEvent` This callback provides updates on user interface messages from the card reader. <Tabs> <Tab title="JSON"> ```json theme={null} {"jsonrpc": "2.0", "method": "ReaderMessageEvent", "params": {"index": 36, "line1": "Authorizing", "line2": "Please wait"}} ``` | Parameter | Description | | :- | :- | | **index** | The index of the message. Decimal value according to the Message Index table. **Note:** The actual text presented on the reader display depends on the Kiosk configuration and may differ from the table values. | </Tab> <Tab title="Android"> ```java Java theme={null} public ReaderMessage(int index, String line1, String line2) ``` Parameters: | Parameter | Description | | :- | :- | | `index` | The index of the message. Decimal value according to the [Reader messages Index table](/docs/integrate-pos-device/emv-core/sdk-methods-functions/reader-messages). | | `line1` | Text is shown on the 1st line of the reader display. | | `line2` | Text is shown on the 2nd line of the reader display. | <Warning> **Reader Configuration** For this feature to work, the reader must be configured to send External Display message events (Tag DF 46 with index 04). </Warning> </Tab> <Tab title="Linux"> ```c Linux theme={null} void on_reader_event(uint8_t msg_index, char* line1, char* line2) { printf("Reader Display: %s | %s\n", line1, line2); } LibOtiKiosk_Register_ReaderEvent_Callback(on_reader_event); ``` </Tab> </Tabs> *** ## `SystemStatusChanged` <Warning> This event is only available for the Android operating system. </Warning> The `SystemStatusChanged` event indicates changes in the SDKs or connected devices' operational state. ```java Java theme={null} void SystemStatusChanged(EmvCoreStatus emvCoreStatus); ``` `EmvCoreStatus` is an enumeration representing the current state of the system. See the possible result values in the table below: | Result | Description | | - | - | | `NotReady` | The SDK is not operational. | | `Ready` | The SDK is ready for transactions. | | `PaymentTransaction` | A transaction is currently in progress. | | `Update` | A firmware or configuration update is ongoing. | | `NoReader` | No card reader is currently connected. | | `NoTerminalId` | Indicates the EMV Core does not have a configured Terminal ID. | | `NoNetwork` | No network connection is available. | | `NoTransaction` | No transaction is currently in progress or was found. | *** ## `TransactionComplete` EMV Core calls `TransactionComplete` when a transaction completes, whether it succeeds or fails. It gives your application the details needed to print a receipt and link transactions to sale events (for example, in a dispute). <Tabs> <Tab title="JSON"> Open loop request: ```json JSON theme={null} { "jsonrpc": "2.0", "method": "TransactionComplete", "params": { "status": "OK", "errorCode": 0, "errorDescription": "", "transactionId": "2046651064", "authorizationDetails": { "AmountAuthorized": 4.50, "AmountRequested": 4.50, "AuthorizationCode": "", "PartialPan": "541333******4111", "CardType": "MasterCard", "IsTransactionApproved": true, "eReceipt": "https://s.wee.ai/tr/...eIHT", "Card_ID": "", "Card_Balance": 0.00, "RRN": "", "TransactionDbID": "2046651064", "Transaction_Referance": "2046651064", "CardToken": "5VXkNqtUDJBxQj9p/qTGt74jWaPHlRs7xxWa1Yu0gDI=", "Additional_Parameters": { "hwSerial": "0207122525168550", "SiteId": "6", "AllowFundsOverAuthAmount": "false", "IncrementalMaxDefaultCredit": "450.0", "EntryMode": "4", "MachineAuTime": "2026-05-10T16:53:39.017", "NayaxTransactionId": "6811150712" } } }, "id": 701 } ``` Closed loop request with mifare\_read: To use `mifare_read`, set the **Mifare Blocks to Read** attribute in Nayax Core under **Embedded Advanced**. The following example uses `KA01B10B14` to read block 1 with key A, and blocks 10 and 14. <img alt="Mifare Blocks to Read configuration showing KA01B10B14" /> ```json JSON theme={null} { "jsonrpc": "2.0", "method": "TransactionComplete", "params": { "status": "LocalCLP", "errorCode": 0, "errorDescription": "", "transactionId": "4701113B", "authorizationDetails": { "CardType": "Mifare", "Card_ID": "4701113B", "Card_Balance": 0.00, "CardToken": "4701113B", "Additional_Parameters": {} } }, "mifare_read": { "UID": "4701113B", "B10": "00000000000000000000000000000000", "B14": "00000000000000000000000000000000" }, "id": 701 } ``` Response: ```json JSON theme={null} {"jsonrpc":"2.0", "result":true, "id":701} ``` **Parameters:** | Parameter | Description | | :- | :- | | **id** | Command ID. | | **status** | Transaction result: `OK`, `Declined`, `Error`, `Timeout`, `Cancelled`, `LocalCLP`, or `PollContinuous`. | | **errorCode** | Numerical error code. `0` when there is no error. | | **errorDescription** | Short technical description of the error, for developer and support use. Do not display to users. | | **transactionId** | Transaction ID. Use this value in `ConfirmTransaction` or `VoidTransaction`. | | **authorizationDetails** | Authorization details including amount authorized, amount requested, authorization code, partial PAN, card type, approval status, and card token. | | **Additional\_Parameters** | Optional data from the PSP in `{"fieldName": "fieldValue"}` format. Use these values for Nayax External Settlement (Remote Settlement). | | **mifare\_read** | Block data read from the Mifare card, based on the `CLP_MIFARE_READ` attribute. Empty when absent. | </Tab> <Tab title="Android"> ```java Java theme={null} void TransactionComplete(AuthorizationDetails authorizationDetails); ``` <Note> **In case of no response** If EMV Core doesn’t get an answer, it will re-send 2 times (for a total of 3 messages), and if it still doesn’t get an answer, it will assume the message received and will not cancel the transaction. </Note> Where: | Parameter | Description | | :- | :- | | `errorDescription` | A short technical description of the error intended to help developers and tech support personnel identify the problem. It should not be presented to users. | | `errorCode` | A numerical code describing the error if one occurs. See the table below for details on each code. | | `status` | Possible statuses: OK, Declined, Error, Timeout, Cancelled, LocalCLP, PollContinuous. | | `amountAuthorized` | Amount approved for the transaction in major units (for example, dollars, not cents). May be lower than the original request if the card is prepaid. | | `amountRequested` | Amount requested for transaction approval in major units (for example, dollars, not cents). | | `authorization_Code` | PSP Transaction Identifier issued for approved transactions (EVO, Apriva, Traderoot). | | `partialPan` | Masked PAN with the card account number's first six and last four digits. | | `cardType` | Card scheme (MasterCard, Visa, Amex, and others). For closed-loop cards, the card technology type. See the closed loop card types table below. | | `authID` | Approval Code from the processor (for some processors). | | `receiptID` | Digital receipt ID in the PSP System. | | `TransactionID` | Transaction ID. Use this value in `ConfirmTransaction` or `VoidTransaction`. | | `Transaction_Reference` | Transaction reference. Use this value in `ConfirmTransaction` or `VoidTransaction`. | | `TransactionDbID` | Deprecated. Use `TransactionID` instead. | | `RRN` | Processor reference number for approved transactions. | | `card_ID` | Mifare UID in case of a Mifare card and `CLP_MIFARE_ENABLED=2`. | | `isTransactionApproved` | Boolean indicating the transaction approval status. | | `eReceipt` | URL for the Nayax eReceipt. See eReceipt settings in Nayax Core for required configuration. | | `CardToken` | A token identifying the card. For payment cards, it returns a Base64 string. For closed-loop cards (for example, Mifare), it returns the card UID. | | `Channel` | Channel used for card reading (for example, Contactless, Magstripe, Contact). | | `AID, TVR, IAD, TSI, ARC` | Card/Transaction parameters that may be used for the receipt. | | `transactionTime` | Transaction time. | | `application_Label` | Card scheme (for example, Visa, MasterCard, American Express). | | `currency` | Currency code according to ISO 4217 (for example, 840 means US dollars). | | `CVM` | Card Verification Method. | | `additional_Parameters` | Optional additional parameters from the payment processor. Used for Nayax External Settlement (Remote Settlement). Includes: `SiteId`, `EntryMode`, `MachineAuTime`, `NayaxTransactionId`, `hwSerial`, `AllowFundsOverAuthAmount`, and `IncrementalMaxDefaultCredit`. | | `hwSerial` | Hardware serial number of the terminal. | | `AllowFundsOverAuthAmount` | Whether incremental charges above the authorized amount are permitted (`"true"` or `"false"`). | | `IncrementalMaxDefaultCredit` | Maximum credit amount allowed for incremental authorization. | | `card_Balance` | Card balance for closed-loop cards managed by Nayax. | | `mifare_read` | Optional. JSON with the results of Mifare blocks read, according to the `CLP_MIFARE_READ` configuration attribute. Empty string when not configured. Returns a JSON object keyed by UID and by block number (for example, `B10`, `B14`). | ### `TransactionComplete` Closed loop card types The following card technology types may be returned in the `cardType` field for closed-loop transactions. | Card Type | Description | | :- | :- | | `Type A` | ISO/IEC 14443 Type A | | `Type B` | ISO/IEC 14443 Type B | | `Mifare` | Mifare | | `Mifare-U` | Mifare Ultralight | | `DesFire` | Mifare DESFire | | `Mifare-P` | Mifare Plus | | `Vicinity` | ISO/IEC 15693 | | `Vicinity-P` | ISO/IEC 15693 HID iClass | | `Felica` | FeliCa JIS X 6319-4 | ### `TransactionComplete` Error codes These are the possible error codes in the response: | Error Type | Error Code | | - | - | | JsonParse | -1 | | General | -1 | | Terminate | -1 | | Timeout | -1 | | Transaction Declined | -1 | | Positive code | Payment Service Provider (PSP) errors | </Tab> <Tab title="Linux"> ```c Linux theme={null} void on_transaction_complete(otiKioskPaymentResponse* resp) { if (resp->status == otiTransactionStatus_OK) { printf("Transaction successful: %s\n", resp->transaction_reference); } else { printf("Transaction failed: %s\n", resp->error_message); } } LibOtiKiosk_Register_TransactionComplete_Callback(on_transaction_complete); ``` **Parameters:** **`cb`**: A callback function of type `void (*)(otiKioskPaymentResponse* resp)`. This function is triggered automatically when a transaction reaches a final state. The callback receives a pointer to an `otiKioskPaymentResponse` struct with the full transaction result: ```c C theme={null} typedef struct { otiTransactionStatus status; // Transaction status int error_code; // Error code if failed char error_message[100]; // Error description double amount_requested; // Requested amount double amount_authorized; // Authorized amount char transaction_reference[128]; // Unique transaction reference char partial_PAN[20]; // Masked card number char card_type[32]; // Card type (Visa, MasterCard, etc.) char card_id[32]; // Card identifier char card_token[128]; // Secure card token char EReceipt[256]; // Electronic receipt URL char Additional_Parameters[256]; // Additional parameters, used for remote settlement double card_balance; // RFU: card balance for closed-loop cards bool is_transaction_approved; // Approval status char authorization_code[128]; // PSP authorization code char rrn[128]; // Processor reference number NayaxTransactionIdInfo nayax_info; // Fields for remote settlement char mifare_read[256]; // Raw JSON of mifare_read params for CLP_MIFARE_READ, empty when absent } otiKioskPaymentResponse; ``` **Struct fields:** | Field | Description | | :- | :- | | `status` | Transaction status. Same values as the JSON `status` field. | | `error_code` | Numerical error code. `0` when there is no error. | | `error_message` | Short technical description of the error, for developer and support use. Do not display to users. | | `amount_requested` | Amount requested for transaction approval, in major units (for example, dollars, not cents). | | `amount_authorized` | Amount approved for the transaction, in major units. May be lower than the requested amount for prepaid cards. | | `transaction_reference` | Transaction ID. Use this value in `ConfirmTransaction` or `VoidTransaction`. | | `partial_PAN` | Masked PAN with the card account number's first six and last four digits. | | `card_type` | Card scheme for open-loop cards, or card technology for closed-loop cards. | | `card_id` | Mifare UID when the card is a Mifare card and `CLP_MIFARE_ENABLED=2`. | | `card_token` | Token identifying the card. Base64 string for payment cards, or the card UID for closed-loop cards. | | `EReceipt` | URL for the Nayax eReceipt. See eReceipt settings in Nayax Core below. | | `Additional_Parameters` | Optional data from the PSP, used for Nayax External Settlement (Remote Settlement). | | `card_balance` | RFU. Card balance for closed-loop cards managed by Nayax. | | `is_transaction_approved` | Whether the transaction was approved. | | `authorization_code` | PSP transaction identifier issued for approved transactions. | | `rrn` | Processor reference number for approved transactions. | | `nayax_info` | Fields required for Nayax External Settlement (Remote Settlement). | | `mifare_read` | Raw JSON of the blocks read from a Mifare card, based on the `CLP_MIFARE_READ` attribute. Empty when absent. | <Note> For the full closed-loop card type list and error code list, see the equivalent fields in the Android tab above. </Note> </Tab> </Tabs> ### eReceipt settings in Nayax Core To receive eReceipts, configure the operator in Nayax Core with the following settings. <Steps> <Step title="Configure VAS provider settings"> In the operator settings, go to the **VAS Provider** tab. Under **eReceipt Platform**, enter the **Provider Name** and **Business ID**. <img alt="Operator VAS Provider tab showing eReceipt Platform with Provider Name and Business ID fields" /> </Step> <Step title="Update machine payment options"> In the machine settings, go to the **Payment** tab. Under **Transaction Options**, uncheck **Enable eReceipt on Transaction end**. <img alt="Machine Payment tab showing Enable eReceipt on Transaction end checkbox under Transaction Options" /> </Step> </Steps> # Payment Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1 The EMV Core SDK provides APIs for managing payment transactions. These APIs let you integrate cashless payment functionality into applications, supporting both open- and closed-loop systems. The SDK handles secure, efficient, and flexible payment processing while offloading complexity to the Nayax backend. The methods available for payment management are: * [CancelTransaction](#canceltransaction) * [ConfirmTransaction](#confirmtransaction) * [GetCardToken](#getcardtoken) * [IncrementalAuthorization](#incrementalauthorization) * [PreAuthorize](#preauthorize) * [VoidTransaction](#voidtransaction) The sections below describe them in more detail. *** ## `CancelTransaction` The `CancelTransaction` method stops the execution of an ongoing `PayTransaction` or `PreAuthorize` call. The system blocks further requests until the cancellation is accepted and confirmed. **Implementation Notes:** * **Before Card Presentation:** If a card has not been presented yet, the Reader poll sequence stops. The display will show **"Cancelling"**; the host application must then update the UI using the `ShowMessage` command. * **During Processing:** If the card was already presented but processing is not finished, the system returns `CannotCancel`. It may take a few seconds to receive the `TransactionComplete` event while the EMV Core waits for the online result. * **After Completion:** If the transaction is already finished, it returns `NoTransaction`. * **Undoing Success:** To undo a completed transaction, use `VoidTransaction`. * **Declined Transactions:** If `TransactionComplete` returns a `Decline` status, there is no need to send a `VoidTransaction` command. * **Events:** In all scenarios, EMV Core will eventually send a `TransactionComplete` event to finalize the state. See the API Signature for the `CancelTransaction` method: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "CancelTransaction", "id": 802} ``` Response: ```json theme={null} {"jsonrpc": "2.0", "result": true, "id": 802} ``` </Tab> <Tab title="Android"> ```java Java theme={null} void CancelTransaction(); ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_CancelTransaction(void); ``` </Tab> </Tabs> <Note> If the card has already been presented and processed, the system will return a `CannotCancel` error. </Note> *** ## `ConfirmTransaction` A confirmation request is the second stage of the authorization flow. It confirms the pre-authorization so that settlement can take place. ### API signature <Tabs> <Tab title="JSON"> Response: ```json JSON theme={null} { "jsonrpc": "2.0", "method": "TransactionComplete", "params": { "status": "OK", "errorCode": 0, "errorDescription": "", "transactionId": "6103587330", "authorizationDetails": { "AmountAuthorized": 4.5, "AmountRequested": 4.5, "AuthorizationCode": "AuthOK", "PartialPan": "541333******4111", "CardType": "MasterCard", "IsTransactionApproved": true, "eReceipt": "", "Card_ID": "2025-11-25 14:35:39.140|6|3", "Card_Balance": 0.0, "RRN": "251125123539", "TransactionDbID": "6103587330", "Transaction_Referance": "6103587330", "CardToken": "5VXkNqtUDJBxQj9p/qTGt74jWaPHlRs7xxWa1Yu0gDI=", "Additional_Parameters": { "SiteId": "6", "EntryMode": "4", "MachineAuTime": "2025-11-25T14:35:38.885", "NayaxTransactionId": "6103587330" } } }, "id": 701 } ``` Request: ```json JSON theme={null} {"jsonrpc":"2.0","method":"ConfirmTransaction", "params": {"amount":450, "fee":0, "productID":42, "transaction_Reference":"6103587330", "AdditionalReceiptData":{"Message": "Purchase confirmed", "VAT_Percentage": 10}}, "id":8} ``` Response: ```json JSON theme={null} {"jsonrpc":"2.0", "result":true, "id":8} ``` **Parameters:** | Parameter | Description | | :- | :- | | **id** | Command ID. | | **amount** | The actual amount to charge, in minor units (cents). | | **transactionReference** | Transaction reference from the PSP. Use the `transactionId` field from the `TransactionComplete` event. | | **productID** | Optional parameter: ID of the product selected by the consumer. This number will be saved on the server and available for reports. Before SDK v1.5, `productID` also controlled whether the pre-authorized amount was final; that behavior is now controlled by `isFinalAmount` in `PreAuthorize`. | | **terminal\_data** | Optional parameter: `terminal_data=(key1=value1,key2=value2)`. | | **AdditionalReceiptData** | Optional. JSON object with extra receipt data to include at confirmation time. | </Tab> <Tab title="Android"> ```java Java theme={null} void ConfirmTransaction(String transactionReference, int actualAmountMinorUnits, int productID) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `transactionReference` | Unique reference from pre-authorization. | | `actualAmountMinorUnits` | The final amount for settlement. | | `productID` | Product identifier. | </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_ConfirmTransaction(uint32_t amount_cents, uint32_t fee_cents, uint32_t product_id, char* transaction_reference, char* additional_receipt_data); ``` **Parameters:** | Parameter | Description | | - | - | | `amount_cents` | Amount to charge in minor units (cents, not dollars). | | `fee_cents` | Deprecated. Not used. | | `transaction_reference` | Unique reference from pre-authorization. | | `product_id` | Product identifier. | | `additional_receipt_data` | Optional. JSON string with extra receipt data to include at confirmation time. Can be `NULL`. | </Tab> </Tabs> *** ## `GetCardToken` The `GetCardToken` method initiates the card tokenization process, returning a card token without performing a financial transaction. EMV Core waits for a card to be presented, reads the data, and triggers a `CardTokenReceived` event: * **Payment Cards:** Returns a Base64 string containing the card token. * **CLP Cards (for example, Mifare):** Returns the card UID. ### API signature <Tabs> <Tab title="JSON"> Request: ```json theme={null} { "method": "GetCardToken", "params": { "continuous": false, "timeout": 60 }, "id": 5820 } ``` Response: ```json JSON theme={null} {"jsonrpc": "2.0", "result": true, "id": 5820} ``` **Parameters:** | Parameter | Description | | :- | :- | | **timeoutSeconds** | Maximum number of seconds to wait. If no card arrives within this time, the request returns a `Timeout` status. Maximum value is 60 seconds. | </Tab> <Tab title="Android"> ```java Java theme={null} void GetCardToken(int timeoutSeconds, boolean continuous) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `timeoutSeconds` | Maximum seconds to wait (max 60). If no card arrives, a `Timeout` status is returned. | | `continuous` | If true, polling restarts immediately after a timeout. A `TransactionComplete` event is sent with status `PollContinuous`. | </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_GetCardToken(otiKioskPaymentParameters *params); ``` </Tab> </Tabs> *** ## `IncrementalAuthorization` The `IncrementalAuthorization` method adds an incremental charge to an existing authorized transaction, and delivers the result through the [`IncrementalAuthorizationResponse`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks#incrementalauthorizationresponse) callback. It's reserved for a future multi-step flow and isn't required today: for the current single-step behavior, see below. ### Single-step incremental authorization For most use cases, you don't need to call this API directly. Nayax Core handles a single-step incremental authorization automatically whenever you settle a transaction for more than the pre-authorized amount: 1. Call `PreAuthorize` (for example, for \$10.00) and read the `IncrementalMaxDefaultCredit` value from the resulting `TransactionComplete` event (for example, \$50.00). 2. Call `ConfirmTransaction`, or send an [External Settlement](/docs/integrate-pos-device/emv-core/payment-flows/pre-authorization-with-external-settlement) request from your server, with an amount up to `IncrementalMaxDefaultCredit` (for example, \$15.03). 3. Nayax Core automatically sends an incremental authorization request to the processor for the difference (in this example, \$5.03). 4. If the incremental authorization succeeds, Nayax Core settles the transaction for the final amount (\$15.03). 5. If it fails, Nayax Core settles the transaction for the original pre-authorized amount (\$10.00). <Note> Nayax doesn't yet support the multi-step flow server-side. Calling `IncrementalAuthorization` today has no effect beyond what's described above. </Note> <Warning> This method is only available for the Android SDK. </Warning> See the `IncrementalAuthorization` API signature in the code below: ```java Java theme={null} void IncrementalAuthorization(int amountMinorUnits, int productID, String transactionReference) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `amountMinorUnits` | Additional amount to charge, in minor units (cents). | | `productID` | Optional. Product ID for reporting. | | `transactionReference` | Transaction reference from `TransactionComplete` (`TransactionID` field). | *** ## `PreAuthorize` Use `PreAuthorize` to pre-authorize a card with the payment processor. EMV Core waits for a card, reads it, and processes it with the payment service if needed. It then sends a `TransactionComplete` event. ### API signature <Tabs> <Tab title="JSON"> Request: ```json JSON theme={null} {"jsonrpc":"2.0","method":"PreAuthorize", "params": {"amount":450, "timeout":10, "productID":0, "continuous":false, "AdditionalReceiptData": {"Message": "Good Morning", "VAT_Percentage": 10}, "isFinalAmount":false, "deferred":false}, "id":801} ``` Response: ```json JSON theme={null} {"jsonrpc": "2.0", "result": true, "id": 801} ``` **Parameters:** | Parameter | Description | | :- | :- | | **amount** | Amount to charge in minor units (cents, not dollars). Example: 450 = \$4.50. | | **fee** | Deprecated. Not used. | | **currency** | Taken from configuration since SDK v1.4. If `CURRENCY_CODE` is not set, SDK v1.5 reads the currency from the reader's tag `9F3C` on the first transaction, and falls back to USD (840) if that's also unavailable. | | **productID** | Optional parameter: ID of the product selected by the consumer. This number will be saved in the server and available for reports. | | **continuous** | If continuous is true, then poll for card will start immediately after card transaction timeout and `TransactionComplete` event will be sent with status ‘PollContinuous’. | | **timeout** | Maximum seconds to wait. If no card arrives, the request returns a `Timeout` status. | | **AdditionalReceiptData** | Optional. JSON object with extra receipt data passed to the PSP and included in the eReceipt. | | **isFinalAmount** | `true`: fixed amount, indicates `pre-selection` flow. `false`: amount may change, indicates `pre-authorization` flow. When used with `deferred=false`, the host must call `ConfirmTransaction` or `VoidTransaction` in both cases. When used with `deferred=true`, no need to call `ConfirmTransaction` or `VoidTransaction`. The transaction settles automatically. In SDK v1.5, `deferred=true` is only supported with `isFinalAmount=true`. | | **deferred** | Optional. `true`: Deferred Authorization (Transit mode). Card read offline, authorization queued for settlement. See [Deferred Transaction](/docs/integrate-pos-device/emv-core/payment-flows/deferred-transaction) for details. | </Tab> <Tab title="Android"> ```java Java theme={null} void PreAuthorize(int amountMinorUnits, int productID, int timeoutSeconds, boolean continuous, JSONObject additionalReceiptData, boolean isDeferred, boolean isFinalAmount) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `amountMinorUnits` | Amount to charge in minor units (for example, cents, not dollars). | | `productID` | ID of the product selected by the consumer. This number will be saved on the server and available for reports. | | `timeoutSeconds` | Maximum wait time for card presentation. | | `continuous` | Whether to enable continuous polling. | | `additionalReceiptData` | Optional. JSON object with extra receipt data passed to the PSP and included in the eReceipt. Pass null if not used. | | `isDeferred` | Optional. `true`: Deferred Authorization (Transit mode). Card read offline, authorization queued for settlement. See [Deferred Transaction](/docs/integrate-pos-device/emv-core/payment-flows/deferred-transaction) for details. | | `isFinalAmount` | `true`: fixed amount, indicates `pre-selection` flow. `false`: amount may change, indicates `pre-authorization` flow. When used with `isDeferred=false`, the host must call `ConfirmTransaction` or `VoidTransaction` in both cases. When used with `isDeferred=true`, no need to call `ConfirmTransaction` or `VoidTransaction`. The transaction settles automatically. In SDK v1.5, `isDeferred=true` is only supported with `isFinalAmount=true`. | </Tab> <Tab title="Linux"> ```c C theme={null} otiKioskPaymentParameters params = { .amount_cents = 1500, // $15.00 .product_id = 12345, .timeout_sec = 60, .continuous = false, .additional_receipt_data = NULL, .is_deferred = false, .is_final_amount = false }; KIOSK_RET result = LibOtiKiosk_PreAuthorize(¶ms); if (result == KIOSK_RET_OK) { printf("Payment initiated successfully\n"); } ``` **Parameters:** | Parameter | Description | | - | - | | `amount_cents` | Amount to charge in minor units (for example, cents, not dollars). | | `product_id` | ID of the product selected by the consumer. This number will be saved on the server and available for reports. | | `timeout_sec` | Maximum wait time for card presentation. | | `continuous` | Whether to enable continuous polling. | | `additional_receipt_data` | Optional. JSON string with extra receipt data passed to the PSP and included in the eReceipt. Can be `NULL`. | | `is_deferred` | Optional. `true` for Deferred Authorization (Transit mode): the card is read offline and the authorization is queued for settlement. | | `is_final_amount` | `true`: fixed amount, indicates the pre-selection flow. `false`: amount may change, indicates the pre-authorization flow. In SDK v1.5, `is_deferred=true` is only supported with `is_final_amount=true`. | </Tab> </Tabs> <Warning> **Before SDK v1.5:** setting `productID` to a non-zero value in `PreAuthorize` marked the pre-authorized amount as final, and it couldn't be changed in `ConfirmTransaction`. To indicate a non-final amount, you set `productID = 0` in `PreAuthorize` and provided the actual product ID in `ConfirmTransaction`. **As of SDK v1.5**, whether the amount is final is controlled by `isFinalAmount` in `PreAuthorize` instead (see the parameter table above). `productID` is now used only for reporting and can be set independently in either call. </Warning> If the transaction is approved (the `TransactionComplete` event returns with status `OK`), your application must call `ConfirmTransaction` or `VoidTransaction` to complete the flow. *** ## `VoidTransaction` This request is used to void a transaction in two specific cases: 1. **Release Funds:** The transaction was **Pre-Authorized** but not **Confirmed**. Voiding releases the reserved funds when the transaction will no longer occur. 2. **Reversal:** The transaction was completed using `PayTransaction` but needs to be canceled. ### API signature <Tabs> <Tab title="JSON"> Request: ```json JSON theme={null} {"jsonrpc": "2.0", "method": "VoidTransaction", "params": {"transaction_Reference": "8453F02DFD33413EBA77334B696D5991"}, "id": 803} ``` Response: ```json JSON theme={null} {"jsonrpc": "2.0", "result": true, "id": 803} ``` **Parameters:** | Parameter | Description | | :- | :- | | **id** | Command ID. | | **transactionReference** | Transaction reference came from PSP with the `TransactionComplete` event. | </Tab> <Tab title="Android"> ```java Java theme={null} void VoidTransaction(String transactionReference) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `transactionReference` | Unique reference from pre-authorization. | </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_VoidTransaction(char* transaction_reference); ``` **Parameters:** | Parameter | Description | | - | - | | `transaction_reference` | Unique reference from pre-authorization. | </Tab> </Tabs> <br /> # Reader Messages Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/sdk-methods-functions/reader-messages Reader messages are critical for communicating the status of the card reader to users during a transaction. The EMV Core SDK provides a `ReaderMessageEvent` callback to relay these messages, which can be displayed in the application’s user interface. The sections below contain tables describing the different reader messages that can be displayed. ## Main reader messages These are the messages sent for the reader's main operational states, transitions, and error conditions: | Category | Hex (Internal) | Decimal (API) | Message Details | | :- | :- | :- | :- | | **Main States** | 0x00 | 0 | (Blank Screen) | | | 0x01 | 1 | Present card | | | 0x11 | 17 | Welcome | | | 0x23 | 35 | Card read OK Remove card | | | 0x04 | 4 | Please remove card | | | 0x0D | 13 | Approved sign | | **Recovery States** | 0x05 | 5 | Please present one card only | | | 0x03 | 3 | Please present one card only | | | 0x27 | 39 | Read error Please try again | | **Stateless Messages** | 0x12 | 18 | Thank You | | | 0x15 | 21 | Please Use Another Card | | | 0x19 | 25 | Please Wait | | | 0x1A | 26 | International Card, Please Swipe! | | **Online Results** | 0x24 | 36 | Authorizing Please wait | | | 0x06 | 6 | Approved | | | 0x09 | 9 | Not Approved | | **Offline Results** | 0x07 | 7 | Approved | | | 0x08 | 8 | Not Approved | | **Error States** | 0x1E | 30 | Timed Out Please insert or swipe card | | | 0x25 | 37 | Communication Failure | | | 0x26 | 38 | Please insert or swipe card | | | 0x0A | 10 | Terminated | | | 0x0B | 11 | PIN Entry Required – see attendant | | | 0x0C | 12 | See Phone | | | 255 | N/A | Deprecated since SDK v1.5. Replaced by indexes 201 to 220 below. | ## Other messages from EMV Core Since SDK v1.5, EMV Core sends additional status messages using dedicated indexes instead of the single index 255 used in earlier versions. You can overwrite each message's default text with the corresponding configuration key. | Decimal (API) | Default text | Configuration key | | :- | :- | :- | | 201 | Loading... | `SAT_MSG_LOADING` | | 202 | Welcome | `SAT_MSG_READER_IDLE` | | 203 | Vending item | `SAT_MSG_VEND_ONLINE` | | 204 | Thank You! Total: X.XX | `SAT_MSG_RESULT` | | 205 | Declined | `SAT_MSG_DECLINED` | | 206 | Please select an item | `SAT_MSG_SELECT` | | 207 | Error Please Try Again | `SAT_MSG_ERROR` | | 208 | Please / Wait ... | `SAT_MSG_DISABLED` | | 209 | No selection Cancelling | `SAT_MSG_CANCEL` | | 210 | Starting over | `SAT_MSG_SELECTION_TIMEOUT` | | 211 | Not enough credit | `SAT_MSG_LOW_BALANCE` | | 212 | Updating... | `SAT_MSG_BUSY` | | 213 | Insert, swipe or Try another card | `SAT_MSG_SWIPE_ALL` | | 214 | Amount too small | `SAT_MSG_MIN_PRICE` | | 215 | Credit received Select product | `SAT_MSG_SELECT_NOCARD` | | 216 | Card not recognized | `SAT_MSG_CARD_NOT_RECOGNIZED` | | 217 | Authorizing... | `SAT_MSG_CLP_AUTHORIZING` | | 218 | Approved Balance: | `SAT_MSG_CLP_APPROVED` | | 219 | Varies. Firmware version or IP address at startup. | `SAT_MSG_SYSTEM_INFO` | | 220 | Varies. Set by the host using the `ShowMessage` command. | `SAT_MSG_CUSTOM_MESSAGE` | <Note> Indexes 221 to 250 are reserved for future EMV Core messages. </Note> # Remote Management Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/sdk-methods-functions/remote-management The EMV Core SDK includes management features that streamline device configuration, firmware updates, and diagnostics. These capabilities reduce maintenance overhead and enhance reliability by allowing centralized control through Nayax’s Terminal Management System (TMS) or local updates when necessary. The following methods are used for managing the SDK: * [Destroy](#destroy) * [GetAttribute](#getattribute) * [GetKioskID](#getkioskid) * [GetPollStatus](#getpollstatus) * [GetStatus](#getstatus) * [GetVersion](#getversion) * [Initialize](#initialize) * [isEMVCoreConnected](#isemvcoreconnected) * [SendToReader](#sendtoreader) * [SetAdditionalReceiptData](#setadditionalreceiptdata) * [SetManagementCallbacks](#setmanagementcallbacks) * [SetPaymentCallbacks](#setpaymentcallbacks) * [ShowMessage](#showmessage) * [UpdateMachineAttributes](#updatemachineattributes) See the sections below for more details on each method. *** ## `Destroy` <Warning> This method is only available for the Android SDK. </Warning> Terminates the session with the reader and releases any associated resources. Use this during application shutdown or when the reader is no longer needed to prevent resource leaks and ensure the proper cleanup of SDK-related processes. See the `Destroy` API signature in the code below: ```java Android theme={null} void Destroy(); ``` *** ## `GetAttribute` Called by the POS application to retrieve a specific attribute value from the EMV Core configuration file. See the `GetAttribute` API signature in the code below: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc":"2.0","method":"GetAttribute", "params": {"Key":"PRE_AUTH_AMOUNT"}, "id":12} ``` Response when the requested attribute exists in the configuration file: ```json theme={null} {"jsonrpc":"2.0", "result":"150", "id":12} ``` Response when the requested attribute doesn’t exist in the configuration file: ```json theme={null} {"jsonrpc":"2.0", "error":{"code": -1, "message": "Get attribute key not found"}, "id":12} ``` **Parameters:** | Parameter | Description | | :- | :- | | **id** | Command ID. | | **key** | Label of the requested configuration attribute (e.g., `PRE_AUTH_AMOUNT`). | </Tab> <Tab title="Android"> ```java Java theme={null} String GetAttribute(String key) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | :- | :- | | `key` | The attribute key in the configuration file. For example, if the config file includes `PRE_AUTH_AMOUNT=100`, providing the key `PRE_AUTH_AMOUNT` will return `100`. | </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_GetAttribute(char* attribute_name, char* out_value, int max_out_size); ``` **Parameters:** | Parameter | Description | | :- | :- | | `attribute_name` | A null-terminated string representing the attribute key in the configuration file (e.g., `"PRE_AUTH_AMOUNT"`). | | `out_value` | A pointer to a caller-allocated buffer where the attribute value will be stored as a null-terminated string. | | `max_out_size` | The maximum capacity of the `out_value` buffer in bytes. This prevents buffer overflows if the retrieved value is longer than expected. | </Tab> </Tabs> *** ## `GetKioskID` Returns the device's unique identification number, which the Nayax server uses to link transactions, configurations, and monitoring to this device. See the `GetKioskID` API signature in the code below: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "GetKioskID", "params": {}, "id": 902} ``` Response: ```json theme={null} {"jsonrpc":"2.0", "result":"00130226001C9C69", "id":902} ``` </Tab> <Tab title="Android"> ```java Java theme={null} String GetKioskID() throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_GetKioskId(char* out_id, int max_out_size); ``` </Tab> </Tabs> *** ## `GetPollStatus` Returns separate status values for the card-polling state and for reader and network resource availability. See the `GetPollStatus` API signature in the code below: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "GetPollStatus", "params": {}, "id": 14} ``` Response: ```json theme={null} {"jsonrpc":"2.0", "result":{"Polling":false, "Resources":"Ready"}, "id":14} ``` </Tab> <Tab title="Android"> ```java Java theme={null} PollStatus GetPollStatus() throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_GetPollStatus(otiKioskPollStatus *out_poll_status); ``` </Tab> </Tabs> `PollStatus` has two fields: `polling` (Boolean, `true` if EMV Core is currently polling for a card) and `resources` (String, resource availability: `Ready`, `NoReader`, or `NoNetwork`). *** ## `GetStatus` Retrieves the reader's current status, including its transaction readiness and connectivity state. This is useful for monitoring the device state during integration or deployment. See the `GetStatus` API signature in the code below: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "GetStatus", "id": 805} ``` Response: ```json theme={null} {"jsonrpc": "2.0", "result": "Ready", "id": 805} ``` </Tab> <Tab title="Android"> ```java Java theme={null} EmvCoreStatus GetStatus() throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_STATUS status; KIOSK_RET result = LibOtiKiosk_GetStatus(&status); if (result == KIOSK_RET_OK) { switch (status) { case OK_READY: printf("Kiosk is ready for transactions\n"); break; case OK_NOT_READY: printf("Kiosk is not ready\n"); break; // Handle other status values... } } ``` </Tab> </Tabs> The possible result values are: `NotReady`, `Ready`, `PaymentTransaction`, `Update`, `NoReader`, `NoTerminalId`, `NoNetwork`, and `NoTransaction`. <Note> * **`Update`**: Indicates the EMV Core is busy with TMS updates (e.g., new firmware or configuration). * **`NoTerminalId`**: Indicates the EMV Core does not have a configured Terminal ID. </Note> <Warning> If `GetStatus` times out, retry up to three times with a five-second interval. If there is still no response, assume EMV Core is unresponsive and restart the process. </Warning> *** ## `GetVersion` Fetches the reader's firmware version and the EMV Core SDK version. This is used to verify that the latest updates have been applied. <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "GetVersion", "params":{"SoftwareComponent": "Reader"}, "id": 5} ``` Response: ```json theme={null} {"jsonrpc": "2.0", "result": "EMVS_v071585", "id": 5} ``` | Parameter | Description | | :- | :- | | **id** | Command ID. | | **SoftwareComponent** | The software component to check. Accepted values: `otiKiosk` (for the EMV Core version) or `Reader`. | </Tab> <Tab title="Android"> ```java Java theme={null} String GetEmvCoreVersion() throws EmvCoreException; String GetReaderVersion() throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_GetKioskVersion(char* out_version, int max_out_size); ``` </Tab> </Tabs> *** ## `Initialize` Initializes the EMV Core SDK and establishes a session with the reader. Call this once during application startup before performing any transactions or management tasks. See the `Initialize` API signature in the code below: <Tabs> <Tab title="Android"> ```java Java theme={null} void Initialize(Context context); ``` </Tab> <Tab title="Linux"> ```c C theme={null} // TCP connection to localhost bool success = LibOtiKiosk_Init(NULL, false); // TCP connection to specific server bool success = LibOtiKiosk_Init("192.168.1.100", false); // Unix domain socket bool success = LibOtiKiosk_Init("/tmp/kiosk_sockets", true); ``` ### Parameters | Parameter | Description | | :- | :- | | `server_address` | **Unix Domain Sockets:** Path to the folder containing sockets (can be NULL). **TCP Sockets:** IP address or hostname (defaults to localhost). | | `is_local` | Set to `true` for Unix domain sockets, or `false` for TCP sockets. | ### Returns * **`true`**: Initialization was successful. * **`false`**: Initialization failed. ### Example Usage ```c C theme={null} // TCP connection to localhost bool success = LibOtiKiosk_Init(NULL, false); // TCP connection to a specific server bool success = LibOtiKiosk_Init("192.168.1.100", false); // Unix domain socket connection bool success = LibOtiKiosk_Init("/tmp/kiosk_sockets", true); ``` </Tab> </Tabs> *** ## `isEMVCoreConnected` <Warning> This method is only available for the Android SDK. </Warning> Retrieves the current status of the reader, including its transaction readiness and connectivity state. See the `isEMVCoreConnected` API signature in the code below: ```java Android theme={null} boolean isEmvCoreConnected(); ``` *** ## `SendToReader` <Warning> This method is only available for the Android SDK. </Warning> Sends a direct command to the payment card reader hardware. This provides low-level access for custom commands, configuration, and diagnostics. See the `SendToReader` API signature in the code below: ```java Android theme={null} SendToReaderResponse SendToReader(String scope, String tag, String data); ``` **Parameters:** | Parameter | Description | | - | - | | `scope` | Command scope. `GET` reads data (all tags allowed). `DO` executes a command (only whitelisted tags allowed). | | `tag` | Reader tag identifier in hex (for example, `DF4D` for firmware version). | | `data` | Command payload as a hex string. Use an empty string for `GET` operations. | **Returns:** A `SendToReaderResponse` with: | Field | Description | | - | - | | `status` | Numerical status code: `0` (SUCCESS), `1` (FAILED), `2` (TIMEOUT), `3` (NO\_ACK), `4` (NACK), `5` (UNSUPPORTED), `6` (UNAUTHORIZED), or `7` (ERROR). | | `data` | Hex-encoded response data on success, or an error message otherwise. | *** ## `SetAdditionalReceiptData` <Warning> This method is only available for the Android SDK. </Warning> Sets additional receipt data to be included in transactions. This is a separate command from the `additionalReceiptData` parameter available inline in [`PreAuthorize` and `ConfirmTransaction`](/docs/integrate-pos-device/emv-core/sdk-methods-functions/payment-1). See the `SetAdditionalReceiptData` API signature in the code below: ```java Android theme={null} JSONObject SetAdditionalReceiptData(List<AdditionalReceiptDataPrms> additionalReceiptData) throws EmvCoreException; ``` **Parameters:** | Parameter | Description | | - | - | | `additionalReceiptData` | List of `AdditionalReceiptDataPrms` objects, each with a key (String) and value (Object) pair to include in the receipt. | **Returns:** A `JSONObject` with the configured receipt data. *** ## `SetManagementCallbacks` <Warning> This method is only available for the Android SDK. </Warning> Registers callbacks for system-level EMV Core events. This includes the `SystemStatusChanged` event, which lets your application monitor the health and maintenance status of the SDK. See the `SetManagementCallbacks` API signature in the code below: ```java Android theme={null} void SetManagementCallbacks(IManagementCallbacks iMaintenanceCallbacks); ``` **Parameters:** `iMaintenanceCallbacks`: Maintenance details and system event handlers. <Note> To learn more about implementation, see the [Event Callbacks](/docs/integrate-pos-device/emv-core/sdk-methods-functions/event-callbacks) documentation. </Note> *** ## `SetPaymentCallbacks` Registers callbacks called by the EMV Core and implemented by the sales application regarding payment functionality. This includes handling events such as `TransactionComplete` and `ReaderMessage`. See the `SetPaymentCallbacks` API signature in the code below: <Tabs> <Tab title="Android"> ```java Java theme={null} void SetPaymentCallbacks(IPaymentCallbacks iPaymentCallbacks); ``` **Parameters:** * `iPaymentCallbacks`: Payment transaction details and event handlers. </Tab> <Tab title="Linux"> ```c C theme={null} void LibOtiKiosk_Register_TransactionComplete_Callback(TransactionCompleteCb_t cb); ``` </Tab> </Tabs> *** ## `ShowMessage` Displays a custom message on the reader’s screen (available only if the reader has a display). See the `ShowMessage` API signature in the code below: <Tabs> <Tab title="JSON"> Request: ```json theme={null} {"jsonrpc": "2.0", "method": "ShowMessage", "params": {"line1": "Please Select", "line2": "Your Product"}, "id": 901} ``` Response: ```json theme={null} {"jsonrpc": "2.0", "result": true, "id": 901} ``` | Parameter | Description | | :- | :- | | **id** | Command ID. | | **line1** | Text to show in the 1st line of the reader display (limited to 16 characters). | | **line2** | Text to show in the 2nd line of the reader display (limited to 16 characters). | </Tab> <Tab title="Android"> ```java Java theme={null} void ShowMessage(String line1, String line2) throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET result = LibOtiKiosk_ShowMessage("Welcome!", "Tap Card"); ``` </Tab> </Tabs> <Warning> This method is exclusive to the **UNO-PLUS** reader. </Warning> *** ## `UpdateMachineAttributes` Updates host machine attributes in Nayax Core. These values are informational only and do not affect payment processing. They are available in Nayax Core for reporting and diagnostics. <Tabs> <Tab title="JSON"> **Request:** ```json theme={null} { "jsonrpc": "2.0", "method": "UpdateMachineAttributes", "params": [ {"id": 542, "value": "AC Charger 1"}, {"id": 543, "value": "ACC1-1234567"}, {"id": 544, "value": "1.0.35-A"}, {"id": 593, "value": "1.2-G3"}, {"id": 541, "value": "manuf-123"} ], "id": 801 } ``` **Response:** ```json theme={null} {"jsonrpc": "2.0", "result": true, "id": 801} ``` </Tab> <Tab title="Android"> ```java Java theme={null} String UpdateMachineAttributes(List<NayaxMachineAttribute> attributes) throws EmvCoreException; ``` </Tab> <Tab title="Linux"> ```c C theme={null} KIOSK_RET LibOtiKiosk_UpdateMachineAttributes(NayaxMachineAttribute attributes[], int count, char* result, int max_result_size); ``` </Tab> </Tabs> **Parameters:** **`key`**: A list of machine attributes to be updated on Nayax Core. The relevant attribute IDs are: | ID | Attribute | Required | | :- | :- | :- | | `541` | Manufacturer Code | Yes | | `542` | Machine Model | Yes | | `543` | Serial Number | Yes | | `544` | Machine SW Version | Yes | | `551` | Type | No | | `593` | VMC HW Version | No | <Warning> You must send attributes `541`, `542`, `543`, and `544` on every call: * **`541` Manufacturer Code**: the manufacturer's English name (for example, `myCompanyName`). * **`542` Machine Model**: the machine model. * **`543` Serial Number**: the machine serial number as it appears on the machine. * **`544` Machine SW Version**: the machine software version. Omitting any of these attributes can result in incomplete reporting and diagnostics data in Nayax Core. </Warning> # Connection Interfaces Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-connections Connector pinout, USB 2.0, and UART TTL connection specifications for the UNO-mini. The UNO-mini connects to the host controller through a single 8-pin Molex connector that multiplexes USB 2.0 and UART TTL interfaces. ## Connector The Molex 5054330871 8-pin connector carries both the USB and UART interfaces. Only one communication interface should be active at a time. <Frame> <img alt="Molex 5054330871 8-pin connector 3D view" /> </Frame> The following diagram shows the pin numbering as seen from the mating face of the connector. <Frame> <img alt="Molex connector pin layout with pins numbered 1 to 8" /> </Frame> The following table lists all pin assignments. | Pin | Signal | | :- | :- | | 1 | Host UART RX | | 2 | Host UART TX | | 3 | TEST LED | | 4 | GND | | 5 | GND\_EXT | | 6 | USB-P | | 7 | Vin Ext (5–12 V) | | 8 | USB-N | ## SDK interface cable Nayax can provide a reference SDK interface cable for integration and testing purposes. <Frame> <img alt="SDK interface cable assembly schematic showing connector, wire gauges, and all pin connections" /> </Frame> This reference cable is not included in the UNO-mini mass-production bill of materials. ## USB 2.0 connection The UNO-mini supports USB 2.0 Full Speed (12 Mbps) communication with the host controller. ### Signal lines Connect the USB interface using the following pin assignments: * Connect USB D+ to pin 6 (USB-P). * Connect USB D- to pin 8 (USB-N). * Connect GND to both pin 4 and pin 5. * Supply the full device power (up to 3 W peak) from the host via pin 7 (Vin Ext). ### Enumeration Upon USB connection, the UNO-mini enumerates as a CDC (Communications Device Class) virtual serial port. The host OS assigns a COM port on Windows or a `/dev/ttyACMx` device node on Linux and Android. * **Linux and Android**: No custom USB driver is required. * **Windows**: The standard CDC driver (`usbser.sys`) is used. Install it manually if it is not loaded automatically. ### Cable requirements Observe the following requirements when designing or selecting the USB cable: * USB D+ and D- lines must be a twisted pair with impedance of 90 Ω ±15 Ω. <Frame> <img alt="USB Data+ and Data- lines twisted together as a pair" /> </Frame> * Maximum cable length: 3 m (per USB 2.0 specification for Full Speed devices). * Use a shielded cable to minimize EMI. Connect the shield to chassis ground at the host end only (single-point grounding). * Do not route the USB cable in the same conduit as high-current power wiring. <Note> Hot-plugging the USB cable is not expected during normal operation. Ensure the host application handles USB disconnection and reconnection events gracefully and restores the communication session automatically. </Note> ## UART TTL connection The UNO-mini supports UART TTL communication as an alternative to USB. <Warning> Do not connect the UNO-mini UART RX/TX lines directly to a 5 V logic system without a level-shifter. Doing so exceeds the absolute maximum input voltage and may permanently damage the UNO-mini. Use a bi-directional level-shifter such as the TXS0102 or SN74LVC2T45 if the host UART operates at 5 V. </Warning> ### Signal lines Connect the UART interface using the following pin assignments: * Connect UART TX from the UNO-mini (host RX) to pin 1 (Host UART RX). * Connect UART RX to the UNO-mini (host TX) to pin 2 (Host UART TX). * Supply power (Vin) on pin 7, and connect GND to pins 4 and 5. ### UART parameters The following table lists the UART interface parameters. | Parameter | Value | Notes | | :- | :- | :- | | **Baud rate** | 115,200 bps | Default; configurable if required | | **Data bits** | 8 | | | **Stop bits** | 1 | | | **Parity** | None | | | **Flow control** | None | No hardware or software flow control | | **Voltage level** | 3.3 V TTL | Do not connect 5 V logic directly | | **TX series resistor** | 470 Ω (on UNO-mini) | Host RX input resistance must be at least several kΩ | ### Host RX input impedance The UNO-mini TX output line includes a 470 Ω series resistor as part of an RC filter. To avoid excessive voltage drop on the TX line, the host RX input impedance must meet the following requirements: * Minimum: 5 kΩ * Recommended: 10 kΩ to 100 kΩ (ensures less than 10% voltage drop across the 470 Ω series resistor) <Frame> <img alt="UART circuit schematic showing UNO-mini TX output with 470 Ω series resistor and host RX connection" /> </Frame> ### Cable recommendations Follow these guidelines when routing UART wiring: * Maximum cable length: 1 m at 115,200 baud without additional line conditioning. * Use shielded twisted pair for UART TX/RX lines. Reduce baud rate if communication errors occur. * Keep UART wiring away from high-current power lines and switching power supplies to minimize noise coupling. * In noisy environments, add ferrite beads at both ends of the UART lines. ## Next steps <CardGroup> <Card title="Get started with EMV Core" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-get-started-1" icon="link"> Install the EMV Core SDK and begin your software integration. </Card> <Card title="EMV Core integration process" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-integration-process" icon="link"> Review the integration and certification milestones for your EMV Core project. </Card> </CardGroup> # Mechanical Integration Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-mechanical Mounting guidelines and serial number display requirements for the UNO-mini. Mounting the UNO-mini correctly ensures reliable contactless card reads and long-term mechanical stability in your enclosure. ## General mounting guidelines Position the UNO-mini according to the following requirements to ensure reliable NFC field performance. * Mount the UNO-mini as close as possible to the front panel. * Mount the UNO-mini as far as possible from metal parts. ## Mounting options The UNO-mini has one mounting screw hole for an M3 screw with a maximum thread depth of 4 mm. Using the M3 screw alone is not sufficient for a production installation. Design a plastic bracket that attaches the UNO-mini firmly to the machine body, and use the M3 screw only as a secondary retention point. Nayax technical support must review and confirm your mechanical mounting design before production. Contact your Nayax integration support team to schedule a design review. ## Nayax serial number The Nayax device serial number is the only way Nayax support can identify your device in Nayax Core. Display the serial number in all three of the following locations. 1. **Machine label**: Attach a physical label to the machine with the text "Nayax SN:" followed by the serial number. <Frame> <img alt="Machine label example showing the Nayax SN field highlighted" /> </Frame> 2. **OEM backend system**: Create a mapping in your backend between the OEM machine ID and the Nayax serial number. <Frame> <img alt="OEM backend device detail screen showing the Nayax SN field highlighted" /> </Frame> 3. **Machine display**: If the machine has a display, show the serial number in a device information section. <Frame> <img alt="Machine display device information section showing the Nayax SN field highlighted" /> </Frame> ## Next steps <CardGroup> <Card title="User interface requirements" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-user-interface" icon="link"> Review EMV logo placement, card scheme brand rules, and LED display requirements. </Card> <Card title="Power supply" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-power-supply" icon="link"> Understand power requirements and wiring recommendations before connecting the device. </Card> </CardGroup> # UNO-mini Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-overview Hardware overview and specifications for the Nayax UNO-mini contactless EMV reader. The UNO-mini is Nayax's compact contactless EMV reader for OEM manufacturers and kiosk integrators who need certified EMV payment acceptance in their hardware. <Frame> <img alt="UNO-mini contactless EMV reader" /> </Frame> ## System architecture The UNO-mini is part of the Nayax OEM POS Solution, a three-component system that handles the full payment stack so you can focus on your application's user interface and business logic. The three components are: * **UNO-mini**: The cashless reader hardware. Handles contactless card reading and EMV processing at the device level. * **EMV Core**: Client software that runs on the kiosk controller (Android, Linux, or RTOS). Serves as the integration layer between your application, the payment processor gateway, and the UNO-mini. * **Nayax Core**: Pre-integrated cloud service for remote management of terminals and clearing transactions worldwide. Nayax also provides documentation and sample code to support system integrators throughout the integration process. ## Specifications The following table lists the main hardware specifications. | Parameter | Value | | :- | :- | | **Power** | 5–14 VDC; 0.7 W idle, 3 W peak | | **CPU** | Arm 32-bit Cortex-M33 with TrustZone and enhanced security features | | **CPU speed** | 160 MHz | | **CPU memory** | Flash: 2 MB; RAM: 786 KB | | **External memory** | Flash: 8 MB | | **Host communications** | USB 2.0 FS; UART TTL | | **Contactless EMV** | EMVCo L1 v3.x compatible; full NFC support including card emulation | | **Security** | 2 AES coprocessors (one with DPA resistance); public key accelerator (DPA resistant); true random number generator (NIST SP800-90B compliant) | | **SAM interfaces** | 1 x micro SAM | | **LEDs** | 4 green (EMV) | | **Operating temperature** | -35°C to 70°C | | **Humidity** | 10%–90% non-condensing | | **Dimensions (H x W x D)** | 49.5 x 49.5 x 10.8/13.4 mm | | **Main connector** | Molex 5054330871, 8 pins | | **Additional connector** | 1 x micro SIM (3FF) | | **Regulatory** | FCC, CE, UL, RoHS, TQM | | **EMV certification** | Levels 1, 2, and 3 | ## Supported payment methods The UNO-mini accepts all major contactless payment methods: * Debit and credit cards * Mobile and NFC contactless payments * Prepaid cards and closed-loop payment solutions ## Next steps <CardGroup> <Card title="Mechanical integration" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-mechanical" icon="link"> Mount the UNO-mini in your hardware enclosure and configure serial number display. </Card> <Card title="Get started with EMV Core" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-get-started-1" icon="link"> Install the EMV Core SDK and connect to the UNO-mini from your host application. </Card> </CardGroup> # Power Supply Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-power-supply Power requirements, wiring recommendations, and reset recovery procedure for the UNO-mini. The UNO-mini requires a stable, regulated DC power supply. Insufficient or noisy power is the most common cause of intermittent operational failures. <Warning> **Power supply minimum requirements** * The DC supply voltage must remain within the 5–14 VDC range at all times. The absolute minimum operational voltage is 4.5 V; voltages below this level may cause the device to enter an inconsistent state. * Use a well-regulated supply voltage. Do not use unfiltered AC-rectified power sources. * Verify supply stability with an oscilloscope during reader installation. * Contact the Nayax technical team if you have any uncertainty about your power supply design. </Warning> ## Power requirements The following table lists the power parameters for the UNO-mini. | Parameter | Value | Notes | | :- | :- | :- | | **Supply voltage range** | 5–14 VDC | Absolute minimum operational: 4.5 V | | **Idle power consumption** | 0.7 W | No active card transaction | | **Peak power consumption** | 3 W | During NFC field activation and card read | | **Recommended supply** | Regulated DC, filtered | Do not use unfiltered AC-rectified sources | | **Reverse polarity protection** | None | Verify correct polarity before connection | The supply must sustain at least 3 W peak load while keeping the output voltage within the 5–14 VDC range under all load conditions. ## Cable wire gauge For power supply wiring, observe the following minimum specifications: * For a 5–6 V supply with cable lengths up to 1 m: use a minimum 26 AWG wire for the Vin (pin 7) and GND (pin 4/5) lines. * For cable lengths greater than 1 m: contact Nayax integration support to confirm your design before production. ## Grounding The UNO-mini connector provides two separate GND pins with distinct functions. Both must be connected correctly. * **Pin 4 (GND)**: Connect to the signal and communications ground reference of the host system. * **Pin 5 (GND\_EXT)**: Connect to the power return ground. ## Power reset recovery In rare cases, the UNO-mini may become unresponsive due to communication failures that cannot be resolved by reinitializing the serial interface alone. The host hardware design should include the ability to cut and restore power to the UNO-mini under software control as a last-resort recovery mechanism. ### Recommended implementation Include a switchable power rail for the UNO-mini Vin line (pin 7), controlled by the host processor. A common implementation uses a P-channel MOSFET or a load switch IC such as the TPS22965 or MAX14689, driven by a GPIO on the host controller. The switch must be capable of sustaining the 3 W peak load. ### Reset sequence Follow these steps when the UNO-mini becomes unresponsive, allowing a configurable timeout (recommended: 30–60 seconds) before escalating to a power reset: 1. Attempt normal communication recovery by reconnecting the USB or UART session. 2. If unresolved, cut power to pin 7. 3. Hold power off for a minimum of 500 ms to allow internal capacitors to fully discharge. 4. Restore power and wait 10 seconds for the UNO-mini to complete its boot sequence before resuming communication. 5. Log the reset event for remote diagnostics. <Warning> Frequent or uncontrolled power cycling may affect device longevity and transaction state consistency. Ensure that any in-flight transaction is voided or resolved before initiating a power reset. </Warning> ## Next steps <CardGroup> <Card title="Connection interfaces" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-connections" icon="link"> Connect the UNO-mini to your host controller via USB or UART TTL. </Card> <Card title="Get started with EMV Core" href="/docs/integrate-pos-device/emv-core/get-started/emv-core-get-started-1" icon="link"> Install the EMV Core SDK and connect to the UNO-mini from your host application. </Card> </CardGroup> # User Interface Requirements Source: https://devzone.nayax.com/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-user-interface EMV logo placement, card scheme branding, and LED and audio requirements for UNO-mini integrations. Integrating the UNO-mini requires your enclosure and display to meet specific EMVCo certification requirements for logos, LEDs, and audio feedback. ## EMV contactless logo The EMV contactless logo must appear on your machine panel at the same position as the logo printed on the UNO-mini device: the center of the antenna. When reproducing the logo, follow the EMVCo sizing, clear space, and color rules. See the [EMVCo Contactless Symbol Reproduction Requirements](/images/docs/uno-mini/EMVCo-Contactless-Symbol-Reproduction-Requirements-Oct-2019.pdf) for the full specification. ## Card scheme brand guidelines Card scheme logos on the machine panel or display are optional. If you choose to display them, they must comply with each scheme's brand guidelines. The following table lists the brand guidelines documentation for each major card scheme. | Card scheme | Brand guidelines | | :- | :- | | Visa | [Visa Merchant Signage](https://www.merchantsignage.visa.com/brandguidelines) | | Mastercard | [Mastercard Brand Center](https://www.mastercard.com/brandcenter) | | American Express | [American Express Checkout](https://www.americanexpress.com/en-us/business/merchant/supplies/details/?pid=CheckoutDL) | | Discover | [Discover Global Network Signage and Logos](https://www.discoverglobalnetwork.com/resources/businesses/signage/) | ## LED and audio requirements The UNO-mini has 4 green LEDs on its front panel. These LEDs are required by EMVCo for POS devices and must be visible to the end user. <Frame> <img alt="UNO-mini front panel showing 4 LED indicators and EMV contactless logo" /> </Frame> There are two compliant ways to present the LEDs to the end user: 1. Create a transparent area in the machine panel to expose the original device LEDs directly. 2. Simulate the LED states on the machine display screen, if one is present. ### LED and audio states The following table lists all LED and audio states as defined in EMVCo Book A v2.10, sections 9.x. LED legend: ○ Off, ● On. Blinking states are noted in the LED pattern column. Audio tones: * **Success tone**: approximately 1500 Hz sine wave, 500 ms * **Alert tone**: approximately 750 Hz double beep (200 ms on / 200 ms off / 200 ms on) | Status | Msg index | Description | LED pattern | Message display | Audio | | :- | :- | :- | :- | :- | :- | | **Not Ready** | — | Reader not powered or not communicating | ○ ○ ○ ○ | No message | None | | **Idle** | 17 | Powered and connected, not polling for card. First LED blinks approximately 200 ms every 5 s. | ● ○ ○ ○ (blink) | Welcome | None | | **Ready to Read** | 1 | Polling for card. Transaction amount may be shown. | ● ○ ○ ○ | € xx.xx / Present card | None | | **Card Read Successfully** | 35 | All four LEDs light in sequence over approximately 250 ms, then remain lit for approximately 750 ms, then turn off. Total duration: 1000 ms. | Sequential flash (all 4) | Card read OK / Remove card | Success tone | | **Authorizing** | 36 | Online authorization in progress | ○ ○ ○ ○ | Authorizing / Please wait | — | | **Approved** | 6 | Transaction approved by issuer or by terminal offline decision | ○ ○ ○ ○ | Approved | None (success tone played at card read) | | **Not Approved** | 9 | Transaction declined by issuer | ○ ○ ○ ○ | Not Approved | Optional alert tone | | **Declined** | 255 | General decline | ○ ○ ○ ○ | Declined | Optional alert tone | | **Read Error** | 39 | Error occurred reading the card | ○ ○ ○ ○ | Read error / Please try again | Optional alert tone | | **Conditions Not Satisfied** | 38 | Contactless conditions not met, for example when risk management requires a contact chip | ○ ○ ○ ○ | Please try another card | Optional alert tone | | **Contactless Collision** | 5 | Multiple contactless cards detected simultaneously | ○ ○ ○ ○ | Present one card only | Optional alert tone | | **Timeout / No Card** | 30 | Transaction timed out with no card presented | ○ ○ ○ ○ | Timeout / No Card | Optional alert tone | | **Terminated** | 10 | Transaction terminated by terminal or application | ○ ○ ○ ○ | Terminated | Optional alert tone | | **PIN Entry Required** | 11 | Card requires PIN entry, which cannot be performed via contactless | ○ ○ ○ ○ | Please try another card | Optional alert tone | | **See Phone** | 12 | Mobile device requires customer action, such as unlocking or approving on the phone | ○ ○ ○ ○ | See Phone | Optional alert tone | ## Next steps <CardGroup> <Card title="Power supply" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-power-supply" icon="link"> Review power requirements and wiring recommendations before connecting the device. </Card> <Card title="Connection interfaces" href="/docs/integrate-pos-device/emv-core/uno-mini/uno-mini-connections" icon="link"> Connect the UNO-mini to your host controller via USB or UART TTL. </Card> </CardGroup> # Security & Authentication Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/security-authentication/index To ensure the security and integrity of every transaction, the Spark API requires a two-part authentication process. All requests must identify the sender and include a digital signature so Nayax can verify that no one has altered the request body. ## Authentication Options Choose the integration path that matches your project status: <CardGroup> <Card icon="key" title="Authentication" href="/docs/integrate-pos-device/spark/security-authentication/spark-authentication"> Sign requests with the current header-based signature method for new integrations. </Card> <Card icon="clock-rotate-left" title="Legacy Authentication" href="/docs/integrate-pos-device/spark/security-authentication/spark-legacy-authentication"> Generate an HMAC signature from the request body to maintain existing integrations. </Card> <Card icon="screwdriver-wrench" title="Interactive Authentication Tool" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool"> Build and inspect ciphers and signature headers without writing code. </Card> </CardGroup> # Authentication Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/security-authentication/spark-authentication To ensure secure communication, every request sent by the Integrator must include two specific authentication headers. These headers verify your identity and ensure the integrity of the transaction data. ## Prerequisites Before you begin, ensure you have the following resources: * A valid Sign Key (shared by Nayax, typically 16 characters) * The associated Sign Key ID <Warning> Your request body must contain the `SparkTransactionId` field. </Warning> ## Authenticate requests Once you have the required resources, you can start authenticating your API requests to Spark by following the steps below: 1. Combine the static string `IntegratorId` with your ID in the following format `IntegratorId: {SignKeyID}`. See the example below: ```text theme={null} IntegratorId: 927 ``` 2. Join the `SparkTransactionId` from your request body with your `Sign Key`, separated by a semicolon (`;`), in the following format: `SparkTransactionId;SignKey` ```text theme={null} 123456789123456789abcdefghijklmnopqr;RbtdDsiVNjkAeRty ``` 3. Perform a **SHA-256** hash on the resulting string using **UTF-8** encoding. Resulting hash: ```text theme={null} 1b7dd1c4010698824de66f13e1387efc28a4bba00b720d4be8cdb3b598b9603e ``` 4. The final header should look like the following: ```text theme={null} TransactionSignature: 1b7dd1c4010698824de66f13e1387efc28a4bba00b720d4be8cdb3b598b9603e ``` ## Request example (cURL) See an example request for the `/StartAuthentication` endpoint: <Note> **Base URL** The Spark API base URL is `https://nayax-spark-dmz.nayax.com/api`. The same host serves the integration and production environments. </Note> ```bash theme={null} curl --location 'https://nayax-spark-dmz.nayax.com/api/StartAuthentication' \ --header 'IntegratorId: 927' \ --header 'TransactionSignature: 1b7dd1c4010698824de66f13e1387efc28a4bba00b720d4be8cdb3b598b9603e' \ --header 'Content-Type: application/json' \ --data '{ "TokenId": 123456, "TerminalId": "0434334921112345", "TerminalIdType": 1, "Random": "123456789qwertyui", "Cipher": "X305dITNTAw2vHsxE+taVcn6UvgBC3fdI6QbqeABgHbo8CKsoZhqISJfslehCiA+L7XYrqvKFci7C6BNj/tr zBuNJwBEjgBzKhhgpJ5ggnw=", "SparkTransactionId": "123456789123456789abcdefghijklmnopqr" }' ``` ## See also <CardGroup> <Card icon="bolt" title="Interactive authentication tool" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool"> Build and inspect ciphers and signature headers in your browser, no code required. </Card> <Card icon="repeat" title="Payment flows" href="/docs/integrate-pos-device/spark/payment-flows/transaction-flows-spark"> How authentication fits into the full Spark transaction sequence. </Card> </CardGroup> # Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/spark Spark is Nayax’s server-to-server API, enabling third-party systems to initiate and manage payment transactions on Nayax terminals remotely. It is designed for use cases where direct communication with the terminal, such as through Marshall, is not possible or desired, or as remote-controlled electric vehicle (EV) chargers, intelligent vending machines, or connected kiosks. Spark enables developers to initiate a session, handle authentication, authorize payments, and trigger settlements, all from their backend system. At the same time, Nayax manages the actual card interactions through its POS devices, such as VPOS Touch. Spark allows you to: * Control terminals remotely over the internet. * Offer flexible user experiences: remote commands, self-managed loyalty cards, and dynamic pricing. * Retain control over the business logic while Nayax handles the payment processing and compliance. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> ## Remote and device start As an integrator, you'll utilize the Spark API to manage distinct transaction flows, initiating sessions either remotely or directly from the device. * With Remote Start, your server initiates the transaction by requesting that Nayax activate a specific device, a flow beneficial for app/computer-driven transactions. * With Device Start the transaction process begins directly from Nayax's terminal when a consumer interacts with it, allowing you to display crucial information, such as tariffs or service station availability, to the user via Nayax's `InfoQuery` API method before the session even formally commences on the machine. This distinction in initiation points is crucial for tailoring your integration to the specific user experience you aim to provide. This section provides guides to assist you in using the Spark API, outlining the integration process, authentication methods, available API methods, and other relevant information. See the pages below to learn more. ## Get started <CardGroup> <Card icon="diagram-project" title="Integration" href="/docs/integrate-pos-device/spark/spark-integration"> Connect your backend to Nayax's payment terminals through Spark's API-driven workflows. </Card> <Card icon="network-wired" title="Network requirements" href="/docs/integrate-pos-device/spark/spark-network-requirement"> Set up HTTPS with TLS 1.2 or 1.3 and whitelist the required IPs. </Card> <Card icon="lock" title="Security & authentication" href="/docs/integrate-pos-device/spark/security-authentication/index"> Complete Spark's two-part authentication process to secure every transaction. </Card> </CardGroup> ## Build your integration <CardGroup> <Card icon="route" title="Payment flows" href="/docs/integrate-pos-device/spark/payment-flows/transaction-flows-spark"> Choose the payment flow that matches how you initiate transactions. </Card> <Card icon="tower-broadcast" title="Webhook callbacks" href="/docs/integrate-pos-device/spark/webhook-callbacks/index"> Use webhooks so Spark alerts your system to important events automatically. </Card> </CardGroup> ## Reference & resources <CardGroup> <Card icon="book-open" title="Spark API reference" href="/reference/integrate-pos-device/spark/overview#"> Browse the full Spark API reference for every endpoint and parameter. </Card> <Card icon="code" title="Sample codes" href="/docs/integrate-pos-device/spark/sample-codes/spark-authentication-code-sample"> Follow a full sample code flow for Spark's authentication mechanism. </Card> <Card icon="folder-open" title="Additional resources" href="/docs/integrate-pos-device/spark/additional-resources/index"> Find technical reference data and troubleshooting help for your Spark integration. </Card> </CardGroup> # Integration Process Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/spark-integration-process A step-by-step guide to integrating with Nayax The Nayax integration process ensures a seamless and efficient implementation, providing technical support at every stage. From initial setup to production deployment, Nayax teams work closely with partners or customer developers to meet all technical and operational requirements. ## Stages of the process The integration process is divided into five main stages: 1. Kickoff Meeting 2. Integration Setup 3. Development Phase 4. Testing & Certification 5. Production Setup <Frame> <img /> </Frame> Each stage is structured to provide technical support and essential resources, ensuring smooth and efficient implementation. ### Kickoff Meeting The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator’s project, the technical teams, and the Nayax Integration Engineer. ### Integration Setup This initial stage establishes the technical foundation for the integration. 1. **Assignment of Integration Engineer:** A Nayax integration engineer is assigned as the primary focal point for the partner or customer developer. 2. **Configuration:** The engineer configures the Nayax Core (backend) and sets up the device with the relevant transaction flow in the integration environment. 3. **Welcome Email:** At the end of this phase, the engineer sends a welcome email with all necessary resources, including the URL, SDK, documentation, tokens, and other required development tools. ### Development Phase This stage focuses on the partner or customer developing their solution. 1. **Partner/Customer Development:** The partner or customer developer creates their solution using the Nayax API/SDK. 2. **Support:** During this phase, the integration engineer provides assistance for any issues or "how-to" queries to ensure progress. <Note> **Support for OCPP/OCPI Integrations** For integrations based on **OCPP/OCPI** standards, this step is not relevant, as these integrations follow predefined flows according to the standard protocol. </Note> ### Testing & Certification This stage verifies that the integration meets Nayax’s standards: 1. **Certification Test Requirements:** Nayax shares specific requirements for certification tailored to the integration type and transaction flow. 2. **Testing:** The partner or customer developer performs a series of tests (typically 9–15, depending on the integration type and flow). 3. **Review:** The Nayax integration engineer reviews the results of these tests to ensure all criteria are met. 4. **Certification:** Upon successfully completing all tests, Nayax issues a certification letter confirming the integration is ready for deployment. ### Production Setup The final stage ensures a smooth deployment in a live environment: 1. **Production Environment Configuration:** Nayax configures the integration in the production environment, including the machine model setup. 2. **Support for Testing:** The integration engineer provides support during production lab or field tests to confirm successful deployment. The Nayax integration process provides a structured, step-by-step approach that ensures reliable and efficient implementation. By collaborating closely with partners and customers, Nayax delivers high-quality solutions that meet industry standards and support successful deployments in the market. # Spark Network Requirements Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/spark-network-requirement Ports, IP addresses, and connection methods to whitelist so Spark terminals can reach Nayax. For communication between Nayax and the Integrator, we support HTTPS with TLS 1.2 and 1.3. ## Whitelist IPs To ensure smooth communication, the Integrator must whitelist the following Nayax public IP addresses. | Environment | Region | IP Addresses | | :- | :- | :- | | Production | Germany (DE) | `137.221.37.126`, `185.159.234.2` | | Production | United States (US) | `72.28.118.100`, `72.28.111.132`, `185.159.233.2` | | Production | Israel (IL) | `185.159.232.2`, `84.110.125.194`, `82.102.172.206`, `212.179.76.198` | | QA | — | `31.154.55.2` | If required, the Integrator should also allow access from the Nayax QA environment so the Nayax QA team can conduct automation testing. ## See also * [Integration Process](/docs/integrate-pos-device/spark/spark-integration-process) * [Authentication](/docs/integrate-pos-device/spark/security-authentication/spark-authentication) # Certification & Testing Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/additional-resources/certification-files This page provides access to essential certification files, API testing tools, and documentation that support your integration and validation of TweezerComm services. ## Certification files These Excel files are required for certification with various payment scenarios. Download and use them during your implementation and certification process: * [Pre-Selection Certification](https://docs-engine.modularity.co.il/_static/Retail_Certification_preSelection.xlsx): Validates terminal behavior before transaction authorization. * [Pre-Authorization Certification](https://docs-engine.modularity.co.il/_static/Retail_Certification_preAuthorization.xlsx): Verifies transaction handling up to the authorization phase. ## Agamento documentation The [Agamento User Manual](https://docs-engine.modularity.co.il/_static/Agamentoguidapp_v1.pdf) is a comprehensive guide for using the Agamento payment application, including configuration, transaction flow, and troubleshooting tips. ## IPs and ports In cases where the IT environment has a firewall or IP whitelist, you will need to open a list of IP addresses and Ports, so that you can use TweezerComm. You can see this list in the file below: * [IP & Port List](/) ## Postman collection Postman is a tool for designing, testing, and documenting APIs. Use the TweezerComm Postman collection to explore and validate endpoint behavior during development. <Note> **Download Postman** You can download Postman for Linux, Windows, or macOS, or use the [web version](https://web.postman.co/). </Note> To get started, click the button below to open the Postman collection. <PostmanButton href="https://orange-water-45471.postman.co/workspace/2bd08c21-8393-42b6-b02a-8374c6e6887e/collection/36813629-e96e299f-a802-4859-931f-8e2fa3ce2b02?utm_source=email&utm_medium=view_collection" /> <Warning> **`DeviceIP`** Remember to change the `{DeviceIP}` to your own in the request URL. </Warning> # Configure Static IP Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/additional-resources/configuring-static-ip Go into the Wifi settings (password 260089) and click on the gears icon: <Frame> <img alt="Picture123 1" /> </Frame> Then on the pencil icon to edit your current connection and scroll down towards "Advanced <Frame> <img alt="Picture5" /> </Frame> And scroll down to IP settings: <Frame> <img alt="Picture6" /> </Frame> And fill in the IP details # Response Codes Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/additional-resources/response-codes This page lists all possible response codes returned by TweezerComm, along with descriptions and result types. ## Response codes The table below describes possible response codes returned from TweezerComm. | Code | Description | Result | Error Trigger | | - | - | - | - | | 0 | TRANSACTION APPROVED | Success | Payment processed successfully | | 10 | PARTIAL APPROVAL | Partial Success | Only part of the amount approved | | 162 | INFORMATIVE TRANSACTION | Info | Non-financial transaction | ## Error codes The table below describes all possible error codes returned by TweezerComm: | Code | Description | Result | Error Trigger | | - | - | - | - | | -64 | VOID NOT POSSIBLE | Failure | Transaction cannot be voided | | -61 | TRANSACTION NOT FOUND | Failure | No record of transaction in system | | -51 | ILLEGAL FIELD | Failure | Invalid data in request fields | | -44 | INCORRECT EXPIRY DATE | Failure | Card expiration date incorrect | | -15 | CARD NOT ALLOWED | Failure | Card type not permitted | | -5 | NO PP RESPOND | Failure | No response from payment processor | | -1 | SYSTEM NOT READY | Failure | System undergoing maintenance | | 1 | BLOCKED CARD | Failure | Card is blocked by issuer | | 2 | STOLEN CARD | Failure | Card reported as stolen | | 3 | CALL CREDIT CARD COMPANY | Failure | Manual verification required | | 4 | TRANSACTION DECLINED | Failure | Issuer declined the transaction | | 5 | FAKE CARD | Failure | Fraudulent card detected | | 6 | LAST 3 DIGITS INCORRECT | Failure | Incorrect CVV/CVC entered | | 7 | SECURITY CODE INCORRECT | Failure | Wrong security code provided | | 8 | INCORRECT AVS | Failure | Address verification mismatch | | 9 | CARD EXPIRED | Failure | Expired credit/debit card | | 11 | MISSING POINTS | Failure | Insufficient reward points | | 12 | CARD NOT ALLOWED | Failure | Restricted card usage | | 13 | DECLINED. INCORRECT BALANCE CODE | Failure | Incorrect balance type | | 14 | DECLINED. CARD NOT ASSOCIATED | Failure | Card not linked to account | | 15 | DECLINED. NETWORK ERROR | Failure | Network issue during processing | | 16 | DECLINED. CURRENCY NOT ALLOWED | Failure | Unsupported currency for transaction | | 26 | CREDIT TERM NOT ALLOWED | Failure | Credit terms not permitted | | 30 | UNKNOWN CARD | Failure | Card details unrecognized | | 36 | CARD EXPIRED NO CONNECTION | Failure | Expired card, network issue | | 44 | INCORRECT TRACK2 | Failure | Magnetic stripe data incorrect | | 45 | INCORRECT PAN | Failure | Incorrect primary account number | | 46 | MSR NOT ALLOWED | Failure | Magnetic stripe reader usage denied | | 50 | NO ACQUIRING DATA | Failure | Acquiring bank details missing | | 126 | TRANSACTION CANCELED | Failure | User or system canceled transaction | | 160 | INCORRECT AUTH NUMBER | Failure | Invalid authorization code | | 161 | BLOCKED CARD | Failure | Card blocked due to fraud | | 200 | CARD DECLINED | Failure | Payment rejected by issuer | | 400 | MUST GO ONLINE | Failure | Requires online processing | | 450 | ONLINE APPROVAL FAILED | Failure | Online authorization rejected | | 458 | AUTH NUM NOT ALLOWED | Failure | Unauthorized authentication number | | 911 | PA ERROR | Failure | 3D Secure authentication error | | 912 | PA TIMEOUT | Failure | 3D Secure authentication timeout | | 991 | PERIODIC IS NEEDED | Failure | Recurring authentication required | | 993 | TIMEOUT | Failure | Transaction request timed out | | 995 | VUID ALREADY EXIST | Failure | Duplicate transaction detected | | 998 | TRANSACTION CANCELED | Failure | Transaction manually canceled | | 4000 | GATEWAY ERROR | Failure | Payment gateway malfunction | | 5003 | ILLEGAL ACTION | Failure | Illegal or unsupported action requested | # Additional Resources Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/additional-resources/tweezercomm-additional-resources This section contains supporting materials that help you work with TweezerComm, including certification files and a complete list of error codes. ## Pages <CardGroup> <Card icon="certificate" title="Certification & Testing" href="/docs/integrate-pos-device/tweezercomm/additional-resources/certification-files"> Access certification files, API testing tools, and integration validation documentation. </Card> <Card icon="list-ol" title="Response Codes" href="/docs/integrate-pos-device/tweezercomm/additional-resources/response-codes"> Look up TweezerComm's response codes, descriptions, and result types. </Card> <Card icon="network-wired" title="Configure Static IP" href="/docs/integrate-pos-device/tweezercomm/additional-resources/configuring-static-ip"> Set a static IP address on the terminal's Wi-Fi connection. </Card> <Card icon="flask" title="Test Terminal Setup" href="/docs/integrate-pos-device/tweezercomm/additional-resources/using-test-cards-real-cards-during-the-integration"> Set up a test terminal so you can use test cards instead of real ones, for Israel or global integrations. </Card> </CardGroup> # Test Terminal Setup Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/additional-resources/using-test-cards-real-cards-during-the-integration This page is separated to 2 sections- depending on whether the integration is running in Israel or globally: # Israel In Israel, you would have your device have a test terminal configurations: This is done in order to be able to access the app without activating the device. ## Setting up test terminal configurations You'd click on Agamento's logo a 7 times- you'd see the "Login" page switch from "Login to DCS" to "Login to DCS QA2", as well as having a "Skip" button: you'd click on said "Skip" button. You'd then go into the Technician menu again, this time into "Payment Services": <Frame> <img alt="Picture7" /> </Frame> And click on "Ashrait EMV", then on "Establishment": <Frame> <img alt="Picture8" /> </Frame> And insert Ashrait's test retail number: 0883012 And then the device would switch from "Disconnected" to "Connected": <Frame> <img alt="Picture9" /> </Frame> <Note> When using test terminal configurations (<u>only relevant in Israel</u>), **the customer must ensure to issue test cards**: this is something that is unrelated to Nayax as we do not issue cards, and can be done via a few different issuers, such as:\ Max, Cal, Isracard etc.\ \ Should a real credit card be presented when configured to test terminal- it would be declined as the card would be directed to SHVA's test servers (who expect test cards only) </Note> ## General settings  You'd also go into the Technician menu -> Settings and ensure that the device has the right POS Type (integration type). We'd remove "Amount dialog"- a screen that pops up prior to the consumer presenting his card regarding whether or not the consumer approves of said transaction (normally customers would like consumer to present their card right away once they initiated a transaction). # Global In any country but Israel, you'd have a "stub" (dummy) billing provider instead of test terminal, which would simulate a real billing provider approving of your presented card- yet there would be no actual contact with a real billing provider and you would not charged for your transactions. In this case, you can use real credit cards without any worries of being charged. # abortDisplay Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortdisplay The `abortDisplay` method is used to cancel ongoing display operations initiated on the terminal (e.g. instructional messages, prompts). ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `abortDisplay`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc":"2.0", "method":"abortDisplay", "id":"123", "params": [ "device",{} ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `device` | `string` | The service name (fixed value) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123", "result": { "statusCode": 0, "statusMessage": "ok" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | `integer` | Operation status (0 = success) | | `statusMessage` | `string` | Message indicating operation result. | # abortDisplayQR Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortdisplayqr The `abortDisplayQR` method is used to cancel an ongoing QR code display previously initiated with the displayQR method. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `abortDisplayQR`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc":"2.0", "method":"abortDisplayQR", "id":"123", "params": [ "device",{} ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `device` | `string` | The service name (fixed value) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123", "result": { "statusCode": 0, "statusMessage": "canceled" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | `integer` | Operation status (0 = success) | | `statusMessage` | `string` | Message indicating operation result. | # abortGetUserInput Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortgetuserinput The `abortGetUserInput` method cancels an ongoing user input request initiated by the [`getUserInput`](/docs/integrate-pos-device/tweezercomm/device-methods/getuserinput) method. This is used when a transaction is canceled or when input is no longer needed. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `abortGetUserInput`. ```json theme={null} { "jsonrpc":"2.0", "method":"abortGetUserInput", "id":"123", "params": [ "device",{} ] } ``` ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123", "result": { "statusCode": 0, "statusMessage": "canceled" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = OK) | | `statusMessage` | string | Status message (e.g., "canceled") | # abortGetUserSelection Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortgetuserselection The `abortGetUserSelection` method is used to cancel an active user selection prompt that was initiated using the `getUserSelection` method. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `abortGetUserSelection`, and include the service name in the `params` array. ```json theme={null} { "jsonrpc": "2.0", "method": "abortGetUserSelection", "id": "123", "params": [ "device", {} ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `device` | `string` | The service name (fixed value) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123", "result": { "statusCode": 0, "statusMessage": "canceled" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | `integer` | Operation status (0 = success) | | `statusMessage` | `string` | Message indicating operation result | # abortReadCard Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortreadcard The `abortReadCard` method is used to cancel an ongoing readCard operation. This is helpful when the user wants to stop card reading before it completes, such as during a timeout, user cancellation, or application logic control. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the method field should be set to `abortReadCard`, and the params must include the fixed value device: ```json theme={null} { "jsonrpc": "2.0", "method": "abortReadCard", "id": "123454352", "params": [ "device" ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | - | - | - | | `params` | array | Must contain the value `device` | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "ok" } } ``` <br /> ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `statusMessage` | string | Operation result message | # abortSwipe Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/abortswipe The `abortSwipe` method is used to cancel an ongoing magnetic card swipe operation previously initiated with `displaySwipeCard`. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `abortSwipe`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc": "2.0", "method": "abortSwipe", "id": "123", "params": [ "device", {} ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `device` | `string` | The service name (fixed value) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123", "result": { "statusCode": 0, "statusMessage": "OK" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | `integer` | Operation status (0 = success) | | `statusMessage` | `string` | Message indicating operation result | # displayQR Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/displayqr The `displayQR` method displays a QR code on the terminal's screen. It supports optional titles, subtitles, and a cancel button. The QR code must belong to a predefined domain. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `displayQR`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc": "2.0", "method": "displayQR", "params": [ "device", { "title": "displayQRtitle", "subtitle": "displayQRSubtitle", "isCancellable": false, "urlData": "https://stackoverflow.com", "timeout": 60 } ], "id": "32323453" } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `title` | `string` | Title text to be shown above the QR code | | `subtitle` | `string` | Subtitle text below the title | | `isCancellable` | `boolean` | Whether a cancel button is displayed (default: true) | | `urlData` | `string` | URL encoded as the QR code (**mandatory**) | | `timeout` | `integer` | Display timeout in seconds (default: 30) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1", "result": { "statusCode": 0, "statusMessage": "ok" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | `integer` | Operation status (0 = success) | | `statusMessage` | `string` | Message indicating operation result | # displaySwipeCard Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/displayswipecard The `displaySwipeCard` method prompts the user to swipe a magnetic card using the terminal's MSR (Magnetic Stripe Reader). You can customize the messages shown on the display. This method returns the Track 2 data of the card once it has been read. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `displaySwipeCard`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc": "2.0", "method": "displaySwipeCard", "params": [ "ashrait", { "string1": "stringDisplay1", "string2": "stringDisplay2", "string3": "stringDisplay3", "string4": "stringDisplay4", "OpenMSR": true, "timeout": 120 } ], "id": "1234" } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `string1` | string | First line of display text | | `string2` | string | Second line of display text | | `string3` | string | Third line of display text | | `string4` | string | Fourth line of display text | | `OpenMSR` | boolean | Whether to open the magnetic stripe reader | | `timeout` | integer | Timeout duration in seconds | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1234", "result": { "statusCode": 0, "track2": "120134687465103900=6163595030067654872" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `track2` | string | Card track 2 data from magnetic stripe | # getConfig Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getconfig The `getConfig` method is used to retrieve the current terminal configuration. It returns a complete configuration object with various system settings, such as printer usage, supported transaction types, and UI behavior. This method is often used with `setConfig` to read and update the terminal configuration. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getConfig`, and the params must include the fixed value device as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getConfig", "id": "123454352", "params": [ "device" ] } ``` ### Request parameters The table below describes the request parameters for this method: | Name | Type | Description | | - | - | - | | `params` | array | Must contain the value `device` | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "configApplied": true, "autoPeriodic": true, "usePrinter": true, "wakeOnTransaction": false, "amountDialog": false, "ashraitServer": "SHVA", "posType": "TC_HTTP", "ecr": "1", "allowCreditCardTrack2": false, "ackTransaction": false, "balanceAtLoyalty": false, "tmsRetailer": "0883012", "manualInterface": true, "fullPANonReceipt": true, "code3": "HANDLE_ON_PINPAD", "slaveMode": false, "startOnBoot": true, "customDataScreen": false, "keypadAlwaysOn": false, "transactionTypesAllowed": [1, 8, 6, 4, 5, 7, 3, 2], "creditTermsAllowed": [1, 8, 3, 6, 2], "limitedAccessReports": false, "limitedAccessSpecialTransactions": false, "moduSMS": false, "ravMutav": false, "ravMutavMain": "", "ravMutavAmex": "", "ravMutavDiners": "", "paymentAggregator": "NONE", "paUser": "", "configVersion": "manual", "remoteAppPackageName": "", "remoteAppActivityName": "", "bonjourReusableSocket": false, "protectInfoPopup": false, "fastCredit": false, "visaSensoryBranding": false, "tcSecondaryPort": false, "processorIP": "", "autoRebootTime": "", "agamentoModel": "EMV", "enforceCardEjection": false, "printTransactionMode": "DEFAULT", "printPreAuthTransactionMode": "DEFAULT", "connectionEnhancement": false, "forcePeriodicBatch": false, "receiptHeaderTitle": "", "receiptHeaderSubtitle1": "", "receiptHeaderSubtitle2": "" } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `configApplied` | bool | Indicates whether the configuration is applied | | `autoPeriodic` | bool | Enables automatic end-of-day batch | | `usePrinter` | bool | Enables internal printer usage | | `wakeOnTransaction` | bool | Wake terminal from screen saver | | `amountDialog` | bool | Show amount dialog before transaction | | `ashraitServer` | string | Deposit gateway provider (e.g., SHVA) | | `posType` | string | Integration method (e.g., TC\_HTTP) | | `ecr` | string | POS identifier | | `allowCreditCardTrack2` | bool | Enable track2 data collection on swipe | | `ackTransaction` | bool | Enable transaction acknowledgment mechanism | | `balanceAtLoyalty` | bool | Use merchant ID for loyalty lookup | | `tmsRetailer` | string | TMS retailer ID | | `manualInterface` | bool | Enable manual entry interface | | `fullPANonReceipt` | bool | Print full PAN on merchant receipt | | `code3` | string | Code 3 handling method | | `slaveMode` | bool | Set terminal as slave mode | | `startOnBoot` | bool | Start Agamento on device boot | | `customDataScreen` | bool | Show custom data screen before transaction | | `keypadAlwaysOn` | bool | Keep keypad active on screen | | `transactionTypesAllowed` | array | List of allowed transaction types | | `creditTermsAllowed` | array | List of allowed credit terms | # getInfo Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getinfo The `getInfo` method retrieves basic metadata about the payment device, including hardware and manufacturer information, serial numbers, and the current timestamp. This can be useful for device diagnostics, remote inventory, and configuration validation. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getInfo`, as shown in the example below: ```json theme={null} { "jsonrpc": "2.0", "method": "getInfo", "params": [ "device" ], "id": "4309656" } ``` ### Request parameters The table below describes the request parameters for this method: | Name | Type | Description | | - | - | - | | `params` | array | Must contain the value `device` | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "4309656", "result": { "statusCode": 0, "statusMessage": "ok", "manufacturer": "LANDI", "model": "APOS A8OVS", "serialNumber": "215RCA893253", "nayaxSerialNumber": "0904041822134284", "timeStampEpoch": 1721214919337, "timeStampString": "17/07/2024 14:15:19" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = OK, others = errors TBD) | | `statusMessage` | string | Status description (e.g., "ok") | | `data` | string | User-provided input data | # getLocation Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getlocation Get the device's GPS location for location-based terminal features. The `getLocation` method retrieves the device's current geographic location, including latitude, longitude, accuracy, and the time of the reading. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getLocation`, as shown in the example below: ```json theme={null} { "jsonrpc": "2.0", "method": "getLocation", "params": [ "device" ], "id": "101" } ``` ### Request parameters The table below describes the request parameters for this method: | Name | Type | Description | | - | - | - | | `params` | array | Must contain the value `device` | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "101", "result": { "statusCode": 0, "statusMessage": "", "latitude": "32.0879", "longitude": "34.7999", "accuracy": "12.4", "timestamp": "1751443200000" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `statusMessage` | string | Operation result message | | `latitude` | string | Latitude coordinate of the device's location. | | `longitude` | string | Longitude coordinate of the device's location. | | `accuracy` | string | Accuracy of the location reading, in meters. | | `timestamp` | string | Epoch timestamp (milliseconds) of when the location was recorded. | # getProperty Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getproperty The `getProperty` method retrieves specific terminal details, such as the terminal serial number (S/N), the DCS hardware serial number, or the Agamento application version. If no property type is specified, it returns a broader dictionary of terminal-related properties. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To call this method, set the method field to `getProperty`, and include the params array: ```json theme={null} { "jsonrpc":"2.0", "method":"getProperty", "id":"123454352", "params": [ "device", 1 ] } ``` ### Request parameters The request must include the params array with the following parameters: * The first parameter is the service name: `device`. * The second parameter (optional) is a numeric property type: * `1` for Terminal Serial Number (S/N) * `2` for DCS Hardware Serial Number * `3` for Agamento Version ## Response The response varies depending on the input: * If a property type is specified, the result is a single string value. ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": "209QCA8T4597" } ``` * If no property type is specified, the result is a dictionary containing multiple device properties. ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "retailerNumber": "0883232", "nayaxSN": "0907042423158538", "isActiveDes": "Active", "emvConfigFileId": 0, "emvProvider": 1, "paymentMethods": "1;2;4;5;9;22;72;", "cibusEnabled": "", "cibusRestaurantId": 0, "cibusPosId": 0, "multipassEnabled": "", "multipassPosId": 0 } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `retailerNumber` | string | Retailer identifier | | `nayaxSN` | string | Nayax serial number | | `isActiveDes` | string | Activation status | | `emvConfigFileId` | int | EMV configuration file ID | | `emvProvider` | int | EMV provider ID | | `paymentMethods` | string | Enabled payment method codes | | `cibusEnabled` | string | Cibus support status | | `cibusRestaurantId` | int | Cibus restaurant ID | | `cibusPosId` | int | Cibus POS ID | | `multipassEnabled` | string | Multipass support status | | `multipassPosId` | int | Multipass POS ID | # getUserInput Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getuserinput The `getUserInput` method prompts the user for a numeric or alphanumeric input on the payment terminal. This is typically used to collect an ID, amount, or any free-form entry required for the transaction or flow. See also the [`abortGetUserInput`](/docs/integrate-pos-device/tweezercomm/device-methods/abortgetuserinput) method to cancel a pending input request. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `getUserInput`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc":"2.0", "method":"getUserInput", "id":"1234567890", "params": [ "device",{ "title": "Main-Title", "subtitle": "Sub-Title", "type": "numeric", "minLength": 2, "maxLength": 10, "timeout": 5 } ] } ``` ### Request parameters The table below describes the parameters of the request: | Parameter | Type | Description | | - | - | - | | `title` | string | The main title is displayed to the user. | | `subtitle` | string | Subtitle is displayed below the title. | | `type` | string | Type of input (`numeric` or `alphanumeric`). | | `minLength` | int | Minimum number of characters allowed. | | `maxLength` | int | Maximum number of characters allowed. | | `timeout` | int | Timeout in seconds before the request expires. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1234567890", "result": { "statusCode": 0, "data": "12456" } } ``` ### Response parameters The table below describes the response parameters for this method: | Parameter | Type | Description | | - | - | - | | `retailerNumber` | string | Retailer identifier. | | `nayaxSN` | string | Nayax serial number. | | `isActiveDes` | string | Activation status. | | `emvConfigFileId` | int | EMV configuration file ID. | | `emvProvider` | int | EMV provider ID. | | `paymentMethods` | string | Enabled payment method codes. | | `cibusEnabled` | string | Cibus support status. | | `cibusRestaurantId` | int | Cibus restaurant ID. | | `cibusPosId` | int | Cibus POS ID. | | `multipassEnabled` | string | Multipass support status. | | `multipassPosId` | int | Multipass POS ID. | # getUserSelection Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getuserselection The `getUserSelection` method prompts the user to choose an option from a predefined list. This is useful for gathering user input where multiple choices are available. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `getUserSelection`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc":"2.0", "method":"getUserSelection", "id":"1234567890", "params": [ "device",{ "title": "Choose item:", "itemsKeys": ["1","2","3","4"], "itemsValues": ["Option1","Option2","Option3","Option4"], "timeout": 60 } ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `title` | string | Main title to display. | | `itemsKeys` | array of string | Values used as the return keys. | | `itemsValues` | array of string | Visible values are presented to the user. | | `timeout` | int | Timeout duration in seconds. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1234567890", "result": { "statusCode": 0, "selection": "1" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success). | | `statusMessage` | string | Operation message (optional). | | `selection` | string | The selected key from the user. | # getVersion Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/getversion The `getVersion` method retrieves version information for one or more applications installed on the device, such as agamento, spi, or ashrait. It returns the current version tags for each requested application. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `getVersion` and the params must include an array of application names, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "getVersion", "id": "123454352", "params": [ [ "agamento", "spi", "ashrait" ] ] } ``` ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": [ "01.05.00", "01_12_00", "01_10_00" ] } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `result` | string | Array of version tags for each app queried | # hideAnimation Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/hideanimation The `hideAnimation` method is used to cancel or hide a currently displayed animation on the device that was previously initiated using the showAnimation method. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `hideAnimation`, and include the service name. ```json theme={null} { "jsonrpc": "2.0", "method": "hideAnimation", "id": "123", "params": [ "device" ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `device` | `string` | The service name (fixed value) | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1234567890", "result": { "statusCode": 0, "data": "12456" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `statusMessage` | string | Message indicating operation result. | # Device Methods Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/index This section covers the API methods for managing payment terminals. Use them to retrieve device information, read card data, configure terminal settings, prompt users for input, control on-screen displays, and send diagnostic logs. The sections below group methods by what they do. ## Device Information & Configuration <CardGroup> <Card icon="circle-info" title="getInfo" href="/docs/integrate-pos-device/tweezercomm/device-methods/getinfo"> Retrieve device metadata, including hardware, manufacturer, and serial number information. </Card> <Card icon="code-branch" title="getVersion" href="/docs/integrate-pos-device/tweezercomm/device-methods/getversion"> Retrieve version information for the apps running on the device. </Card> <Card icon="sliders" title="getProperty" href="/docs/integrate-pos-device/tweezercomm/device-methods/getproperty"> Retrieve specific terminal details, such as serial numbers or hardware identifiers. </Card> <Card icon="gear" title="getConfig" href="/docs/integrate-pos-device/tweezercomm/device-methods/getconfig"> Retrieve the terminal's current configuration object. </Card> <Card icon="pen-to-square" title="setConfig" href="/docs/integrate-pos-device/tweezercomm/device-methods/setconfig"> Apply configuration settings to the terminal. </Card> <Card icon="location-dot" title="getLocation" href="/docs/integrate-pos-device/tweezercomm/device-methods/getlocation"> Retrieve the device's current geographic location. </Card> </CardGroup> ## Card Reading <CardGroup> <Card icon="credit-card" title="readCard" href="/docs/integrate-pos-device/tweezercomm/device-methods/readcard"> Read card data from the magnetic stripe or NFC reader. </Card> <Card icon="ban" title="abortReadCard" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortreadcard"> Cancel an ongoing readCard operation. </Card> <Card icon="share-from-square" title="readCardForExternalTransaction" href="/docs/integrate-pos-device/tweezercomm/device-methods/readcardforexternaltransaction"> Read card data so an external processor can authorize the transaction. </Card> </CardGroup> ## User Input & Selection <CardGroup> <Card icon="keyboard" title="getUserInput" href="/docs/integrate-pos-device/tweezercomm/device-methods/getuserinput"> Prompt the user for numeric or alphanumeric input on the terminal. </Card> <Card icon="ban" title="abortGetUserInput" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortgetuserinput"> Cancel an ongoing getUserInput request. </Card> <Card icon="list-check" title="getUserSelection" href="/docs/integrate-pos-device/tweezercomm/device-methods/getuserselection"> Prompt the user to choose from a predefined list of options. </Card> <Card icon="ban" title="abortGetUserSelection" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortgetuserselection"> Cancel an active getUserSelection prompt. </Card> </CardGroup> ## Display & Animations <CardGroup> <Card icon="circle-play" title="showAnimation" href="/docs/integrate-pos-device/tweezercomm/device-methods/showanimation"> Show an approved or declined animation on the device. </Card> <Card icon="eye-slash" title="hideAnimation" href="/docs/integrate-pos-device/tweezercomm/device-methods/hideanimation"> Cancel or hide the animation currently showing on the device. </Card> <Card icon="id-card" title="displaySwipeCard" href="/docs/integrate-pos-device/tweezercomm/device-methods/displayswipecard"> Prompt the user to swipe a magnetic card on the terminal. </Card> <Card icon="ban" title="abortSwipe" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortswipe"> Cancel an ongoing card swipe operation. </Card> <Card icon="qrcode" title="displayQR" href="/docs/integrate-pos-device/tweezercomm/device-methods/displayqr"> Show a QR code on the terminal's screen. </Card> <Card icon="ban" title="abortDisplayQR" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortdisplayqr"> Cancel an ongoing QR code display. </Card> <Card icon="ban" title="abortDisplay" href="/docs/integrate-pos-device/tweezercomm/device-methods/abortdisplay"> Cancel ongoing display operations, such as prompts or messages. </Card> </CardGroup> ## Diagnostics & Events <CardGroup> <Card icon="bolt" title="sendGeneralEvent" href="/docs/integrate-pos-device/tweezercomm/device-methods/sendgeneralevent"> Send operational events or status updates from the terminal. </Card> <Card icon="arrows-rotate" title="updatePinpadTransactionStatus" href="/docs/integrate-pos-device/tweezercomm/device-methods/updatepinpadtransactionstatus"> Report a transaction's outcome back to the device after an external processor authorizes it. </Card> <Card icon="file-arrow-up" title="uploadLogs" href="/docs/integrate-pos-device/tweezercomm/device-methods/uploadlogs"> Send diagnostic logs from the terminal for troubleshooting. </Card> </CardGroup> <Note> **Send Requests** See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how to structure and send requests. </Note> # readCard Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/readcard The `readCard` method reads data from a card using either the magnetic swipe reader (MSR) or the contactless NFC reader. It supports Mifare cards only for NFC. This method is commonly used in loyalty or identification scenarios. If the user cancels the operation or the request times out, it can be aborted using the abortReadCard method. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the method field should be set to `readCard` the parameters should define the reader configuration and user interface messages. ```json theme={null} { "jsonrpc": "2.0", "method": "readCard", "id": "1234567890", "params": [ "device", { "readMsr": true, "readMifare": true, "message1": "SWIPE OR PRESENT CARD", "message2": "", "message3": "", "timeout": 40, "cancelable": true, "mifare": { "type": "classic", "commType": 2, "appId": "A12345", "appKey": "00000000000000000000000000000123", "appKeyNo": 0, "appCryptoMethod": 1, "fileNo": 0, "fileType": 0, "expectedDataLen": 4 } } ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | - | - | - | | `readMsr` | bool | Whether to enable the magnetic stripe reader. | | `readMifare` | bool | Whether to enable the NFC reader (Mifare only). | | `message1` | string | Main message shown to the user. | | `message2` | string | First subtitle shown to the user. | | `message3` | string | Second subtitle shown to the user. | | `timeout` | int | Timeout in seconds. | | `cancelable` | bool | Whether to allow canceling the operation. | **Mifare Object Parameters** | Name | Type | Description | | - | - | - | | `type` | string | Card type (classic, desfireev2, etc.) | | `commType` | int | Communication type | | `appId` | string | Application ID | | `appKey` | string | Application key | | `appKeyNo` | int | Application key number | | `appCryptoMethod` | int | Crypto method | | `fileNo` | int | File number | | `fileType` | int | File type | | `expectedDataLen` | int | Expected data length | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "ok", "cardEntryMode": 1, "cardId": "string" } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `statusMessage` | string | Operation result message | | `cardEntryMode` | int | Entry mode: 0 = Swipe, 1 = Contactless | | `track2` | string | Track 2 data (for swipe only) | | `cardId` | string | Card ID (for contactless only) | # readCardForExternalTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/readcardforexternaltransaction Read card data from the device for authorization by an external payment processor. The `readCardForExternalTransaction` method reads card data from the device so that the transaction can be authorized by an external processor instead of the built-in payment engine. Once the card is read, pass the returned `pinpadCardDataId` to [`updatePinpadTransactionStatus`](/docs/integrate-pos-device/tweezercomm/device-methods/updatepinpadtransactionstatus) to report the outcome of the external authorization back to the device. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `readCardForExternalTransaction`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc": "2.0", "method": "readCardForExternalTransaction", "params": [ "device", { "vuid": "44d96006", "readMifare": true } ], "id": "16115875" } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `vuid` | string | Vendor (client) unique transaction identifier. Mandatory. | | `readMifare` | bool | Whether to enable the NFC reader (Mifare only). | # sendGeneralEvent Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/sendgeneralevent The `sendGeneralEvent` method allows the terminal to communicate specific operational events or status updates to the system. This is mainly used to monitor the results of background processes such as periodic communications, setup routines, or reporting transaction-specific data. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `sendGeneralEvent`, as shown in the example below: ```json theme={null} {   "id": "123",   "method": "sendGeneralEvent",   "jsonrpc": "2.0",   "params": [     "device",     {       "eventCode": 0,       "eventData": {         "transactionAmount": "100.00",         "card": "6935"       }     }   ] } ``` ### Request parameters The table below describes the request parameters for this method: | Name | Type | Description | | :- | :- | :- | | `params[0]` | string | Must contain the value `device` | | `params[1]` | object | Contains the `eventCode` and associated `eventData` | | `eventCode` | integer | The identifier for the specific event ([see Enums below](#event-code-enums)) | | `eventData` | object | Metadata related to the event, such as amount, card digits | #### Event Code Enums | Value | Name | | :- | :- | | **0** | `GeneralEventCode_Event` | | **1** | `GeneralEventCode_EventEstablishmentFinishedSuccessfully` | | **2** | `GeneralEventCode_EventPeriodicFinishedSuccessfully` | | **3** | `GeneralEventCode_EventEstablishmentFailed` | | **4** | `GeneralEventCode_EventPeriodicFailed` | | **5** | `GeneralEventCode_EventMiniSettlementFailed` | | **6** | `GeneralEventCode_EventCardReadError` | | **7** | `GeneralEventCode_EventMustToGoOnlineError` | | **8** | `GeneralEventCode_EventTransactionReport` | ## Response A successful request will return the following response: ```json theme={null} {    "jsonrpc": "2.0",    "id": "123",    "result": {        "statusCode": 0,        "statusMessage": "ok"    } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Operation status (0 = OK, others = errors TBD) | | `statusMessage` | string | Status description (e.g., "ok") | <br /> # setConfig Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/setconfig The `setConfig` method applies configuration settings to the terminal. These can include settings such as deposit server preferences, enabling the manual interface, or forcing a reset. It is recommended that you call `setConfig` on each device initialization to ensure consistent configuration. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the `method` field needs to be set to `setConfig` and the params must include the service name and a dictionary of configuration fields, as shown in the example request below: ```json theme={null} { "jsonrpc": "2.0", "method": "setConfig", "id": "1234567890", "params": [ "device", { "ashraitServer": "NAYAX", "manualInterface": true, "reset": true } ] } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | - | - | - | | `ashraitServer` | string | The deposit server to use (e.g., "NAYAX"). | | `manualInterface` | bool | Enable or disable manual card entry. | | `reset` | bool | Whether to apply the configuration with reset. | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "1234567890", "result": { "statusCode": 0 } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | # showAnimation Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/showanimation The `showAnimation` method is used to display an animation on the device to indicate either an approved or declined action. This is typically shown after transaction processing. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> To invoke this method, set the `method` field to `showAnimation`, and include the service name and parameters as shown below. ```json theme={null} { "jsonrpc": "2.0", "method": "showAnimation", "id": "1", "params": [ "device", { "name": "approved", "repeat": false, "hideAfter": 4, "string1": "stringDisplay1", "string2": "stringDisplay2" } ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `name` | string | Animation name. Valid values: `approved`, `declined` | | `repeat` | boolean | Whether the animation should repeat (default: false) | | `hideAfter` | integer | Seconds to wait before hiding (0 = stay visible) | | `string1` | string | Optional text to display as the first message | | `string2` | string | Optional text to display as the second message | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "1", "result": { "statusCode": 0, "statusMessage": "ok" } } ``` ### Response parameters The table below describes the response parameters for this method: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (`0` = success). | | `statusMessage` | string | Message indicating operation result. | # updatePinpadTransactionStatus Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/updatepinpadtransactionstatus Report the outcome of an externally authorized transaction back to the device. The `updatePinpadTransactionStatus` method reports the outcome of an externally authorized transaction back to the device, after the card was read using [`readCardForExternalTransaction`](/docs/integrate-pos-device/tweezercomm/device-methods/readcardforexternaltransaction). See [Pinpad Mode](/docs/integrate-pos-device/tweezercomm/pinpad-mode) for more on this flow. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `updatePinpadTransactionStatus`. * The service must be set to `engine` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "updatePinpadTransactionStatus", "id": "123454352", "params": [ "engine", { "pinpadCardDataId": "a1b2c3d4e5f6", "tranResultStatus": 1, "processorTerminalId": "12345", "paymentMethodId": "1", "tranType": 1 } ] } ``` ### Request parameters The table below describes the parameters of the request: | Name | Type | Description | | - | - | - | | `pinpadCardDataId` | string | Identifier returned by [`readCardForExternalTransaction`](/docs/integrate-pos-device/tweezercomm/device-methods/readcardforexternaltransaction). | | `tranResultStatus` | integer | Result of the external authorization. `1` = PINPAD\_ONLY\_APPROVED, `2` = PINPAD\_ONLY\_DECLINED, `3` = PINPAD\_ONLY\_CANCELED. | | `processorTerminalId` | string | Merchant ID for the processor terminal. | | `paymentMethodId` | string | Payment method identifier. Currently only `1` (credit card) is supported. | | `tranType` | integer | Transaction type code. See Transaction Type Values below. | **Transaction Type Values** | Value | Name | | - | - | | `1` | Sale | | `2` | Refund | | `3` | Pre-Authorization | | `4` | Deferred Authorization | | `5` | CNP | | `6` | Pre-Authorization Completion | | `7` | Void | # uploadLogs Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/device-methods/uploadlogs The `uploadLogs` method sends diagnostic logs from the terminal to the Modularity back-end systems. This is useful for troubleshooting, support, and system monitoring. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, the method field should be set to `uploadLogs`, and the params must include the service name device: ```json theme={null} { "jsonrpc": "2.0", "method": "uploadLogs", "id": "123454352", "params": [ "device" ] } ``` ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "result": { "statusCode": 0, "statusMessage": "ok" } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `statusCode` | integer | Operation status (0 = success) | | `statusMessage` | string | Operation message | # Two Phases Transaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction The two-phases transaction flow for the SHVA payment service divides a single transaction into two distinct steps: * An initial information retrieval phase * A subsequent authorization phase This flow is often used by clients who implement a loyalty mechanism, as it allows for user interaction between the two phases, such as canceling or changing transaction values. ## Transaction flow To understand the 2 Phases transaction flow, consider the following sequence of events: <Frame> <img /> </Frame> Here's a breakdown of each step: 1. The client application (labeled as DC) initiates the first phase of the transaction by sending a [`doTransactionPhase1`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase1) request to the Nayax Device. 2. The Nayax Device prompts the cardholder to present their card by either inserting, showing, or swiping it. 3. The Nayax Device responds to the DC with a [`doTransactionPhase1`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase1) response, which contains the card and transaction properties. 4. After any necessary user interaction (e.g., changes or cancellations), the DC sends a [`doTransactionPhase2`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase2) request to the Nayax Device to complete the transaction. 5. The Nayax Device sends an authorization request to the Payment Server. 6. The payment server processes the request and sends an authorization response back to the Nayax Device, which then relays the Authorization response to the DC. 7. At the end of the day, the DC sends a [`doPeriodic`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) request to the Nayax Device, which communicates with the payment server to complete the day's batch process. The Nayax Device then sends a [`doPeriodic`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) response back to the DC. ## See also <CardGroup> <Card icon="bolt" title="Regular transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction"> Process and authorize a payment request in a single step. </Card> <Card icon="hourglass-half" title="Pre-authorization (Israel)" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> <Card icon="clock" title="Deferred payment" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment"> Run a pre-authorization phase followed by a final authorization phase. </Card> <Card icon="arrows-split-up-and-left" title="Split transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction"> Split a transaction's payment across multiple sub-merchants. </Card> </CardGroup> # Regular Transaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction Unlike the two-phase model, the Single-phase transaction flow for the SHVA payment service processes and authorizes a payment request in a single, continuous sequence. This streamlined approach is used for regular payments where no intermediate user interaction is required. ## Transaction flow To understand the single-phase transaction flow, consider the following sequence of events: <Frame> <img /> </Frame> Here's a breakdown of each step: 1. The client application (labeled as DC) initiates the transaction by sending a [`doTransaction`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait) request to the Nayax Device. 2. The Nayax Device prompts the cardholder to present their card by inserting, showing, or swiping it. 3. The Nayax Device sends an authorization request to the Payment Server. 4. The Payment Server processes the request and sends an Authorization response back to the Nayax Device. 5. The Nayax Device relays the Authorization response to the DC, completing the payment portion of the flow. 6. At the end of the day, the DC sends a [`doPeriodic`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) request to the Nayax Device, which then communicates with SHVA to complete the day's batch process. The Nayax Device sends a [`doPeriodic`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) response back to the DC. ## See also <CardGroup> <Card icon="layer-group" title="Two phases transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction"> Split a transaction into an information retrieval step and a completion step. </Card> <Card icon="hourglass-half" title="Pre-authorization (Israel)" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> <Card icon="clock" title="Deferred payment" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment"> Run a pre-authorization phase followed by a final authorization phase. </Card> <Card icon="arrows-split-up-and-left" title="Split transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction"> Split a transaction's payment across multiple sub-merchants. </Card> </CardGroup> # Deferred Payment Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment The Deferred transaction flow processes a payment request in two distinct phases: 1. A Pre-Authorization phase 2. A final Authorization and Settlement phase This two-step approach is particularly useful for transactions where the final amount or details may change after the initial card interaction. ## Transaction flow To understand the Deferred transaction flow, consider the following sequence of events: <Note> Steps inside the green area are performed online, and the ones inside the red area are performed offline. </Note> <Frame> <img /> </Frame> Here's a breakdown of each step: 1. After the client application (POS) performs its [`doPeriodic()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) to settle the stored card transactions. 2. `setConfig()` will switch the device to work in deferred mode, using offline mode. 3. The POS sends a [`doTransaction()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait) request to the Nayax Device, triggering a new transaction. 4. The cardholder taps their contactless card. 5. The Nayax Device checks for "Deferred pre-conditions" and, upon approval, returns the transaction result as `Approved->Pending`. This means the transaction is approved. <Note> Once the deferred mode is finished working, continue to step 6. </Note> 6. The client application calls `setConfig()` setting off-line mode to false. 7. The client application calls the `authorizePendingTransactions()`, sending the pending transactions to Nayax's device asking to settle them (but no settlement is performed yet). 8. The Nayax Device communicates with SHVA to initiate the pending transaction authorization. 9. The transaction results are returned to the Device. 10. The transaction results are returned to the client application. 11. The flow concludes with a final [`doPeriodic()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) call from the client application, to settle all authorized transactions. ## See also <CardGroup> <Card icon="bolt" title="Regular transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction"> Process and authorize a payment request in a single step. </Card> <Card icon="layer-group" title="Two phases transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction"> Split a transaction into an information retrieval step and a completion step. </Card> <Card icon="hourglass-half" title="Pre-authorization (Israel)" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> <Card icon="arrows-split-up-and-left" title="Split transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction"> Split a transaction's payment across multiple sub-merchants. </Card> </CardGroup> # Israel Payment Flows Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-israel-payment-flows TweezerComm follows structured payment flows to ensure secure and efficient transaction processing. These define how different transaction types are handled within the system, including transactions for loyalty cards. Understanding these flows enables client applications to integrate appropriately with the AshraitEMV Application (AEA) and optimize payment processing capabilities. The pages below provide a more detailed description of each one: <CardGroup> <Card icon="bolt" title="Regular Transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction"> Process and authorize a payment request in a single step. </Card> <Card icon="layer-group" title="Two Phases Transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction"> Split a transaction into an information retrieval step and a completion step. </Card> <Card icon="hourglass-half" title="Pre-Authorization (Israel)" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> <Card icon="clock" title="Deferred Payment" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment"> Run a pre-authorization phase followed by a final authorization phase. </Card> <Card icon="arrows-split-up-and-left" title="Split Transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction"> Split a transaction's payment across multiple sub-merchants. </Card> </CardGroup> # Pre-Authorization (Israel) Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel Tweezercomm's pre-authorization transactions are processed, authorized, and either settled or canceled based on the response from the payment server. This process also includes a resilience mechanism for handling errors. ## Transaction flow To understand the pre-authorization transaction flow, consider the following sequence of events: <Frame> <img /> </Frame> Here's a breakdown of each step: 1. The client application (POS) sends a [`doTransaction()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait) request to the Nayax Device with a parameter (`Trancode=2`) to initiate a pre-authorization. 2. The cardholder inserts, shows, or swipes their card. 3. The Nayax Device communicates with the payment server to perform the pre-authorization. 4. The payment server responds, and the Nayax Device relays the `Authorization result` back to the POS. 5. At a later time, the POS sends another [`doTransaction()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait) request, this time with a parameter (`Trancode=3`) to initiate the completion of the pre-authorized transaction. 6. The Nayax Device communicates with the payment server to complete the transaction. 7. The payment server responds with a `Completion result`, which the Nayax Device sends back to the POS. 8. At the end of the day, the POS sends a [`doPeriodic()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) request. The Nayax Device communicates with the payment server to perform the settlement of the day's transactions and sends a [`doPeriodic()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) result back to the POS. ## See also <CardGroup> <Card icon="bolt" title="Regular transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction"> Process and authorize a payment request in a single step. </Card> <Card icon="layer-group" title="Two phases transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction"> Split a transaction into an information retrieval step and a completion step. </Card> <Card icon="clock" title="Deferred payment" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment"> Run a pre-authorization phase followed by a final authorization phase. </Card> <Card icon="arrows-split-up-and-left" title="Split transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction"> Split a transaction's payment across multiple sub-merchants. </Card> </CardGroup> # Split Transaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-split-transaction The Split Transaction flow is used for transactions involving multiple sub-merchants. The diagram illustrates how a Milgam System can initiate a transaction on the Nayax Device and receive a response that includes a specific attribute for a sub-retailer. ## Transaction flow To understand the Split transaction flow, consider the following sequence of events: <Frame> <img /> </Frame> Here's a breakdown of each step: 1. The Milgam System sends one or more [`addSubRetailer()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/addsubretailer) requests to the Nayax Device. In the example, three such requests are made. 2. The Milgam System performs its [`doPeriodic()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic) call and then initiates a transaction with a [`doTransaction()`](/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait) request. 3. The cardholder presents their card. 4. The Nayax Device communicates with the payment server to perform the Authorization and Settlement of the transaction. 5. The payment server sends the transaction result back to the Nayax Device. 6. The Nayax Device relays the transaction result to the Milgam System, including a `subRetailer` attribute with the value `XXXXX` to identify the relevant sub-retailer. ## See also <CardGroup> <Card icon="bolt" title="Regular transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/single-phase-transaction"> Process and authorize a payment request in a single step. </Card> <Card icon="layer-group" title="Two phases transaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/2-phase-transaction"> Split a transaction into an information retrieval step and a completion step. </Card> <Card icon="hourglass-half" title="Pre-authorization (Israel)" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-pre-authorization-israel"> Process and authorize a transaction, then settle or cancel it based on the payment server's response. </Card> <Card icon="clock" title="Deferred payment" href="/docs/integrate-pos-device/tweezercomm/israel-payment-flows/tweezercomm-deferred-payment"> Run a pre-authorization phase followed by a final authorization phase. </Card> </CardGroup> # abortTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/aborttransaction-copy The `abortTransaction` method cancels an ongoing transaction before it is registered in the database, meaning before a doTransaction Response is received (= prior to a consumer's card presentation / prior to a transaction timeout taking place).\ This ensures that transactions in progress but not yet finalized can be safely terminated without affecting the merchant's records. This method is beneficial when a user initiates a transaction but cancels before completion or when an issue is detected during processing that requires stopping the transaction. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `abortTransaction`. * The service must be set to `ashrait` in the `params`. The request includes a list of parameters, with the first being the service name, which is currently fixed as `ashrait`, and the second being a dictionary containing all other transaction-specific details. ```json theme={null} {     "jsonrpc":"2.0",     "method":"abortTransaction",     "params":[         "ashrait",         {            "vuid":"cb740169-7758-4f55-b685-b90652b9aba6"         }     ],     "id":"123454352" } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | - | - | - | | `vuid` | string | Vendor (client) unique transaction identifier. | ## Response A successful request will return the following response: ```json theme={null} {     "jsonrpc": "2.0",     "result": {         "statusCode": 0,         "statusMessage": "ok"     },     "id": "123454352" } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | - | - | - | | `statusCode` | integer | The operation status (`0` = success) | | `statusMessage` | string | The operation message (e.g., `ok`) | <br /> # addSubRetailer Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/addsubretailer The `addSubRetailer` method is used to load sub-retailers into the terminal. This method can only be used if the main retailer is defined as RAV-SAPAK at Shva. <Warning> **Use `doPeriodic`** After loading new retailers, you should use the `doPeriodic` method. </Warning> ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `addSubRetailer`. * The service must be set to `ashrait` in the `params`. The request needs to include the `retailerId` list. ```json theme={null} { "jsonrpc": "2.0", "method": "addSubRetailer", "id": "123454352", "params": [ "ashrait", { "retailerId": [ "0883806", "0884806" ] } ] } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `retailerId` | array | List of retailers. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "OK" } } ``` ### Response parameters The table below describes the response parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> Transaction status. A value of `0` indicates a successful (approved) transaction. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> Transaction message (e.g., `ok`) </td> </tr> <tr> <td> `mutag` </td> <td> integer </td> <td> Card brand </td> </tr> <tr> <td> `solek` </td> <td> integer </td> <td> Acquirer </td> </tr> <tr> <td> `manpik` </td> <td> integer </td> <td> Card Issuer </td> </tr> <tr> <td> `uid` </td> <td> string </td> <td> Transaction unique identifier </td> </tr> <tr> <td> `posEntryMode` </td> <td> integer </td> <td> POS Entry Mode, type of card transaction. Values are: `0` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), `81` (Fallback (no AID)) </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> Masked personal account number (PAN) </td> </tr> <tr> <td> `rrn` </td> <td> string </td> <td> Transaction authorization number from the authorized entity </td> </tr> <tr> <td> `issuerAuthNum` </td> <td> string </td> <td> Issuer authorization number </td> </tr> <tr> <td> `acquirerMerchantID` </td> <td> string </td> <td> Merchant ID in the acquirer system </td> </tr> <tr> <td> `authCodeManpik` </td> <td> integer </td> <td> Code of authorization. Values are: `0` (Unauthorized transaction), `1` (Authorized by issuer), `2` (Declined by issuer), `3` (Stip approved ABS), `4` (Stip declined ABS), `5` (Voice approval), `6` (Voice declined), `7` (Approved by issuer pre-auth), `8` (Approved by card) </td> </tr> <tr> <td> `gatewayToken` </td> <td> string </td> <td> Gateway token of the card </td> </tr> <tr> <td> `appVersion` </td> <td> string </td> <td> Payment application version </td> </tr> <tr> <td> `retailerId` </td> <td> string </td> <td> Terminal retailer Id </td> </tr> <tr> <td> `ecrNo` </td> <td> string </td> <td> POS identifier </td> </tr> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor unique identifier </td> </tr> <tr> <td> `tranCode` </td> <td> string </td> <td> Transaction Code </td> </tr> <tr> <td> `merchantReceipt` </td> <td> array of key/value </td> <td> Merchant receipt to print or save </td> </tr> <tr> <td> `customerReceipt` </td> <td> array of key/value </td> <td> Customer receipt to print </td> </tr> </tbody> </table> # getSubRetailer Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/addsubretailer-copy The `getSubRetailer` method retrieves a list of all sub-retailers loaded on the terminal and shows their current status. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getSubRetailer`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "getSubRetailer", "params": [ "ashrait" ], "id": "123454352" } ``` ### Request parameters This method doesn't require any parameters beyond the standard service name. ## Response A successful call returns the list of sub-retailers and their status. ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "OK", "subRetailers": [ { "retailerId": "0883806", "retailerName": "", "isActivated": true, "isStartWork": false }, { "retailerId": "0884806", "retailerName": "", "isActivated": true, "isStartWork": false } ] } } ``` ### Response parameters The `result object` contains the following fields: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The status of the operation. `0` indicates success. | | `statusMessage` | string | A message describing the status, such as "OK". | | `subRetailers` | array of objects | A list containing sub-retailer objects. See table below. | ### Sub-retailer object structure Each object in the `subRetailers` array has the following structure: | Name | Type | Description | | :- | :- | :- | | `retailerId` | string | The unique identifier for the sub-retailer. | | `retailerName` | string | The name of the sub-retailer (may be empty). | | `isActivated` | boolean | `true` if the sub-retailer was added to the terminal successfully. | | `isStartWork` | boolean | `true` only after a `doPeriodic` call has been successfully run. | <br /> # authorizePendingTransactions Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/authorizependingtransactions The `authorizePendingTransactions` method processes and finalizes all transactions that are currently in a pending state. This method is essential for merchants who use deferred payment transactions. It allows them to finalize multiple pending transactions in a single batch operation and retrieve a summary of which transactions were approved or declined. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field needs to be set to `authorizePendingTransactions`. * The service must be set to `ashrait` in the `params`. ```json theme={null} {    "jsonrpc":"2.0",    "method":"authorizePendingTransactions",    "params":[       "ashrait",       {}    ],    "id":1 } ``` This method does not require any parameters in the params object. ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} {    "jsonrpc": "2.0",    "id": "1",    "result": {        "statusCode": 0,        "approvedTransactions": [            "25102113483608830127760"        ],        "declinedTransactions": [],        "totalAmount": 100,        "totalCount": 1    } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The overall status of the batch operation. A value of `0` indicates the batch was processed successfully. | | `approvedTransactions` | array of strings | A list of transaction unique identifiers (UIDs) that were successfully authorized and captured. | | `declinedTransactions` | array of strings | A list of transaction unique identifiers (UIDs) that were declined during the authorization attempt. | | `totalAmount` | integer | The total amount (in cents) of all transactions that were approved in this batch. | | `totalCount` | integer | The total number of transactions that were approved in this batch. | <br /> # cancelTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/canceltransaction-1 The `cancelTransaction` method is used to cancel a transaction that has already been approved and is registered in the database. <Warning> Such a transaction can be canceled as long as it is stored in the AEA database, which is cleared after the end-of-day batch when `doPeriodic` is called. </Warning> The client can also implement this action by calling `doTransactionPhase1` with the appropriate tranCode. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `cancelTransaction`. * The service must be set to `ashrait` in the params. The request includes a list of parameters, with the first being the service name, which is currently fixed as `ashrait`, and the second being a dictionary containing all other transaction-specific details. ```json theme={null} {     "jsonrpc": "2.0",     "method": "cancelTransaction",     "params": [         "ashrait",         {             "originalUID": "24071711552508830122539", "vuid": "1234567"         }     ],     "id": "123454352" } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `originalUID` | string | The original UID of the transaction to be canceled. | | `vuid` | string | Vendor (client) unique transaction identifier. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc":"2.0", "result":{ "statusCode": 0, "statusMessage": "׳”׳¢׳¡׳§׳” ׳׳•׳©׳¨׳”", "appVersion": "01.05.22", "retailerId": "0883012013", "ecrNo": "1", "vuid": "ee5e7af5-7719-4726-992f-0eb2915b992a", "tranCode": 1, "currency": "376", "amount": 100, "mutag": 1, "mutagName": "Mastercard", "manpik": 2, "solek": 2, "cardNumber": "*********", "cardNumberOriginalLength": "************************", "expDate": "2305", "cardName": "Mastercard", "tokenizedCardNumber": "c8ae19356dd1d7e946165fab67a14516", "tranType": 1, "posEntryMode": 5, "isClub": false, "isPrepaid": false, "creditTerms": 1, "uid": "23031212432508830123729", "rrn": "948767075 ", "authCodeManpik": 1, "issuerAuthNum": "0652073", "acquirerMerchantID": "6543505", "sysTraceNumber": "01001001", "authorizationCommStat": "{\"connectRetries\":0,\"connectTotalTime\":555,\"authorizationTotalTime\":744,\"smallBlockedTotalTime\":0}", "merchantReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ], "customerReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ] }, "id":1 } ``` ### Response parameters The table below describes the response parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> Transaction status. A value of `0` indicates a successful (approved) transaction. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> Transaction message (e.g., `ok`) </td> </tr> <tr> <td> `mutag` </td> <td> integer </td> <td> Card brand </td> </tr> <tr> <td> `solek` </td> <td> integer </td> <td> Acquirer </td> </tr> <tr> <td> `manpik` </td> <td> integer </td> <td> Card Issuer </td> </tr> <tr> <td> `uid` </td> <td> string </td> <td> Transaction unique identifier </td> </tr> <tr> <td> `posEntryMode` </td> <td> integer </td> <td> POS Entry Mode, type of card transaction. Values are: `0` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), `81` (Fallback (no AID)) </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> Masked personal account number (PAN) </td> </tr> <tr> <td> `rrn` </td> <td> string </td> <td> Transaction authorization number from the authorized entity </td> </tr> <tr> <td> `issuerAuthNum` </td> <td> string </td> <td> Issuer authorization number </td> </tr> <tr> <td> `acquirerMerchantID` </td> <td> string </td> <td> Merchant ID in the acquirer system </td> </tr> <tr> <td> `authCodeManpik` </td> <td> integer </td> <td> Code of authorization. Values are: `0` (Unauthorized transaction), `1` (Authorized by issuer), `2` (Declined by issuer), `3` (Stip approved ABS), `4` (Stip declined ABS), `5` (Voice approval), `6` (Voice declined), `7` (Approved by issuer pre-auth), `8` (Approved by card) </td> </tr> <tr> <td> `gatewayToken` </td> <td> string </td> <td> Gateway token of the card </td> </tr> <tr> <td> `appVersion` </td> <td> string </td> <td> Payment application version </td> </tr> <tr> <td> `retailerId` </td> <td> string </td> <td> Terminal retailer Id </td> </tr> <tr> <td> `ecrNo` </td> <td> string </td> <td> POS identifier </td> </tr> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor unique identifier </td> </tr> <tr> <td> `tranCode` </td> <td> string </td> <td> Transaction Code </td> </tr> <tr> <td> `merchantReceipt` </td> <td> array of key/value </td> <td> Merchant receipt to print or save </td> </tr> <tr> <td> `customerReceipt` </td> <td> array of key/value </td> <td> Customer receipt to print </td> </tr> </tbody> </table> # doMiniSettlement Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dominisettlement The `doMiniSettlement` method is used to settle transactions. <Note> Supported processors: CG, PC. </Note> ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `doMiniSettlement`. * The service must be set to `ashrait` in the `params`. ```json theme={null} {     "jsonrpc":"2.0",     "method":"doMiniSettlement",     "params":[         "ashrait"     ],     "id":1 } ``` ## Response A successful request will return the following response: ```json theme={null} {     "jsonrpc": "2.0",     "result": {         "statusCode": 0,         "ackNumber": "1234567",         "queriedTransactions": ["12345","12345"]     },     "id": 1 } ``` ### Response parameters The table below describes the response parameters for this method. | Name                 | Type             | Description                                                                   | | :- | :- | :- | | `statusCode`           | integer           | Operation status. A value of `0` indicates success. All other values are errors. | | `ackNumber`           | string           | The processor's reference number.                                             | | `queriedTransactions` | array of strings | A list of successfully transmitted transaction UIDs.                           | # doPeriodic Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic The `doPeriodic` method should be called at least once a day to deposit transactions and update the AEA database. This method generates a Z report summarizing the day's transactions. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `doPeriodic`. * The service must be set to `ashrait` in the `params`. * An optional string specifying the report format (`narrow`, `medium`, `wide`, or `xml`) The request contains a list of parameters that can include a `forceUpdateParams` boolean flag to force the terminal to update its retailer parameters. ```json theme={null} { "jsonrpc": "2.0", "method": "doPeriodic", "params": [ "ashrait", "wide", { "forceUpdateParams": true } ], "id": 2 } ``` ### Request parameters This method's parameters are a list of values, not a dictionary. * Service Name (string, mandatory): The service name. Currently, this is a fixed value: ashrait. * Report Format (string, optional): The format of the report. Values include narrow, medium, wide, or xml. * Force Update (boolean, optional): An optional dictionary with a `forceUpdateParams` key. When true, it forces the terminal to update the retailer parameters. ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc": "2.0", "id": "2", "result": { "statusCode": 0, "report": " MODULARITY 12 \n׳ž׳¡׳₪׳¨ ׳ž׳¡׳•׳£: 0883012 \n׳×׳׳¨׳™׳š: 17/07/2024\n...", "ackNumber": "23346317", "queriedTransactions": [ "24071711405408830122531", "24071711552508830122539", "24071711552508830122539" ] } } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Operation status. A value of `0` indicates `OK`. | | `statusMessage` | string | Operation message (e.g., `ok`) | | `report` | string | End of day / Z report content | | `ackNumber` | string | Acknowledge number of this batch | | `queriedTransactions` | string array | Transactions of the current batch | # doTransaction Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransaction-ashrait The `doTransaction` method initiates and processes payment transactions within the TweezerComm protocol. It enables client applications, such as point-of-sale (POS) systems or electronic cash registers (ECRs), to interact with the Agamento payment terminal for secure transaction execution. This method supports multiple transaction types, including: * Regular Transactions: Standard payments using credit cards or closed-loop payment methods. * Refunds: Partial or full refunds of previous transactions. * Pre-Authorizations: Reserve a specified amount on a customer’s card for later confirmation. * Deferred Payments: Approving transactions even in cases where there is no immediate network connectivity. * MOTO (Mail Order/Telephone Order) Transactions: Processing card-not-present transactions securely. * Pre-Authorization Completion and Cancellation: Completing or voiding previously authorized transactions. The sections below will describe the request parameters in more detail: ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field needs to be set to `doTransaction`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "doTransaction", "params": [ "ashrait", { "amount": 2000, "vuid": "1234567890", "currency": "376", "creditTerms": 1, "tranCode": 1, "tranType": 1, "cardNumber": "4580000000000000", "expDate": "2308", "cvv": "666" } ], "id": 1 } ``` ### Request parameters The table below describes the parameters of the request: <Warning> **Mandatory Fields** `vuid`, `amount` and `tranType` are mandatory for all requests. All others depend on the type of transaction made. </Warning> <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor (client) unique transaction identifier. </td> </tr> <tr> <td> `amount` </td> <td> integer </td> <td> Amount in cents. </td> </tr> <tr> <td> `tranCode` </td> <td> integer </td> <td> The transaction code. Below are the possible values for this parameter: `1`: Single Step Transaction `2`: Refund (Partial refund is supported) `3`: Pre Authorization `4`: Deferred `5`: MOTO `6`: Complete Pre Authorization `7`: Cancel Pre Authorization </td> </tr> <tr> <td> `tranType` </td> <td> integer </td> <td> The transaction type code. Below are the possible values for this parameter: `1` - Regular `3` - Forced Transaction `6` - Cash Back `7` - Cash `30` - Balance `53` - Refund </td> </tr> <tr> <td> `originalTransactionId` </td> <td> string </td> <td> The original transaction ID, this parameter is used when refunding a transaction. </td> </tr> <tr> <td> `pan` </td> <td> string </td> <td> Card number (PAN) for MOTO transactions. </td> </tr> <tr> <td> `exp` </td> <td> string </td> <td> Card expiration date. </td> </tr> <tr> <td> `cvv` </td> <td> string </td> <td> Card verification value (3 digits). </td> </tr> <tr> <td> `apmCode` </td> <td> integer </td> <td> Additional payment method (not EMV). Below are the possible values for this parameter: `2`: Nayax Prepaid `4`: 10BIS `5`: Cibus `9`: Multipass `28`: Goodi </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> The card number is for the MOTO payment method (not EMV).\ Mandatory for MOTO. Irrelevant for the rest of the payment methods </td> </tr> <tr> <td> `productInfo` </td> <td> string </td> <td> Send product info to DCS. </td> </tr> </tbody> </table> ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.05.22", "retailerId": "0883012013", "ecrNo": "1", "vuid": "ee5e7af5-7719-4726-992f-0eb2915b992a", "tranCode": 1, "currency": "376", "amount": 100, "mutag": 1, "mutagName": "Mastercard", "manpik": 2, "solek": 2, "cardNumber": "*********", "expDate": "2305", "cardName": "Mastercard", "tokenizedCardNumber": "c8ae19356dd1d7e946165fab67a14516", "tranType": 1, "posEntryMode": 5, "isClub": false, "isPrepaid": false, "creditTerms": 1, "uid": "23031212432508830123729", "rrn": "948767075 ", "authCodeManpik": 1, "issuerAuthNum": "0652073", "acquirerMerchantID": "6543505", "sysTraceNumber": "01001001", "merchantReceipt": [ { "fieldName": "סכום", "fieldValue": "1000" }, { "fieldName": "ATC", "fieldValue": "0289" } ], "customerReceipt": [ { "fieldName": "סכום", "fieldValue": "1000" }, { "fieldName": "ATC", "fieldValue": "0289" } ] } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> The status of the operation. `0` indicates success. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> A message describing the status, such as "OK". </td> </tr> <tr> <td> `mutag` </td> <td> integer </td> <td> The card brand. </td> </tr> <tr> <td> `solek` </td> <td> integer </td> <td> The acquirer. </td> </tr> <tr> <td> `manpik` </td> <td> integer </td> <td> The card issuer. </td> </tr> <tr> <td> `uid` </td> <td> string </td> <td> The transaction unique identifier. </td> </tr> <tr> <td> `posEntryMode` </td> <td> integer </td> <td> POS Entry Mode, type of card transaction. Values include: `0` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), and `81` (Fallback (no AID)). </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> The masked personal account number (PAN). </td> </tr> <tr> <td> `rrn` </td> <td> string </td> <td> Transaction authorization number from the authorized entity. </td> </tr> <tr> <td> `issuerAuthNum` </td> <td> string </td> <td> The issuer authorization number. </td> </tr> <tr> <td> `acquirerMerchantID` </td> <td> string </td> <td> The merchant ID in the acquirer system. </td> </tr> <tr> <td> `authCodeManpik` </td> <td> integer </td> <td> Code of authorization. Values include: `0` (Unauthorized), `1` (Authorized by issuer), `2` (Declined by issuer), `3` (Stip approved), `4` (Stip declined), `5` (Voice approval), `6` (Voice declined), `7` (Approved pre-auth), `8` (Approved by card). </td> </tr> <tr> <td> `gatewayToken` </td> <td> string </td> <td> The gateway token for the card. </td> </tr> <tr> <td> `appVersion` </td> <td> string </td> <td> The payment application version. </td> </tr> <tr> <td> `retailerId` </td> <td> string </td> <td> The terminal retailer ID. </td> </tr> <tr> <td> `ecrNo` </td> <td> string </td> <td> The POS identifier. </td> </tr> <tr> <td> `vuid` </td> <td> string </td> <td> The vendor unique identifier. </td> </tr> <tr> <td> `tranCode` </td> <td> string </td> <td> The transaction code. </td> </tr> <tr> <td> `merchantReceipt` </td> <td> array of key/value </td> <td> The merchant receipt data to print or save. </td> </tr> <tr> <td> `customerReceipt` </td> <td> array of key/value </td> <td> The customer receipt data to print. </td> </tr> </tbody> </table> # doTransactionPhase1 Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase1 The `doTransactionPhase1` method begins a new transaction and retrieves its properties. Upon successful completion of this phase, the client can then proceed to the next stage of the process by calling the `doTransactionPhase2` method to finalize the transaction. This method is essential for initiating a transaction, validating key information, and preparing the system for the final processing step. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `doTransactionPhase1`. * The service must be set to `ashrait` in the `params`. The request includes a list of parameters, with the first being the service name, which is currently fixed as ashrait, and the second being a dictionary containing all other transaction-specific details. ```json theme={null} { "jsonrpc":"2.0", "method":"doTransactionPhase1", "params":[ "ashrait", { "amount":2000, "vuid":"1234567890", "currency":"376", "creditTerms":1, "tranCode":1, "tranType":1, "cardNumber":"4580000000000000", "expDate":"2308", "cvv":"666" } ], "id":1 } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | - | - | - | | `tranCode` | integer | Transaction Code. Values include: `1` (Normal), `2` (Pre Auth), `3` (Pre Auth Completion), `4` (Pre Auth Cancelation), `5` (Cancel), `6` (Authorized transaction). | | `amount` | integer | Amount of the transaction in cents. | | `currency` | string | Currency code in ISO 4217 format. | | `ecrID` | string | ECR/POS unique ID. Mandatory only if multiple clients use the same Merchant ID. | | `vuid` | string | Vendor (client) unique transaction identifier. | | `tranType` | integer | Transaction type. Values include: `1` (Regular), `3` (Forced Transaction), `6` (Cash Back), `7` (Cash), `30` (Balance), `53` (Refund). | | `creditTerms` | integer | Credit card payment options. Values include: `1` (Regular), `2` (Special Credit), `3` (Immediate), `6` (Credit), `8` (Settlements). | | `creditPayments` | integer | The number of credit payments. | | `payments` | integer | The number of payments, not including the first payment.<br />For example, if payments value is 2, the actual number of payments for the consumer would have is 3.<br />If the firstPaymentAmount is not provided in the request- all of the payments will be divided equally. | | `payments` | integer | The number of additional payments for the transaction, not including the first payment.<br />For example, if "payments" value is 2, the actual number of payments for the consumer would have is 3.<br /><br />If the firstPaymentAmount is not provided in the request- all of the payments amounts will be divided equally. | | `firstPaymentAmount` | integer | Amount in cents of the first payment. | | `paymentIndex` | integer | The index to which the payments are linked. Values include: `1` (Linked to Madad), `2` (Linked to Dollar). | | `cashBackAmount` | integer | Cash back amount in cents. | | `tipAmount` | integer | Tip amount in cents. | | `ipayCode` | integer | Type of benefit. Values include: `0` (currency), `1` (stars), `2` (points), `3` (club), `99` (no benefit). | | `ipayAmount` | integer | Amount of benefit in cents. | | `ipayPercent` | integer | Percent of benefit (0-100). | | `ipayUnits` | integer | Number of benefit units. | | `posEntryMode` | integer | POS Entry Mode, type of card transaction. Mandatory if card data is supplied. Values include: `1` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), `81` (Fallback (no AID)) | | `cardTrack2` | string | Card track2 data. | | `cardNumber` | string | Card number (PAN) for card-not-present (CNP) transactions. | | `expDate` | string | Card expiration date in `YYMM` format. | | `cvv` | string | Card verification value (3 digits). | | `cardHolderID` | string | Personal ID of the card holder. | | `zipCode` | string | ZIP code. | | `city` | string | City. | | `address` | string | Address. | | `authNum` | string | Authorization Number (7 digits). | | `originalUID` | string | Original transaction unique identifier. | | `language` | string | UI Language. Values include `Hebrew` and `English`. | | `conversionAmount` | integer | The amount in ILS after conversion from the foreign currency. Mandatory if the `currency` field is not 376 or 840. | | `changeRate` | integer | The foreign currency exchange rate in precision of 4 digits after the decimal point. For example, 4.210 = 42100. Mandatory if the `currency` field is not 376 or 840. | | `retailer` | string | SHVA retailer number, compared with the SHVA retailer number of the payment terminal. | | `additionalInfo` | json of strings | Private vendor data sent to the payment gateway (up to 300 characters). | | `cardless` | bool | Complete the transaction without showing the card. | | `petrol` | bool | Do a petrol transaction. | | `hideAnimation` | bool | Don't show animation at the end of the transaction. | ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc":"2.0", "result":{ "statusCode":0, "statusMessage":"ok", "mutag":2, "solek":6, "manpik":6, "cardNumber":"458003***7640", "posEntryMode":40, "creditType":0, "isClub":false, "isPrePaid":false, "isImmediate":false, "isIpayAllowed":false, "maxPayments":18, "maxCreditPayments":18, "minCreditPayments":3, "minCreditAmount":2500, "uid":"18071016383608830129318" }, "id":1 } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The transaction status. A value of `0` indicates a successful (approved) transaction. | | `statusMessage` | string | The transaction message (e.g., `ok`). | | `mutag` | integer | The card brand. | | `solek` | integer | The acquirer. | | `manpik` | integer | The card issuer. | | `cardNumber` | string | The masked personal account number (PAN). | | `posEntryMode` | integer | The POS Entry Mode. The values are the same as those in the request. | | `creditTerms` | integer | The credit card payment options. The values are the same as those in the request. | | `cardName` | string | The name of the credit card. | | `isClub` | boolean | A flag indicating if the card belongs to a club. | | `isPrePaid` | boolean | A flag for prepaid transactions. | | `isImmediate` | boolean | A flag for immediate transactions. | | `allowedCreditTerms` | array of integers | An array of allowed credit terms for this transaction. | | `isIpayAllowed` | boolean | A flag indicating if a benefit is allowed for this transaction. | | `maxPayments` | integer | The maximum number of payments allowed. | | `maxCreditPayments` | integer | The maximum number of credit payments allowed. | | `minCreditPayments` | integer | The minimum number of credit payments allowed. | | `minCreditAmount` | integer | The minimum allowed credit amount in cents. | | `uid` | string | The transaction unique identifier. | | `tokenizedCardNumber` | string | The tokenized PAN. | # doTransactionPhase2 Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase2 The `doTransactionPhase2` method completes the transaction that was started with `doTransactionPhase1`. Only the `vuid` is required to complete the transaction. The client can change any of the items sent in the `doTransactionPhase1` call. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `doTransactionPhase2`. * The service must be set to `ashrait` in the `params`. The request includes a list of parameters containing all transaction-specific details. ```json theme={null} { "jsonrpc":"2.0", "method":"DoTransactionPhase2", "params":[ "ashrait", { "vuid":"123456789", "loyaltyAmount":5000, "creditTerms":1 } ], "id":1 } ``` ### Request parameters The table below describes the request parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor (client) unique transaction identifier </td> </tr> <tr> <td> `creditTerms` </td> <td> integer </td> <td> Credit card payment options. Values are: `1` (Regular), `2` (Special Credit), `3` (Immediate), `6` (Credit), `8` (Settlements) </td> </tr> <tr> <td> `creditPayments` </td> <td> integer </td> <td> The number of credit payments </td> </tr> <tr> <td> `payments` </td> <td> integer </td> <td> The number of payments </td> </tr> <tr> <td> `firstPaymentAmount` </td> <td> integer </td> <td> Amount in cents of the first payment </td> </tr> <tr> <td> `otherPaymentAmount` </td> <td> integer </td> <td> Amount in cents of the rest of the payments </td> </tr> <tr> <td> `paymentIndex` </td> <td> integer </td> <td> The index to which the payments are linked. Values are: `1` (Linked to Madad), `2` (Linked to Dollar) </td> </tr> <tr> <td> `ipayCode` </td> <td> integer </td> <td> Type of benefit. Values are: `0` (currency), `1` (stars), `2` (points), `3` (club), `99` (no benefit) </td> </tr> <tr> <td> `ipayAmount` </td> <td> integer </td> <td> Amount of benefit in cents </td> </tr> <tr> <td> `ipayPercent` </td> <td> integer </td> <td> Percent of benefit (`0-100`) </td> </tr> <tr> <td> `ipayUnits` </td> <td> integer </td> <td> Number of benefit units </td> </tr> <tr> <td> `loyaltyAmount` </td> <td> integer </td> <td> Discounted amount in cents </td> </tr> </tbody> </table> ## Response A successful request will return the following response: ```json theme={null} { "jsonrpc":"2.0", "result":{ "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.05.22", "retailerId": "0883012013", "ecrNo": "1", "vuid": "ee5e7af5-7719-4726-992f-0eb2915b992a", "tranCode": 1, "currency": "376", "amount": 100, "mutag": 1, "mutagName": "Mastercard", "manpik": 2, "solek": 2, "cardNumber": "*********", "cardNumberOriginalLength": "************************", "expDate": "2305", "cardName": "Mastercard", "tokenizedCardNumber": "c8ae19356dd1d7e946165fab67a14516", "tranType": 1, "posEntryMode": 5, "isClub": false, "isPrepaid": false, "creditTerms": 1, "uid": "23031212432508830123729", "rrn": "948767075 ", "authCodeManpik": 1, "issuerAuthNum": "0652073", "acquirerMerchantID": "6543505", "sysTraceNumber": "01001001", "authorizationCommStat": "{\"connectRetries\":0,\"connectTotalTime\":555,\"authorizationTotalTime\":744,\"smallBlockedTotalTime\":0}", "merchantReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ], "customerReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ] }, "id":1 } ``` ### Response parameters The table below describes the response parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> Transaction status. A value of `0` indicates a successful (approved) transaction. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> Transaction message (e.g., `ok`) </td> </tr> <tr> <td> `mutag` </td> <td> integer </td> <td> Card brand </td> </tr> <tr> <td> `solek` </td> <td> integer </td> <td> Acquirer </td> </tr> <tr> <td> `manpik` </td> <td> integer </td> <td> Card Issuer </td> </tr> <tr> <td> `uid` </td> <td> string </td> <td> Transaction unique identifier </td> </tr> <tr> <td> `posEntryMode` </td> <td> integer </td> <td> POS Entry Mode, type of card transaction. Values are: `0` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), `81` (Fallback (no AID)) </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> Masked personal account number (PAN) </td> </tr> <tr> <td> `rrn` </td> <td> string </td> <td> Transaction authorization number from the authorized entity </td> </tr> <tr> <td> `issuerAuthNum` </td> <td> string </td> <td> Issuer authorization number </td> </tr> <tr> <td> `acquirerMerchantID` </td> <td> string </td> <td> Merchant ID in the acquirer system </td> </tr> <tr> <td> `authCodeManpik` </td> <td> integer </td> <td> Code of authorization. Values are: `0` (Unauthorized transaction), `1` (Authorized by issuer), `2` (Declined by issuer), `3` (Stip approved ABS), `4` (Stip declined ABS), `5` (Voice approval), `6` (Voice declined), `7` (Approved by issuer pre-auth), `8` (Approved by card) </td> </tr> <tr> <td> `gatewayToken` </td> <td> string </td> <td> Gateway token of the card </td> </tr> <tr> <td> `appVersion` </td> <td> string </td> <td> Payment application version </td> </tr> <tr> <td> `retailerId` </td> <td> string </td> <td> Terminal retailer Id </td> </tr> <tr> <td> `ecrNo` </td> <td> string </td> <td> POS identifier </td> </tr> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor unique identifier </td> </tr> <tr> <td> `tranCode` </td> <td> string </td> <td> Transaction Code </td> </tr> <tr> <td> `merchantReceipt` </td> <td> array of key/value </td> <td> Merchant receipt to print or save </td> </tr> <tr> <td> `customerReceipt` </td> <td> array of key/value </td> <td> Customer receipt to print </td> </tr> </tbody> </table> # removeSubRetailer Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase2-copy-1 The `removeSubRetailer` method removes a sub-retailer from the terminal. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Integration](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `removeSubRetailer`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "removeSubRetailer", "params": [ "ashrait", { "retailerId": "0883012" } ], "id": "123454352" } ``` ### Request parameters The `params` array contains the service name followed by a dictionary. | Name | Type | Description | | :- | :- | :- | | `retailerId` | string | The ID of the sub-retailer to remove. | ## Response A successful call returns a status code and message. ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "OK" } } ``` ### Response parameters The result object contains the following fields: | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | The status of the operation. `0` indicates success. | | `statusMessage` | string | A message describing the status, such as `"OK"`. | # getReport Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getreport-1 The `getReport` method is used to retrieve various reports, such as Z or X reports, and lists of specific transaction types. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getReport`. * The `params` array must contain the service name (`ashrait`) followed by the desired action name. ```json theme={null} {     "jsonrpc":"2.0",     "method":"getReport",     "params":[         "ashrait", "queryPreAuthTransactions"     ],     "id":"123454352" } ``` ### Request parameters The table below describes the request parameters for this method. | Name | Type | Description | | :- | :- | :- | | `actionName` | string | The specific action or report to perform. See the table below for values. | #### Action Name Values | Value | Description | | :- | :- | | `x` | Retrieves an X report. | | `z` | Retrieves a Z report. | | `accm` | Retrieves an ACCM report. | | `queryTransactions` | Lists all pending deferred transactions on the device. | | `queryReports` | Lists acknowledgment numbers of all reports from the device. | | `queryPreAuthTransactions` | Lists all uncompleted J5 transactions on the device. | | `queryDeferredAuthTransactions` | Lists all pending deferred transactions on the device. | ## Response The response varies based on the requested action. Query actions return a list of transactions, while report actions return a printable slip. ```json theme={null} {     "jsonrpc": "2.0",     "result": {         "statusCode": 0, "statusMessage": "ok",         "queriedTransactions": [             "24120312004508832326548"         ]     },     "id": "123454352" } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | :- | :- | :- | | `statusCode` | integer | Operation status. A value of `0` indicates success. All other values are errors. | | `statusMessage` | string | The operation message (e.g., `ok`). | | `slip` | string | Returned for report actions (`x`, `z`, `accm`). Contains the report data to be printed. | | `queriedTransactions` | array of strings | Returned for query actions. Contains a list of the requested transaction or report identifiers. | <br /> # getStatus Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getreport-copy The `getStatus` method checks the status of the AEA (the payment application) service to see if it's ready to process transactions (as opposed to getInternalStatus which provides information about the payment terminal's readiness to do the first part of processing a new transaction).\ It's a quick way to diagnose the terminal's health, but you should call it infrequently. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getStatus`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "getStatus", "params": [ "ashrait" ], "id": 1 } ``` ### Request parameters This method doesn't require any parameters beyond the standard service name. ## Response A successful call returns a string indicating the current status of the payment application. ```json theme={null} { "jsonrpc": "2.0", "result": "ashraitReady", "id": 1 } ``` ### Response parameters The table below describes the response parameters for this method. | Value | Description | | :- | :- | | `ashraitReady` | Ready for transactions. | | `ashraitNotEstablished` | The terminal setup hasn't been completed. | | `ashraitReadyOnline` | Ready, but all transactions will be processed online due to an old database. | | `ashraitError` | A general error occurred (e.g., a corrupted database). | | `ashraitNotReady` | Not ready for transactions. | # getRetailerInfo Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getreport-copy-1 The `getRetailerInfo` method allows the client application to verify the merchant (retailer) name and ID associated with the device. This can be used after the establishment process (process done by Nayax's team) or client setup to confirm that the correct merchant information such as the ID and name provided by the ABS (Shva) has been configured. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getRetailerInfo`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "getRetailerInfo", "params": [ "ashrait" ], "id": "136bdaa3" } ``` ### Request parameters This method doesn't require any parameters beyond the standard service name. ## Response A successful call returns the retailer's identification details. ```json theme={null} { "jsonrpc": "2.0", "id": "136bdaa3", "result": { "id": "0883012013", "name": "MODULARITY 12", "transmitTime": 1721217720 } } ``` ### Response parameters The table below describes the response parameters for this method. | Name | Type | Description | | :- | :- | :- | | `id` | string | The unique identifier for the retailer. | | `name` | string | The registered name of the retailer. | | `transmitTime` | integer | The time the information was transmitted, in Unix epoch format. | # getInternalStatus Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getstatus-copy The `getInternalStatus` method checks the internal service state of the AEA (the payment application). It helps determine if the device is idle, busy, or in a specific stage of a transaction. You should call this method infrequently. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getInternalStatus`. * The service must be set to `ashrait` in the `params`. ```json theme={null} { "jsonrpc": "2.0", "method": "getInternalStatus", "params": [ "ashrait" ], "id": "123454352" } ``` ### Request parameters This method doesn't require any parameters beyond the standard service name. ## Response A successful call returns an object containing the internal status string. ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "status": "idle" } } ``` ### Response parameters The result `object` contains the following field: | Name | Type | Description | | :- | :- | :- | | `status` | string | A string representing the internal state of the device. | ### Possible status values The status field will contain one of the following strings: | Value | Description | | :- | :- | | `IDLE` | The device is in idle mode and ready for a new request. | | `BUSY` | The device is busy and cannot handle new requests at this time. | | `PHASE2_READY` | The device has completed transaction phase 1 and is ready for phase 2. | | `AUTH_READY` | The device is ready for authorization. | # getTransactionByUid Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/gettransactionbyvuid-copy The `getTransactionByUid` method returns a transaction by its unique identifier (UID). If no UID is provided, the method returns the last transaction. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getTransactionByUid`. * The service must be set to `ashrait` in the `params`. ```json theme={null} {     "jsonrpc":"2.0",     "method":"getTransactionByUid",     "params":[         "ashrait",         {            "originalUID":"24071711405408830122531"         }     ],     "id":"123454352" } ``` ### Request parameters <br /> The table below describes the request parameters for this method. | Name           | Type   | Description                                                           | | :- | :- | :- | | `originalUID` | string | Optional. The UID of the transaction to retrieve. If omitted, the last transaction is returned. | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc":"2.0", "result":{ "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.05.22", "retailerId": "0883012013", "ecrNo": "1", "vuid": "ee5e7af5-7719-4726-992f-0eb2915b992a", "tranCode": 1, "currency": "376", "amount": 100, "mutag": 1, "mutagName": "Mastercard", "manpik": 2, "solek": 2, "cardNumber": "*********", "cardNumberOriginalLength": "************************", "expDate": "2305", "cardName": "Mastercard", "tokenizedCardNumber": "c8ae19356dd1d7e946165fab67a14516", "tranType": 1, "posEntryMode": 5, "isClub": false, "isPrepaid": false, "creditTerms": 1, "uid": "23031212432508830123729", "rrn": "948767075 ", "authCodeManpik": 1, "issuerAuthNum": "0652073", "acquirerMerchantID": "6543505", "sysTraceNumber": "01001001", "authorizationCommStat": "{\"connectRetries\":0,\"connectTotalTime\":555,\"authorizationTotalTime\":744,\"smallBlockedTotalTime\":0}", "merchantReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ], "customerReceipt":[ {"fieldName":"׳¡׳›׳•׳","fieldValue":"1000"}, {"fieldName":"ATC","fieldValue":"0289"} ] }, "id":1 } ``` ### Response parameters The table below describes the response parameters for this method. <table> <thead> <tr> <th> Name </th> <th> Type </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `statusCode` </td> <td> integer </td> <td> Transaction status. A value of `0` indicates a successful (approved) transaction. </td> </tr> <tr> <td> `statusMessage` </td> <td> string </td> <td> Transaction message (e.g., `ok`) </td> </tr> <tr> <td> `mutag` </td> <td> integer </td> <td> Card brand </td> </tr> <tr> <td> `solek` </td> <td> integer </td> <td> Acquirer </td> </tr> <tr> <td> `manpik` </td> <td> integer </td> <td> Card Issuer </td> </tr> <tr> <td> `uid` </td> <td> string </td> <td> Transaction unique identifier </td> </tr> <tr> <td> `posEntryMode` </td> <td> integer </td> <td> POS Entry Mode, type of card transaction. Values are: `0` (MSR), `5` (CTLS MSR), `40` (Contact EMV), `50` (Phone), `51` (Signature only), `80` (Fallback (err)), `81` (Fallback (no AID)) </td> </tr> <tr> <td> `cardNumber` </td> <td> string </td> <td> Masked personal account number (PAN) </td> </tr> <tr> <td> `rrn` </td> <td> string </td> <td> Transaction authorization number from the authorized entity </td> </tr> <tr> <td> `issuerAuthNum` </td> <td> string </td> <td> Issuer authorization number </td> </tr> <tr> <td> `acquirerMerchantID` </td> <td> string </td> <td> Merchant ID in the acquirer system </td> </tr> <tr> <td> `authCodeManpik` </td> <td> integer </td> <td> Code of authorization. Values are: `0` (Unauthorized transaction), `1` (Authorized by issuer), `2` (Declined by issuer), `3` (Stip approved ABS), `4` (Stip declined ABS), `5` (Voice approval), `6` (Voice declined), `7` (Approved by issuer pre-auth), `8` (Approved by card) </td> </tr> <tr> <td> `gatewayToken` </td> <td> string </td> <td> Gateway token of the card </td> </tr> <tr> <td> `appVersion` </td> <td> string </td> <td> Payment application version </td> </tr> <tr> <td> `retailerId` </td> <td> string </td> <td> Terminal retailer Id </td> </tr> <tr> <td> `ecrNo` </td> <td> string </td> <td> POS identifier </td> </tr> <tr> <td> `vuid` </td> <td> string </td> <td> Vendor unique identifier </td> </tr> <tr> <td> `tranCode` </td> <td> string </td> <td> Transaction Code </td> </tr> <tr> <td> `merchantReceipt` </td> <td> array of key/value </td> <td> Merchant receipt to print or save </td> </tr> <tr> <td> `customerReceipt` </td> <td> array of key/value </td> <td> Customer receipt to print </td> </tr> </tbody> </table> # getTransactionByVuid Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/gettransactionbyvuid-copy-1 The `getTransactionByVuid` method retrieves a transaction using its vendor-unique identifier (vuid). This allows client applications to fetch transaction details, including status, amount, and processing details. This method helps track transactions, confirm their status, and retrieve essential metadata, such as entry mode, timestamps, and deposit status. ## Request <Note> **JSON-RPC 2.0** All methods in TweezerComm follow a JSON-RPC 2.0 structure. See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how the requests are structured and sent. </Note> In the request, ensure to configure the following: * The `method` field must be set to `getTransactionByVuid`. * The service must be set to `ashrait` in the `params`. ```json theme={null} {     "jsonrpc":"2.0",     "method":"getTransactionByVuid",     "params":[         "ashrait",         {            "vuid":"48a70a44-a919-4587-901e-bafb073aef0e"         }     ],     "id":"123454352" } ``` ### Request parameters See the table below for a description of the available request parameters for this method. | Name | Type | Description | | - | - | - | | `vuid` | string | Vendor (client) unique transaction identifier. | ## Response A successful request will return a response similar to the one in the code block below: ```json theme={null} { "jsonrpc": "2.0", "id": "123454352", "result": { "statusCode": 0, "statusMessage": "TRANSACTION APPROVED", "appVersion": "01.06.62", "vuid": "48a70a44-a919-4587-901e-bafb073aef0e", "amount": 100, "transactionId": "2038587830", "entryMode": 4, "transactionOriginalRequestId": "fa19cf10-2294-441e-9739-9c8521801cff", "transactionOriginalTime": "2025-03-05 23:41:32.963", "transactionOriginalAmount": 100, "isFinalAmount": 1, "transactionDeposited": 1, "tranType": 1, "currencyCode": "840", "originalSiteId": 1, "mainBoardSerial": "000177234933444", "hwSerial": "0900044624102737" } } ``` ### Response parameters Below is a table with all the possible response parameters and their description: | Name | Type | Description | | - | - | - | | `id` | string | Request identifier | | `statusCode` | integer | Status code of the transaction | | `statusMessage` | string | Status message of the transaction | | `appVersion` | string | Application version | | `vuid` | string | Vendor-unique transaction identifier | | `amount` | integer | Transaction amount | | `transactionId` | string | Transaction identifier | | `entryMode` | integer | Entry mode of the transaction (Swipe, Contact, NFC) | | `transactionOriginalRequestId` | string | Original transaction request ID | | `transactionOriginalTime` | string | Original transaction timestamp | | `transactionOriginalAmount` | integer | Original transaction amount | | `isFinalAmount` | integer | Indicator if the amount is final | | `transactionDeposited` | integer | Deposit status of the transaction | | `mainBoardSerial` | string | Main board serial of the device | | `hwSerial` | string | Hardware serial of the device | # Israel Payment Methods Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/israel-payment-methods/tweezercomm-israel-payment-methods This section describes the API methods for handling transactions in Israel with the `ashrait` payment service, which allows you to do the following. * Start different types of transactions. * Cancel transactions that are in progress but not yet finished. * Look up details of past transactions using a unique ID. * Get reports about various transaction records. These tools give you complete control over your payment processes, so you can manage, track, and report on all your transactions. ## Transaction Processing <CardGroup> <Card icon="play" title="doTransaction" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/dotransaction"> Start and process a payment transaction over the TweezerComm protocol. </Card> <Card icon="forward-step" title="doTransactionPhase1" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase1"> Start a new transaction and retrieve its properties. </Card> <Card icon="flag-checkered" title="doTransactionPhase2" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dotransactionphase2"> Complete a transaction that doTransactionPhase1 started, using only the vuid. </Card> <Card icon="ban" title="abortTransaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/aborttransaction-copy"> Cancel an ongoing transaction before it registers in the database. </Card> <Card icon="circle-xmark" title="cancelTransaction" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/canceltransaction-1"> Cancel a transaction that the system already approved and registered. </Card> </CardGroup> ## Settlement & Reporting <CardGroup> <Card icon="calendar-day" title="doPeriodic" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/doperiodic"> Deposit transactions daily, update the AEA database, and generate a Z report. </Card> <Card icon="money-check-dollar" title="doMiniSettlement" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/dominisettlement"> Settle transactions through the CG or PC payment processors. </Card> <Card icon="chart-column" title="getReport" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getreport-1"> Retrieve Z or X reports and lists of specific transaction types. </Card> </CardGroup> ## Transaction Lookup & Status <CardGroup> <Card icon="magnifying-glass" title="getTransactionByUid" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/gettransactionbyvuid-copy"> Look up a transaction by its unique identifier (UID). </Card> <Card icon="fingerprint" title="getTransactionByVuid" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/gettransactionbyvuid-copy-1"> Look up a transaction by its vendor-unique identifier (vuid). </Card> <Card icon="gauge" title="getInternalStatus" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/getinternalstatus"> Check the internal status of the AEA engine. </Card> </CardGroup> ## Retailer Management <CardGroup> <Card icon="store" title="addSubRetailer" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/addsubretailer"> Load sub-retailers onto the terminal. </Card> <Card icon="list-ul" title="getSubRetailer" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/addsubretailer-copy"> List all sub-retailers loaded on the terminal and their status. </Card> <Card icon="circle-info" title="getRetailerInfo" href="/docs/integrate-pos-device/tweezercomm/israel-payment-methods/getreport-copy-1"> Verify the merchant name and ID associated with the device. </Card> </CardGroup> <Note> **Send Requests** See [Get Started](/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started) for more details on how to structure and send requests. </Note> # PinPad Mode Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/pinpad-mode The TweezerComm protocol allows you to use the device in pin-pad mode. In this mode, you can read the card details and use the EMV tags and data to create your own transaction object. ## Pinpad mode flow The diagram below illustrates the steps involved in using the TweezerComm methods to handle card presentation and PIN entry on a Nayax Device, focusing on Contactless and Swipe transactions. <Frame> <img /> </Frame> Here's a breakdown of each step of the flow: 1. The client application sends a `startPinpadTransaction()` Request to the Nayax Device to prepare it for a card-based transaction. 2. The Nayax Device responds with a `startPinpadTransaction()` Response and then begins to display a prompt for the cardholder to Insert, Show, or Swipe card. 3. The cardholder physically presents their card by inserting, swiping, or tapping it on the Nayax Device. 4. If the cardholder inserts the card (triggering the need for a PIN), the flow continues with the Client sending a `doPinpadTransaction()` Request to prompt for the PIN input. 5. The cardholder enters their PIN directly on the Nayax Device. The device responds to the client with the `doPinpadTransaction()` Response after the PIN is captured. 6. Once the necessary card and PIN data are securely captured, the Client sends an `endPinpadTransaction()` Request to the Nayax Device. 7. The Nayax Device confirms the PinPad process is complete with the `endPinpadTransaction()` Response, returning the device to an idle state. # Resilience Mechanism Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/resilience-mechanism-copy TweezerComm has a resilience mechanism for handling transaction completion or cancellation in case of errors or failures. Whenever an error occurs, such as a `statusCode != 0`, TweezerComm automatically falls back to this mechanism, using retries and verification steps to complete or cancel the transaction and prevent inconsistencies. ## How it works The flow chart describes the flow of the mechanism. <Frame> <img alt="" /> </Frame> When a transaction requires completion (settlement) or cancellation, the system checks whether it received a response, and the flow varies depending on the outcome. * If the system receives a response, it checks the `StatusCode`. If the value equals `0`, it finishes the completion process; otherwise, it triggers the retry mechanism. * If the system doesn't receive a response, it retrieves transaction details using the `getTransactionByVuid()` method. * To check whether the transaction is complete, the system evaluates whether `IsFinalAmount=1` and `TransactionDeposited=1/2`. * If those values don't match, the system triggers the retry mechanism. The process loops back to the start of the Completion/Cancel flow until it reaches a definitive success or failure condition. ## See also <CardGroup> <Card icon="route" title="Payment flows" href="/docs/integrate-pos-device/tweezercomm/global-payment-flows/payment-flows-copy-1"> See the payment flows this resilience mechanism protects. </Card> <Card icon="fingerprint" title="GetTransactionByVuid" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/gettransactionbyvuid"> Retrieve transaction details using the vendor-unique identifier (vuid). </Card> </CardGroup> # TC Service Source: https://devzone.nayax.com/docs/integrate-pos-device/tweezercomm/tc-service TC Service allows you to use the Agamento app as a background service. If you want to run your own Android app on the device and perform transactions using Agamento, you can configure Agamento to operate as a TC Service. Every time your app initiates a transaction, Agamento will be triggered and come into action. The communication between the apps is based on the TweezerComm protocol. <Frame> <img /> </Frame> ## Demo APK The APK is a demo tool for using the TC service. It includes a basic implementation of how to work with our Agamento app as a service and send TweezerComm requests. * [Demo .APK file](https://docs-engine.modularity.co.il/_static/TCServiceDemo.apk) This will help you gain a better understanding of how it works, making it easier for you to implement it. ## Sample code Use the code sample below to understand how to integrate with our Agamento app as a service within your APK. * [TC Service Implementation Sample Code](https://github.com/ModularityLtd/TcsDemo) The only part you need to adjust in the code is the JSON fields that will be sent in the requests. For example, refer to the `doTransaction` Command function (located in `AgamentoMethods.java`). In that function, you will find where the fields and values for the JSON file are set. For instance, `put(“currency”,CURRENCY)` is set based on the configured currency at the beginning of the code: `String CURRENCY = “376”` <Frame> <img /> </Frame> <Note> **TweezerComm Commands** The TweezerComm commands should be based on the API and relevant to your specific payment service. </Note> ## See also <CardGroup> <Card icon="rocket" title="Get started" href="/docs/integrate-pos-device/tweezercomm/tweezercomm-get-started"> See how TweezerComm structures and sends requests using JSON-RPC 2.0. </Card> <Card icon="code" title="Global payment methods" href="/docs/integrate-pos-device/tweezercomm/global-payment-methods/payment-services-methods-copy-1"> Browse the API methods for the global engine payment service. </Card> </CardGroup> # Additional Resources Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/additional-resources/index This section provides supplementary resources, detailed technical data, and common troubleshooting information to aid integrators in their work with the Nayax Spark API. These pages give you quick access to facts, definitions, and code examples that complement the main documentation flows and guides. ## Available Guides <CardGroup> <Card icon="id-badge" title="Closed Loop Card Support" href="/docs/integrate-pos-device/spark/additional-resources/smc-support"> Use closed-loop cards, such as RFID tags or loyalty cards, in Spark's start and stop flows. </Card> <Card icon="display" title="PosDisplay Format" href="/docs/integrate-pos-device/spark/additional-resources/spark-posdisplay-format"> Format data so it displays correctly on the terminal screen. </Card> <Card icon="receipt" title="eReceiptData Format" href="/docs/integrate-pos-device/spark/additional-resources/spark-ereceiptdata-format"> Structure transaction data for the eReceiptData field on digital receipts. </Card> <Card icon="list-check" title="Response Codes" href="/docs/integrate-pos-device/spark/additional-resources/spark-response-codes"> Look up response codes and the API methods that return them. </Card> </CardGroup> # Closed Loop Card Support Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/additional-resources/smc-support SMC (Self-Managed Cards) is a Spark feature that enables integrators to utilize closed-loop cards, such as RFID tags, company-issued badges, or loyalty cards, within Spark's Remote/Device start flows and Device Stop flow. Rather than relying on Nayax or the acquiring bank to authorize the card, your system is responsible for validating and authorizing it. It is ideal when: * You want to offer payment-free access (e.g., for employees or VIPs) * You’re using a loyalty card or RFID solution already in place * You don't need authorization from an external acquirer (no bank approval involved) This enables greater flexibility for internal payment systems, free access programs, or custom logic-based validation. <Note> **Enabling SMC** To support this feature, you must use a dedicated “Payment Method”. Machines supporting this Payment Method will be able to support Spark Self-Managed cards and Credit Cards only (no additional Prepaid cards of different Providers). Please ask your Nayax Integration Engineer for more information and configuration assistance. </Note> ## How SMC works When SMC is enabled: * Spark treats all card taps as automatically authorized * Your backend is expected to decide whether to proceed or cancel the session * Spark still performs the normal callback flow (`TransactionCallback`,`TransactionNotify`, `StopNotify`) This makes the card interaction fast and seamless while shifting responsibility to your backend to match card data against your internal system and decide whether to continue, cancel, or log the session. ## Card UID The Payment card's Unique ID (Card UID) is a critical identifier for Spark self-managed cards. While Nayax automatically approves these cards, it's the integrator's responsibility to validate their authenticity and authorization for service. If an integrator determines a card is invalid or unauthorized, they must initiate a `/CancelTransaction` request. <Warning> **Card Validation** If you don’t validate the card on your side, unauthorized users could start sessions. Always compare the `UID` data in the callback. </Warning> ## Use case example A typical SMC transaction would look like the following: 1. The card is detected and accepted by Spark. 2. Your backend receives a `/TransactionCallback` with card hash and UID. 3. You look up the badge in your internal employee system. 4. If approved, the session continues, and a `/Settlement` is sent later. 1. If denied, your backend sends `/CancelTransaction`. <Warning> **Completion** `/Settlement` is mandatory and will indicate a valid Spark Self-Managed card was presented. `/CancelTransaction` is mandatory and will indicate an invalid card was presented or if the transaction is completed with no charge (no service provided / settlement=0). </Warning> ## See also <CardGroup> <Card icon="credit-card" title="TransactionCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback"> Notifies you when a card tap completes an authorization attempt. </Card> </CardGroup> # eReceiptData Format Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/additional-resources/spark-ereceiptdata-format The Nayax eReceipt Platform enables seamless integration with digital receipt providers, enabling them to offer digital receipt services to Nayax customers. Integrators who possess additional transaction information on their third-party servers can use the `eReceiptData` field to include this data in the consumer's digital receipt. The `eReceiptData` field is currently relevant only for Pre-Authorization flows within the `/Settlement` method. Pre-selection is not yet supported for this feature. Any information provided in this field will be presented directly on the consumer's eReceipt. Therefore, it is crucial to avoid sharing sensitive or irrelevant data. ## Format specification The `eReceiptData` field expects a JSON object. This object allows for the organization of data into distinct sections, each containing an array of key-value pair objects. ```json theme={null} { "sectionName1": [ {"key": "value", "key": "value"} ], "sectionName2": [ {"key": "value", "key": "value", "key": "value", "key": "value"} ], "sectionName3": [ {"key": "value", "key": "value", "key": "value", "key": "value"} ] } ``` If you do not wish to use a specific section name, you can leave a blank space for the `sectionName`. The fields will appear on the digital receipt in the order they are provided within the JSON structure. For further details on integrating with the Nayax eReceipt Platform, please contact your designated Nayax Point of Contact (POC). # PosDisplay Format Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/additional-resources/spark-posdisplay-format This page details the required format for data sent to the Nayax POS device for display. Adhering to this format ensures information is presented correctly on the terminal screen, enhancing the user experience. ## Format specification Each display element must consist of a `label` and a `value`, separated by a colon (`:`). Elements are then delimited by a semicolon (`;`). Complete values may optionally arrive empty. The overall structure is as follows: ``` str0{label}:str0{value};str1{label}:str1{value};str2{label}:str2{value};str3{label}:str3{value};...;str5{label}:str5{value};\` ``` Where: * `str0`: This element is special and holds the value that will be presented in the headline of the POS device screen. If `str0` is not provided, the default headline displayed is "Tariff". * `str1`: This element is special and holds a value that will be propagated to the next user interface (UI) slide when payment presentation is requested. If `str1` is not provided, subsequent strings (`str2`, `str3`, etc.) will shift one line up in the display. # Response Codes Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/additional-resources/spark-response-codes Here's a comprehensive list of response codes, their descriptions, and the relevant Spark API methods. This table helps you understand the outcomes of your API calls, from successful transactions to various error types. These codes arrive in the `Status` object of a declined response, as `ErrorCode`, alongside `Verdict` and `ErrorDescription`. For example: `"Status": {"Verdict": "Declined", "ErrorCode": 50, "ErrorDescription": "External Settlement Failed"}`. | Response Code | Description | Relevant API Methods | | - | - | - | | `20` | Machine Has No Device | `/TriggerTransaction` | | `21` | Device Not Connected to MQTT Server | `/TriggerTransaction` | | `22` | Missing Device IP | `/TriggerTransaction` | | `23` | IP Is Non-VPN | `/TriggerTransaction` | | `24` | Machine Not Responding | `/TriggerTransaction` | | `25` | Unknown Machine ID | `/TriggerTransaction` | | `26` | Validation Error | `/StartAuthentication` | | `27` | Unknown Transaction ID | `/Settlement`, `/CancelTransaction` | | `28` | Already Cancelled | `/CancelTransaction` | | `29` | Not Allowed to Wake Device | `/TriggerTransaction` | | `30` | Spark Integrator Not Active | `/StartAuthentication` | | `31` | Cancellation Failed | `/CancelTransaction` | | `32` | Transaction Not Found or Old | `/Settlement`, `/CancelTransaction` | | `33` | Fail To Authenticate | `/StartAuthentication` | | `34` | Missing Amount | `/TriggerTransaction`, `/Settlement` | | `35` | Settlement Failed | `/Settlement` | | `36` | Site ID Not Found | `/Settlement`, `/CancelTransaction` | | `37` | Authorization Failed | [`/TransactionCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback) | | `38` | Transaction Callback Failed | [`/TransactionCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback), [`/DeclineCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/declinecallback) | | `40` | Timeout Callback Failed | [`/TimeoutCallback`](/reference/spark/transactions/timeoutcallback) | | `44` | Timeout on POS Device | [`/DeclineCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/declinecallback) | | `45` | Cancelled on POS Device | [`/DeclineCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/declinecallback) | | `50` | Deferred Settlement Failed | /ExternalSettlement | | `51` | Deferred Cancel Failed | /ExternalCancel | | `52` | No Support for Deferred Settlement/Cancel | /ExternalSettlement, /ExternalCancel | | `992` | Nayax Time Out Error | `All` | | `997` | Nayax Validation Error | `All` | | `999` | Nayax General Error | `All` | # Additional Features Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/additional-features Optional Nayax Core settings for Spark machines, including POS display timeouts, idle mode images, Auto Cancel, and eReceipt. These optional settings extend a Spark machine beyond the core start, stop, and settlement flows. Apply the ones that fit your integration on top of the configuration for the feature you set up. ## POS display (tariff) This feature uses the Spark `PosDisplay` field to show dynamic text on the device while it is triggered to start a payment, such as tariff information. Two settings control how long the device shows this information: * **Approve button UI display duration**: the display timeout of an **OK** button on the device screen. For example, you can show tariff information with an **OK** button for the consumer to approve before the transaction continues. If the timeout is reached and the button is not pressed, the flow is cancelled. After a button press, the display changes to a present card state. The limit is 0 to 60 seconds. The default is `0`, which means do not display. * **Informative State Display Timeout**: how long, in seconds, an informative state such as tariff information is displayed. Set this when **Approve button UI display duration** is `0`, so no approve button is shown. A red **X** lets the consumer cancel the flow. The limit is 0 to 10 seconds. The default is `4`. A value of `0` means do not display. The two settings combine as follows: | Approve button UI display duration | Informative State Display Timeout | Expected behavior | | :-: | :-: | :- | | 45 | 0 | The tariff is shown with an **OK** button. After 45 seconds with no action, the flow is cancelled. If the consumer presses **OK**, the display changes to the present card state. | | 0 | 10 | The tariff is shown for 10 seconds, then the display moves to the present card state automatically. | | 0 | 0 | The tariff is not displayed at all. | ## Idle mode custom image You can set a custom image on the device screen while it is in idle mode to tell consumers how to act. Create the image yourself, then contact your Nayax Support representative to have it uploaded to your machine. ## Auto cancel Auto Cancel is an automatic service that cancels unsettled transactions left in a pending settlement or cancellation state. It runs automatically for all Nayax acquirers, based on a default configuration per acquirer. To set Auto Cancel for your Operator to fit your type of business, contact your Nayax Support representative. Provide the minimum time after which, if no settlement or cancellation has reached the Nayax gateway, it is safe to cancel the transaction. ## eReceipt For eReceipt support, contact your Nayax Support representative for assistance with the relevant configuration. For the data format used in settlement requests, see [eReceiptData Format](/docs/integrate-pos-device/spark/additional-resources/spark-ereceiptdata-format). ## Next steps <CardGroup> <Card title="PosDisplay format" icon="display" href="/docs/integrate-pos-device/spark/additional-resources/spark-posdisplay-format"> See the structure of the PosDisplay field used for tariff text. </Card> <Card title="Payment flows" icon="arrow-right-arrow-left" href="/docs/integrate-pos-device/spark/payment-flows/transaction-flows-spark"> Review the Spark transaction flows at the API level. </Card> </CardGroup> # Machine Configuration Overview Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/index Set up your Operator and machine in Nayax Core before configuring a Spark feature, including device firmware requirements and provider association. Before a Spark feature works on a terminal, you configure the machine in Nayax Core, the Nayax back-office system. First, confirm your Operator is linked to your Spark provider. Then select or create the machine and open the page for the feature you are integrating. ## Prerequisites You need the following before you start: * A VPOS Touch or Onyx terminal that is not connected through a cable. * An account in Nayax Core with an actor, a machine, and a user role. * Your Spark provider entity set up in Nayax Core. You must log in to Nayax Core with your credentials before any action described on this page. <Note> Certain provider-level configurations are managed internally by Nayax and are not exposed in the Nayax Core interface. If you need one of these changed, contact your Nayax Support representative. </Note> ## Device Firmware Requirements To procure a Nayax device, power supply, and cables, contact your Nayax Sales representative. To support the Spark features you plan to use, the device must run one of the firmware versions below, or a newer official version: | Feature | Minimum firmware version | | :- | :- | | Remote Start (with Device Stop) | `4.0.24.3-RC06` | | Device Start (with Device Stop) | `4.0.25.5-RC04` | ## Associate Your Operator with Spark Confirm that your Operator is associated with your Spark entity in Nayax Core: <Steps> <Step title="Open the Operator Screen"> Log in to Nayax Core, then click **Administration > Operator**. </Step> <Step title="Find Your Operator"> Start typing the Operator name in the **Operator** search bar and select it from the suggestions, then click **Search**. Alternatively, click **Search** and locate the Operator in the hierarchy. </Step> <Step title="Open the VAS Provider Tab"> Select the Operator in the hierarchy, then click the **VAS Provider** tab. Under the **Spark** section, your Spark integration name appears in the **Provider Name** field. </Step> </Steps> <Note> If you do not see the **VAS Provider** tab, or the **Provider Name** under the **Spark** section is not your Spark integration name, contact your Nayax Support representative. </Note> ## Select or Create Your Machine Open the machine you want to configure for Spark, or create one if none exists: <Steps> <Step title="Open the Machines Screen"> Log in to Nayax Core, then click **Operations > Machines**. </Step> <Step title="Find Your Machine"> Start typing your Operator name in the **Operator** search bar and select it from the suggestions, then click **Search**. Alternatively, click **Search** and locate the Operator in the hierarchy. A list of machines appears with their actor tree. </Step> <Step title="Open or Create the Machine"> Click the machine you want to configure. If no machine is available, you can create a new machine or duplicate an existing one. For step-by-step guidance, click the **Need Assistance** button on the right. <Frame> <img alt="Machines screen in Nayax Core with the Need Assistance button highlighted" /> </Frame> </Step> <Step title="Set the Machine Model"> For a new machine, under **General Information > General > Machine Model**, use the machine model suggested by Nayax Support. The machine model determines the initial machine configuration in Nayax Core, which can save you steps later. You can change or add configurations to the initial setup at any time. <Frame> <img alt="General Information section with the Machine Model field" /> </Frame> </Step> <Step title="Connect a Nayax Device"> Under **General Information > Hardware > Device Number**, enter your device number and click **Save**. If no device is available, contact your Nayax Support representative. <Frame> <img alt="Hardware section with the Device Number field" /> </Frame> </Step> </Steps> For general payment configurations, contact your Nayax Support representative. For the configurations specific to each Spark feature, see the page for the feature you are integrating. For optional settings such as POS display timeouts and idle mode images, see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features). ## Next Steps <CardGroup> <Card title="Remote Start Configuration" icon="bolt" href="/docs/integrate-pos-device/spark/machine-configuration/spark-remote-start-configuration"> Configure a machine so your server can start transactions remotely. </Card> <Card title="Device Start Configuration" icon="circle-play" href="/docs/integrate-pos-device/spark/machine-configuration/spark-device-start-configuration"> Configure a machine so transactions start from the terminal itself. </Card> <Card title="Device Stop Configuration" icon="hand" href="/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration"> Configure a machine so a card at the terminal stops an active transaction. </Card> <Card title="External Settlement Configuration" icon="money-check" href="/docs/integrate-pos-device/spark/machine-configuration/spark-external-settlement-configuration"> Configure a machine so your server settles or cancels a terminal-authorized transaction. </Card> </CardGroup> # Device Start Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/spark-device-start-configuration Configure a machine in Nayax Core to support Spark Device Start, for a single service station or for two to six service stations. The settings on this page prepare a machine for Spark Device Start, where a transaction starts from the terminal when a consumer interacts with it. Configure a single service station when the device serves one service point, or multiple service stations when it serves two to six. Apply these settings to the machine you selected in [Machine Configuration](/docs/integrate-pos-device/spark/machine-configuration). For other machine configurations not covered here, contact your Nayax Support representative. ## Single service station Use this configuration when the Nayax device serves one service point. ### Card readers These settings control the device hardware and how a transaction can start: * **Decimal Place**: defines the Nayax device and affects the **Default Credit** value. This is usually `2`. * **Transaction Start Method**: set to **Button**, **Contactless**, and **Contact** so a transaction can start either from a card presented in idle mode or from a button press on the device screen. * **VPOS Button Function**: set to **5 - Btn Start/Card Start + External Cancel**. <Frame> <img alt="Card Readers settings for single station Device Start" /> </Frame> ### MDB The **MDB Flags** setting tells the server which payment flow the device supports. Device Start uses the **Pre-Authorization** flow, which applies when the transaction starts before the consumer chooses a product or service and before the final amount is known. Set **MDB Flags** to **\* Flags Disabled**. <Frame> <img alt="MDB Flags set to Flags Disabled for the Pre-Authorization flow" /> </Frame> ### Payment The **Default Credit** setting sets the authorization amount for the Pre-Authorization flow. The value is in cents and is affected by the **Decimal Place** value. The settlement value must not be higher than this amount. ### Pulse/ccTalk These settings define the credit applied per pulse and the authorization source: * **Credit per Pulse 1**: set to `1`. * **Number of Pulses per Vend 1**: set to `1`. * **Pulse Options**: set to **Use Default Credit for Authorization**. ### VPOS touch The **VAS configurations** setting informs the server that the machine supports the Spark Device Start flow. Set it to **Spark Device Start (V2)**. Without this indication, Device Start does not function. This setting covers both Device Start and Device Stop. After you finish, click **Save** to store the configuration. ## Multiple service stations (2, 4, or 6) Use this configuration when the Nayax device serves two to six service points. The device supports an even number of service stations only (2, 4, or 6). ### Card readers These settings control the device hardware and how a transaction can start: * **Decimal Place**: defines the Nayax device and affects the **Default Credit** value. When the device serves more than one service point, the decimal place also affects the amount shown for each service station. This is usually `2`. * **Transaction Start Method**: set to **Product**. With service station selection, the flow must start by selecting the desired service station first. <Frame> <img alt="Card Readers settings for multi station Device Start with Transaction Start Method set to Product" /> </Frame> ### MDB The **MDB Flags** setting tells the server which payment flow the device supports. Multi-station Device Start uses the **Pre-Authorization** flow. Set **MDB Flags** to **\* Flags Disabled**. ### Payment The **Default Credit** setting sets the authorization amount for the Pre-Authorization flow. The value is in cents and is affected by the **Decimal Place** value. The settlement value must not be higher than this amount. ### Pulse/ccTalk This section sets up the display for two to six service stations. Each pulse line represents one service station the device serves. The amount shown for each service station is the **Credit per Pulse** multiplied by the **Number of Pulses**. The authorization amount can be the same for every service station or set individually: * For an identical amount across all stations, set the amount in **Default Credit** and set **Pulse Options** to **Use Default Credit for Authorization**. * For different amounts per station, configure **Credit per Pulse** and **Number of Pulses** and do not use **Pulse Options**. Configure the following attributes. Separate each value with a semicolon, and match the position of each value to its service station: * **Credit per Pulse 1-6 (Cents)**: the amount to display for each service station, stations 1 to 6. This is multiplied by **Number of Pulses per Vend 1-6**. To hide the prices from the display, set this to `0`. * **Number of Pulses per Vend 1-6**: set each station to `1` (`1;1;1;1;1;1`). The amount displayed is **Credit per Pulse** multiplied by this number, so a value of `1` shows the **Credit per Pulse** amount unchanged. * **Pulse Identifier 1-6**: the identifier shown in idle mode for each service point. The default values are `1` to `6`. * **Pulse Title 1-6**: an optional description shown below each identifier. When set, the screen alternates between the price and the title every 3 seconds. If you do not set a title, the description screen is not shown. Examples: Charger, Air and Vac, Washer and Dryer. * **Pulse Options**: set to **Use Default Credit for Authorization** to base the authorization on the **Default Credit** amount and ignore the amounts shown per station. To use the displayed amounts instead, leave this attribute unset. * **Pulse Line Welcome Message**: an optional one-line message shown during idle mode, above the service stations layout. The default is "Choose Desired Machine". Use it to tell consumers how to start a flow. For example, with **Decimal Place** `2` and currency USD, setting **Credit per Pulse 1-6** to `200;200;200;300;300;400` and **Number of Pulses per Vend 1-6** to `1;1;1;1;1;1` displays six prices: three at \$2, two at \$3, and one at \$4. Setting **Pulse Options** to **Use Default Credit for Authorization** then authorizes each transaction against **Default Credit**. <Frame> <img alt="Idle mode display showing service stations with prices and a custom welcome message" /> </Frame> ### VPOS touch The **VAS configurations** setting informs the server that the machine supports the Spark Device Start flow. Set it to **Spark Device Start (V2)**. Without this indication, Device Start does not function. This setting covers both Device Start and Device Stop. After you finish, click **Save** to store the configuration. ## Configuration summary Use the following table as a quick reference for the Device Start settings: | Group | Property | Single service station | Multiple service stations | | :- | :- | :- | :- | | Card Readers | Decimal Place | Usually 2 | Usually 2 | | Card Readers | Transaction Start Method | Button+Contactless+Contact | Product | | Card Readers | VPOS Button Function | 5 - Btn Start/Card Start + External Cancel | — | | MDB | MDB Flags | Pre-Authorization: Flags Disabled | Pre-Authorization: Flags Disabled | | Payment | Default Credit | Authorization value (settlement value must not be higher) | Authorization value (settlement value must not be higher) | | Print Receipt Format | Receipt Button Display Duration | Optional, for eReceipt. Recommendation: 15 | Optional, for eReceipt. Recommendation: 15 | | Print Receipt Format | Receipt QR Display Duration | Optional, for eReceipt. Recommendation: 60 | Optional, for eReceipt. Recommendation: 60 | | Pulse/ccTalk | Credit per Pulse 1 | Greater than 0 | — | | Pulse/ccTalk | Number of Pulses per Vend 1 | 1 | — | | Pulse/ccTalk | Pulse Options | Use Default Credit for Authorization | Use Default Credit for Authorization | | Pulse/ccTalk | Credit per Pulse 1-6 (Cents) | — | 0, or prices to display them | | Pulse/ccTalk | Number of Pulses per Vend 1-6 | — | 1 per service station (for example, 1;1;1;1) | | Pulse/ccTalk | Pulse Identifier 1-6 | — | The service station identifiers | | Pulse/ccTalk | Pulse Title 1-6 | — | Optional: one word per service station | | Pulse/ccTalk | Pulse Line Welcome Message | Optional: replace the default "Choose Desired Machine" | Optional: replace the default "Choose Desired Machine" | | VPOS Touch | Approve button UI display duration | 0 to 60 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | 0 to 60 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | | VPOS Touch | Informative State Display Timeout | 0 to 10 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | 0 to 10 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | | VPOS Touch | VAS configurations | Spark Device Start (V2) | Spark Device Start (V2) | | VPOS Touch | Vend Flow Options | Optional, for eReceipt: Dynamic Receipt | Optional, for eReceipt: Dynamic Receipt | ## Next steps <CardGroup> <Card title="Device start" icon="circle-play" href="/docs/integrate-pos-device/spark/payment-flows/spark-device-start"> See how the Device Start transaction flow works at the API level. </Card> <Card title="Device stop configuration" icon="hand" href="/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration"> Add the settings to stop a transaction from the device. </Card> </CardGroup> # Device Stop Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration Configure a machine in Nayax Core to support Spark Device Stop alongside the Remote Start or Device Start feature. The settings on this page prepare a machine for Spark Device Stop, where a card presented at the terminal stops an active transaction. Device Stop runs alongside Remote Start or Device Start on the same machine, so apply these settings on top of the configuration for whichever start flow you use. ## Card readers The **Transaction Start Method** setting defines what can start a transaction through the card reader while it is idle. Set it to **Accept All** so the card reader accepts cards in idle mode to trigger the Device Stop flow. <Note> When you pair Device Stop with Remote Start, this attribute must be **Accept All**, not **Accept Nothing**: Device Stop determines the value when the two run together. </Note> ## VPOS touch The **VAS configurations** setting informs the server that the machine supports the Spark Device Stop feature. Set it based on the start flow you pair with Device Stop: * **Remote Start with Device Stop**: set **Spark Device Stop**, or both **Spark Device Stop** and **Spark Remote Start**. Both options work. * **Device Start with Device Stop**: set **Spark Device Start (V2)** only. The Device Start (V2) value covers both Device Start and Device Stop. <Frame> <img alt="VAS configurations for Remote Start paired with Device Stop" /> </Frame> <Frame> <img alt="VAS configurations for Device Start paired with Device Stop" /> </Frame> After you finish, click **Save** to store the configuration. ## Configuration summary Use this table as a quick reference for Device Stop, depending on the start flow you pair it with: | Group | Property | Remote Start with Device Stop | Device Start with Device Stop | | :- | :- | :- | :- | | Card Readers | Transaction Start Method | Accept All | Single station: Button+Contactless+Contact. Multiple stations: Product | | VPOS Touch | VAS configurations | Spark Device Stop (or Spark Device Stop and Spark Remote Start) | Spark Device Start (V2) (or Spark Device Stop and Spark Device Start (V2)) | ## Next steps <CardGroup> <Card title="Device stop" icon="hand" href="/docs/integrate-pos-device/spark/payment-flows/spark-device-stop"> See how the Device Stop transaction flow works at the API level. </Card> <Card title="Additional features" icon="sliders" href="/docs/integrate-pos-device/spark/machine-configuration/additional-features"> Configure POS display timeouts, idle mode images, and other options. </Card> </CardGroup> # External Settlement Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/spark-external-settlement-configuration Configure a machine in Nayax Core to support Spark External Settlement, where a server settles or cancels a terminal-authorized transaction. The settings on this page prepare a machine for Spark External Settlement, where your server completes or cancels a transaction that was authorized directly on the terminal. Most attribute groups need no change to support this feature. ## MDB The **MDB Flags** setting tells the server which payment flow the device supports: * **Pre-Authorization** is used when the transaction starts before the consumer chooses a product or service and before the final amount is known. Set **MDB Flags** to **\* Flags Disabled**. * **Pre-Selection** is the flow used when the price is known when the card is presented. Set **MDB Flags** to **02 PreSelection Enabled**. <Frame> <img alt="MDB Flags set to Flags Disabled for the Pre-Authorization flow" /> </Frame> ## VPOS touch The **VAS configurations** setting is optional for External Settlement. You can add an indication that the machine performs Spark External Settlement. This is not required for the flow to work and is only for management purposes. <Warning> Spark External Settlement cannot coexist with any other Spark flow (Remote Start, Device Start, or Device Stop) on the same machine. </Warning> After you finish, click **Save** to store the configuration. ## Configuration summary Use this table as a quick reference for the External Settlement settings: | Group | Property | Value | | :- | :- | :- | | MDB | MDB Flags | Pre-Authorization: Flags Disabled. Pre-Selection: PreSelection Enabled | | VPOS Touch | VAS configurations | Optional: Spark External Settlement | ## Next steps <CardGroup> <Card title="External settlement" icon="money-check" href="/docs/integrate-pos-device/spark/payment-flows/external-settlement"> See how the External Settlement flow works at the API level. </Card> <Card title="External cancel" icon="ban" href="/docs/integrate-pos-device/spark/payment-flows/external-cancel"> Learn how to release captured funds when no service is delivered. </Card> </CardGroup> # Remote Start Configuration Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/machine-configuration/spark-remote-start-configuration Configure a machine in Nayax Core to support the Spark Remote Start feature, where your server starts transactions on the terminal remotely. The settings on this page prepare a machine for Spark Remote Start, where your server starts a transaction on the terminal instead of a consumer acting on the device. Apply them to the machine you selected in [Machine Configuration](/docs/integrate-pos-device/spark/machine-configuration). ## Card readers These settings control the device hardware and how a transaction can start: * **Decimal Place**: defines the Nayax device and affects the **Default Credit** value. This is usually `2`. * **Transaction Start Method**: set to **Accept Nothing**. This defines what can start a transaction through the card reader while it is idle. For Remote Start, the server calls the card reader, so no physical action is needed and physical starts are blocked. <Frame> <img alt="Card Readers settings with Transaction Start Method set to Accept Nothing" /> </Frame> <Note> If you use Device Stop on this machine, the **Transaction Start Method** is set differently. Follow [Device Stop Configuration](/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration). </Note> ## Communication This setting defines how the Nayax device communicates with the Nayax servers: * **Communication Mode**: set to **MQTT Enabled**. For Remote Start, the server has to wake the device, so the device must listen for requests coming from the server. The MQTT protocol supports this. The alternative is **VPN Enabled**, which needs a SIM card that supports the protocol. * **MQTT - Primary Address**: contact your Nayax Support representative for the address that fits your device location. The remaining MQTT settings hold default values. Do not change them unless instructed. <Frame> <img alt="Communication settings with Communication Mode set to MQTT Enabled" /> </Frame> ## MDB The **MDB Flags** setting tells the server which payment flow the device supports: * **Pre-Authorization** is used when the transaction starts before the consumer chooses a product or service and before the final amount is known. Set **MDB Flags** to **\* Flags Disabled**. * **Pre-Selection** is the flow used when the price is known when the card is presented. Set **MDB Flags** to **02 PreSelection Enabled**. <Frame> <img alt="MDB Flags set to Flags Disabled for the Pre-Authorization flow" /> </Frame> ## Payment These settings control the authorization amount and how long the device waits for a card: * **Default Credit**: set the authorization amount. This applies to the Pre-Authorization flow only. It is the amount authorized when the `Amount` field in the `TriggerTransaction` request is empty. The value is in cents and is affected by the **Decimal Place** value. * **Present Card Timeout**: the time in seconds the device waits for a card after the server wakes it. The default is 15 seconds. We recommend 30 to 60 seconds so consumers have enough time to reach the terminal and present their card. In the Pre-Authorization flow, the settlement value must not be higher than the amount that was authorized. <Warning> When the device reaches the **Present Card Timeout** and no card is presented, no `TransactionCallback` is sent. Set your own timeout too, equal to or longer than this value, so your system can handle a missing callback. </Warning> ## Pulse/ccTalk These settings define the credit applied per pulse: * **Credit per Pulse 1**: set to `1`. * **Number of Pulses per Vend 1**: set to `1`. ## VPOS touch The **VAS configurations** setting is optional for Remote Start. You can add an indication that the machine performs Spark Remote Start. This is not required for the flow to work and is only for management purposes. <Note> Spark Remote Start and Spark Device Start cannot coexist on the same machine. </Note> After you finish, click **Save** to store the configuration. ## Configuration summary Use the following table as a quick reference for the Remote Start settings: | Group | Property | Value | | :- | :- | :- | | Card Readers | Decimal Place | Usually 2 | | Card Readers | Transaction Start Method | Accept Nothing (for Device Stop, see [Device Stop Configuration](/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration)) | | Communication | Communication Mode | MQTT Enabled or VPN Enabled | | Communication | MQTT - Primary Address | Contact your Nayax Support representative | | MDB | MDB Flags | Pre-Authorization: Flags Disabled. Pre-Selection: PreSelection Enabled | | Payment | Default Credit | Authorization value (settlement value must not be higher) | | Payment | Present Card Timeout | Recommendation: 30 to 60 seconds | | Print Receipt Format | Receipt Button Display Duration | Optional, for eReceipt. Recommendation: 15 | | Print Receipt Format | Receipt QR Display Duration | Optional, for eReceipt. Recommendation: 60 | | Pulse/ccTalk | Credit per Pulse 1 | Greater than 0 | | Pulse/ccTalk | Number of Pulses per Vend 1 | 1 | | VPOS Touch | Approve button UI display duration | 0 to 60 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | | VPOS Touch | Informative State Display Timeout | 0 to 10 seconds (see [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#pos-display-tariff)) | | VPOS Touch | VAS configurations | Optional: Spark Remote Start | | VPOS Touch | Vend Flow Options | Optional, for eReceipt: Dynamic Receipt | | VPOS Touch | Idle Mode Custom Image | See [Additional Features](/docs/integrate-pos-device/spark/machine-configuration/additional-features#idle-mode-custom-image) | | VPOS Touch | Idle Mode Screens | Contact your Nayax Support representative | ## Next steps <CardGroup> <Card title="Remote start" icon="bolt" href="/docs/integrate-pos-device/spark/payment-flows/spark-remote-start"> See how the Remote Start transaction flow works at the API level. </Card> <Card title="Device stop configuration" icon="hand" href="/docs/integrate-pos-device/spark/machine-configuration/spark-device-stop-configuration"> Add the settings to stop a transaction from the device. </Card> </CardGroup> # External Cancel Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/external-cancel The **External Cancel** is a mandatory operation for authorized transactions where the service or product was not provided. Its purpose is to release the captured funds on the consumer's card immediately. If no service is provided, you must send a cancellation request immediately. Failure to do so results in funds being captured, leading to a poor consumer experience and potential disputes. ### External cancel flow methods The External Cancel flow makes use of the following Spark methods: * [StartAuthentication](/reference/spark/transactions/startauthentication) * [ExternalCancel](/reference/spark/transactions/externalcancel) ### External cancel flow This flow is required when a transaction was authorized on the Nayax Device, but the service failed or was canceled at the point of interaction. To understand the External Cancel flow, see the diagram below: <Frame> <img /> </Frame> <br /> Below is a breakdown of the diagram: 1. **Authorization Request**: The process begins when a transaction is initiated on the Nayax Device, which sends an authorization request to the Nayax Server. 2. **Authorization Response**: The Nayax Server authorizes the amount with the payment provider and sends the response to the device. The device then returns to an **IDLE** state. 3. **Service Failure**: A failure occurs, and no service or product is delivered to the consumer. 4. **/StartAuthentication**: To resolve the failed transaction, the **Third-Party Server** initiates communication by calling the [StartAuthentication](/reference/spark/transactions/startauthentication) method. 5. **Authentication Response**: The Nayax Server validates the credentials and responds with a success message. 6. **/ExternalCancel**: The **Third-Party Server** sends the [ExternalCancel](/reference/spark/transactions/externalcancel) request. This must include the original `NayaxTransactionId` and `SiteId`. 7. **Financial Reversal**: Upon receiving the request, the Nayax Server performs the cancellation with the payment provider to release the funds. 8. **External Cancel Response**: The Nayax Server confirms the cancellation outcome to the Third-Party Server. ## Failure handling and retries If a request fails, the follow-up action depends on which stage of the process failed: | Failure Type | Description | Recommended Action | | :- | :- | :- | | **Authentication Failure** | The [StartAuthentication](/reference/spark/transactions/startauthentication) call failed. | The Third-Party Server should retry the authentication request immediately. | | **External Cancel Failure** | The [ExternalCancel](/reference/spark/transactions/externalcancel) call failed or returned an error. | **No manual action required.** If the initial request fails, the Nayax Server provides a safeguard by automatically retrying the cancellation later (AutoCancel). | <Danger> **Important Terminologies:** In a **Pre-Authorization** flow, this operation is a "Cancel." In a **Pre-Selection** flow, it is a "Void." You must indicate the correct type in your request payload. </Danger> <br /> # External Settlement Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/external-settlement The **Spark External Settlement** feature allows third-party servers to complete or cancel transactions authorized directly on a Nayax payment terminal but not initiated via a standard Spark flow. This provides integrators with the flexibility to trigger the settlement stage externally based on their own business logic, supporting all machine protocols (Pulse, MDB, Marshall) and currently only PreAuthorization flow. The External Settlement flow makes use of the following Spark methods: * [`StartAuthentication`](/reference/spark/transactions/startauthentication) * [`ExternalSettlement`](/reference/spark/transactions/externalsettlement) * [`ExternalCancel`](/reference/spark/transactions/externalcancel) ## External settlement flow The **External Settlement** flow allows a third party to complete a transaction that was authorized directly on a terminal. <Note> **Prerequisite** For this flow to function, the **External Settlement** setting must be enabled by Nayax. </Note> Once enabled, the Nayax Engine instructs the device not to send its own settlement command after a successful authorization, keeping the transaction in an unsettled state until an external request is received. <Danger> **Note** This feature applies only to transactions authorized outside of the Spark start flows (Remote Start or Device Start). In addition, in case of using External Settlement with Marshall Multisession, note that you should not send a "Close Session" command for settlement. </Danger> To understand the external settlement flow, see the diagram below: <Frame> <img alt="" /> </Frame> Below is a breakdown of the diagram: 1. **Authorization Request:** The process begins with transaction initiation on the Nayax Device, which sends an authorization request to the Nayax Server. 2. **Authorization Response:** The Nayax Server performs authorization with the payment provider and sends the response back to the device, which then returns to an IDLE state. The transaction remains authorized but unsettled. 3. **/StartAuthentication:** After the service or product is provided (or fails to be provided), the 3rd Party Server initiates communication by calling the [StartAuthentication](/reference/spark/transactions/startauthentication) method. This call must include an encrypted cipher to securely authenticate both Nayax and the integrator. 4. **Start Authentication Response:** The Nayax Server decrypts the cipher, validates the credentials and timestamps, and responds with a hashed `SparkTransactionId` to confirm authenticity. 5. **/ExternalSettlement (If Service Provided):** The 3rd Party Server sends the settlement request. * **Critical Identification:** The request must contain the `NayaxTransactionId` and `SiteId` to correctly match the original transaction. * **Time Limit:** Transactions must be settled within **48 hours** of initiation. Settlement attempts after this window will fail. 6. **External Settlement Response:** The Nayax Server settles with the payment provider and sends a success/failure response to the 3rd Party Server. **Alternatively (If Service/Product(s) Not Provided):** 5. **/ExternalCancel:** The 3rd Party Server sends an [ExternalCancel](/reference/spark/transactions/externalcancel) request. This is **mandatory** to release the consumer's captured funds if no service was delivered. For **Pre-Selection** flows, this method is referred to as a **Void**, while for **Pre-Authorization**, it is a **Cancel**. 6. **External Cancel Response:** The Nayax Server initiates the financial cancellation with the payment provider and confirms the outcome to the 3rd Party Server. ## Outcomes and error handling Integrators should monitor the `ErrorCode` and `StatusMessage` within the `Status` object to determine the result of a request and the necessary follow-up action. | Outcome | Event Code | Description | Recommended Action | | :- | :-: | :- | :- | | **Success** | N/A | Transaction successfully settled or cancelled. | No further action required. | | **Authentication Failure** | 33 | Nayax could not verify the credentials for the 3rd-party server. | Retry the authentication request immediately. | | **Capability Validation Failed** | 52 | The Machine or VAS Provider is not configured for External Settlement. | Check Nayax Core configuration; ensure "Support External Settlement" is TRUE. | | **External Settlement Failed** | 50 | Request failed due to missing fields, unmatched identifiers, or system errors. | Retry up to 5 times within 24 hours of the first attempt. | | **External Cancel Failed** | 51 | Cancellation failed due to missing fields or processing errors. | No manual action required. Nayax will automatically retry via AutoCancel. | | **Transaction Already Completed** | 50 / 51 | Transaction was already completed or invalidated. | Validate the transaction status in your system. | ### Troubleshooting tips * **Missing Mandatory Fields**: If fields like `SiteId` are missing, the system returns event code 50 or 51 and specifies the missing fields in the `StatusMessage`. * **Transaction Not Found**: If you receive a "Transaction was not found" error, ensure that `NayaxTransactionId` and `SiteId` exactly match the original transaction data. * **Card Scheme Compliance**: Transactions that remain unsettled for too long will be automatically canceled by the system. However, integrators must not rely on this and should send an External Cancel immediately if no settlement will occur to avoid poor user experience and potential disputes. ## Advanced settlement features ### Digital receipts (`eReceiptData`) For operators using the Nayax eReceipt platform, the `ExternalSettlement` request includes an `eReceiptData` field. * This field allows you to add custom data (in JSON format) such as company name, station name, or support information directly to the digital receipt. * **Format Example**: `{"General":[{"Company":"Your Payments","Station Name":"812"}]}`. ### Product management (`ProductInfo`) If you manage a Products Map in Nayax Core, you can include an array of objects to report exactly what was sold: * **Value**: The decimal amount of a single product. * **Code**: The integer representing the Product Code in the Products Map. * **Quantity**: The number of units provided. **Example**: `[{"Value": 6.50, "Code": 12, "Quantity": 3}]`. ## See also <CardGroup> <Card title="StartAuthentication" icon="key" href="/reference/spark/transactions/startauthentication"> Authenticates the 3rd-party server before an external settlement or cancel request. </Card> <Card title="ExternalSettlement" icon="money-check-dollar" href="/reference/spark/transactions/externalsettlement"> Completes a transaction that was authorized outside a standard Spark flow. </Card> <Card title="ExternalCancel" icon="ban" href="/reference/spark/transactions/externalcancel"> Releases captured funds when no service was provided. </Card> </CardGroup> # Device Start Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/spark-device-start The Device Start flow initiates directly at the Nayax terminal, allowing consumers to begin a session by selecting a service or presenting their card. This enables interactive communication with the terminal, such as displaying tariffs or confirming service station availability, before the session officially begins on the machine. The Device Start flow makes use of the following Spark methods: * [`StartSession`](/reference/spark/transactions/startsession) * [`InfoQuery`](/reference/spark/transactions/infoquery) * [`TransactionNotify`](/reference/spark/transactions/transactionnotify) * [`Settlement`](/reference/spark/transactions/settlement) * [`CancelTransaction`](/reference/spark/transactions/canceltransaction) * [`TimeoutCallback`](/reference/spark/transactions/timeoutcallback) <Note> **Pre-Authorization Only** Device Start currently only supports pre-authorization, for an option with Pre-Selection see [Remote Start](/docs/integrate-pos-device/spark/payment-flows/spark-remote-start). </Note> ## Pre-authorization flow To understand the device start pre-authorization flow, see the diagram below: <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. A consumer selects a service station (and/or presents a card) on the Nayax Device, which sends an [`InfoQuery`](/reference/spark/transactions/infoquery) request to the Nayax Server. 2. The Nayax Server sends a [`StartSession`](/reference/spark/transactions/startsession) to the 3rd Party Server. 3. The 3rd Party Server responds to the Nayax Server with a `StartSession Response`. 4. The Nayax Server sends an `InfoQuery` to the 3rd Party Server. 5. The 3rd Party Server responds to the Nayax Server with an `InfoQuery`. 6. The Nayax Server sends an `InfoQuery` command back to the Nayax Device. 7. The consumer presents their card (if they haven't already done so). An `AuthorizationRequest` is sent from the Nayax Device to the Nayax Server. 8. The Nayax Server performs authorization with a Payment Provider and then sends a [`TransactionNotify`](/reference/spark/transactions/transactionnotify) to the 3rd Party Server. 9. The 3rd Party Server responds to the Nayax Server with a [`TransactionNotify`](/reference/spark/transactions/transactionnotify) Response. 10. The Nayax Server sends an `AuthorizationResponse` back to the Nayax Device. At this point, the service can be provided on the Service Station, and the Nayax Device is back to idle. 11. The 3rd Party Server sends a [`Settlement`](/reference/spark/transactions/settlement) command to the Nayax Server. 12. The Nayax Server performs the settlement with the Payment Provider and then sends a [`Settlement`](/reference/spark/transactions/settlement) back to the 3rd Party Server. # Device Stop Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/spark-device-stop The Spark API facilitates card validation and comparison via the Nayax point-of-sale (POS) terminal. Integrators have two options for handling card validation during a device stop flow: * `StopNotify`: This method should be used when you want to handle card validation yourself. * `StopCallback`: This option allows you to leave card validation to Nayax. In both cases, Nayax does not manage session lifecycles; this responsibility lies entirely with you. You will still need to stop the session yourself. ## `StopNotify` If you choose to perform the card comparison, Nayax will send a `StopNotify` request. It provides the details of the card used for the stop event. You then need to match these cards to an ongoing session and return the relevant Spark and Nayax transaction IDs for the session to be stopped. Rejecting a `StopNotify` request will result in a rejection message displayed on the Nayax terminal for the consumer. However, this rejection does not impact the actual session status, as Nayax does not manage the session. You still need to perform the necessary actions to stop the session on your end. ## `StopCallback` If you prefer Nayax to perform the card comparison, Nayax will send a `StopCallback`. In this scenario, Nayax searches for an unsettled transaction associated with the card used for the stop request. If a match is found, Nayax will notify you with the relevant Spark and Nayax transaction IDs, indicating which session needs to be stopped. You remain responsible for actually stopping the session. Learn more about this endpoint on the following page: <CardGroup> <Card icon="hand" title="StopCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/stopcallback"> Notifies you when a consumer presents a card to stop an active session. </Card> </CardGroup> ## See also <CardGroup> <Card icon="shield-halved" title="Security & authentication" href="/docs/integrate-pos-device/spark/security-authentication/index"> Sign every request with Spark's two-part authentication process. </Card> </CardGroup> # Remote Start Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/spark-remote-start In the Remote Start Flow, your remote server initiates the transaction, directing Nayax to activate a specific device. This method is particularly suited for scenarios where the transaction begins from an application or a computer, rather than directly at the Nayax terminal. The Remote Start flows use the following Spark methods: * [StartAuthentication](/reference/spark/transactions/startauthentication) * [TriggerTransaction](/reference/spark/transactions/triggertransaction) * [TransactionCallback](/reference/spark/transactions/transactioncallback) * [Settlement](/reference/spark/transactions/settlement) * [CancelTransaction](/reference/spark/transactions/canceltransaction) * [TimeoutCallback](/reference/spark/transactions/timeoutcallback) * [DeclineCallback](/reference/spark/transactions/declinecallback) <Note> **Payment Flows** Remote Start supports both pre-authorization and pre-selection transaction flows. The sections below provide a more detailed breakdown of each flow. </Note> ## Pre-authorization flow To understand the remote start pre-authorization flow, see the diagram below: <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. A consumer starts a session on a service station, which sends a `StartAuthentication` request to the Nayax Server via a 3rd Party Server. 2. The Nayax Server responds to the 3rd Party Server with a `StartAuthenticationResponse`. 3. The 3rd Party Server sends a `TriggerTransaction` request to the Nayax Server. 4. The Nayax Server sends a "Wake Up" command to the Nayax Device. 5. The Nayax Device responds to the Nayax Server, confirming it has woken up. 6. The Nayax Server sends a `TriggerTransactionResponse` back to the 3rd Party Server. 7. The consumer presents their card to the Nayax Device. The Nayax Device then sends an `AuthorizationRequest` to the Nayax Server. 8. The Nayax Server performs authorization with a Payment Provider and sends a [`TransactionCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback) to the 3rd Party Server. 9. The 3rd Party Server acknowledges the transaction callback by sending a [`TransactionCallbackACK`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback) (HTTP 200) to the Nayax Server. At this point, the service can be provided on the Service Station. 10. The Nayax Server sends an `AuthorizationResponse` to the Nayax Device, indicating the outcome of the authorization. The Nayax Device then returns to an idle state. 11. The 3rd Party Server sends a `Settlement` request to the Nayax Server. 12. The Nayax Server performs the settlement with the Payment Provider and sends a `SettlementResponse` back to the 3rd Party Server. ## Pre-selection flow To understand the remote start pre-selection flow, see the diagram below: <Frame> <img /> </Frame> Below is a breakdown of the diagram: 1. A consumer starts a session on a service station, which sends a `StartAuthentication` request to the Nayax Server via a 3rd Party Server. 2. The Nayax Server responds to the 3rd Party Server with a `StartAuthentication` Response. 3. The 3rd Party Server sends a `TriggerTransaction` request to the Nayax Server. 4. The Nayax Server sends a "Wake Up" command to the Nayax Device. 5. The Nayax Device responds to the Nayax Server, confirming it has woken up. 6. The Nayax Server sends a `TriggerTransaction` response back to the 3rd Party Server. 7. The consumer presents their card to the Nayax Device. The Nayax Device then sends an `AuthorizationRequest` to the Nayax Server. 8. The Nayax Server processes transactions by performing sales, authorizations, and settlements with a Payment Provider. Concurrently, it sends a [`TransactionCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback) to the 3rd Party Server. 9. The 3rd Party Server acknowledges the transaction callback by sending a [`TransactionCallback`](/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback) (HTTP 200) to the Nayax Server. At this point, the service can be provided at the Service Station. 10. The Nayax Server sends an `AuthorizationResponse` to the Nayax Device, indicating the outcome of the authorization. The Nayax Device then returns to an idle state. ## See also <CardGroup> <Card icon="credit-card" title="TransactionCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback"> Notifies you when a card tap completes an authorization attempt. </Card> </CardGroup> # Payment Flows Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/payment-flows/transaction-flows-spark Spark supports multiple payment flows to handle different use cases depending on who initiates the payment process. * **Remote Start**: Your server initiates the transaction remotely, often in response to a consumer action outside the physical payment device (for example, plugging in an EV charger). * **Device Start**: The transaction begins directly from the Nayax payment terminal, where the consumer interacts with the device to select a service point or product. Each flow involves a specific sequence of API calls and device interactions tailored for either integrator-driven or device-driven control, and uses a standard set of Spark API methods, such as `StartAuthentication`, `TriggerTransaction`, and `Settlement`. The timing and responsibility differ depending on the initiator and logic owner. To learn more about each one, see the following pages. <CardGroup> <Card icon="circle-play" title="Device Start" href="/docs/integrate-pos-device/spark/payment-flows/spark-device-start"> Starts a session at the Nayax terminal when a consumer selects a service or presents a card. </Card> <Card icon="server" title="Remote Start" href="/docs/integrate-pos-device/spark/payment-flows/spark-remote-start"> Starts a transaction from your server and directs Nayax to activate a specific device. </Card> <Card icon="hand" title="Device Stop" href="/docs/integrate-pos-device/spark/payment-flows/spark-device-stop"> Validates a presented card and stops the matching session on the terminal. </Card> <Card icon="money-check-dollar" title="External Settlement" href="/docs/integrate-pos-device/spark/payment-flows/external-settlement"> Lets a third-party server complete or cancel a transaction authorized outside a Spark flow. </Card> <Card icon="ban" title="External Cancel" href="/docs/integrate-pos-device/spark/payment-flows/external-cancel"> Releases captured funds immediately when an authorized transaction did not deliver its service. </Card> </CardGroup> # Authentication Code Sample Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/sample-codes/spark-authentication-code-sample This page provides a detailed sample code flow for integrating Spark's authentication mechanism into your third-party application. The core requirement for all API calls to the Spark DMZ is to ensure security and integrity by generating an encrypted payload (Cipher) and authenticating the request with a Signature header. <Note> **Samples in C#** The following code snippets are provided in **C#** for example purposes. Developers should implement the same logic (e.g., AES-256 ECB encryption, SHA-256 hashing) in their chosen programming language to successfully communicate with the Spark DMZ. </Note> ## Step 1: generating the cipher The Cipher field is a securely encrypted payload that must be included in the request body. It serves as a strong mechanism to prove that you possess the necessary secret token without transmitting it openly. This function creates the final, encrypted Cipher string to be included in the request body. ```csharp C# theme={null} private string CreateCipher(string sparkTransactionId, string tokenSecretString, string random, bool needTimeStampInRandom = true) { string timeStamp = needTimeStampInRandom ? $"{DateTime.UtcNow:yyMMddHHmm}" : string.Empty; // 1. Create the unencrypted payload string string unencryptedCipher = $"{sparkTransactionId}={random}{timeStamp}"; // 2. Encrypt the payload using AES-256 ECB return CryptoUtils.EncryptAesECB256(unencryptedCipher, tokenSecretString); } ``` Where: * `sparkTransactionId`: Transaction identifier (use "1234" for testing) * `tokenSecretString`: Your secret token (key) which is used as the AES-256 ECB encryption key. * `random`: 17-digit random number. * `timestamp`: UTC time in format `yyMMddHHmm` (optional) ## Step 2: create signature The signature authenticates each request by combining the serialized request body with your header hash key and computing a SHA-256 hash. This signature is sent in the HTTP headers, along with your integrator ID, to verify the request's origin and integrity. This function calculates the signature string and packages it into the required HTTP headers. ```csharp C# theme={null} public Dictionary<string, string> CreateSignature<T>(T request, int integratorId) where T : class { // 1. Serialize the entire request body to a JSON string string serializedRequest = _jsonClient.Serialize(request, indent: false); _integratorDictionary.TryGetValue(integratorId, out Dictionary<string, string> headerHashKeyDictionary); if (headerHashKeyDictionary.IsNullOrEmpty() || serializedRequest.IsNullOrEmpty()) { return null; } // 2. Retrieve the Integrator's HeaderHashKey (integratorValue) // This value is shared and known only to the integrator and Nayax systems. headerHashKeyDictionary.TryGetValue("HeaderHashKey", out string integratorValue); if (integratorValue.IsNullOrEmpty()) { return null; } return new Dictionary<string, string> { { "IntegratorId", integratorId.ToString() }, { "Signature", $"{ByteUtils.CalculateSHA256($"{serializedRequest};{integratorValue}")}" } }; } ``` Where: * `request`: The whole request body object (StartAuthenticationRequest3rdParty in this case) * `integratorId`: Your unique integrator ID. * `IntegratorValue`: A secret `HeaderHashKey` used to authenticate the integrator. The output will be a dictionary containing the two mandatory HTTP request headers: `IntegratorId` and `Signature`. ## Request model The request model defines the structure of data sent to initiate authentication with Spark. Each authentication request must include your token ID, terminal identification details, and the encrypted cipher (created using the `CreateCipher()` method), and the random 17-digit number used in cipher generation. ```csharp C# theme={null} public class StartAuthenticationRequest3rdParty { public int TokenId { get; set; } public string TerminalId { get; set; } public int TerminalIdType { get; set; } public string Cipher { get; set; } public string Random { get; set; } } ``` ## Response model The response model defines the structure of data returned after initiating authentication with Spark. It includes the hashed transaction ID and status information. ```csharp C# theme={null} public class StartAuthenticationResponse3rdParty { [JsonProperty("HashedSparkTransactionId", Required = Required.Always)] public string HashedSparkTransactionId { get; set; } [JsonProperty("Status", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] public Status Status { get; set; } } public class Status { public string Verdict { get; set; } public int ErrorCode { get; set; } public string StatusMessage { get; set; } } ``` <br /> # Interactive Authentication Tool Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool Use this tool to handle Spark authentication without writing any code. Everything runs in your browser, so your token and sign key never leave your machine. The tabs at the top cover the three operations the tool performs: * **StartAuthentication**: build or inspect the cipher and the `TransactionSignature` header for the `StartAuthentication` call, the integrator's first request to open a transaction. The **Auth** and **Legacy Auth (v1)** sub-tabs cover the current and legacy signature flows. * **StartSession**: build or inspect the `Cipher` your server returns when Nayax sends a `StartSession` request to open a session. * **Header Signature**: generate the `IntegratorId` and `TransactionSignature` headers that authenticate a Spark API request. <SparkAuthTool /> ## See also <CardGroup> <Card icon="key" title="Authentication" href="/docs/integrate-pos-device/spark/security-authentication/spark-authentication"> The current standard for all new integrations. Header-based signature. </Card> <Card icon="clock-rotate-left" title="Legacy authentication" href="/docs/integrate-pos-device/spark/security-authentication/spark-legacy-authentication"> For maintaining existing integrations. HMAC signature over the JSON body. </Card> </CardGroup> # Legacy Authentication Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/security-authentication/spark-legacy-authentication Spark uses a two-part security mechanism: * Token-based identification to associate the request with your account. * HMAC signature using a shared secret (`Sign Key`) to ensure the request body hasn’t been tampered with in transit. This page will guide you to securely authenticate Spark API requests using Nayax’s custom HMAC signature mechanism. This involves signing each request body with a shared `Sign Key` and attaching two mandatory headers: `Signature` and `IntegratorId`. ## Prerequisites Before you begin, make sure you have the following resources: * A valid Sign Key (shared by Nayax, typically 16 characters) * The associated Sign Key ID <Warning> **Mandatory** This signature mechanism is required for all Spark endpoints. Requests without a valid signature will be rejected with `401 Unauthorized`. </Warning> ## Authenticate requests Once you have the required resources, you can start authenticating your API requests to Spark by following the steps below: 1. Prepare the JSON body with all the necessary fields (e.g., `TerminalId`, `Cipher`, etc.). Here’s a simplified example for the [StartAuthentication](/reference/spark/transactions/startauthentication) endpoint: ```json theme={null} { "TokenId": 116383, "TerminalId": "0434334921100366", "TerminalIdType": 1, "Random": "123456789qwertyui", "Cipher": "X305dITNTAw2vHsxE+taVcn6UvgBC3fdI6QbqeABgHbo8CKsoZhqISJfslehCiA+L7XYrqvKFci7C6BNj/trzBuNJwBEjgBzKhhgpJ5ggnw=" } ``` 2. Serialize the JSON request content, removing whitespace and line breaks. Do not alter values or add escape characters unless they are part of the actual payload. <Frame> <img /> </Frame> We used this [JSON lint tool](https://jsonlint.com/) to do so in the example. The result is the following. ```json theme={null} {"TokenId":116383,"TerminalId":"0434334921100366","TerminalIdType":1,"Random":"123456789qwertyui","Cipher":"X305dITNTAw2vHsxE+taVcn6UvgBC3fdI6QbqeABgHbo8CKsoZhqISJfslehCiA+L7XYrqvKFci7C6BNj/trzBuNJwBEjgBzKhhgpJ5ggnw="} ``` 3. Generate the `Signature` header following the steps below: 1. Concatenate the serialized request and the Sign Key, separated by ";". ```json theme={null} {"TokenId":116383,...,"Cipher":"..."};RbtdDsiVNjkAeRty ``` 2. Hash the result using SHA-256 (UTF-8 encoded): <Frame> <img /> </Frame> We used [this tool](https://emn178.github.io/online-tools/sha256.html) to do so in the example. Use the output as your `Signature` header. ```json theme={null} 536a5813206bcb663d98715d10a6b2612364245c865cdd5f781ff4428c4a6137 ``` 4. Add the `IntegratorId` and `Signature` headers to your request. <Note> **Base URL** The Spark API base URL is `https://nayax-spark-dmz.nayax.com/api`. The same host serves the integration and production environments. </Note> ```json theme={null} curl -X POST https://nayax-spark-dmz.nayax.com/api/StartAuthentication \ --header 'IntegratorId: 927' \ --header 'Signature: 536a5813206bcb663d98715d10a6b2612364245c865cdd5f781ff4428c4a6137' \ --header 'Content-Type: application/json' \ --data '{ "TokenId": 116383, "TerminalId": "0434334921100366", "TerminalIdType": 1, "Random": "123456789qwertyui", "Cipher": "X305dITNTAw2vHsxE+taVcn6UvgBC3fdI6QbqeABgHbo8CKsoZhqISJfslehCiA+L7XYrqvKFci7C6BNj/trzBuNJwBEjgBzKhhgpJ5ggnw=" }' ``` For this example, the [`/StartAuthentication`](/reference/spark/transactions/startauthentication) method was used, but the process is relevant for any Spark endpoint request and response. <Warning> **UTF-8 Encoding** Ensure the Signature is correctly generated from the minified JSON and UTF-8 hash. </Warning> ### Build `cipher` Your ciphertext combines the following: * A 36-character Spark Transaction ID (a GUID with hyphens). * A single "=" character. * A 17-character alphanumeric Random String. * A 10-character `YYMMDDhhmm` UTC Timestamp. Follow these steps to generate and encrypt your cipher: 1. Concatenate the Spark Transaction ID, the "=" character, the Random String, and the Timestamp to form the 64-character ciphertext, as in the example below: ``` 12c7cec2-c690-4425-9a1f-db0db60e2d8c=123456789qwertyui2306061021 ``` 2. Extract the 32 rightmost characters from your provided Token to create the 256-bit AES encryption key. For example, suppose the token is the following: ``` some_long_token_wRvTVTkungMIKThTVbj_fiXdfoGclhn0 ``` The encryption key is as follows: ``` wRvTVTkungMIKThTVbj_fiXdfoGclhn0 ``` 3. Encrypt the 64-character ciphertext using AES in ECB mode. Ensure the plaintext is padded (e.g., using PKCS7) to a multiple of 16 bytes. Base64 encode the resulting encrypted bytes for transmission, which yields an output similar to the example below: ``` X305dITNTAw2vHsxE+taVcn6UvgBC3fdI6QbqeABgHbo8CKsoZhqISJfslehCiA+L7XYrqvKFci7C6BNj/trzBuNJwBEjgBzKhhgpJ5ggnw= ``` ## See also <CardGroup> <Card icon="bolt" title="Interactive authentication tool" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool?auth=legacy"> Build and inspect the legacy cipher and `Signature` header in your browser, no code required. </Card> <Card icon="repeat" title="Payment flows" href="/docs/integrate-pos-device/spark/payment-flows/transaction-flows-spark"> How authentication fits into the full Spark transaction sequence. </Card> </CardGroup> # DeclineCallback Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/webhook-callbacks/declinecallback The `DeclineCallback` API call is used to notify you of a failure in the Spark transaction process. It is typically triggered after a successful `/TriggerTransaction` response with a verdict of `Approved`, but when the flow subsequently fails for any reason before payment authorization. This callback is essential for integrators to detect and gracefully handle cases where a session cannot proceed, such as when: * The consumer did not present a payment card, and the terminal timed out. * The consumer canceled the transaction on the Nayax Device. * A failure occurred on the device during the card presentation. * Other terminal-side errors that disrupt the flow. In such cases, no payment authorization is granted, and the transaction flow is terminated. If appropriate, the integrator may choose to re-attempt the `/TriggerTransaction` method. ## Request Spark sends a POST request to the `https://<YOUR_DOMAIN>/DeclineCallback` endpoint: ```json theme={null} { "MachineId": 71234996, "HwSerial": "0434334921100366", "SparkTransactionId": "12c7cec2-c690-4425-9a1f-db0db60e2d8c", "Status": { "Verdict": "Declined", "ErrorCode": 44, "ErrorDescription": "Timeout on POS Device" } } ``` ### Request parameters The table below describes the parameters of the request: | Field | Type | Required | Description | | - | - | - | - | | `MachineId` | Integer | Yes | The ID of the vending machine or terminal | | `HwSerial` | String | Yes | Serial number of the hardware terminal | | `SparkTransactionId` | String | Yes | The unique identifier of the failed Spark transaction | | `Status` | Object | Yes | An object indicating decline details | | `Status.Verdict` | String | Yes | Always "Declined" | | `Status.ErrorCode` | Integer | Yes | Decline reason code:<br />`44`: Timeout on POS Device<br />`45`: Cancelled on POS Device<br />`38`: Transaction Callback Failed | | `Status.ErrorDescription` | String | Yes | Description of the decline reason | ## Response This is a callback from Nayax, so no response body is required. Return `200 OK` to acknowledge it. # Webhook Callbacks Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/webhook-callbacks/index Webhooks are a crucial part of the Spark API, as they serve as automatic callbacks that alert your system to important events without requiring constant monitoring. For example, the `DeclineCallback` is triggered if a transaction fails after a successful `TriggerTransaction` request. This could happen if a consumer cancels the transaction on the device or if the terminal times out. Other webhooks, like `TimeoutCallback` and `StopCallback`, let you know when a session times out or when a consumer presents a card to stop a session, respectively. By using these callbacks, you can quickly handle failures and other events, ensuring your system's transaction state remains accurate without requiring constant polling. ## Available Webhooks <CardGroup> <Card icon="credit-card" title="TransactionCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback"> Notifies you when a card tap completes an authorization attempt. </Card> <Card icon="hand" title="StopCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/stopcallback"> Notifies you when a consumer presents a card to stop an active session. </Card> <Card icon="clock" title="TimeoutCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/timeoutcallback"> Notifies you when a payment session times out before completing. </Card> <Card icon="circle-xmark" title="DeclineCallback" href="/docs/integrate-pos-device/spark/webhook-callbacks/declinecallback"> Notifies you when a transaction fails after authorization begins. </Card> </CardGroup> ### Enable Custom Headers (Optional) This feature allows Nayax to send up to two static custom headers (e.g., for a shared secret or routing ID) with every callback to your system for enhanced security and verification. To enable custom headers for your integration: 1. **Request enablement** – Contact your Nayax Integration Support Engineer and ask to enable custom headers for your integration in the Nayax Backoffice. 2. **Provide header details** – Share the following information with your Integration Support Engineer: * Header Key – Up to 2 keys (minimum 1). * Header Value – Up to 2 values (minimum 1). # StopCallback Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/webhook-callbacks/stopcallback The `StopCallback` endpoint is used to notify the integrator that a consumer has presented their payment card at the terminal in an attempt to stop an ongoing session. This process allows the Spark integrator to validate and match the card against an active session that was originally authorized on the same terminal. This is primarily used in the Pre-Authorization transaction flow, if you choose to implement it. <Note> **Enable `StopCallback`** This feature must be enabled in Nayax Core during the integration. </Note> While the payment terminal is in Idle mode, it can accept a card presentation. If Nayax recognizes the card as belonging to an active transaction, it sends the `StopCallback` with the transaction details. If a session match is found, you need to send a `Settlement` request to complete the session termination. ## Request Spark sends a POST request to your configured `StopCallback` endpoint: `https://<YOUR_DOMAIN>/StopCallback` The body parameters are as in the example below: ```json theme={null} { "StopSiteId": 4, "MachineId": 71234996, "HwSerial": "0434334921100366", "CardLast4Digits": "1234", "CardHash": "7f2082ba5dbccf706b6987e75b62083f65b5695bc2d8c827c3e46769d007a9e6", "SparkTransactionId": "12c7cec2-c690-4425-9a1f-db0db60e2d8c", "NayaxTransactionId": 2004545072, "CardUid": "1288528281124927", "MachineAuTime": "20240205194122328", "ServiceStationNumber": "5" } ``` ### Request parameters The table below describes the parameters of the request: | Field | Type | Required | Description | | - | - | - | - | | `StopSiteId` | Integer | Yes | ID of the site where the session stop was triggered. | | `MachineId` | Integer | Yes | Unique ID of the vending machine or device. | | `HwSerial` | String | Yes | Hardware serial number of the terminal. | | `CardLast4Digits` | String | Yes | Last 4 digits of the card used for the transaction. | | `CardHash` | String | Yes | Hashed value of the payment card. | | `SparkTransactionId` | String | Yes | Spark transaction identifier of the original initiated session. | | `NayaxTransactionId` | Integer | Yes | Unique Nayax transaction ID. | | `CardUid` | String | No | Unique identifier of the card, if available. See a more detailed explanation on the [SMC Support](/docs/integrate-pos-device/spark/additional-resources/smc-support) page. | | `MachineAuTime` | String | Yes | Terminal's local timestamp in format `yyyyMMddHHmmssSSS`. | | `ServiceStationNumber` | String | No | Identifier of the charging point or station used. | ## Response This is a callback from Nayax, so no response body is required. Return `200 OK` to acknowledge it within 5 seconds. If no acknowledgment arrives in that time, the consumer experience is considered failed. # TimeoutCallback Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/webhook-callbacks/timeoutcallback The `TimeoutCallback` API call notifies that the payment session has timed out due to inactivity or failure to complete the expected flow within a defined period. This callback is typically triggered when the user does not proceed with the session after a pre-authorization and no further actions, such as `CancelTransaction` or `Settlement`, are received. <Note> **Pre-Authorization Only** This method is only relevant for transactions with Pre-Authorization. </Note> It serves as a final indication that the session should be considered terminated. <Warning> **Timed-out Session** Do not attempt any further actions for the timed-out session. Use the `SparkTransactionId` to reconcile or log the timeout event. </Warning> ## Request Spark sends a POST request to your configured `TimeoutCallback` endpoint: `https://<YOUR_DOMAIN>/TimeoutCallback` The request body is as in the example below: ```json theme={null} { "TerminalId": "0434334921100366", "MachineId": 71234996, "HwSerial": "0434334921100366", "SparkTransactionId": "12c7cec2-c690-4425-9a1f-db0db60e2d8c" } ``` ### Request parameters The table below describes the parameters of the request. | Field | Type | Required | Description | | - | - | - | - | | `TerminalId` | String | Yes | Identifier of the terminal that initiated the transaction. | | `MachineId` | Integer | Yes | ID of the vending machine or device. | | `HwSerial` | String | Yes | Hardware serial number of the terminal. | | `SparkTransactionId` | String | Yes | Unique Spark transaction identifier. | ## Response This is a callback from Nayax, so no response body is required. Return `200 OK` to acknowledge it. # TransactionCallback Source: https://devzone.nayax.com/docs/integrate-pos-device/spark/webhook-callbacks/transactioncallback The terminal uses the `TransactionCallback` endpoint to notify the integrator about the result of a card tap. It is triggered automatically when a user presents a card, and an authorization flow is initiated with the payment provider. This callback is essential for proceeding to transaction confirmation or rejection handling. ## Request The Spark platform sends a POST request to your configured `TransactionCallback` endpoint. The call would be sent to the following endpoint: `(Customer's URL)/TransactionCallback` The payload includes the full result of the card scan operation: ```json theme={null} { "NayaxTransactionId": 2004545072, "SparkTransactionId": "12c7cec2-c690-4425-9a1f-db0db60e2d8c", "SiteId": 2, "TerminalId": "0434334921100366", "MachineId": 71234996, "HwSerial": "0434334921100366", "AuthStatus": { "Verdict": "Approved", "ErrorCode": 0, "ErrorDescription": "", "StatusMessage": "" }, "CardLast4Digits": "1234", "CardHash": "7f2082ba5dbccf706b6987e75b62083f65b5695bc2d8c827c3e46769d007a9e6", "CardUid": "1288528281124927", "MachineAuTime": "20240205194122328", "Amount": 15.0, "CardBrand": "MASTERCARD", "CardFirst6Digits": "555561", "AuthCode": "3494297", "AuTime": "20240205194122328", "CurrencyCode": "ILS", "CurrencyNumeric": "376", "FiscalRrn": "1A2b3C4d5E6f7g8H9i", "NayaxRRN": "527109494297" } ``` ### Request parameters The table below describes all the parameters of the request: | Field | Type | Required | Description | | - | - | - | - | | `NayaxTransactionId` | Integer | Yes | Internal Nayax transaction ID. | | `SparkTransactionId` | String | Yes | Unique session ID generated in `StartAuthentication`. | | `SiteId` | Integer | Yes | ID of the vending site or Spark location. | | `TerminalId` | String | Yes | Unique ID of the terminal that read the card. | | `MachineId` | Integer | Yes | Identifier of the vending machine or device. | | `HwSerial` | String | Yes | Hardware serial number of the terminal. | | `AuthStatus` | Object | Yes | Card authorization result. | | `AuthStatus.Verdict` | String | Yes | Authorization decision (`Approved`, `Declined`, etc.). | | `AuthStatus.ErrorCode` | Integer | No | An optional error code if the card was declined. | | `AuthStatus.ErrorDescription` | String | No | Explanation of the error, if any. | | `AuthStatus.StatusMessage` | String | No | Status message returned by Spark. | | `CardLast4Digits` | String | Yes | The last four digits of the presented card. | | `CardHash` | String | Yes | One-way hash of the full card number. | | `CardUid` | String | Yes | UID of the card (for prepaid cards). See a more detailed explanation on the [SMC Support](/docs/integrate-pos-device/spark/additional-resources/smc-support) page. | | `MachineAuTime` | String | Yes | Timestamp from the machine in the format `yyyyMMddHHmmssSSS`. | | `Amount` | Number | Yes | Transaction amount in the main currency unit (decimal place 0, e.g., 15.0 for \$15.00) | | `CardBrand` | String | No | Card brand used (e.g., Visa, MasterCard). | | `CardFirst6Digits` | String | No | The first 6 digits of the credit card (card BIN). | | `AuthCode` | String | No | Authorization code returned by the payment provider. | | `AuTime` | String | No | Authorization server timestamp. | | `CurrencyCode` | String | No | ISO currency code (e.g., "EUR"). | | `CurrencyNumeric` | String | No | ISO 4217 numeric code (e.g., "978"). | | `FiscalRrn` | String | No | Fiscal reference number for accounting/reporting. | | `NayaxRRN` | String | No | Internal Nayax settlement reference number. | <Note> **Nayax Callback** This is a callback from Nayax, no response body is required. A simple 200 OK server acknowledgment is sufficient. </Note> # Create New Queue Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/create-new-queue Creating an Amazon SQS queue is the first step in setting up your integration with Nayax. ## Select AWS region Once the prerequisites are complete, you can proceed to select the AWS region where your queue will be created. 1. Go to the top-right corner of the AWS console. 2. Select the region where you will create the queue. <Warning> **Region pricing and latency** It's important to note that the region you select will affect the pricing and latency. </Warning> <Frame> <img /> </Frame> ## Create a queue Now that you’ve selected a region, the next step is to create a new queue. 1. Click the **three lines** icon located in the upper left corner of the AWS console. 2. Select the **All services** option. <Frame> <img /> </Frame> 3. Search the **Application Integration** category and select **Simple Queue Services** (SQS). <Frame> <img /> </Frame> 4. Then, click **Create Queue**. <Frame> <img /> </Frame> 5. In the **Details** section: a. Select **Standard** as the queue type. b. Enter a unique name for your queue. <Frame> <img /> </Frame> 6. Configure the additional sections based on your needs: * **Configuration:** Define basic settings for the queue. * **Encryption:** Secure your queue messages with encryption. * **Access policy:** Set permissions for accessing the queue. * **Redrive allow policy (Optional):** Enable or disable policies for message redriving. * **Dead-letter queue (Optional):** Configure a queue for undeliverable messages. * **Tags (Optional):** Add tags to categorize and manage your queue. <Note> **Optional Sections** Optional sections such as Redrive allow policy, Dead-letter queue, and Tags should be filled in based on your specific requirements. They help customize your queue's functionality and management. </Note> 7. Click the **Create Queue** button. <Frame> <img /> </Frame> Once the queue is successfully created, a confirmation message will appear on the screen along with the **Queue URL** and **ARN (Amazon Resource Name)**. Copy these values, which will be needed for integration and permissions setup in subsequent steps. <Frame> <img /> </Frame> <br /> # Create User for Queue Access Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/create-user-for-queue-access After setting up the queue permissions, AWS requires a user account to interact with the queue programmatically. This user will utilize the previously created policy to secure queue access. ## Types of AWS users AWS offers various methods to manage users and provide access to resources, including users created in IAM, federated users, and users managed through IAM Identity Center. 1. **IAM Users (Long-Term Credentials)** * **Description:** These are users created directly in AWS IAM, with long-term credentials (e.g., Access Keys) to access AWS resources. * **Primary Use Cases:** * Applications or services that cannot use IAM roles. * Third-party clients requiring programmatic access keys. * Scenarios where the **IAM Identity Center** is unavailable. * **Considerations:** * Long-term credentials are not recommended for individuals as they pose greater security risks. Regularly rotate access keys to minimize potential security threats. 2. **IAM Identity Center Users (Short-Term Credentials)** * **Description:** Users created in the **IAM Identity Center** (formerly AWS SSO) can obtain temporary credentials to interact with AWS resources. * **Primary Use Cases:** * Workforce users (e.g., employees) needing centralized and secure access to multiple AWS accounts or applications. * Integration with external identity providers like **Okta, Microsoft Entra, or Active Directory** for access management. * **Advantages:** * Supports MFA (multi-factor authentication) for enhanced security. * Simplifies access with single sign-on (SSO) and centralized control. 3. **Federated Users** * **Description:** Users authenticated through an external identity provider (IdP), such as Login with Amazon, Facebook, Google, or a corporate IdP compatible with **SAML 2.0 or OIDC**. * **Primary Use Cases:** * Integrating existing users from a corporate directory or mobile/web app without creating IAM users in AWS. * **Advantages:** * Leverages temporary credentials for increased security. * Enables seamless SSO for a smoother and more secure user experience. <Warning> **Key Recommendation** * For individuals or internal users, it is recommended to use **IAM Identity Center** to manage centralized access and provide temporary credentials. * For programmatic integrations requiring long-term credentials, use **IAM Users** with strict policies and frequent key rotation. * Consider **federating users** if your organization already has an identity management system or for cases requiring access from mobile or web applications. For more information, see [**Support programmatic user access**](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_identity-management.html#gs-get-keys). </Warning> In this case, you will create a **Programmatic Access user**. ## Add user To create a user, follow these steps: 1. Go to **Users** in the left side menu under **Identity and Access Management (IAM)**. 2. Click the **Create User** button. <Frame> <img /> </Frame> 3. Set a username for the user. 4. Click the **Next** button. <Frame> <img /> </Frame> ## Set permissions Attach the previously created policy to the user to grant the necessary permissions. In the **Permissions options** section: 1. Select **Attach policies directly**. In the **Permissions policies** section: 2. Filter policies by typing the policy name created earlier. 3. Select the policy created earlier. 4. Click the **Next** button. <Frame> <img /> </Frame> ## Review and create user (Optional) AWS tags can help identify and track resource usage for pricing and management purposes: 1. Click the **Add new tag** button. 2. Add a tag with a key like **`NAME`** and a value for tracking resources. 3. Review all the settings to ensure they are correct. 4. Click the **Create User** button. <Frame> <img /> </Frame> Once the user is created, you will receive a confirmation message indicating successful setup. <Frame> <img /> </Frame> ## Assign programmatic access user The next step in configuring programmatic access is generating access credentials for the created user. These credentials will allow interaction with the queue programmatically. 1. To view the user, you have 2 options: a. Click the **View user button** located in the **User created successfully** note. b. Select **TXQueueUser** in the User name column. <Frame> <img /> </Frame> 2. Click **Create access key** in the Summary section. <Frame> <img /> </Frame> 3. Select the **Command Line Interface** option. <Frame> <img /> </Frame> 4. Enable the checkbox to confirm your understanding of the recommendations. 5. Then, click the **Next** button. <Frame> <img /> </Frame> 6. Finally, click the **Create access key** button. <Frame> <img /> </Frame> ## Save access credentials After creating the access key, you will be shown the **Access Key ID** and **Secret Access Key**, which are necessary for integration. Perform one or both of the following actions: 1. Click Show to view the keys and manually copy them. 2. Click Download CSV to save the keys in a secure file. It is recommended to do both. <Warning> **Credentials** This is the last time these credentials will be available to download. However, you can create new credentials at any time. </Warning> 3. Click the **Done** button. <Frame> <img /> </Frame> ## Summary Once completed, you will have the required credentials to access the queue. The details necessary to continue the setup in the [**Nayax Core**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/nayax-back-office-setup) are: * **Queue URL** * **Access Key ID** * **Secret Access Key** <br /> # Amazon Queue Setup Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/index To set up Amazon SQS integration with Nayax, we recommend exploring the following documentation pages: 1. [**Create New Queue**](/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/create-new-queue): Learn how to set up a queue to receive data securely and efficiently. 2. [**Set Up Queue Permissions**](/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/set-up-queue-permissions): This guide covers configuring access controls to manage queue security. 3. [**Create User for Queue Access**](/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/create-user-for-queue-access): Follow this guide to create and configure an IAM user with the appropriate permissions. ## Prerequisites Before proceeding, ensure the following: * You have an [**Amazon AWS account**](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank\&all-free-tier.sort-order=asc). * You are logged in to the **AWS Management Console**. Once these prerequisites are met, follow the steps below to set up the Amazon SQS Queue. # Queue Permissions Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/set-up-queue-permissions Having created the queue in the previous step, the next task is configuring permissions to manage access. This involves creating a policy, setting up user access, and assigning the policy to the created user. Policies define the actions allowed on the queue and are crucial for controlling access to your AWS resources. ## Manage access to AWS resources To begin configuring access to your queue, you first need: 1. Click the **three lines** icon located in the upper left corner of the AWS console. 2. Select the **All services** option. 3. Search the **Security, Identity, & Compliance** category and select **IAM** (Identity and Access Management). <Frame> <img /> </Frame> 4. Click **Policies** on the left side menu. <Frame> <img /> </Frame> ## Create policy Policies are created to define what actions users can perform on your queue. Follow these steps to create a new policy: 1. Click the **Create Policy** button. <Frame> <img /> </Frame> 2. In the **Service > Choose a service** field, search and select **SQS**. <Frame> <img /> </Frame> ## Set permissions for SQS Now that you’ve selected SQS as the service, define the permissions needed for the queue: 1. Under **Actions**, select the permissions you need for the queue. <Frame> <img /> </Frame> ## Set policy to specific ARN The Policy you are creating can be assigned to any Queue. In this case, you’ll assign it to the specific queue created earlier. <Note> **Resources** Ensure that the **Specific** resource is selected. </Note> To Add the ARN of the previously created queue, follow these steps: 1. Click **Add ARNs**. <Frame> <img /> </Frame> 2. Enter the copied ARN in the **Resource ARN** field. You can find this value from the confirmation screen displayed at the end of the [**Create New Queue**](/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/create-new-queue) process. 3. Click the **Add ARNs** button. <Frame> <img /> </Frame> 4. Click the **Next** button. <Frame> <img /> </Frame> ## Review and create the policy Before finalizing the policy, review its details to ensure all configurations are correct. This step is essential to avoid potential issues with permissions. In the **Policy details** section: 1. Enter a unique **name** to identify this policy. 2. Add a description for this policy **(Optional)**. <Frame> <img /> </Frame> 3. Finally, click the **Create Policy** button. <Frame> <img /> </Frame> Once the policy is created, you will receive a confirmation that it has been successfully set up. <Frame> <img /> </Frame> <br /> # Overview Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/overview Nayax supports two methods for delivering transaction reports to your systems. Choose the method that best fits your integration needs: <CardGroup> <Card title="Amazon SQS" icon="bolt" href="/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/nayax-back-office-setup"> **Online (Real-time delivery)** Transactions are pushed to your Amazon SQS queue immediately as they occur. Ideal for systems that need up-to-the-minute data. </Card> <Card title="SFTP / email" icon="clock" href="/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-transaction-delivery#scheduled-file-report-sftp--email"> **Periodic (Batch delivery)** Transaction reports are delivered to an SFTP server or email address at the end of each hour or day. Ideal for back-office batch processing. </Card> </CardGroup> ## Amazon SQS (real-time) Amazon SQS (Simple Queuing Service) is a queue mechanism that provides a robust, redundant, and reliable way to transfer data between systems without managing retry logic. By integrating SQS with Nayax Core, operators can securely transmit payment details, machine events, and audit data while maintaining data integrity and encryption. The SQS integration is a two-step process: * [Setting up Amazon Queue in AWS](/docs/manage-data-operations/amazon-sqs/amazon-queue-setup/index) * [Configuring Nayax Core](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/nayax-back-office-setup) ## Email/SFTP (periodic) Nayax Core can be configured to deliver a transaction report file to an SFTP server or email address on a recurring schedule (hourly or daily). The report uses the same transaction fields as SQS and supports CSV or XML output with configurable delimiters. Setup is done entirely in Nayax Core. See the [Scheduled File Report (Email/SFTP)](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-transaction-delivery#scheduled-file-report-sftp--email) section of the transaction delivery guide. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> # Nayax Core Setup Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/nayax-back-office-setup Nayax Core supports delivery of transaction and operational data through multiple channels. You can configure real-time delivery to Amazon SQS, or set up periodic batch delivery to an SFTP server or email address. To set up Nayax Core, we recommend reviewing the following documentation pages: * [**Transaction Report Delivery**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-transaction-delivery): Configure real-time delivery of transaction data to Amazon SQS, or set up periodic delivery via SFTP or Email. * [**DEX Audit File Delivery**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-eva-dts-dexddcmp-audit-file-delivery): Enable audit file delivery in compliance with EVA DTS standards. * [**Event and Alert Delivery**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-events-delivery): Configure delivery of system events for real-time tracking and monitoring. * [**SQS Message Encryption**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery): Implement encryption for secure data transmission. By following these guides, you can fully configure Nayax Core for all supported delivery methods. # SQS Message Encryption Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery To set up Encryption on Delivery to Amazon SQS, you must have access to Nayax Core and Lynx API with the appropriate user permissions. Specifically, the following roles: * **Lynx - SQS Encryption** To enable the encryption on the messages sent to Amazon SQS, you should mark the **Enable Encryption** check box in the relevant configuration section as described in the previous sections. ## Access the Lynx API 1. [**Log into Lynx Operational**](https://lynx.nayax.com/operational/signin) 2. Enter your Nayax Core credentials. <Frame> <img /> </Frame> ## Generate encryption keys You will need the **Actor ID (Operator ID)** to generate encryption keys, which can be found in Nayax Core under **Administration > Operator > Details** tab. 1. Click the **Generate New Token** button in the top-right corner of the Lynx API interface. 2. Select the **PUT /v1/actors/GenerateEncKey** row to reveal more details. 3. Enter the `actorID` parameter value. 4. Click the **Try it out!** button to generate a new encryption key. <Warning> **Encryption Key Usage and Refresh Guidelines** * If the Enable Encryption checkbox is marked in any SQS message delivery configuration within Nayax Core, all messages sent to the queue will be encrypted using the generated encryption key. * The encryption key can be refreshed by repeating the steps above. Each new key will have an incremented `enc_ver` value, indicating the key version number. </Warning> <Frame> <img /> </Frame> The Response will contain the following values: | Field Name | Description | | - | - | | **actor\_id** | Auto-generated unique id, represents the hierarchical entity in the hierarchy tree | | **enc\_ver** | Numerator identifying Encryption Key Version | | **enc\_key** | Encryption Key, Alphanumeric GUID used to encrypt Messages delivered to Amazon SQS | | **created\_dt** | Encryption Key Creation Date and Time | Example Response <Frame> <img /> </Frame> ## List encryption keys You can retrieve all previously generated keys using the Lynx API's GET Encryption Keys option: 1. Click on **GET /v1/actors/GetEncKeys** row to reveal more details 2. Enter the `actorID` parameter value. 3. Click the **Try it out!** button to view the list of generated keys. By following these steps, you can ensure secure and encrypted message delivery to Amazon SQS. <Frame> <img /> </Frame> Example Response: <Frame> <img /> </Frame> ## Decrypt messages You can also use the encryption key to perform the decryption of messages. See the code block below: ```cs theme={null} public string Decrypt(string cipherText) { using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText))) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } } } } } } // AES Encryption Example string key = "0123456789abcdef"; // 16 bytes key string iv = "abcdef9876543210"; // 16 bytes IV AesEncryption aes = new AesEncryption(key, iv); string original = "Hello, World!"; string decrypted = aes.Decrypt(encryptedMessage); ``` Where: 1. It initializes the AES algorithm with a `key` and an initialization vector (`IV`) and then creates a `decryptor`. 2. The encrypted message, provided as a `Base64` string is converted back into bytes and read using a `MemoryStream` and `CryptoStream` with the `decryptor`. 3. The decrypted data is then read and returned as the original plaintext string. The method essentially reverses the encryption process to retrieve the original message. <br /> # DEX Audit File Delivery Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-eva-dts-dexddcmp-audit-file-delivery To set up DEX file delivery to Amazon SQS, you must have access to **Nayax Core** with the appropriate user permissions. Specifically, the following roles are required: * **VMO-Manager** * **DEX Notify - SQS** Additionally, ensure you have the **Amazon SQS Queue URL**, **Access Key**, and **Secret Key** obtained during the queue setup process. <Note> **Prerequisite: Dex Read Schedule Configuration** These setup instructions assume that the DEX Read schedule has already been configured. </Note> ## Operator level setup Follow these steps to configure DEX delivery at the operator level in the Nayax Core: 1. Go to **Administration > Operator**. <Frame> <img /> </Frame> 2. Find the Operator you wish to set up. 3. Click the **Search** button. 4. Select the operator to display all tabs and details. 5. Go to the **Dex** tab. 6. Click to open the **Dex Notify** section. <Frame> <img /> </Frame> 7. Set up Dex Transmission to Amazon SQS: a. Select the checkbox next to **Amazon SQS** to enable this option. b. Enter the SQS credentials (**Access Key**, **Secret Key** and **Queue URL**). c. Click the **Validate** button to ensure the Queue credentials are correct. d. Enable Encryption (Optional). See the [**Set Up Encryption**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery) section for details. <Frame> <img /> </Frame> 8. Choose Dex Format and Filter settings: a. Ensure the format is set to **No Formatting**. b. Select the desired DEX Read Types. Only the selected Dex Origins will be sent to the Queue. <Frame> <img /> </Frame> 9. Click the **Save Information** button to apply the changes. <Frame> <img /> </Frame> <Warning> **Operator Defaults vs Machine-Level Configuration** Setting up DEX delivery at the operator level does not initiate the delivery of DEX files to the queue. Instead, these configurations act as defaults for new machines under the operator’s hierarchy. You can propagate these settings using the **Apply Dex to** button or perform individual setups at the machine level as explained below. <Frame> <img /> </Frame> </Warning> ## Machine level setup <Note> **Prerequisite: Dex Read Schedule Configuration** These setup instructions assume that the DEX Read schedule has already been configured. </Note> To configure DEX delivery at the machine level: 1. Go to **Operations > Machines** in the Nayax Core. <Frame> <img /> </Frame> 2. Find the Operator you wish to set up. 3. Click the **Search** button. 4. Select the operator to display all tabs and details. 5. Go to the **Dex** tab. 6. Click to open the **Dex Notify** section. <Frame> <img /> </Frame> 7. Set up Dex Transmission to Amazon SQS: a. Select the checkbox next to **Amazon SQS** to enable this option. b. Enter the SQS credentials (**Access Key**, **Secret Key** and **Queue URL**). c. Click the **Validate** button to ensure the Queue credentials are correct. d. Enable Encryption (Optional). See the [**Set Up Encryption**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery) section for details. <Frame> <img /> </Frame> 8. Choose Dex Format and Filter settings: a. Ensure the format is set to **No Formatting**. b. Select the desired DEX Read Types. Only the selected Dex Origins will be sent to the Queue. <Frame> <img /> </Frame> 9. Click the **Save** button to apply the changes. <Frame> <img /> </Frame> ## Example DEX/DDCMP audit file JSON message Below is an example of the JSON message format for the DEX/DDCMP audit file that will be sent to Amazon SQS upon completing the setup: ``` { "HWSerial": "534332119000155", "MachineDate": "20200325 090132_660", "OperatorIdentifier": "500454", "Origin": "AUTOMATIC", "DexData": "DXS*AUTSENSIT3*VA*V0/6*1\r\nST*001*0001\r\nID1*P138140482*AMS SENSIT III*****6*0\r\nID4*2*0178*1\r\nID5*200325*0358**NA\r\nCB1*P138140482*AMS SENSIT III*3426- v1.37*2.50\r\nVA1*7037419*11431*0*0*3165272*6786*0*0\r\nCA1*000045003002*ILS-G801- 009*3600\r\nCA2*4110*8*0*0\r\nCA3*0*0*0*0*1950*0*1950*0*0*0\r\nCA4*0*0*100*0\r\nCA6*9823*1014\r\nCA7*0*0*0*0\r\nCA8*0*18800\r\nCA10*0*0 \r\nCA15*0\r\nBA1*151100011754*XBA-EUR40000*0120\r\nDA1*332119000155*DMX - 2011 *0100\r\nDA2*7033309*11423*0*0\r\nDA4*0*0\r\nDA5*0*0*3165272*6786***31038*220\r\nDA9*0*0\r\nPA1*10*550*Kinder Bueno Whi\r\nPA2*2*1100*0*0\r\nPA1*11*600*dortos green\r\nPA2*241*143500*0*0*156*73500*0*0*0*0\r\nPA1*13*600*Bamba nugget\r\nPA2*271*161300*0*0*178*94700*0*0*0*0\r\nPA1*15*450*bamba big\r\nPA2*504*273000*0*0*375*190037*0*0*20*1700\r\nPA1*17*600*Chips\r\nPA2*269*161300*0*0*191*88050*0*0*0*0\r\nPA1*19*600*Chips\r\nPA2* 196*117300*0*0*145*73350*0*0*0*0\r\nPA1*21*600*milka\r\nPA2*282*168900*0*0*149*66800*0*0*34*3400\r\nPA1*23*350*Bisli Gril\r\nPA2*453*213350*0*0*315*108300*0*0*5*650\r\nPA1*25*550* Bisli Gril\r\nPA2*332*174350*0*0*205*81350*0*0*0*0\r\nPA1*27*600*nishnushim\r\nPA2*280*164700*0*0*179*73750*0*0*0*0\r\nPA1*29*600*Abadi\r\nPA2 *254*135500*0*0*142*54600*0*0*9*900\r\nPA1*31*600*Click BW\r\nPA2*363*233500*0*0*179*89050*0*0*22*2100\r\nPA1*33*700*Click- cariot\r\nPA2*372*244700*0*0*165*76500*0*0*0*0\r\nPA1*35*700*Click-BW\r\nPA2*425*289100*0*0*282*163500*0*0*0*0\r\nPA1*37*700*Click- Red\r\nPA2*462*313000*0*0*237*119900*0*0*0*0\r\nPA1*39*700*crunch red\r\nPA2*428*292300*0*0*220*118000*0*0*0*0\r\nPA1*40*550*mekupelet\r\nPA2*269*151650*0*0*129*50450*0*0*2*1100\r\nPA1*41*550*Kinder Bueno Whi\r\nPA2*494*275350*0*0*301*121000*0*0*0*0\r\nPA1*42*550*Twix\r\nPA2*353*196800*0*0*261*101387*0*0*0*0\r\nPA1*43*550*Pesek azman\r\nPA2*302*167350*0*0*203*91100*0*0*1*550\r\nPA1*44*600*gardena\r\nPA2*389*232900*0*0*278*87600*0*0*0*0\r\nPA1*45*600*Kitkat- Chunky\r\nPA2*388*232300*0*0*201*78350*0*0*0*0\r\nPA1*46*600*Mike and Ike\r\nPA2*370*221400*0*0*233*82950*0*0*0*0\r\nPA1*47*600*Mentos\r\nPA2*285*170700*0*0*164*45450*0*0*0*0\r\nPA1*48*600*must\r\nPA2*346 *205700*0*0*223*104550*0*0*0*0\r\nPA1*49*500*Must\r\nPA2*272*119765*0*0*200*83950*0*0*12*5388\r\nPA1*50*550*bueno\r\nPA2*432*242150*0 *0*216*76350*0*0*0*0\r\nPA1*51*550*Corny Choco Bana\r\nPA2*404*226050*0*0*235*76950*0*0*7*350\r\nPA1*52*600*Corny Chocolate\r\nPA2*324*184000*0*0*180*77050*0*0*0*0\r\nPA1*53*1350*EXCE\r\nPA2*358*343750*0*0*197*193574*0*0*33*2600\r\nPA1*54*1200*volta ge\r\nPA2*214*145700*0*0*111*60150*0*0*3*1500\r\nPA1*55*1350*EXCE\r\nPA2*408*437050*0*0*235*268737*0*0*67*6300\r\nPA1*56*500*Fitness \r\nPA2*288*165800*0*0*115*43050*0*0*5*4500\r\nPA1*57*500*Fitness \r\nPA2*227*134600*0*0*102*28100*0*0*0*0\r\nPA1*58*500*Fitness \r\nPA2*143*82500*0*0*84*23137*0*0*0*0\r\nPA1*59*100*Embedded Testing****1\r\nPA2*31*15004*0*0\r\nEA1*EGS*200205*0104***58\r\nEA1*EGT*200205*0112***63\r\nEA1*EGS*200205*0412***57\r\nEA1*EGT*200205* 0418***66\r\nEA1*EGS*200205*0454***56\r\nEA1*EGT*200205*0455***59\r\nEA1*EGS*200205*0456***62\r\nEA1*EGT*200205*0457***64\r\nEA1*EGS* 200205*0705***57\r\nEA1*EGT*200205*0708***63\r\nEA7*0*151\r\nEA3*6923*200325*0358*1234567890*200325*0307*1234567890**9823*6923\r\nEA4 *151213*0630*1234567890\r\nSD1*****AUTO*AUTO\r\nMA5*TEMP*59*15\r\nG85*3CE2\r\nSE*110*0001\r\ } ``` ## JSON message fields description The following table describes the fields included in the DEX/DDCMP audit file JSON message: | **Field Name** | **Type** | **Description** | | - | - | - | | **HWSerial** | `string` | Hardware serial number of the machine. | | **MachineDate** | `string` | Date and time recorded by the machine. | | **OperatorIdentifier** | `string` | Unique identifier for the machine operator. | | **Origin** | `string` | Source or origin of the data. | | **DexData** | `string` | DEX protocol data captured from the machine. | <br /> # Event and Alert Delivery Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-events-delivery To set up Events and Alerts Delivery to Amazon SQS, you must have access to **Nayax Core** with the appropriate user permissions. Specifically, the following roles are required: * **VMO - Manager** Additionally, ensure you have the **Amazon SQS Queue URL**, **Access Key**, and **Secret Key** obtained during the queue setup process. ## Operator level setup Follow these steps to configure Events and Alerts Delivery in Nayax Core: 1. Go to **Administration > Operator**. <Frame> <img /> </Frame> 2. Find the Operator you wish to set up. 3. Click the **Search** button. 4. Select the operator to display all tabs and details. <Frame> <img /> </Frame> 5. Go to the **Events Report** tab. 6. Setup General and Alert via SQS: a. Select the checkbox next to **Is Active** to enable this option. b. Enter the SQS credentials (**Access Key**, **Secret Key** and **Queue URL**). c. Click the **Validate** button to ensure the Queue credentials are correct. d. Enable Encryption (Optional). See the [**Set Up Encryption**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery) section for details. <Frame> <img /> </Frame> 7. Apply Data Filters for Event Delivery a. Ensure the format is set to **No Formatting**. b. Select the desired DEX Read Types. Only the selected Dex Origins will be sent to the Queue. 8. Click the **Save Information** button to apply the changes. <Frame> <img alt="" /> </Frame> ## Example event/alert JSON message Below is an example of the JSON message format for Events and Alerts that will be sent to Amazon SQS: ```json theme={null} { "distributorld": "27594", "distributorName": "Nayax Demo", "operatorld": "2000144542", "operatorName": "Daniel_OP", "actorld": "2000144542", "actorName": "Daniel_OP", "machineld": "697356467", "machineName": "EX PP Machine", "machineNumber": null, "machineSerial": null, "deviceld": "25795395", "deviceSerial": "0404041919567757", "eventSourceld": "6", "eventSourceName": "Device", "eventCode": "1", "eventName": "Power up", "eventData": "Device Serial #:0404041919567757\nDevice FW Version:4.0.0.5-rc3 - Jan 9 2019\nDevice Hardware:4.13\nVPOS\nSerial #:\nVPOS FW Version:2009-rc07\nMDB Max Response Time:7\nDevice MDB Level:1\nDecimal Place:2\nManufacturer\nCode:4805701\nMachine MDB Level:1\nModem IMEI: 357036091438914\nModem Model (HW Revision): UE910-EUD\nModem FW\nVersion:12.00.414\nModem Type:3G\nSIM Card Serial #:89462008002001388010\nSIM Card Mobile Number:NO CLIn\nMobile\nOperator Name:42501\nModem CDMA SN (MEID):\nLast Power Down time: 23/03/2020 14:27:30", "eventDateTimeGMT": "2020-03-23T14:11:35.980", "eventDateTimeVMC": "2020-03-23T17:11:35.980", "enc_ver": "1", "enc_key": "63562b7245cb478cb38a509ec764e012" } ``` ## JSON message fields description The following table describes the fields included in the Event/Alert JSON message: | **Field Name** | **Type** | **Description** | | - | - | - | | **distributorId** | `string` | Unique identifier for the distributor. | | **distributorName** | `string` | Name of the distributor. | | **operatorId** | `string` | Unique identifier for the operator. | | **operatorName** | `string` | Name of the operator. | | **actorId** | `string` | Unique identifier for the actor. | | **actorName** | `string` | Name of the actor. | | **machineId** | `string` | Unique identifier for the machine. | | **machineName** | `string` | Name of the machine. | | **machineNumber** | `string` | Internal number assigned to the machine. | | **machineSerial** | `string` | Serial number of the machine. | | **deviceId** | `string` | Unique identifier for the device. | | **deviceSerial** | `string` | Serial number of the device. | | **eventSourceId** | `string` | Unique identifier for the event source. | | **eventSourceName** | `string` | Name of the event source. | | **eventCode** | `string` | Code associated with the event. | | **eventName** | `string` | Name of the event. | | **eventData** | `string` | Data associated with the event. | | **eventDateTimeGMT** | `string` | Event date and time in GMT format. | | **eventDateTimeVMC** | `string` | Event date and time as recorded by the machine. | | **enc\_ver** | `string` | Encryption version used for the data. | | **enc\_key** | `string` | Encryption key used for securing the data. | <br /> # Transaction Report Delivery Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-transaction-delivery ## Prerequisites To set up Transaction Delivery to Amazon SQS, you must have access to the Nayax Core with the appropriate user permissions. Specifically, the following roles are required: * **Transaction Dispatcher** * **Transactions Report Subscriber** Without both roles, the **Transactions Report** tab does not appear in Nayax Core. Additionally, ensure you have the **Amazon SQS Queue URL**, **Access Key**, and **Secret Key** obtained during the queue setup process. ## Operator Level Setup Follow these steps to configure transaction delivery at the operator level in the Nayax Core: 1. Log in to the **Nayax Core**. <Frame> <img alt="Nayax Core Login" /> </Frame> 2. Go to **Administration > Operator**. <Frame> <img alt="Administration Operator Menu" /> </Frame> 3. Find the Operator you wish to set up. 4. Click the **Search** button. 5. Select the operator to display all tabs and details. 6. Go to the **Transactions Report** tab. <Frame> <img alt="Transactions Report Tab" /> </Frame> 7. Set up Transaction Dispatching by completing the following steps: a. Select the checkbox next to **Amazon SQS** to enable this option. b. Enter the SQS credentials (**Access Key**, **Secret Key** and **Queue URL**). c. Click the **Validate** button to ensure the Queue credentials are correct. d. Enable Encryption (Optional). See the [**Set Up Encryption**](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/set-up-encryption-on-amazon-sqs-delivery) section for details. e. Choose payment methods to send. Only the selected payment methods will be dispatched to the Queue. You can also select the transaction type: * Free Transactions * Cancelled Transactions * Refund Transactions * Declined Transactions f. Select the Columns of information to include. See the [Transaction JSON Reference](/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/transaction-json-reference) page for a description of available fields. <Frame> <img alt="SQS Configuration Settings" /> </Frame> 8. Click the **Save Information** button to apply the changes. <Frame> <img alt="Save Information Button" /> </Frame> By completing these steps, your transaction data will be securely delivered to Amazon SQS based on the configuration you've set up. ## Scheduled File Report (SFTP / Email) In addition to real-time Amazon SQS delivery, Nayax Core can deliver transaction reports periodically — either hourly or daily — to an SFTP server or by email. This is configured on the same **Transactions Report** tab, in the **Scheduled File Report Via Email / SFTP** section. ### Enable and configure the report 1. In the **Transactions Report** tab, scroll to the **Scheduled File Report Via Email / SFTP** section. 2. Toggle **Enable Report** to on. 3. Configure the report format: | Field | Description | | - | - | | **File Type** | Select **XML** or **CSV**. | | **Delimiter** | Choose Tab, Semicolon, Comma, Space, Pipe, or Other. | | **Other** | Custom delimiter character (only when **Other** is selected). | | **Include Headers Row** | Toggle on to include a column header row in the file. | 4. Set the **Report Interval**: **Hourly** (select the minute) or **Daily** (select the time of day). ### Connection details Fill in the delivery connection details: | Field | Required | Description | | - | - | - | | **IP Address** | Yes | Server hostname or IP address. | | **Port** | Yes | Server port. | | **Folder** | No | Remote destination folder path. | | **User** | Yes | Username. | | **Password** | Yes | Password. | | **Fingerprint** | No | Server fingerprint for verification. | Click **Validate** to test the connection, then save. <Frame> <img alt="SFTP Setup Configuration" /> </Frame> <Card title="Transaction JSON Reference" icon="brackets-curly" href="/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/transaction-json-reference"> View the example JSON message and full field descriptions for transactions delivered to Amazon SQS. </Card> # Transaction Message Fields Source: https://devzone.nayax.com/docs/manage-data-operations/amazon-sqs/set-up-nayax-core/transaction-json-reference Example transaction JSON message and field descriptions for Amazon SQS delivery. Each time a transaction is processed, Nayax Core delivers a JSON message to your SQS queue. The message has two layers: * **Root fields** (`TransactionId`, `MachineId`, `SiteId`, etc.) identify the transaction and machine at a high level. * **`Data` object** contains the full transaction detail, including payment method, card info, timestamps, pricing, and a nested `Products` array listing each item vended. A full description of every field is in the [JSON Message Fields Description](#json-message-fields-description) table below. The following is an example message: ```json theme={null} { "TransactionId": 3804536984, "RemoteStartTransactionId": null, "PaymentMethodId": 2, "SiteId": 6, "MachineTime": "2020-04-20T10:34:05.063", "Void": false, "MachineId": 54265, "Data": { "Card String": "0077020491", "Settlement Time (Date only)": "2020-04-20", "Settlement Time (Time only)": "07:34:15", "SeValue": 1.0000, "Operator Identifier": "500905", "Machine Group": "Snack's", "Raw ENI Loyalty Num": null, "Machine Name": "Oleg's Simulator 1", "Machine AuTime": "2020-04-20T10:34:05.063", "Machine SeTime": "2020-04-20T10:34:15.433", "Currency": "EUR", "Brand": null, "CLI": null, "Extra Charge": 0.0000, "Payment Service (Mobile using Credit Card)": "Prepaid Credit using Prepaid Credit", "Payment Method ID (1)": 2, "Recognition Method ID (3)": 3, "Catalog Number": "", "Device Number": "0000000000500902", "Actor Hierarchy": "Dually / Nayax Test Bunny / Connect 2020 Rocks /", "Payment Method Description": "Prepaid Credit", "Recognition Description": "Prepaid Credit", "Card First 4 Digits": "0077", "Card Last 4 Digits": null, "Card Type": "MIFARE received as Hexadecimal", "Transaction ID": 3804536984, "Site ID": 6, "Authorization Time": "2020-04-20T07:34:05.063", "Authorization Value": 6.0000, "PayServTransid": "200420073405", "sePayServTransId": null, "Settlement Time": "2020-04-20T07:34:15.433", "Cancel Type": null, "Is Revalue Transaction": false, "Preselection Status": 0, "Is Phone Registration": false, "Is Multivend": false, "Settlment Failed": null, "Sale ID": -1, "Sale Value": 0.0000, "Updated DT": "2020-04-20T07:34:15.433", "Constant Preauthorization Value": null, "Is Partial Confirmation": null, "Authorization Code": null, "Authorization Date and Time": null, "Authorization RRN": "200420073405", "Event Code": null, "Guest Name": null, "Token": null, "Zip Code": null, "Billing Provider ID": null, "AVS Only": null, "BOD Transaction Key": null, "Disable Debit Cards": null, "Force Transactions Terminal": null, "Use Phone Transaction": null, "License ID": null, "Merchant ID": null, "Billing Site ID": null, "Terminal ID": null, "User Password": null, "With ZIP": null, "Use Phone Contactless": false, "Use Phone Contact": false, "Debit Card Prefix": null, "Actor Description": "Connect 2020 Rocks", "Institute Description": "NAYAX US", "Location Code": 234234, "Location Description": "Booth 134", "Operator Institute Code": 4, "Area Description": "Connect 2020 Rocks", "OP Button Code": "Z1", "Barcode": null, "Cost Price": null, "Card Price": null, "Prepaid Price": null, "Machine Price": 4.0000, "Cash Price": null, "Default Price": null, "Actor Code": 12, "Display Card Number": "0077020491", "Card Holder Name": "Automatically Created", "User Identity": "1", "Billing Provider Name": null, "Is Offline Transaction": null, "Is EMV Transaction": null, "Machine AuTime (Date only)": "2020-04-20", "Machine AuTime (Time only)": "10:34:05", "Machine SeTime (Date only)": "2020-04-20", "Machine SeTime (Time only)": "10:34:15", "Updated DT (Date only)": "2020-04-20", "Updated DT (Time only)": "07:34:15", "Customer Type": 1, "Actor ID": 32622, "Client Id": "", "Contract Name": null, "Payout Day": null, "Contract Id": null, "Airport Id": null, "Is Refund Card": false, "Contract Number": null, "Airport Code": null, "Payed Value": 1.0000, "Consumer ID": 1906814004668638903, "Discount Card ID": 340897206534728, "Discount Card Number": "1424243531", "Discount Card User Identity": "", "Discount Card Physical Type ID": 30000531, "Discount Card Activation Date": null, "Discount Card Expiration Date": null, "Products": [ { "Product(Product Name(MDB Code,PA Code))": "Bounty(0,A1)", "Product Group": "Snacks", "Product Code in Map": 0, "Product PA Code": "A1", "Product Volume Type": "600 ml", "Product Name": "Bounty", "Product VAT Id": null, "Product Tax Value": null, "Product Tax Code": null, "Product Vat Amount": null, "Product Net Price": null, "Product External Prepaid Price": null, "Product Group Code": null, "Product Group Sub Code": null, "Product Retail Price": null, "Product Discount Percentage": 0.00, "Product Discount Amount": 0.0000, "Product Bruto": 1.0000, "Product Catalog Number": "" } ] } } ``` ## JSON message fields description The following table describes the fields included in the transaction JSON message: | **Field Name** | **Type** | **Description** | | - | - | - | | **Machine Name** | `String` | Machine / POS Name as defined under Operations > Machines > Machine Name | | **Machine Model** | `String` | Model of the machine used. | | **Operator Identifier** | `String` | Machine / POS Number as defined under Operations > Machines > Machine Number | | **Machine AuTime** | `Date Time` | Machine Authorization Date and Time based on Machine Time Zone | | **Machine SeTime** | `Date Time` | Machine Settlement Date and Time based on Machine Time Zone | | **Currency** | `String` | Transaction Currency Based on Machine Configuration | | **Card String** | `String` | First 4 and Last 4 digits of the payment card | | **Brand** | `String` | Credit Card Brand Name | | **CLI** | `String` | Consumer Phone Number, applicable when transaction made through Mobile | | **SeValue** | `Decimal` | Settlement Value, the amount charged | | **Extra Charge** | `Decimal` | Extra Charge Convenience fee | | **Payment Service (Mobile using Credit Card)** | `String` | Payment service used, e.g., mobile payment via credit card. | | **Payment Method ID (1)** | `Integer` | Payment Method ID (Nayax Internal Identifier) | | **Recognition Method ID (3)** | `Integer` | Recognition Method ID (Nayax Internal Identifier) | | **Catalog Number** | `String` | Product Catalog Number as defined under Administration > Products > Product ID | | **Product (Product Name(MDB Code, PA Code=Price))** | `String` | Sold Product Name with MDB Code and PA Code identifiers as defined in Machine Product Map and Price of Sold Item | | **Device Number** | `String` | Nayax Device Serial Number | | **Actor Hierarchy** | `String` | Actor Hierarchy as Breadcrumbs | | **Payment Method Description** | `String` | Payment Method Name | | **Recognition Description** | `String` | Recognition Name | | **Card First 4 Digits** | `String` | Credit Card First 4 digits | | **Card Last 4 Digits** | `String` | Credit Card Last 4 digits | | **Card Type** | `String` | Description of Card Type used in current transaction | | **Machine Group** | `String` | Machine Group Name as defined on Machine | | **Product Group** | `String` | Sold Item Product Group Name | | **Transaction ID** | `Integer` | Transaction ID (Nayax Internal Identifier) | | **Site ID** | `Integer` | Nayax Servers Site ID | | **Authorization Time** | `Date Time` | Transaction Authorization Date and Time (GMT) | | **Authorization Value** | `Decimal` | Transaction Authorization Amount | | **PayServTransid** | `String` | Payment Service Provider Transaction ID | | **sePayServTransId** | `String` | Payment Service Provider Settlement Transaction ID | | **Settlement Time** | `Date Time` | Transaction Settlement Date and Time (GMT) | | **Product Code in Map** | `Integer` | Product Selection Item Number (MDB Code) | | **Cancel Type** | `Integer` | Transaction Cancel Type Value stored on transaction level to indicate cancel reason if transaction was canceled (e.g. Product Selection Timeout); value 255 means successfully settled transaction | | **Is Revalue Transaction** | `Boolean` | Bit indicating if transaction is a Revalue Transaction | | **Preselection Status** | `Integer` | Transaction Preselection Status, Server value to indicate transaction status on server side (internal use for transaction processing options) | | **Is Phone Registration** | `Boolean` | Bit indicating if transaction is part of Phone Registration (Old Deprecated functionality) | | **Is Multivend** | `Boolean` | Bit indicating if transaction is a Multivend (Multi selection sale/vend) | | **Settlment Failed** | `Boolean` | Indicates if the settlement process failed. | | **Sale ID** | `Integer` | Sale/Discount ID, holds value if transaction had a discount applied on it | | **Sale Value** | `Decimal` | Sale/Discount Amount | | **Updated DT** | `Date Time` | Transaction Update Date and Time (GMT) | | **Constant Preauthorization Value** | `Decimal` | Authorization Amount as defined under Operations > Machines > Machine Payment Tab > Constant Preauthorization Field | | **Is Partial Confirmation** | `Boolean` | Bit indicating if a transaction is a partial confirmation (applicable only when Credit Call is the defined billing provider) | | **Authorization Code** | `String` | Code for authorization. | | **Authorization Date and Time** | `Date Time` | Authorization Date and Time (GMT) | | **Authorization RRN** | `String` | Authorization Retrieval Reference Number – Reference number for transaction | | **Event Code** | `Integer` | Code associated with the event. | | **Guest Name** | `String` | Name of the guest, if applicable. | | **Token** | `String` | Token associated with the transaction. | | **Zip Code** | `String` | ZIP code of the location, if applicable. | | **Billing Provider ID** | `Integer` | Identifier for the billing provider. | | **AVS Only** | `Boolean` | Indicates if the transaction was AVS-only. | | **BOD Transaction Key** | `String` | Key for the BOD transaction. | | **Disable Debit Cards** | `Boolean` | Indicates if debit cards are disabled. | | **Force Transactions Terminal** | `String` | Indicates if transactions are forced on the terminal. | | **Use Phone Transaction** | `Boolean` | Indicates if phone-based transactions are used. | | **License ID** | `Integer` | Identifier for the license. | | **Merchant ID** | `String` | Identifier for the merchant. | | **Billing Site ID** | `Integer` | Identifier for the billing site. | | **Terminal ID** | `Integer` | Unique identifier for the terminal. | | **User Name** | `String` | User name associated with the transaction. | | **User Password** | `String` | Password of the user. | | **With ZIP** | `Boolean` | Indicates if ZIP verification was performed. | | **Use Phone Contactless** | `Boolean` | Indicates if contactless phone transactions are used. | | **Use Phone Contact** | `Boolean` | Indicates if phone contact transactions are used. | | **Debit Card Prefix** | `String` | Prefix for debit cards. | | **Actor Description** | `String` | Actor Hierarchy Entity Name of Machine's Direct Actor | | **Institute Description** | `String` | Institute / Customer Name | | **Location Code** | `Integer` | Institute Location Code | | **Location Description** | `String` | Institute Location Name | | **Operator Institute Code** | `Integer` | Operator Institute Code as defined under Administration > Operator > Operator Institutes > Code Column | | **Area Description** | `String` | Description of the area where the transaction occurred. | | **Product PA Code** | `String` | Product PA Code as defined under Operations > Machines > Machine Product Map > PA Code column | | **OP Button Code** | `String` | Product OP Button Code as defined under Operations > Machines > Machine Product Map > OP Button Code column | | **Product Volume Type** | `String` | Product Volume Type as defined under Administration > Products > Product Volume Type field | | **Barcode** | `String` | Product Barcode as defined under Administration > Products > Product Barcode Field | | **Cost Price** | `Decimal` | Product Cost Price as defined under Administration > Products > Product Cost Price Field | | **Card Price** | `Decimal` | Product Credit Card Price as defined under Operations > Machines > Machine Product Map > Credit Card Price Column | | **Prepaid Price** | `Decimal` | Product Prepaid Card Price as defined under Operations > Machines > Machine Product Map > Credit Card Price Column | | **Machine Price** | `Decimal` | Product Machine Price as displayed under Operations > Machines > Machine Product Map > Machine Price Column | | **Cash Price** | `Decimal` | Product Cash Display Price as defined under Operations > Machines > Machine Product Map > Cash Display Price Column | | **Default Price** | `Decimal` | Product Default Retail Price as Defined under Operations > Machines > Machine Product Map > Default Retail Price Column | | **Product Name** | `String` | Product Name as defined under Administration > Products > Product Name field | | **Actor Code** | `Integer` | Operator Internal Code Fields as defined under Administration > Operator > Operator Internal Code | | **Display Card Number** | `String` | Nayax Prepaid Card Display Card Number | | **Card Holder Name** | `String` | Nayax Prepaid Card Holder Name | | **User Identity** | `String` | Nayax Prepaid Card Holder User Identity | | **Billing Provider Name** | `String` | Billing Provider Name as defined on Machine's Actor Hierarchy | | **Is Offline Transaction** | `Boolean` | Bit indicating if this is an EMV Offline Transaction | | **Is EMV Transaction** | `Boolean` | Bit indicating if this is an EMV Transaction | | **Machine AuTime (Date only)** | `Date` | Machine Authorization Date based on Machine Time Zone | | **Machine AuTime (Time only)** | `Time` | Machine Authorization Time based on Machine Time Zone | | **Machine SeTime (Date only)** | `Date` | Machine Settlement Date based on Machine Time Zone | | **Machine SeTime (Time only)** | `Time` | Machine Settlement Time based on Machine Time Zone | | **Settlement Time (Date only)** | `Date` | Machine Settlement Date (GMT) | | **Settlement Time (Time only)** | `Time` | Machine Settlement Time (GMT) | | **Updated DT (Date only)** | `Date` | Transaction Update Date (GMT) | | **Updated DT (Time only)** | `Time` | Transaction Update Time (GMT) | | **Raw ENI Loyalty Num** | `String` | Raw ENI loyalty number. | | **Parsed ENI Loyalty Num** | `String` | Parsed ENI loyalty number. | | **Products** | `Object` | By checking this box, no column with Product prefix will be presented on the report. | | **Product VAT Id** | `Integer` | VAT identifier for the product. | | **Product Tax Value** | `Decimal` | Product Tax Value as defined under Administration > Products > Product Group VAT Info > Tax Value Field | | **Product Tax Code** | `Integer` | Product Tax Code as defined under Administration > Products > Product Group VAT Info > Tax Code Field | | **Product Vat Amount** | `Decimal` | Product VAT Amount calculated based on the Tax Value as defined on Product Group | | **Product Net Price** | `Decimal` | Product NET Price calculated by reducing Extra Charge and Product VAT Amounts from Settlement Value | | **Product External Prepaid Price** | `Decimal` | Product External Prepaid Price as defined under Operations > Machines > Machine Product Map > External Prepaid Price Column | | **Customer Type** | `Integer` | Type of customer involved in the transaction. | | **Product Group Code** | `Integer` | Product Group Code as defined under Administration > Products > Product Group Info > Code Field | | **Actor ID** | `Integer` | Actor Hierarchy Entity ID of Machine's Direct Actor | | **Product Group Sub Code** | `Integer` | Product Group Sub Code as defined under Administration > Products > Product Group Info > Sub Code Field | | **Product Retail Price** | `Decimal` | Product Retail Price as defined under Operations > Machines > Machine Product Map > Retail Price Column | | **Product Discount Percentage** | `Decimal` | Percentage of discount applied to the product. | | **Product Discount Amount** | `Decimal` | Discount amount applied to the product. | | **Product Bruto** | `Decimal` | Gross value of the product. | | **Product Catalog Number** | `String` | Product Catalog Number as defined under Administration > Products > Product ID Field | | **Client Id** | `String` | Unique ID for the client. | | **Contract Name** | `String` | Name of the contract associated with the transaction. | | **Payout Day** | `Integer` | Day when the payout is scheduled. | | **Contract Id** | `String` | ID of the contract associated with the transaction. | | **Airport Id** | `Integer` | Unique ID of the airport, if applicable. | | **Member Type** | `String` | Type of membership associated with the transaction. | | **Is Refund Card** | `Boolean` | Bit indicating if this is a Nayax Refund Card | | **Contract Number** | `String` | Number of the contract associated with the transaction. | | **Airport Code** | `String` | Actor Airport Code as defined under Administration > Operator > Operator Airport Code Field | | **Payed Value** | `Decimal` | Transaction Charge Amount | | **Consumer ID** | `Integer` | Unique Consumer Identifier | | **Discount Card ID** | `Integer` | Discount Count Card ID (Nayax Internal Unique Identifier) | | **Discount Card Number** | `String` | Discount Card Number – Card Unique Identifier | | **Discount Card User Identity** | `String` | Discount Card User Identity as defined under Consumers > Cards Management > Discount Card User Identity Field | | **Discount Card Physical Type ID** | `String` | Discount Card Physical Type Lut Value ID, example: 30000531 - Contactless Sticker | | **Discount Card Activation Date** | `Date Time` | Discount Card Activation Date as defined under Consumers > Cards Management > Discount Card Activation Date Field | | **Discount Card Expiration Date** | `Date Time` | Discount Card Expiration Date as defined under Consumers > Cards Management > Discount Card Expiration Date Field | | **Is Money** | `Boolean` | Indicates if the transaction is a money transaction. | | **Prepaid Card Current Regular Credit** | `Decimal` | Current regular credit balance on the prepaid card. | | **Prepaid Credit Amount Charge** | `Decimal` | Amount charged to the prepaid credit. | | **Prepaid Credit Transaction Charge** | `Decimal` | Transaction charge applied to the prepaid credit. | | **Prepaid Card Current Revalue Credit** | `Decimal` | Current revalue credit balance on the prepaid card. | | **Prepaid Revalue Credit Amount Charge** | `Decimal` | Amount charged for prepaid revalue credit. | | **Is Revalue Reward Transaction** | `Boolean` | Indicates if the transaction is a revalue reward transaction. | | **Prepaid Card Monthly Amount Credit Usage** | `Decimal` | Monthly credit usage amount on the prepaid card. | | **Prepaid Card Monthly Transactions Credit Usage** | `Integer` | Monthly number of credit transactions on the prepaid card. | | **Loyalty Card Number** | `String` | Loyalty card number associated with the transaction. | | **Product Unit Of Measure** | `String` | Unit of measure for the product. | | **Product Quantity** | `Integer` | Quantity of the product in the transaction. | | **Campaign ID** | `Integer` | Campaign ID used in current transaction (Nayax Internal Identifier). | | **Campaign Type** | `String` | Description of Campaign Type used in current transaction (1-Punch card, 2-Discount). | | **Product ID** | `Integer` | Product ID (Nayax Internal Identifier). | | **Card ID** | `Integer` | Card ID used in current transaction (Nayax Internal Identifier). | | **Machine Serial Number** | `String` | Machine Serial Number as provided by the Machine Operator | | **Machine ID** | `Integer` | Machine ID, automatically generated Nayax internal ID for machine | | **Transaction Status ID** | `Integer` | Transaction Status ID, indicating transaction status with a numeric value | | **Transaction Status Name** | `String` | Transaction Status Name, indicating transaction status name | | **Device Transaction ID (DTID)** | `Integer` | Device transaction ID generated by the device | | **Vendor Transaction UID (VUID)** | `String` | Transaction ID generated by the Payment Provider | | **Card BIN** | `Integer` | Credit Card BIN (Bank Identification Number) 6-8 digit number used to identify Card Issuer and Bank | | **Batch Ref Number** | `String` | Batch Reference Number | | **operator transaction id** | `String` | The operator transaction ID as received in the device authorization command using a Marshal request | | **Retail Store Id** | `String` | Data coming from Operator and shown in Nayax reports | | **Retail Pos Id** | `String` | Data coming from Operator and shown in Nayax reports | | **Operator Data 1** | `String` | Data coming from Operator and shown in Nayax reports | | **Credit Card Type** | `String` | Credit Card Type indicating if this is a Debit or Credit Card | | **original authorization time** | `Date Time` | Original authorization time | | **Is Offline Payment** | `Boolean` | Bit indicating if a deferred transaction | | **Energy Consumed (kWh)** | `Decimal` | Energy Consumed (kWh) | | **Product Provider** | `String` | Product Provider as defined under Administration > Products > Provider field | | **Original Transaction ID** | `Integer` | Original Transaction ID (Nayax Internal Identifier) | | **Processing Fee Sum** | `Decimal` | Processing Fee Sum | | **Net Price Excluding GST and Processing Fee Sum** | `Decimal` | Net Price Excluding GST (VAT) and Processing Fee Sum | | **Revalue Type** | `String` | Revalue type - can be Cash revalue or Credit card revalue | # App Tokens (JWT) Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/app-tokens App tokens let you grant limited, time-boxed API access to your own downstream customers or integrations. Each token carries an expiration date you set and permissions a Nayax admin assigns, scoped to exactly what the integration needs. ## Token types Nayax Core offers two choices under **Add Token**. Pick **App Token** for this flow. The app token is a JWT. **Lynx Token** is an API key, covered on [Security & Token](/docs/manage-data-operations/lynx-api/security#access-token). The app token you create is a refresh token. You exchange it for a short-lived access token, and that access token authenticates your Lynx API requests. | Token type | Lifetime | Used for | | - | - | - | | App token (refresh token) | Up to 100 years | Requesting access tokens | | Access token | 24 hours | Making Lynx API requests | ## Scopes A scope is a permission string that defines what a token can access. Scopes follow the format `{domain}:{action}` or `{domain}:{resource}:{action}`, where the domain identifies the area the scope applies to, the optional resource narrows it to a specific resource within that domain, and the action identifies the allowed operation. Common scope examples: * `machines:read` grants read access to machine data. * `orders:*:read` grants read access to all order-related resources. * `users:app-token:create` grants permission to create app tokens. <Warning> Avoid assigning the bare `*` scope. It grants full access to every resource and action, which defeats the purpose of scoping a token to a specific integration. </Warning> ## Claim types An app token carries its permissions in one of three claim types, each with its own priority and validation behavior. | Claim | Purpose | Priority | Validation | | - | - | - | - | | `appScope` | Authenticates external services and integrations | Checked before `scope` | Must match exactly if present | | `internalScope` | Authenticates internal Nayax microservices | Checked before `scope` | Must match exactly if present | | `scope` | Standard OAuth2 (a token-based authorization scheme) user-level scope | Checked last, as a fallback | Checked after other authorization checks pass | For most customer integrations, `appScope` is the claim type a Nayax admin assigns to describe the machines, devices, or orders the integration needs to access. ## Prerequisites You need a Nayax Core account to create the app token. A Nayax admin must assign its scopes and claim type before you can use it, so requesting a token involves waiting on that approval rather than a fully self-service flow. ## Create an app token You create the app token yourself in Nayax Core, but you don't choose its scopes or claim type. A Nayax admin assigns those separately. <Steps> <Step title="Create the app token in Nayax Core"> From [Security & Token](/docs/manage-data-operations/lynx-api/security#access-token), navigate to the **User Tokens** section, then click **Add Token**. <Frame> <img /> </Frame> In the **Add App Token** dialog, select **App Token**, enter an optional **Token Name** such as `Analytics Platform - Read Only`, set an **Expiration Date**, then click **Generate**. <Frame> <img /> </Frame> </Step> <Step title="Wait for a Nayax admin to assign scopes"> The admin picks the `appScope`, `internalScope`, or `scope` claims described above, based on what the integration needs. You can't set these yourself. </Step> </Steps> Once the admin assigns the scopes, you have a scoped app token with the requested claims and expiration, ready to exchange for an access token. ## Exchange the app token Exchange it for an access token before making requests, using the Lynx API's endpoint below. ```bash theme={null} curl -X POST "https://lynx-api.nayax.com/v1/issue-access-token" \ -H "Authorization: jwt <YOUR_REFRESH_TOKEN>" ``` <Warning> The Lynx API endpoint expects `Authorization: jwt <YOUR_REFRESH_TOKEN>`, not `Bearer`. Sending a refresh token with the `Bearer` scheme to this endpoint fails. </Warning> The endpoint returns the access token in the following shape: ```json theme={null} { "Token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` `Token` is the access token itself, a JWT. Use it as a `Bearer` credential on subsequent Lynx API requests. For example, retrieving a list of machines: ```bash theme={null} curl -X GET "https://qa-lynx.nayax.com/operational/v1/machines" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` ## Security best practices Follow these practices when requesting and managing app tokens. ### Storage Store app tokens in a secure key management system, or as environment variables if you manage your own servers. Encrypt tokens at rest. Never store a token in a plain text file, commit it to version control, or include it in a URL. ### Scope and expiration Grant only the scopes an integration needs, and request the shortest expiration that covers its use case, rather than creating tokens casually. Nayax limits each user to 50 tokens, so plan token reuse across integrations that need the same access. ## Troubleshooting If a request using an app token, or the access token it produces, fails, check the following common causes. ### 401 Unauthorized The token is invalid or has expired. Verify the token hasn't passed its expiration date and that you're sending it with the correct authorization scheme for the endpoint you're calling. ### 403 Forbidden The API returns `{"message": "Insufficient permissions to perform this action."}`. The token's scopes don't include the resource or action you're requesting. Compare the required scope for the endpoint against the `appScope`, `internalScope`, or `scope` claims on your token, and request a token with the missing scope if needed. ### 429 Too Many Requests You've exceeded the rate limit. Cache and reuse access tokens for their full 24-hour lifetime instead of requesting a new one on every call. ## Next steps <CardGroup> <Card title="Retrieve machine information" icon="magnifying-glass" href="/docs/manage-data-operations/lynx-api/machines/retrieve-machine-information"> Make your first authenticated call with the access token. </Card> <Card title="Lynx API reference" icon="book" href="/reference/manage-data-operations/lynx-api/overview"> Browse the full set of available endpoints. </Card> </CardGroup> # Add Credit to Card Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/cards/add-credit-to-card This guide will walk you through adding credit to a card using the Lynx API. At the end, you’ll learn how to verify these changes in Nayax Core. The following endpoint is used in this guide: <EndpointCard title="Add Credit to a Card" href="/reference/lynx/cards/add-credit-to-a-card" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Methods to add credit to card Adding credit to a card increases its available balance, allowing the cardholder to perform transactions. Lynx API offers a couple of ways to do so: * **PUT Method**: With this option, you can use the same endpoints for creating or retrieving a card's data, but using a **PUT** request with the new amount of credit. For example, you can use the [Update Card by ID](/reference/lynx/cards/update-card-by-id) endpoint with the `CardID` in the URL and the updated credit amount in the body parameters. * **POST Method**: Lynx API also offers a specific endpoint to perform a **POST** request with the credit to be added to a card. This is a much simpler option, since you will not have to deal with the bigger body objects the **PUT** Method has. In this guide, we will explore the **POST** method to add credit to a card. But you can check the Updating Card Details page for more details on **PUT** requests. ## Adding credit To add credit to a card you can use the **POST** method on the [Add Credit to a Card](/reference/lynx/cards/add-credit-to-a-card) endpoint. Sending the card's Unique Identifier in the URL. See the example query below: <CodeGroup> ```sh Request theme={null} curl --request POST \ --url 'https://qa-lynx.nayax.com/operational/v1/cards/{CardUniqueIdentifier}/credit/add?CardCredit=50&CreditChangeRemarks=Adding%20credit' \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "value": 50 } ``` </CodeGroup> <Note> Replace `{CardUniqueIdentifier}` with the actual identifier of the card. </Note> The amount to add is sent on the query parameters, see the available parameters on the list below: * `CardCredit`: The credit amount to be added. * `CreditChangeRemarks`: A note about the transaction for tracking purposes. ## Verifying credit on Nayax Core Once the request to add the card credit is successful, you can go to Nayax Core and check the card´s credit and history in the **Card Management** tab. Follow the steps below to do so. 1. Access your Nayax Core Dashboard 2. On the top menu, navigate to Consumers > Card Management <Frame> <img /> </Frame> 3. Search for the card to which the credit was added and select it. <Frame> <img /> </Frame> 4. Open the **Change Credit** tab and check the **Credit History** section. <Frame> <img /> </Frame> There you will be able to see Credit History of the card and find the credit added through the Lynx API, and match the amount or remark to the ones sent in the request. <br /> # Create Cards Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/cards/create-cards Cards serve as versatile solutions for various business needs, such as facilitating payments, issuing refunds, providing discounts, or granting access to services. This page will guide you through creating a card with Lynx API and how to verify it in Nayax Core. ## Card types Nayax offers several types of cards, each designed for a distinct purpose: * **Prepaid Card**: Preloaded with funds, prepaid cards are ideal for controlled spending. They are commonly used for gift cards, employee stipends, or consumer transactions and offer convenience and security. * **Technician Card**: Issued to service technicians or employees, these cards facilitate access to specific systems or authorize work-related transactions, ensuring secure operations in the field. * **Refund Card**: Designed to process refunds, these cards efficiently return funds to customers, simplifying financial workflows and enhancing customer satisfaction. * **Discount Card**: Used in loyalty programs or promotional campaigns, discount cards offer exclusive benefits like reduced prices or special offers, encouraging customer retention and engagement. In this guide, we will be showing an API request creating a prepaid card, but all of them can be created in the same way. ## Card creation To create a new virtual credit card with Lynx API you can use the **POST** method on two different endpoints: <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> The sections below will guide you through creating a card using any of these options through Lynx API. ### V1 endpoint The V1 option requires only the essential fields for basic card creation, with minimal optional fields. To create the card, send a **POST** request to the [Create Virtual Card](/reference/lynx/cards/create-virtual-card) endpoint, filling in the card details in the body parameters. See the example in the code block below: ```sh theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/cards \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "ActorID": 2001492652, "CardDisplayNumber": "1234-5678-9012", "CardUniqueIdentifier": "UNIQUE-CARD-12345", "CardHolderName": "John Doe", "CardStatus": 1, "CardType": 33, "CardUserIdentity": "USER12345", "CountryID": 840, "Currency": 1, "MobileNumber": "0505555555", "MemberType": 801, "CardActivationDate": "2024-11-14T09:00:00Z", "CardPhysicalType": 30000529, "CardImageUrl": "https://example.com/image.png", "CardExpirationDate": "2025-11-14T09:00:00Z", "CardNote": "Prepaid card for internal use", "wd_limits_money": 5000.00, "use_wd_limit": true, "wd_limits_trans": 100 }' ``` These are the mandatory fields when using the V1 option: * `ActorID`: Operator ID tracks the card issuer. * `CardUniqueIdentifier`: A unique identifier for the card. * `CardStatus`: Card's status (1 = Active, 2 = Inactive). * `CardType`: Type of card. * Prepaid Card: `33` * Technician Card: `31` * Refund Card: `34` * Discount Card: `30000616` * `CountryID`: Country code based on ISO standards (viewable in the "Lookups" section). * `Currency`: Currency ID code. * `CardPhysicalType`: The physical type of the card, options are: * `0000528`: Swipe Card * `30000529`: Contact Card * `30000530`: Contactless Card * `30000531`: Contactless Sticker * `30000532`: Monyx App Virtual ID * `30000533`: Custom 3rd Party ID * `30000534`: Dual Card Contact + Contactless * `30000535`: Dual Card Swipe + Contactless * `30000601`: Monyx Virtual Card * `943237560`: QR Code A successful request will return a JSON object containing the details of the newly created card. ### V2 endpoint The V2 option provides extended functionality, including additional fields for detailed customization. This version lets you specify card type, physical type, membership level, activation and expiration dates, and group limits. To create the card, send a **POST** request to the [ Create New Card](/reference/lynx/cards/create-new-card) endpoint, filling in the card details in the body parameters. See the example in the code block below: ```sh theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v2/cards \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "CardDetails": { "ActorID": 2001492652, "CardUniqueIdentifier": "UNIQUE-CARD-67890", "CardDisplayNumber": "9876-5432-1234", "CardTypeID": 31, "PhysicalTypeID": 30000528, "Notes": "Technician card with custom limits", "Status": 1, "ExternalApplicationUserID": "EXT-USER-56789" }, "CardHolderDetails": { "CardHolderName": "Alice Doe", "UserIdentity": "USER-56789", "CountryID": 840, "MobileNumber": "1234567890", "Email": "alice.doe@example.com", "MemberTypeID": 801 }, "CardCreditAttributes": { "CurrencyID": 1, "Credit": 100, "RevalueCredit": 50, "CreditTypeMoneyBit": true, "CreditAccumulateBit": true, "CreditSingleUseBit": false, "RevalueCashBit": true, "RevalueCreditCardBit": true, "AmountMonthlyReload": 200, "TransactionsMonthlyReload": 20, "DiscountTypeBit": 1, "DiscountValue": 10 }, "CardCreditLimits": { "AmountDailyLimit": 500, "AmountWeeklyLimit": 2000, "TransactionsDailyLimit": 10, "TransactionsWeeklyLimit": 50, "AmountMonthlyLimit": 10000, "TransactionsMonthlyLimit": 200, "DiscountTransactionsTotalLimit": 100, "MaxRevalueAmountLimit": 1000, "WeekDayLimitEnabledBit": true, "WeekDayAmountLimit": "100,200,300,400,500,600,700", "WeekDayTransactionLimit": "10,20,30,40,50,60,70" }, "CardDateRules": { "ActivationDate": "2024-11-14T09:00:00Z", "ExpirationDate": "2025-11-14T09:00:00Z", "RevalueExpirationDate": "2025-10-10T09:00:00Z", "SetSingleUseDate": "2024-12-01T09:00:00Z", "RemoveSingleUseDate": "2024-12-15T09:00:00Z" }, "CardRevalueRewardRules": [ { "RuleID": 1, "RewardActorID": 123456, "Status": true, "RevalueAmount": 100, "RewardValueTypeBit": true, "RewardValue": 5 } ], "GroupLocationLimits": [ { "CardGroupEnabledBit": true, "GroupName": "Group A", "CardGroupId": 123, "GroupDailyLimit": 1000 } ] }' ``` These are the mandatory fields when using the V2 option: * `CardDetails` * `ActorID`: Operator ID. * `CardUniqueIdentifier`: Unique card identifier. * `CardTypeID`: Type of card. * `PhysicalTypeID`: Physical card type. * `Status`: 1 for Active. * `CardHolderDetails` * `CardHolderName`: Name of the cardholder. * `CountryID`: ISO country code. * `MemberTypeID`: Membership type. * `CardCreditAttributes` * `CurrencyID`: Currency code. A successful request will return a JSON object with the details of the created card, providing flexibility and control over card features. ## Verifying the card in Nayax Core Once you send the request to create the card using any endpoints mentioned above, you can go to Nayax Core and check if the card is present in the **Card Management** screen. Follow the steps below to do so. 1. Access your Nayax Core Dashboard 2. On the top menu, navigate to **Consumers > Card Management** <Frame> <img alt="" /> </Frame> 3. Now, you can search for the created card and select it from the list. <Frame> <img alt="" /> </Frame> The card created through the Lynx API is available in the Nayax Core, confirming it was successfully created. <Note> The `ExternalApplicationUserID` field won't appear in Nayax Core, but it would appear when using the **GET** method of the [cards](/reference/lynx/cards/get-cards) endpoint. </Note> # Retrieve Card Data Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/cards/retrieve-card-data The Lynx API provides several GET methods to retrieve detailed information about cards. These let you query card details, check credit balances, access revalue history, and more. <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to use it to authenticate your API requests properly. </Warning> ## Verifying card details in Nayax Core To see the details of a card in Nayax Core, Access the **Card Management** tab and use the search bar to look for the card you want to check, and select it. <Frame> <img /> </Frame> You will see all the details of the card presented to you, this is the same data retrieved by the Lynx API Endpoints mentioned before. ## Get cards <EndpointCard title="Get Cards" href="/reference/lynx/cards/get-cards" method="get" /> This general endpoint will retrieve an overview of all cards, including essential details like Card ID, Card Holder Name, and Card Status. See the example query: ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/cards \ --header 'accept: application/json' \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' ``` This endpoint can also retrieve details of a specific card instead of all cards by adding query parameters to the request. For example, to get the details of a card with the Card Unique Identifier `1409315030` you can use the query in the code block below. ```sh Request theme={null} curl --request GET \ --url 'https://qa-lynx.nayax.com/operational/v1/cards?CardUniqueIdentifier=1409315030%20' \ --header 'accept: application/json' \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' ``` Any of the following details of a card can be used as a query parameter: * `CardID` * `CardUniqueIdentifier` * `CardDisplayNumber` * `CardMobileNumber` * `ExternalApplicationUserID` * `CardEmail` * `CardHolderName` ## Get card by the card's display number <EndpointCard title="Get Card by the Card's Display Number" href="/reference/lynx/cards/get-card-by-the-cards-display-number" method="get" /> It fetches card details based on its display number, which is the physical card number. This is ideal for cases where only the display number is available for reference. See the code block below for an example query: ```sh theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/cards/displayNumber/{CardDisplayNumber} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` <Note> Replace `{CardDisplayNumber}` with the actual number of the card. </Note> ## Get prepaid card <EndpointCard title="Get Prepaid Card" href="/reference/lynx/cards/get-prepaid-card" method="get" /> It retrieves details of a prepaid card associated with a specific card ID. Use this to manage prepaid cards or verify their status and attributes. See the code block below for an example query: ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/cards/CardID/prepaid \ --header 'accept: application/json' \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' ``` <Note> Replace `{CardID}` with the actual `CardID` of the card. </Note> The response will have the details of the requested card. ## Get the credit from a card <EndpointCard title="Get the Credit from a Card" href="/reference/lynx/cards/get-the-credit-from-a-card" method="get" /> This option fetches the current credit balance for a specific card, identified by its unique identifier. Use it to monitor card balances, such as those of prepaid or technician cards. See the code block below for an example query: <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/cards/{CardUniqueIdentifier}/credit \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "value": 5320 } ``` </CodeGroup> <Note> Replace `{CardUniqueIdentifier}` with the actual identifier of the card. </Note> The response will include the credit balance of the card. ## Get card's revalue <EndpointCard title="Get Card's Revalue" href="/reference/lynx/cards/get-cards-revalue" method="get" /> Retrieves the revalue amount associated with a specific card, identified by the card's unique identifier. See the query example below: ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/cards/{CardUniqueIdentifier}/revalue \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` <Note> Replace `{CardUniqueIdentifier}` with the actual identifier of the card. </Note> The response will include the revalue amount of the card. # Disable a Device Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/devices/disabling-a-device Sometimes, you may want to disable a device associated with a Machine to stop it from processing payments and orders. This can quickly be done programmatically with Lynx API using the endpoint below. <EndpointCard title="Update Device" href="/reference/lynx/devices/update-device" method="put" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Disabling the device Use the [Update Device](/reference/lynx/devices/update-device) endpoint to update the device's status. You need to provide the `DeviceID`, `ActorID` (operator ID), and the new status flag. See an example request in the code block below: ```sh theme={null} curl -X PUT "https://qa-lynx.nayax.com/operational/v1/devices/<DEVICE_ID>" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "ActorID": "<ACTOR_ID>", "StatusID": 2 }' ``` <Note> **Path Params** Replace `<DEVICE_ID>` with the actual identifier of the device you want to disable. </Note> In the Body Parameters, you need to provide the following: | **Body Parameter** | **Type** | **Description** | | :- | :- | :- | | `ActorID` | `int64` | The identifier of the operator associated with the device. | | `StatusID` | `int32` | The status identifier of the device: **1** = Active, **2** = Inactive. | So, to disable the device, change the `StatusID` to 2. The response will show details about the device, confirming that the device's status has been disabled. ## Validate the updates You can also use the [Get Device by DeviceID](/reference/lynx/devices/get-device-by-deviceid) endpoint to retrieve the device's information and validate the update's success. Another way to validate this is within Nayax Core, where you can check the details of each device and validate their current status. Follow the steps below to do so: 1. In your Dashboard, go to **Administration > Devices**. 2. Use the search function to filter through the list of devices. 3. Select the desired device from the list. 4. Open the **General Information** tab and see the **Status** field. <Frame> <img /> </Frame> <br /> # Retrieve Device Information Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/devices/getting-all-devices-under-an-operator In Nayax Core, devices have various attributes, such as the device's operator, model or ID, and status. These can all be seen in the **Devices** menu, which you can access in the following way: 1. In your Dashboard, go to **Administration > Devices**. 2. Use the search function to filter through the list of devices. 3. Select the desired device from the list. 4. Open the **General Information** tab. <Frame> <img alt="" /> </Frame> Here, you can see the General information about the selected device. ## Lynx API methods Lynx API allows you to retrieve all this information from one device or a group of devices programmatically using the following endpoints: <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ### Retrieve a device by `deviceID` Using the [Get Device by DeviceID](/reference/lynx/devices/get-device-by-deviceid) endpoint, providing it with the `deviceID` as a path parameter, you can retrieve that device's details. See an example request and response in the code block below: <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/devices/{DeviceID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "VposChipId": "string", "IsDeviceExists": true, "FWVersionNumber": "string", "VposVersionNumber": "string", "DeviceID": 0, "ActorID": 0, "DeviceTypeLutID": 0, "DeviceSerial": "string", "IMEI": "string", "DeviceDescription": "string", "SimCardID": 0, "FWVersionID": 0, "RequestedFwID": 0, "PollInterval": 0, "StatusID": 0, "LastUpdated": "2024-12-09T14:40:50.980Z", "IsCollectMultipleParameters": true, "IsLogged": true, "FRequestedNewVersionDate": "2024-12-09T14:40:50.980Z", "FTookNewVersionDate": "2024-12-09T14:40:50.980Z", "HardwareVersion": "string", "IsRental": true, "RentalEndMonth": 0, "RentalEndYear": 0, "IsToBeReturned": true, "FeeCommunicationThreshold": 0, "BillingPlanID": 0, "BillingPlanActivationDate": "2024-12-09T14:40:50.980Z", "DeviceCreationDate": "2024-12-09T14:40:50.980Z", "CreatedBy": 0, "UpdatedBy": 0, "DistributorBillingPlanID": 0, "ChipID": "string", "OrderID": 0, "ExternalFlashSize": 0, "BoardSerial": "string", "FlashSize": 0, "DeviceFamily": "string", "ModemModel": "string", "TrialEndDate": "2024-12-09T14:40:50.980Z", "VerticalTypeID": 0, "VerticalProductTypeID": 0, "VerticalTypeLutID": 0, "VerticalProductTypeLutID": 0, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> <Note> **Path Params** Replace `<DeviceID>` with the actual identifier of the device. </Note> ### Retrieve all devices Using the Get All Devices endpoint, you can retrieve a list of available devices. The code block below shows an example request and response. <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/devices \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} [ { "VposChipId": "string", "IsDeviceExists": true, "FWVersionNumber": "string", "VposVersionNumber": "string", "DeviceID": 0, "ActorID": 0, "DeviceTypeLutID": 0, "DeviceSerial": "string", "IMEI": "string", "DeviceDescription": "string", "SimCardID": 0, "FWVersionID": 0, "RequestedFwID": 0, "PollInterval": 0, "StatusID": 0, "LastUpdated": "2024-12-09T14:40:50.980Z", "IsCollectMultipleParameters": true, "IsLogged": true, "FRequestedNewVersionDate": "2024-12-09T14:40:50.980Z", "FTookNewVersionDate": "2024-12-09T14:40:50.980Z", "HardwareVersion": "string", "IsRental": true, "RentalEndMonth": 0, "RentalEndYear": 0, "IsToBeReturned": true, "FeeCommunicationThreshold": 0, "BillingPlanID": 0, "BillingPlanActivationDate": "2024-12-09T14:40:50.980Z", "DeviceCreationDate": "2024-12-09T14:40:50.980Z", "CreatedBy": 0, "UpdatedBy": 0, "DistributorBillingPlanID": 0, "ChipID": "string", "OrderID": 0, "ExternalFlashSize": 0, "BoardSerial": "string", "FlashSize": 0, "DeviceFamily": "string", "ModemModel": "string", "TrialEndDate": "2024-12-09T14:40:50.980Z", "VerticalTypeID": 0, "VerticalProductTypeID": 0, "VerticalTypeLutID": 0, "VerticalProductTypeLutID": 0, "Refs": { "additionalProp": "string" } } ] ``` </CodeGroup> This endpoint allows you to use filters in the query parameters. See the table below for all the available query params- note that you should include at least the ActorId in the query (can add other filters as well should you be interested): | **Query Parameter** | **Type** | **Description** | | - | - | - | | `ActorId` | `int64` | The unique identifier of the actor associated with the devices. | | `isConnected` | `boolean` | Filter devices based on their connection status. | | `pageNumber` | `int32` | Defaults to 1. The page number for paginated results. | | `pageSize` | `int32` | Defaults to 1000. The number of results per page. | | `nayaxDeviceSerial` | `string` | The serial number of the Nayax device. | | `orderId` | `int32` | Filter devices based on the associated order ID. | | `statusId` | `int32` | Filter devices based on their status ID. | | `createdDt` | `date-time` | Filter devices based on their creation date. | | `updatedDt` | `date-time` | Filter devices based on the last updated date. | | `boardSerial` | `string` | The serial number of the device's mainboard. | | `imei` | `string` | The International Mobile Equipment Identity number of the device. | | `chipId` | `string` | The unique identifier for the chip in the device. | # Move Devices Between Operators Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/devices/moving-device-between-operators Lynx API allows you to reassign devices from one operator to another within the hierarchy in your Nayax system. This is particularly useful for businesses managing multiple operators, regions, or organizational units, ensuring seamless control and tracking of devices as they change hands. This page presents how to move a device from one operator to another using the Lynx API. In the step-by-step guide below, you'll use the following endpoint: <EndpointCard title="Move Devices" href="/reference/lynx/devices/move-devices-to-actor-id" method="put" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Moving devices Use the [Move Devices](/reference/lynx/devices/move-devices-to-actor-id) endpoint to assign or move devices to the specified `actorId`. The request body should include an array of device identifiers, such as serial numbers. See the example request in the code block below: ```sh Request theme={null} curl -X PUT "https://qa-lynx.nayax.com/operational/v1/devices/move/<ACTOR_ID>" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '[ "SN12345X", "SN67890Y" ]' ``` <Note> **Path Params** Replace `<ACTOR_ID>` with the target actor's unique identifier for the new operator. </Note> As you can see, the body of the request above contains two serial numbers for devices that will be moved to the targeted Operator. The response will return the status of each device moved. See the code block below: ```json Response theme={null} [ { "HW_serial": "SN12345X", "actor_id": 3001492652, "is_connected": true }, { "HW_serial": "SN67890Y", "actor_id": 3001492652, "is_connected": false } ] ``` Where: | Parameter | Description | | :- | :- | | `HW_serial` | The hardware serial number of the device. | | `actor_id` | Confirms the new `actorId` to which the device was moved | | `is_connected` | Indicates whether or not the device was connected to a virtual machine before moving it. | <br /> # Product Groups Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/create-product-group Product groups categorize your operator's products into logical clusters such as "Beverages" or "Snacks," making inventory tracking and restocking easier to manage. In Nayax Core, you can create a product group in the following way: 1. Go to **Administration > Products**. 2. Click **Create > Add Product Group**. 3. Fill in the required product group details in the form: * **Operator**: Select which operator is associated with the group. * **Description**: The name of the product group. 4. Click **Save** to finish. <Frame> <img /> </Frame> ## Create a product group via API Use the [Create New Product Groups](/reference/lynx/product-groups/create-new-product-groups) endpoint to create a product group programmatically. <EndpointCard title="Create New Product Groups" href="/reference/lynx/product-groups/create-new-product-groups" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> <br /> Send a POST request with the following body parameters: ```sh theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/productGroups \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "ActorID": 12345, "ProductGroupName": "Beverages", "ProductGroupCode": 1001, "ProductGroupSubCode": 10, "ProductGroupCategoryCode": "DRINKS" }' ``` | **Parameter** | `Type` | Description | | - | - | - | | **ActorID** | `int64` | The unique identifier of the actor associated with the product group. | | **ProductGroupName** | `string/null` | The name of the product group to be created (for example, "Beverages"). | | **ProductGroupCode** | `int64/null` | The code associated with the product group. | | **ProductGroupSubCode** | `int64/null` | A sub-code for further categorizing the product group. | | **ProductGroupCategoryCode** | `string/null` | The category code associated with the product group (for example, "DRINKS"). | After creating your product groups, you're ready to [create products](/docs/manage-data-operations/lynx-api/inventory-management/create-products). # Operator Products Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/create-products Operator products are the individual items in your catalog, such as "Energy Drink" or "Potato Chips," each with its own pricing, barcode, and group assignment. In Nayax Core, you can create a product in the following way: 1. Go to **Administration > Products**. 2. Click **Create > Add Product**. 3. Fill in the required fields in the form: * **Operator**: Choose which operator the product belongs to. * **Group**: Choose the product group from that operator to which this product belongs. * **Product Name**: The name of the product. * **Status**: Whether the product is active or not. 4. Click **Save** to finish. <Frame> <img alt="" /> </Frame> ## Create a product via API Use the [Create New Operator Product](/reference/lynx/products/create-new-operator-product) endpoint to create a product programmatically. <EndpointCard title="Create New Operator Product" href="/reference/lynx/products/create-new-operator-product" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> <br /> Send a POST request with the `OperatorID` as a path parameter and the product details in the request body: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/operators/{OperatorID}/products \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "NayaxProductID": 12345, "ProductGroupID": 1001, "ActorID": 67890, "ProductManufacturerID": 55, "ProductName": "Energy Drink", "ProductCatalogNumber": "ED123", "ProductBarcode": "0123456789123", "ProductPackageQuantity": 24, "ProductDescription": "A refreshing energy drink.", "ProductVolumeTypeID": 3, "DEXProductName": "Energy_Drink", "ProductCostPrice": 1.20, "ProductDefaultRetailPrice": 2.50, "ProductMinimumPickQTY": 5, "ProductStatus": 1, "ProductCashPrice": 2.40, "ProductCreditCardPrice": 2.60, "ProductPrepaidCardPrice": 2.50, "ProductExternalPrepaidCardPrice": 2.55, "ProductMemberTypePriceBit": true, "ProductPictureURL": "https://example.com/energy-drink.jpg", "CaloriesPer100g": 45.0, "CaloriesPerServing": 110.0, "EANCode": "0123456789123", "ProductCreatedBy": 7890, "ProductCreationDate": "2024-11-25T14:00:00Z", "ProductUpdatedBy": 7890, "ProductLastUpdated": "2024-11-25T14:30:00Z", "VatId": 10 }' ``` <Note> **Path Param** Ensure that you send the `OperatorID` as a path param to specify what operator the product belongs to. </Note> <br /> In the body parameters, send the following details about the product: | **Parameter** | `Type` | Description | | - | - | - | | **NayaxProductID** | `int64/null` | The unique identifier for the product in the Nayax system. | | **ProductGroupID** | `int32/null` | The unique identifier of the product group to which the product belongs. | | **ActorID** | `int64/null` | The unique identifier of the actor associated with the product. | | **ProductManufacturerID** | `int32/null` | The unique identifier of the product's manufacturer. | | **ProductName** | `string/null` | The name of the product. | | **ProductCatalogNumber** | `string/null` | The catalog number assigned to the product. | | **ProductBarcode** | `string/null` | The barcode associated with the product. | | **ProductPackageQuantity** | `int32/null` | The quantity of product units per package. | | **ProductDescription** | `string/null` | A description of the product. | | **ProductVolumeTypeID** | `int32/null` | The volume type identifier associated with the product. | | **DEXProductName** | `string/null` | The name of the product in the DEX (Data Exchange) format. | | **ProductCostPrice** | `double/null` | The cost price of the product. | | **ProductDefaultRetailPrice** | `double/null` | The default retail price of the product. | | **ProductMinimumPickQTY** | `int32/null` | The minimum quantity of the product that can be picked. | | **ProductStatus** | `int32/null` | The status of the product, typically representing availability. | | **ProductCashPrice** | `double/null` | The price of the product when paid with cash. | | **ProductCreditCardPrice** | `double/null` | The price of the product when paid with a credit card. | | **ProductPrepaidCardPrice** | `double/null` | The price of the product when paid with a prepaid card. | | **ProductExternalPrepaidCardPrice** | `double/null` | The price of the product when paid with an external prepaid card. | | **ProductMemberTypePriceBit** | `boolean/null` | Indicates if the product has member-type-specific pricing. | | **ProductPictureURL** | `string/null` | The URL of the product's picture. | | **CaloriesPer100g** | `double/null` | The number of calories per 100 grams of the product. | | **CaloriesPerServing** | `double/null` | The number of calories per serving of the product. | | **EANCode** | `string/null` | The European Article Number (EAN) code associated with the product. | | **ProductCreatedBy** | `int64/null` | The identifier of the user who created the product entry. | | **ProductCreationDate** | `date-time/null` | The date and time when the product was created. | | **ProductUpdatedBy** | `int64/null` | The identifier of the user who last updated the product entry. | | **ProductLastUpdated** | `date-time/null` | The date and time when the product was last updated. | | **VatId** | `int32/null` | The VAT (Value Added Tax) identifier associated with the product. | ### Create multiple products at once You can create multiple products for a single machine using the [Create Machine Products](/reference/lynx/machine-products/create-machine-products) endpoint. This allows you to add several products in one request, even if they belong to different product groups. ```sh Request theme={null} curl -X POST "https://qa-lynx.nayax.com/operational/v1/machines/<MACHINE_ID>/machineProducts" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '[ { "MachineID": 5001, "ProductName": "Cola Drink", "MDBCode": 1, "CashPrice": 1.75, "CreditCardPrice": 1.80, "RetailPrice": 1.85, "ProductGroupID": 201, "DEXProductName": "Cola Drink", "IsActive": true }, { "MachineID": 5001, "ProductName": "Potato Chips", "MDBCode": 2, "CashPrice": 2.25, "CreditCardPrice": 2.30, "RetailPrice": 2.40, "ProductGroupID": 202, "DEXProductName": "Potato Chips", "IsActive": true } ]' ``` <Note> **Path Params** In the example above, replace `<MACHINE_ID>` with the actual machine identifier you need products added. </Note> <br /> The response JSON returned from this API call will confirm that the products have been successfully added by returning the objects representing each product in a list. ```json Response theme={null} [ { "DexPrice": 1.75, "ProductRef": "PROD001", "MachineProductRef": "MACH001-A1", "ProductGroupRef": "BEVERAGES", "MachineRef": "MACH001", "MachineProductID": 101, "NayaxProductID": 1001, "MachineID": 5001, "MDBCode": 1, "PAR": 10, "CashPrice": 1.75, "CreditCardPrice": 1.80, "MachinePrice": 1.70, "RetailPrice": 1.85, "DEXProductName": "Cola Drink", "PACode": "PA001", "PCCode": "PC001", "ProductMinimumPickQTY": 5, "VendOutAlertThreshold": 2, "LastUpdated": "2024-10-10T17:30:00.000Z", "MissingStockByDEX": 0, "DEXMissingStockLastUpdated": "2024-10-10T17:30:00.000Z", "PrePaidCardPrice": 1.65, "OperatorButtonCode": "BTN001", "LastUpdatedByMobile": "2024-10-10T17:30:00.000Z", "ProductGroupID": 201, "MissingStockByMDB": 0, "MDBMissingStockLastUpdated": "2024-10-10T17:30:00.000Z", "SelectionVendOutBit": false, "CommissionValue": 0.05, "ExternalPrepaidPrice": 1.60, "product_mark_for_alerts": 1, "last_sale_dt": "2024-10-09T16:30:00.000Z", "last_sale_mdb_dt": "2024-10-09T16:30:00.000Z", "slow_mover": false }, { "DexPrice": 2.25, "ProductRef": "PROD002", "MachineProductRef": "MACH001-B2", "ProductGroupRef": "SNACKS", "MachineRef": "MACH001", "MachineProductID": 102, "NayaxProductID": 1002, "MachineID": 5001, "MDBCode": 2, "PAR": 15, "CashPrice": 2.25, "CreditCardPrice": 2.30, "MachinePrice": 2.20, "RetailPrice": 2.40, "DEXProductName": "Potato Chips", "PACode": "PA002", "PCCode": "PC002", "ProductMinimumPickQTY": 3, "VendOutAlertThreshold": 1, "LastUpdated": "2024-10-10T17:30:00.000Z", "MissingStockByDEX": 0, "DEXMissingStockLastUpdated": "2024-10-10T17:30:00.000Z", "PrePaidCardPrice": 2.10, "OperatorButtonCode": "BTN002", "LastUpdatedByMobile": "2024-10-10T17:30:00.000Z", "ProductGroupID": 202, "MissingStockByMDB": 1, "MDBMissingStockLastUpdated": "2024-10-10T17:30:00.000Z", "SelectionVendOutBit": true, "CommissionValue": 0.10, "ExternalPrepaidPrice": 2.05, "product_mark_for_alerts": 1, "last_sale_dt": "2024-10-08T15:00:00.000Z", "last_sale_mdb_dt": "2024-10-08T15:00:00.000Z", "slow_mover": true } ] ``` Where: | **Parameter** | **Description** | | - | - | | `DexPrice` | The DEX protocol price of the product. | | `ProductRef` | Reference identifier for the product. | | `MachineProductID` | Unique identifier for the product in the machine. | | `MachineID` | Identifier of the associated machine. | | `MDBCode` | MDB protocol code for the product. | | `CashPrice` | Price of the product for cash payments. | | `CreditCardPrice` | Price for credit card payments. | | `RetailPrice` | The retail price set for the product. | | `DEXProductName` | Name of the product as recorded by DEX. | | `ProductGroupID` | Identifier for the product group. | | `LastUpdated` | Timestamp of the last update. | | `IsActive` | Indicates if the product is active. | ### Update product You can use the [Update Specific Product](/reference/lynx/products/update-specific-product) endpoint to change a product's details by adding the product's `NayaxProductID` in the path params and the information to change in the body request. As in the example request below: ```sh Request theme={null} curl --request PUT \ --url https://qa-lynx.nayax.com/operational/v1/products/{NayaxProductID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "ProductName": "Updated Chocolate Bar", "ProductGroupID": 1002, "ProductDefaultRetailPrice": 3.00, "ProductCashPrice": 2.90, "ProductCreditCardPrice": 3.10, "ProductDescription": "Updated description for the chocolate bar.", "IsActive": true }' ``` The body parameters are the same as in the Create Product request. If the request is successful, the response will contain the updated details of the product. After creating your products, you're ready to [map them to machines](/docs/manage-data-operations/lynx-api/inventory-management/machine-products-1). # Inventory Workflow Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/inventory-workflow Inventory management in Nayax follows a four-step sequence where each step must be completed before the next. 1. **[Create Product Groups](/docs/manage-data-operations/lynx-api/inventory-management/create-product-group)**: Group products into logical categories such as "Beverages," "Snacks," or "Confectionery" to organize your catalog. 2. **[Create Products](/docs/manage-data-operations/lynx-api/inventory-management/create-products)**: Add individual items to the operator’s catalog with details like product name, price, and group association. 3. **[Map Products to Machines](/docs/manage-data-operations/lynx-api/inventory-management/machine-products-1)**: Assign products to each machine’s bins or selections to define its layout and track available stock. 4. **[Pick Lists](/docs/manage-data-operations/lynx-api/inventory-management/pick-lists)**: Create a restocking list that identifies the products and quantities needed from the warehouse for each machine. <Warning> **Products and Operators** Product groups and their products are directly associated to an operator, and cannot be added to other operators. </Warning> Once the workflow is complete, see [Pick List Actions](/docs/manage-data-operations/lynx-api/inventory-management/pick-list-actions) for how to update, retrieve, or delete existing pick lists. # Machine Products Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/machine-products-1 Mapping products to machines (planogram setup) assigns specific products to a machine's bins or selections, defining its layout for inventory tracking and restocking. You can create product maps in Nayax Core by following the steps below: 1. Go to **Administration > Product Maps**. 2. Click **Add New Product Map**. 3. Fill in the required fields for the product map: * **Operator Name**: Specify which operator the map belongs to. * **Machine Model**: Select which machine the map is for. * **Map Name**: The name of the product map. * **Status**: Whether the map is active or not. 4. Click **Save**. <Frame> <img alt="" /> </Frame> Now, you can add products to this map. Follow the steps below to do so: 1. Select the map from the list. 2. Click on the **Map Items** tab. 3. Add products to the map using one of the following options: * **Add BIN**: Adds one product directly to the list. * **Add Multiple BINS**: Opens a pop-up window to select multiple products at once. <Frame> <img alt="" /> </Frame> ## Add a machine product via API Use the [Create Machine Products](/reference/lynx/machine-products/create-machine-products) endpoint to add one or more products to a machine's product map programmatically. <EndpointCard title="Create Machine Products" href="/reference/lynx/machine-products/create-machine-products" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> <br /> Send a POST request with the `MachineID` as a path parameter and an array of product objects in the request body: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/machines/{MachineID}/machineProducts \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' [ { "NayaxProductID": 0, "MDBCode": 0, "PAR": 0, "CashPrice": 0, "CreditCardPrice": 0, "MachinePrice": 0, "RetailPrice": 0, "DEXProductName": "string", "PACode": "string", "PCCode": "string", "ProductMinimumPickQTY": 0, "VendOutAlertThreshold": 0, "PrePaidCardPrice": 0, "OperatorButtonCode": "string", "CommissionValue": 0, "ExternalPrepaidPrice": 0 } ] ' ``` You can add more than one product object in the array to add multiple products to the map in a single request. <Note> **Path Params** Change the `MachineID` with the unique identifier of the machine to map its products. </Note> In the body parameters, fill in the following: | Parameter | Description | | - | - | | `NayaxProductID` | A unique identifier for the product in the Nayax system. | | `MDBCode` | The MDB (Multi-Drop Bus) code associated with the product. | | `PAR` | The price adjustment ratio for the product. | | `CashPrice` | The price of the product when purchased with cash. | | `CreditCardPrice` | The price of the product when purchased with a credit card. | | `MachinePrice` | The price of the product set directly on the vending machine. | | `RetailPrice` | The suggested retail price of the product. | | `DEXProductName` | The product name as it appears in the DEX (Data Exchange) format. | | `PACode` | The PA (Price Adjustment) code associated with the product. | | `PCCode` | The PC (Product Category) code associated with the product. | | `ProductMinimumPickQTY` | The minimum quantity of the product required for restocking or picking. | | `VendOutAlertThreshold` | The stock level threshold that triggers a vend-out alert. | | `PrePaidCardPrice` | The price of the product when purchased using a prepaid card. | | `OperatorButtonCode` | The code used by the operator to select the product manually. | | `CommissionValue` | The commission value associated with the product. | | `ExternalPrepaidPrice` | The price of the product when purchased with an external prepaid solution. | After mapping products to your machines, you're ready to [generate pick lists](/docs/manage-data-operations/lynx-api/inventory-management/pick-lists). # Pick List Actions Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/pick-list-actions Pick list actions in Nayax Core are available in the **Operations > Machine Inventory** menu. <Frame> <img /> </Frame> These actions can also be performed through Lynx API using the following endpoints: <Columns> <EndpointCard title="Get Pick List" href="/reference/lynx/machine-inventory/get-pick-list" method="get" /> <EndpointCard title="Update Pick List" href="/reference/lynx/machine-inventory/update-pick-list" method="put" /> <EndpointCard title="Delete Pick List" href="/reference/lynx/machine-inventory/delete-pick-list" method="delete" /> </Columns> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Get a pick list Use the [Get Pick List](/reference/lynx/machine-inventory/get-pick-list) endpoint to retrieve the pick list associated with a specific machine. ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/machines/{MachineID}/pickList \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` <Note> **Path Param** Change `MachineID` with the actual ID of the machine to retrieve the pick list from. </Note> A successful response returns the pick list with all products associated with the machine. ## Update a pick list Use the [Update Pick List](/reference/lynx/machine-inventory/update-pick-list) endpoint to modify product quantities or other details in a machine's pick list. ```sh Request theme={null} curl --request PUT \ --url https://qa-lynx.nayax.com/operational/v1/machines/inventory/picklists/update \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "MachineId": 12345, "Products": [ { "MachineProductId": 67890, "PickQty": 10 }, { "MachineProductId": 54321, "PickQty": 5 } ] }' ``` The request body contains the following parameters: | Parameter | Type | Description | | :- | :- | :- | | `MachineId` | `int64` | The unique identifier of the machine whose pick list is being updated. | | `Products` | `array of objects` | A list of products to update. Each object contains `MachineProductId` (unique identifier of the product in the machine) and `PickQty` (updated quantity to be picked). | A successful response returns the pick list with the updated pick quantities. ## Delete a pick list Use the [Delete Pick List](/reference/lynx/machine-inventory/delete-pick-list) endpoint to remove the pick list associated with a specific machine. ```sh Request theme={null} curl --request DELETE \ --url https://qa-lynx.nayax.com/operational/v1/machines/{MachineID}/pickList \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` A `200 OK` response confirms the pick list has been deleted. ## See also * [Inventory Workflow](/docs/manage-data-operations/lynx-api/inventory-management/inventory-workflow) * [Pick Lists](/docs/manage-data-operations/lynx-api/inventory-management/pick-lists) # Pick Lists Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/inventory-management/pick-lists A pick list identifies the products and quantities a machine needs for restocking, based on its current stock levels and sales data. In Nayax Core, you can create pick lists following the steps below: 1. In your Dashboard, go to **Operations > Inventory Dashboard**. 2. Use the search filter to look for your desired machine. 3. Right-click the machine and select **Pick List > Generate Pick List**. <Frame> <img alt="" /> </Frame> ### Generate for multiple machines To generate a pick list for more than one machine at once, for example all machines under a specific Route: 1. Add the filter to the search feature. 2. Select all the machines in the list (you can also individually select the machines you want). 3. Click **Actions > Generate Pick List**. <Frame> <img /> </Frame> ## Generate a pick list via API Use the [Create Pick List](/reference/lynx/machine-inventory/create-pick-list) endpoint to generate a pick list for a specific machine based on its current stock levels and sales data. <EndpointCard title="Create Pick List" href="/reference/lynx/machine-inventory/create-pick-list" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> <br /> Send a POST request with the `MachineID` as a path parameter. The endpoint returns `204 No Content` on success — no response body is returned. ```sh Request theme={null} curl -X POST "https://qa-lynx.nayax.com/operational/v1/machines/<MACHINE_ID>/pickLists" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" ``` The endpoint also accepts optional query parameters to refine the pick list — see the [Create Pick List](/reference/lynx/machine-inventory/create-pick-list) reference page for details. After generating a pick list, see [Pick List Actions](/docs/manage-data-operations/lynx-api/inventory-management/pick-list-actions) to retrieve, update, or delete it. # Overview Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/lynx-overview Lynx is Nayax's Management API for machines, devices, and inventory, with QA and production base URLs. Lynx is Nayax's Management API. It allows you to integrate with Nayax Core and manage your machines, devices, and inventory from your own environment. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> <Tip> **New to Lynx?** Create a sandbox account to start building. Submit the [integration request form](https://lynx-integration-request.nayax.com) and Nayax provisions your sandbox environment automatically. [Learn more](/docs/manage-data-operations/lynx-api/request-access). </Tip> ## Environments All guides in this section use QA URLs in their examples. Replace the hostname when going to production. | Environment | Base URL | | - | - | | QA | `https://qa-lynx.nayax.com/operational` | | Production | `https://lynx.nayax.com/operational` | ## Key benefits of the Lynx API The Lynx API offers a wide range of benefits for businesses looking to automate and streamline their operations: * **Simple integration**: Integrate the Lynx API with your existing in-house systems. * **Comprehensive capabilities**: Perform a variety of actions, including: * Inventory management and optimization * Machine and device configuration * Executing remote actions and commands * Managing prepaid cards ## Lynx use cases The Lynx API supports several real-world use cases, for example: * **ERP system integration**: Integrate with ERP systems for real-time updates and management. * **Prepaid card top-up**: Add credit to prepaid cards using automated workflows. * **Consumer management**: Automate prepaid card management for workplace or retail environments. * **Inventory management**: Create pick lists, perform stock updates, and optimize inventory levels across multiple machines. ## See also * [Security & Token](/docs/manage-data-operations/lynx-api/security) * [Managing Cards](/docs/manage-data-operations/lynx-api/cards/managing-cards) * [Payments](/docs/manage-data-operations/lynx-api/refunds/payments) * [Machines](/docs/manage-data-operations/lynx-api/machines/machines-devices) * [Devices](/docs/manage-data-operations/lynx-api/devices/devices-1) * [Operator](/docs/manage-data-operations/lynx-api/operator/index) # Create New Machine Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/create-new-machine-guides In Nayax Core, you can create a new machine in the **Machines** menu. Follow the steps below to do so. 1. In your Dashboard go to **Operations > Machines**. 2. Click **Create > New Machine**. <Frame> <img /> </Frame> 3. Now you can fill all the details on the form, once you are finished click on **Save**. Lynx API allows you to do this process programmatically through a POST request. This page will guide you on how to do so using the endpoint below: <EndpointCard title="Create New Machine" href="/reference/lynx/machines/create-new-machine" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Request to create new machine Use the [Create New Machine](/reference/lynx/machines/create-new-machine) endpoint to create a new machine. The following code block exemplifies the request to create a new machine: <CodeGroup> ```sh Request theme={null} curl -X POST "https://qa-lynx.nayax.com/operational/v1/machines" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "ActorID": 2001492652, "CountryID": 105, "CurrencyID": 2, "MachineGroupID": 210631347, "MachineModelID": 305, "MachineName": "New Vending Machine", "MachineStatusBit": 1, "LanguageID": 7, "SalesSourceID": 30000512, "MachineTypeID": 555001, "GeoCountry": 1 }' ``` ```json Response theme={null} { "MachineID": 942488501, "ActorID": 2001492652, "CountryID": 105, "CurrencyID": 2, "InstituteID": 3001, "LocationID": 4001, "MachineGroupID": 210631347, "MachineModelID": 305, "MachineName": "Marshall Vending", "MachineNumber": "MV001", "MachineStatusBit": 1, "LanguageID": 7, "OperatorActorID": 2001492652, "DistributorActorID": 3001492652, "AreaActorID": 4001492652, "SalesSourceID": 30000512, "MachineTypeID": 555001, "SerialNumber": "SN12345X", "VPOSSerialNumber": "VP12345", "DeviceSerialNumber": "SN12345X", "VPOSID": 98765, "DeviceID": 123456, "UseLocationFrom": 1, "GeoCountry": 1, "GeoState": "New York", "GeoCity": "New York City", "GeoAddress": "123 Main St", "GeoStreetNumber": "123", "GeoLongitude": -73.935242, "GeoLatitude": 40.730610, "GeoZoom": 15, "GeoZipCode": "10001", "SearchAddress": "123 Main St, New York, NY", "Remarks": "High-traffic area", "DexType": 2, "DexMidnightReadsEnableBit": true, "DexG85CheckEnableBit": true, "DexDivideBillsBy": 100, "DexG85CheckParsingFilterEnableBit": true, "UseCardPriceCorrectCashPriceBit": false, "MachineTimeZoneOffset": -5, "DexReadInterval": 30, "LocationType": 1, "ApplyDisplayPickListSelectionsToReportsBit": true, "DisplayPickListSelectionsAs": 1, "LastUpdated": "2024-10-09T14:38:53.474Z", "MachineProfile": 0, "CityID": 101, "RegionID": 201, "CountryDialingCode": 1, "DexIgnoreCRCCheckBit": true, "DexParseLABit": false, "ProductMapID": 501, "Longitude": -73.935242, "Latitude": 40.730610, "DexTotalSalesMinusCardSalesBit": true, "RouteActorID": 5001492652, "MachineLogicAlertEnableBit": true, "AlertRuleSetId": 601, "MachineMemberTypePricingEnableBit": false, "DexMultiplyCoinsBy": 10, "DexMultiplyTubesBy": 5, "CustomerID": 12345, "CommissionType": 2, "CommissionDefaultValue": 0.05, "CreatedBy": 105, "CreatedOn": "2023-06-01T12:00:00.000Z", "UpdateBy": 107, "TubeSource": 2, "BillSource": 3, "SmartStickerId": 8080, "EnableRemoveVendBit": true, "EnableEreceiptBit": true, "ProductMapAutomaticCreationBit": true, "Refs": { "Documentation": "https://example.com/machine/942488501" } } ] ``` </CodeGroup> You need to provide various mandatory fields in the body parameters, such as: | **Field Name** | **Description** | | - | - | | `ActorID` | The operator's ID under which the machine is being created. | | `CountryID` | ID representing the machine's country. Use the [Get Countries](/reference/lynx/lookups/get-countries) endpoint for a list of available country codes. | | `CurrencyID` | ID for the machine's currency. Use the [Get Currencies](/reference/lynx/lookups/get-currencies) endpoint for a list of available currency codes. | | `MachineGroupID` | ID of the group to which the machine belongs. You can view existing groups with the [List All Machine Groups for Actor](/reference/lynx/actors/list-all-machine-groups-for-actor) endpoint. | | `MachineModelID` | ID for the machine's model. To obtain the machine model of an existing machine, you can copy and paste the `MachineModelId` from the [Get Specific Machine Basic Info](/reference/lynx/machines/get-specific-machine-basic-info) endpoint for a specific machine. | | `MachineName` | The name of the virtual machine. | | `MachineStatusBit` | Status of the machine: `1` for active, `2` for inactive. | | `LanguageID` | ID represents the language used by the machine. | | `SalesSourceID` | ID indicating the sales source. should be `30000512`, which means live transactions (other options are irrelevant) | | `MachineTypeID` | The type of the machine determines its icon in Nayax Core. | | `GeoCountry` | Country code where the machine is located. | You will receive a response containing the details of the newly created machine, including the newly created machine's `MachineID`. ## Verify creation Once a new machine is created, you can verify it in Nayax Core, as in the steps below: 1. Go to **Operations > Machines**. 2. Use the **Search** feature to filter the Machine, and select it from the list. <Frame> <img alt="" /> </Frame> As you can see in the image above, once you select it you can see all its information on the **General Information** tab. <br /> # Get Monyx ID Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/get-monyx-id Lynx API allows you to retrieve the Monyx ID of a machine with a GET request. This page will guide you on how to do so using the endpoint below. <EndpointCard title="Get Payment Methods for Machine" href="/reference/lynx/machines/get-payment-methods-for-machine" method="get" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Retrieving the monyx ID You'll use the [Get Payment Methods for Machine](/reference/lynx/machines/get-payment-methods-for-machine) to get the Monyx ID, see the request below: ```sh Request theme={null} curl -X GET "https://qa-lynx.nayax.com/operational/v1/machines/{MachineID}/paymentMethods" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` <Note> **Path Params** Replace `<MachineID>` with the actual machine unique identifier you want to search. </Note> With a successful request, the endpoint will return the information on the available payment methods of the machine. See the code block below: ```json Response theme={null} { "MachineID": "98108", "PaymentMethodID": 22, "ConvenienceFeePercentageEdit": false, "ConvenienceFeeValue": 0, "lastUpdated": "2021-05-25T08:01:05.473", "ExternalPaymentProviderUsername": null, "ExternalPaymentProviderPassword": null, "ExternalPaymentProviderTerminalID": null, "ExternalPaymentProviderLocationIdentifier": null, "PaymentMethodWorkingDays": null, "PaymentMethodCustomData": "{\\\"use_phone_contactless\\\":false,\\\"use_phone_transaction\\\":false,\\\"monyx_machine_id\\\":31066766}", "ConvenienceFeeBackupValue": 0, "PaymentMethodIDString": null } ``` You can find the Monyx ID in the `PaymentMethodCustomData` parameter, in this example it would be: `"monyx_machine_id\":31066766` <br /> # Get a Machine's ID by the Device's ID Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/getting-a-machines-id-by-the-devices-serial-number This page presents how to retrieve a Machine's ID using its Device ID with Lynx API and also with Nayax Core. The guide will use the following endpoint: <EndpointCard title="Get All Machines" href="/reference/lynx/machines/get-all-machine-basic-info" method="get" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Retrieving the machine's ID To retrieve a machine's ID using its serial number, you need to use the [Get All Machines](/reference/lynx/machines/get-all-machine-basic-info) endpoint. By providing the device's serial number in the request you can retrieve the corresponding machine's unique identifier. The code block below exemplifies the request, using the `DeviceSerial` as a query parameter to filter the result: ```sh theme={null} curl -X GET "https://qa-lynx.nayax.com/operational/v1/machines?DeviceSerial=<DEVICE_SERIAL_NUMBER>" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` <Note> Remember to replace `<DEVICE_SERIAL_NUMBER>` with the actual device's serial number. </Note> The response will include details about the machine, including the Machine's ID. ```json theme={null} [ { "MachineID": 942488501, "ActorID": 2001492652, "CountryID": 1, "CurrencyID": 2, "InstituteID": 3001, "LocationID": 4001, "MachineGroupID": 210631347, "MachineModelID": 305, "MachineName": "Marshall Vending", "MachineNumber": "MV001", "MachineStatusBit": 1, "LanguageID": 7, "OperatorActorID": 2001492652, "DistributorActorID": 3001492652, "AreaActorID": 4001492652, "SalesSourceID": 30000512, "MachineTypeID": 555001, "SerialNumber": "SN12345X", "VPOSSerialNumber": "VP12345", "DeviceSerialNumber": "SN12345X", "VPOSID": 98765, "DeviceID": 123456, "UseLocationFrom": 1, "GeoCountry": 1, "GeoState": "New York", "GeoCity": "New York City", "GeoAddress": "123 Main St", "GeoStreetNumber": "123", "GeoLongitude": -73.935242, "GeoLatitude": 40.730610, "GeoZoom": 15, "GeoZipCode": "10001", "SearchAddress": "123 Main St, New York, NY", "Remarks": "High-traffic area", "DexType": 2, "DexMidnightReadsEnableBit": true, "DexG85CheckEnableBit": true, "DexDivideBillsBy": 100, "DexG85CheckParsingFilterEnableBit": true, "UseCardPriceCorrectCashPriceBit": false, "MachineTimeZoneOffset": -5, "DexReadInterval": 30, "LocationType": 1, "ApplyDisplayPickListSelectionsToReportsBit": true, "DisplayPickListSelectionsAs": 1, "LastUpdated": "2024-10-09T14:38:53.474Z", "MachineProfile": 0, "CityID": 101, "RegionID": 201, "CountryDialingCode": 1, "DexIgnoreCRCCheckBit": true, "DexParseLABit": false, "ProductMapID": 501, "Longitude": -73.935242, "Latitude": 40.730610, "DexTotalSalesMinusCardSalesBit": true, "RouteActorID": 5001492652, "MachineLogicAlertEnableBit": true, "AlertRuleSetId": 601, "MachineMemberTypePricingEnableBit": false, "DexMultiplyCoinsBy": 10, "DexMultiplyTubesBy": 5, "CustomerID": 12345, "CommissionType": 2, "CommissionDefaultValue": 0.05, "CreatedBy": 105, "CreatedOn": "2023-06-01T12:00:00.000Z", "UpdateBy": 107, "TubeSource": 2, "BillSource": 3, "SmartStickerId": 8080, "EnableRemoveVendBit": true, "EnableEreceiptBit": true, "ProductMapAutomaticCreationBit": true, "Refs": { "Documentation": "https://example.com/machine/942488501" } } ] ``` <br /> ## Nayax Core You can also find the Machine ID in Nayax Core in the machine's details, to do so follow the steps below: 1. Access **Operations > Machines**. 2. Use the **Search** feature to find the machine. 3. Select the machine from the list. 4. Access the **General Information** tab to find the **Machine ID** under the **Hardware** section. <Frame> <img /> </Frame> <br /> # Get Machine's Last Sales Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/getting-a-machines-last-sales In some cases, you may want to see the last sales of a machine to retrieve information about specific transactions. Nayax Core allows you to do so in the following way: 1. Go to **Operations > Machines**. 2. Choose your machine and click **Info > Last Sales**. <Frame> <img /> </Frame> You will be presented with a list containing the latest machine transactions. ## Lynx API Lynx API allows you to do this process programmatically through a GET request. This page will guide you on how to do so using the endpoint below. <EndpointCard title="Get Last Sales for Machine by MachineID" href="/reference/lynx/machines/get-last-sales-for-machine-by-machineid" method="get" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ### Retrieving the last sales You'll use the [Get Last Sales for Machine](/reference/lynx/machines/get-last-sales-for-machine-by-machineid) endpoint, adding the machine's unique identifier as a path parameter to retrieve details about the respective machine. This lets you view the latest sales activity associated with the searched machine. See the example request in the code block below: ```sh Request theme={null} curl -X GET "https://qa-lynx.nayax.com/operational/v1/machines/<MachineID>/lastSales" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` <Note> **Path Params** Replace `<MachineID>` with the actual machine unique identifier you want to search. </Note> With a successful request, the endpoint will return with a list of recent sales related to the machine. This response JSON will have the following format: ```json Response theme={null} [ { "TransactionID": 2108816976, "PaymentServiceTransactionID": "PS123456789", "PaymentServiceProviderName": "Stripe", "MachineID": 942488501, "MachineName": "Marshall Vending", "MachineNumber": "MV001", "InstituteLocationName": "New York Warehouse", "AuthorizationValue": 10.00, "SettlementValue": 9.50, "CurrencyCode": "USD", "PaymentMethod": "Credit Card", "RecognitionMethod": "Chip", "CardNumber": "************1234", "CardBrand": "Visa", "CLI": "+1234567890", "ProductName": "Bottled Water", "MultivendTransactionBit": true, "MultivendNumverOfProducts": 2, "UnitOfMeasurement": "Item", "Quantity": 2, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2024-10-09T16:53:51.225Z", "MachineAuthorizationTime": "2024-10-09T16:53:51.225Z", "SettlementDateTimeGMT": "2024-10-09T16:54:51.225Z", "SiteID": 2, "SiteName": "IL1" } ] ``` The table below describes the parameters on the response: | **Field** | **Description** | | - | - | | `TransactionID` | `2108816976`, identifying the transaction. | | `PaymentServiceTransactionID` | Provides details about the payment processor transaction. | | `PaymentServiceProviderName` | Indicates the name of the payment processor. | | `MachineID` | Refers to the machine where the transaction took place. | | `MachineName` | Name of the machine where the transaction occurred. | | `AuthorizationValue` | The authorized transaction amount. | | `SettlementValue` | The settled transaction amount. | | `CurrencyCode` | The currency used in the transaction (e.g., `USD`). | | `PaymentMethod` | The method used for payment. | | `RecognitionMethod` | How the payment was recognized. | | `CardNumber` | The card number used for payment. | | `CardBrand` | The brand of the card used for payment. | | `ProductName` | Specifies the item sold in the transaction. | | `Quantity` | The quantity of the item sold. | | `AuthorizationDateTimeGMT` | The authorization timestamp in GMT. | | `SettlementDateTimeGMT` | The settlement timestamp in GMT. | # Get a Machine's Last Sales & Generate eReceipt Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/getting-a-machines-last-sales-ereceipt-information This page presents how to retrieve a Machine's Last Sales using its Machine ID with Lynx API and also with Nayax Core. The guide will use the following endpoints: <Columns> <EndpointCard title="Get Last Sales" href="/reference/lynx/machines/get-last-sales-for-machine-by-machineid" method="get" /> <EndpointCard title="Generate eReceipt" href="/reference/lynx/ereceipt/generate-ereceipt-for-your-transaction" method="post" /> </Columns> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Retrieving a machine's last sales To retrieve a machine's Last Sales using its Machine ID, you need to use the [Get Last Sales for Machine](/reference/lynx/machines/get-last-sales-for-machine-by-machineid) endpoint. By providing the machine's Machine ID in the request you can retrieve the corresponding machine's unique identifier. The code block below exemplifies the request, using the `MachineID` as a query parameter to filter the result: ```sh theme={null} curl -X 'GET' \ 'https://qa-lynx.nayax.com/operational/v1/machines/<MACHINE_ID>/lastSales' \ -H 'accept: text/plain' \ -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' ``` <Note> Remember to replace `<MACHINE_ID>` with the actual machine's Machine ID. </Note> The response will include details about the machine, including the Machine's ID. ```json theme={null} [ { "TransactionID": 4625276436, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 700, "SettlementValue": 700, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 700.00)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-02-08T09:31:51.817", "MachineAuthorizationTime": "2026-02-08T11:31:51.46", "SettlementDateTimeGMT": "2026-02-09T01:53:07.96", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4625272758, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 44.64, "SettlementValue": 44.64, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 44.64)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-02-08T09:28:18.38", "MachineAuthorizationTime": "2026-02-08T11:28:18.117", "SettlementDateTimeGMT": "2026-02-08T09:29:37.527", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4600648084, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.05, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.05)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-02-03T08:18:01.53", "MachineAuthorizationTime": "2026-02-03T10:18:01.143", "SettlementDateTimeGMT": "2026-02-03T08:18:15.617", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4600630276, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.05, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.05)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-02-03T08:07:52.03", "MachineAuthorizationTime": "2026-02-03T10:07:51.663", "SettlementDateTimeGMT": "2026-02-03T08:08:11.187", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4545673740, "PaymentServiceTransactionID": "260122075902", "PaymentServiceProviderName": "Stub Billing", "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.1, "CurrencyCode": "AUD", "PaymentMethod": "Credit Card", "RecognitionMethod": "Credit Card", "CardNumber": "5453 xxxx xxxx 5803", "CardBrand": "MASTERCARD", "CLI": null, "ProductName": "Unknown(0 = 0.10)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-22T07:59:02.103", "MachineAuthorizationTime": "2026-01-22T09:59:02.07", "SettlementDateTimeGMT": "2026-01-22T08:53:02.977", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4545672122, "PaymentServiceTransactionID": "260122075814", "PaymentServiceProviderName": "Stub Billing", "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.1, "CurrencyCode": "AUD", "PaymentMethod": "Credit Card", "RecognitionMethod": "Credit Card", "CardNumber": "5453 xxxx xxxx 5803", "CardBrand": "MASTERCARD", "CLI": null, "ProductName": "Unknown(0 = 0.10)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-22T07:58:14.687", "MachineAuthorizationTime": "2026-01-22T09:58:14.643", "SettlementDateTimeGMT": "2026-01-22T07:58:30.44", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4515594836, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.1, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.10)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-15T11:44:11.867", "MachineAuthorizationTime": "2026-01-15T13:44:11.53", "SettlementDateTimeGMT": "2026-01-15T11:45:58.207", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4515585818, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.05, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.05)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-15T11:40:29.583", "MachineAuthorizationTime": "2026-01-15T13:40:29.207", "SettlementDateTimeGMT": "2026-01-15T11:40:49.12", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4515573274, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.1, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.10)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-15T11:35:16.5", "MachineAuthorizationTime": "2026-01-15T13:35:16.15", "SettlementDateTimeGMT": "2026-01-15T11:36:57.857", "SiteID": 4, "SiteName": "US" }, { "TransactionID": 4515568878, "PaymentServiceTransactionID": null, "PaymentServiceProviderName": null, "MachineID": 629665354, "MachineName": "Marshall temp- do not touch #3", "MachineNumber": "", "InstituteLocationName": null, "AuthorizationValue": 0.1, "SettlementValue": 0.1, "CurrencyCode": "AUD", "PaymentMethod": "Prepaid Credit", "RecognitionMethod": "Prepaid Credit", "CardNumber": "2736390748", "CardBrand": null, "CLI": null, "ProductName": "Unknown(0 = 0.10)\n", "MultivendTransactionBit": false, "MultivendNumverOfProducts": 0, "UnitOfMeasurement": null, "Quantity": 1, "EnergyConsumed": 0, "AuthorizationDateTimeGMT": "2026-01-15T11:33:23.537", "MachineAuthorizationTime": "2026-01-15T13:33:23.113", "SettlementDateTimeGMT": "2026-01-15T11:34:58.007", "SiteID": 4, "SiteName": "US" } ] ``` <br /> ### Nayax Core You can also find the Machine's Last Sales in Nayax Core in the machine's details, to do so follow the steps below: 1. Access **Operations > Machines**. 2. Use the **Search** feature to find the machine. 3. Select the machine from the list. 4. Click on **Info > Last Sales**: <Frame> <img /> </Frame> <br /> ## Generating eReceipt To generate a transaction's eReceipt, you need to use the [Generate eReceipt](/reference/lynx/ereceipt/generate-ereceipt) endpoint. By providing the following information in the request: * TransactionID, MachineAuthorizationTime, SiteID - all 3 fields' values are retrieved via the Last Sales method mentioned above * Machine ID * Consumer's full name * Consumer's email address You can retrieve the corresponding machine's unique identifier. The code block below exemplifies the request, using the `DeviceSerial` as a query parameter to filter the result: ```sh theme={null} curl -X 'POST' \ 'https://qa-lynx.nayax.com/operational/v1/ereceipt/generate' \ -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ -H 'accept: text/plain' \ -H 'Content-Type: application/json-patch+json' \ -d '{ "TrasactionID": <TRANSACTION_ID>, "TransactionDateTime": <MACHINE_AUTHORIZATION_TIME>, "TrasactionSiteID": <SITE_ID>, "MachineID": <MACHINE_ID>, "FullName": "string", "Email": "string" }' ``` <Note> Remember to replace `<TRANSACTION_ID>`, `<MACHINE_AUTHORIZATION_TIME>`, `<SITE_ID>`, `<MACHINE_ID>` with the actual details of the transaction. </Note> The response will include details about the eReceipt sent, including the PDF's link. ```json theme={null} { "ReceiptURL": "https://nayax-ereceipt.s3.amazonaws.com/2026/02/12/YaelLawtonStubBilling/OFpQBN-x25GKRbZE8ySlnDnrO44iYVAEUKcw-vKmpoY1/ereceipt4625276436.pdf", "EmailSent": true, "EreceiptID": 6203654 } ``` ### Nayax Core You can also find the Machine's Last Sales in Nayax Core in the machine's details, to do so follow the steps below: 1. Access **Reports > Online Reports > Dynamic Transactions Monitor**. <Frame> <img /> </Frame> 2. Use the **Search** feature to find the relevant transaction by the transaction ID. <Frame> <img /> </Frame> 3. Select the relevant transaction from the list. 4. Right-click on the transaction, then select **Generate eReceipt**: <Frame> <img /> </Frame> <br /> 5. Insert the relevant details and click on "Generate eReceipt": <Frame> <img /> </Frame> # Restart a Machine Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/restart-a-machine Restart a Nayax device remotely by updating a device attribute on the machine. The device picks up the change on its next poll and restarts, then reconnects to the server on its own. <EndpointCard title="Update Specific Machine Attribute" href="/reference/lynx/machine-attribute/update-specific-machine-attribute" method="put" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use them to authenticate your API requests. </Warning> ## Restart a machine Use the [Update Specific Machine Attribute](/reference/lynx/machine-attribute/update-specific-machine-attribute) endpoint to set device attribute `144` on the machine. Provide the `MachineID` and the attribute's `DeviceAttributeID` as path parameters, and the attribute value as a body parameter: ```bash Request theme={null} curl -X PUT "https://qa-lynx.nayax.com/operational/v1/machines/<MACHINE_ID>/attributes/144" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "DeviceAttributeID": 144, "MachineID": <MACHINE_ID>, "DeviceAttributeValue": "1" }' ``` <Note> Replace `<MACHINE_ID>` with your machine's unique identifier, and `<YOUR_ACCESS_TOKEN>` with your Lynx API token. </Note> This table outlines the body parameters: | **Name** | **Type** | **Description** | | :- | :- | :- | | `DeviceAttributeID` | `int` | The device attribute to update. Use `144` to restart the device. | | `MachineID` | `int` | The unique identifier of the machine, matching the path parameter. | | `DeviceAttributeValue` | `string` | The value to assign to the attribute. Use `"1"` to trigger the restart. | The endpoint returns the updated attribute on success: ```json Response theme={null} { "DeviceAttributeID": 144, "MachineID": <MACHINE_ID>, "DeviceAttributeValue": "1", "DeviceAttributeCodeID": null, "DeviceAttributeName": "Restart device", "DeviceAttributeGroup": "Communication", "DeviceAttributeReadOnlyBit": false, "MachineAttributeRef": "/v1/machines/<MACHINE_ID>/attributes/144", "MachineRef": "/v1/machines/<MACHINE_ID>" } ``` The device restarts within a few minutes once it polls the queue. Restarting also applies any other configuration changes waiting in the queue. <Note> If attribute `144` has never been set on the machine, a `GET` request for it returns `204 No Content` instead of an error, and the attribute is omitted from the machine's full attribute list until you set it. </Note> ## Restart versus reboot A restart is the lighter of the two power operations. It powers the device off and on and applies any other pending configuration. A reboot is heavier: it activates the bootloader. Use a restart unless you specifically need the bootloader. <Warning> Do not trigger a restart during an active transaction. Wait until the device is idle so you do not interrupt a payment in progress. </Warning> ## Confirm the restart After the device restarts, it sends a `PowerUp` event back to the server confirming it is online again. Use this event to verify the restart completed. ## Next steps <CardGroup> <Card title="Machine attributes" icon="sliders" href="/docs/manage-data-operations/lynx-api/machines/updating-a-machines-attribute"> Update other machine attributes through the Lynx API. </Card> <Card title="Retrieve machine information" icon="magnifying-glass" href="/docs/manage-data-operations/lynx-api/machines/retrieve-machine-information"> Look up a machine's details and current status. </Card> </CardGroup> # Retrieve Machine Information Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/retrieve-machine-information In Nayax Core, machines have various attributes, such as the Operator of the machine, the machine's model or ID, and its status. These can all be seen in the **Machines** menu, which you can access in the following way: 1. In your Dashboard, go to **Operations > Machines**. 2. Use the search function to filter through the list of machines. 3. Select the desired machine from the list. 4. Open the **General Information** tab. <Frame> <img /> </Frame> You can see all the key information about the machine you may need for other requests there. <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> The Lynx API provides four methods to retrieve machine information programmatically. Use the section that matches the identifier you have available. ## Retrieve a machine by `MachineID` Use the [Get Specific Machine Basic Info](/reference/lynx/machines/get-specific-machine-basic-info) endpoint to retrieve the details of a machine with a specific `MachineID`. Insert the `MachineID` in the path parameter of the request. <EndpointCard title="Get Specific Machine Basic Info" href="/reference/lynx/machines/get-specific-machine-basic-info" method="get" /> <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/machines/{MachineID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "MachineID": 0, "ActorID": 0, "CountryID": 0, "CurrencyID": 0, "InstituteID": 0, "LocationID": 0, "MachineGroupID": 0, "MachineModelID": 0, "MachineName": "string", "MachineNumber": "string", "MachineStatusBit": 0, "LanguageID": 2, "OperatorActorID": 0, "DistributorActorID": 0, "AreaActorID": 0, "SalesSourceID": 0, "MachineTypeID": 555001, "SerialNumber": "string", "VPOSSerialNumber": "string", "DeviceSerialNumber": "string", "VPOSID": 0, "DeviceID": 0, "UseLocationFrom": 0, "GeoCountry": 0, "GeoState": "string", "GeoCity": "string", "GeoAddress": "string", "GeoStreetNumber": "string", "GeoLongitude": 0, "GeoLatitude": 0, "GeoZoom": 0, "GeoZipCode": "string", "SearchAddress": "string", "Remarks": "string", "DexType": 0, "DexMidnightReadsEnableBit": true, "DexG85CheckEnableBit": true, "DexDivideBillsBy": 0, "DexG85CheckParsingFilterEnableBit": true, "UseCardPriceCorrectCashPriceBit": true, "MachineTimeZoneOffset": 0, "DexReadInterval": 0, "LocationType": 0, "ApplyDisplayPickListSelectionsToReportsBit": true, "DisplayPickListSelectionsAs": 0, "LastUpdated": "2024-11-25T14:04:50.909Z", "MachineProfile": 0, "CityID": 0, "RegionID": 0, "CountryDialingCode": 0, "DexIgnoreCRCCheckBit": true, "DexParseLABit": true, "ProductMapID": 0, "Longitude": 0, "Latitude": 0, "DexTotalSalesMinusCardSalesBit": true, "RouteActorID": 0, "MachineLogicAlertEnableBit": true, "AlertRuleSetId": 0, "MachineMemberTypePricingEnableBit": true, "DexMultiplyCoinsBy": 0, "DexMultiplyTubesBy": 0, "CustomerID": 0, "CommissionType": 0, "CommissionDefaultValue": 0, "CreatedBy": 0, "CreatedOn": "2024-11-25T14:04:50.909Z", "UpdateBy": 0, "TubeSource": 0, "BillSource": 0, "SmartStickerId": 0, "EnableRemoveVendBit": true, "EnableEreceiptBit": true, "ProductMapAutomaticCreationBit": true, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> ## Retrieve a machine by `DeviceSerialNumber` Use the [Get Specific Machine Basic Info by Device](/reference/lynx/machines/get-specific-machine-basic-info-by-device) endpoint to retrieve the details of a machine associated with a specific `DeviceSerialNumber`. Insert the `DeviceSerialNumber` in the path parameter of the request. <EndpointCard title="Get Specific Machine Basic Info by Device" href="/reference/lynx/machines/get-specific-machine-basic-info-by-device" method="get" /> <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/devices/{DeviceSerialNumber}/machine \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "MachineID": 0, "ActorID": 0, "CountryID": 0, "CurrencyID": 0, "InstituteID": 0, "LocationID": 0, "MachineGroupID": 0, "MachineModelID": 0, "MachineName": "string", "MachineNumber": "string", "MachineStatusBit": 0, "LanguageID": 2, "OperatorActorID": 0, "DistributorActorID": 0, "AreaActorID": 0, "SalesSourceID": 0, "MachineTypeID": 555001, "SerialNumber": "string", "VPOSSerialNumber": "string", "DeviceSerialNumber": "string", "VPOSID": 0, "DeviceID": 0, "UseLocationFrom": 0, "GeoCountry": 0, "GeoState": "string", "GeoCity": "string", "GeoAddress": "string", "GeoStreetNumber": "string", "GeoLongitude": 0, "GeoLatitude": 0, "GeoZoom": 0, "GeoZipCode": "string", "SearchAddress": "string", "Remarks": "string", "DexType": 0, "DexMidnightReadsEnableBit": true, "DexG85CheckEnableBit": true, "DexDivideBillsBy": 0, "DexG85CheckParsingFilterEnableBit": true, "UseCardPriceCorrectCashPriceBit": true, "MachineTimeZoneOffset": 0, "DexReadInterval": 0, "LocationType": 0, "ApplyDisplayPickListSelectionsToReportsBit": true, "DisplayPickListSelectionsAs": 0, "LastUpdated": "2024-11-25T14:04:50.909Z", "MachineProfile": 0, "CityID": 0, "RegionID": 0, "CountryDialingCode": 0, "DexIgnoreCRCCheckBit": true, "DexParseLABit": true, "ProductMapID": 0, "Longitude": 0, "Latitude": 0, "DexTotalSalesMinusCardSalesBit": true, "RouteActorID": 0, "MachineLogicAlertEnableBit": true, "AlertRuleSetId": 0, "MachineMemberTypePricingEnableBit": true, "DexMultiplyCoinsBy": 0, "DexMultiplyTubesBy": 0, "CustomerID": 0, "CommissionType": 0, "CommissionDefaultValue": 0, "CreatedBy": 0, "CreatedOn": "2024-11-25T14:04:50.909Z", "UpdateBy": 0, "TubeSource": 0, "BillSource": 0, "SmartStickerId": 0, "EnableRemoveVendBit": true, "EnableEreceiptBit": true, "ProductMapAutomaticCreationBit": true, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> ## Retrieve a machine by `VPOSSerial` Use the [Get Specific Machine Basic Info by VPOS](/reference/lynx/machines/get-specific-machine-basic-info-by-vpos) endpoint to retrieve the details of a machine associated with a specific `VPOSSerial`. Insert the `VPOSSerial` in the path parameter of the request. <EndpointCard title="Get Specific Machine Basic Info by VPOS" href="/reference/lynx/machines/get-specific-machine-basic-info-by-vpos" method="get" /> <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/vpos/{VPOSSerial}/machine \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "MachineID": 0, "ActorID": 0, "CountryID": 0, "CurrencyID": 0, "InstituteID": 0, "LocationID": 0, "MachineGroupID": 0, "MachineModelID": 0, "MachineName": "string", "MachineNumber": "string", "MachineStatusBit": 0, "LanguageID": 2, "OperatorActorID": 0, "DistributorActorID": 0, "AreaActorID": 0, "SalesSourceID": 0, "MachineTypeID": 555001, "SerialNumber": "string", "VPOSSerialNumber": "string", "DeviceSerialNumber": "string", "VPOSID": 0, "DeviceID": 0, "UseLocationFrom": 0, "GeoCountry": 0, "GeoState": "string", "GeoCity": "string", "GeoAddress": "string", "GeoStreetNumber": "string", "GeoLongitude": 0, "GeoLatitude": 0, "GeoZoom": 0, "GeoZipCode": "string", "SearchAddress": "string", "Remarks": "string", "DexType": 0, "DexMidnightReadsEnableBit": true, "DexG85CheckEnableBit": true, "DexDivideBillsBy": 0, "DexG85CheckParsingFilterEnableBit": true, "UseCardPriceCorrectCashPriceBit": true, "MachineTimeZoneOffset": 0, "DexReadInterval": 0, "LocationType": 0, "ApplyDisplayPickListSelectionsToReportsBit": true, "DisplayPickListSelectionsAs": 0, "LastUpdated": "2024-11-25T14:04:50.909Z", "MachineProfile": 0, "CityID": 0, "RegionID": 0, "CountryDialingCode": 0, "DexIgnoreCRCCheckBit": true, "DexParseLABit": true, "ProductMapID": 0, "Longitude": 0, "Latitude": 0, "DexTotalSalesMinusCardSalesBit": true, "RouteActorID": 0, "MachineLogicAlertEnableBit": true, "AlertRuleSetId": 0, "MachineMemberTypePricingEnableBit": true, "DexMultiplyCoinsBy": 0, "DexMultiplyTubesBy": 0, "CustomerID": 0, "CommissionType": 0, "CommissionDefaultValue": 0, "CreatedBy": 0, "CreatedOn": "2024-11-25T14:04:50.909Z", "UpdateBy": 0, "TubeSource": 0, "BillSource": 0, "SmartStickerId": 0, "EnableRemoveVendBit": true, "EnableEreceiptBit": true, "ProductMapAutomaticCreationBit": true, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> ## Retrieve all machine basic info Use the [Get All Machine Basic Info](/reference/lynx/machines/get-all-machine-basic-info) endpoint to retrieve basic information for all machines, with optional filtering by the query parameters listed below. <EndpointCard title="Get All Machine Basic Info" href="/reference/lynx/machines/get-all-machine-basic-info" method="get" /> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/machines \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` | **Parameter** | `Type` | Description | | - | - | - | | **ResultsLimit** | `int32` | The maximum number of results to return; it is set to 100 by default. | | **ResultsOffset** | `int32` | The number of results to skip before starting to return results; set to 0 by default. | | **ActorID** | `int64` | Filter results by the actor ID associated with the machine. | | **OperatorIdentifier** | `string` | Filter results by the operator identifier. | | **MachineID** | `int64` | Filter results by the machine ID. | | **MachineSerialNumber** | `string` | Filter results by the machine's serial number. | | **MachineName** | `string` | Filter results by the machine's name. | | **DeviceID** | `int32` | Filter results by the device ID associated with the machine. | | **VposID** | `int64` | Filter results by the VPOS ID associated with the machine. | # Machine Attributes Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/machines/updating-a-machines-attribute This page uses the Lynx API to update an attribute of a machine. In the step-by-step guide below, you'll use the following endpoint: <Columns> <EndpointCard title="Bulk Update Machine Attributes" href="/reference/lynx/machine-attribute/bulk-update-machine-attributes" method="put" /> <EndpointCard title="Update Specific Machine Attribute" href="/reference/lynx/machine-attribute/update-specific-machine-attribute" method="put" /> </Columns> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Updating machine's attribute Use the [Bulk Update Machine Attributes](/reference/lynx/machine-attribute/bulk-update-machine-attributes) endpoint to update specific machine attributes. Provide the `MachineID` as a path parameter, along with the attributes you want to change as body parameters, as exemplified below: ```sh Request theme={null} curl -X PUT "https://qa-lynx.nayax.com/operational/v1/machines/<MACHINE_ID>/attributes" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "DeviceAttributeID": 1001, "MachineID": 942488501, "DeviceAttributeValue": "Updated Vending Machine Name", "DeviceAttributeCodeID": 3002, "DeviceAttributeName": "MachineName", "DeviceAttributeGroup": "General", "DeviceAttributeReadOnlyBit": false }' ``` <Note> Replace `<MACHINE_ID>` with the actual machine's unique identifier, you want to update the attributes. </Note> This table outlines the key attributes available for update: | **Name** | **Type** | **Description** | | :- | :- | :- | | `DeviceAttributeID` | `int64` | A unique ID that identifies the specific attribute of the device. | | `MachineID` | `int64` | The unique identifier of the machine associated with this attribute. | | `DeviceAttributeValue` | `string` | The value assigned to the device attribute. | | `DeviceAttributeCodeID` | `int32` | The code identifier that categorizes the device attribute. | | `DeviceAttributeName` | `string` | The name of the device attribute being modified. | | `DeviceAttributeGroup` | `string` | The group or category to which the device attribute belongs. | | `DeviceAttributeReadOnlyBit` | `boolean` | Indicates whether the device attribute is read-only. | The response will indicate whether the update was entirely successful or if there were any failures. ```json Response theme={null} { "isFullySuccess": true, "failureItems": [ { "id": "123456", "error": "Attribute update failed due to invalid value." } ] } ``` Where: * `isFullySuccess` indicates whether the update was entirely successful (`true` if successful, `false` if there were any issues). * `failureItems` is an array of any failed items, where each entry includes: * `id`: The identifier of the failed item (e.g., attribute ID). * `error`: A description of the error encountered during the update. <Note> If `isFullySuccess` is `true` and `failureItems` is empty. The update was completed successfully without any errors. </Note> <br /> # Create Operator Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/operator/create-operator In Nayax Core, you can create and manage operators using the **Operator** menu. To create a new Operator, follow the steps below: 1. Go to **Administration > Operator**. 2. Click **Create > Add New Operator**. 3. Now, you must fill out the required details on the form. 1. **Operator Internal Code**: This is the SAP Customer number. 2. **Parent**: Refers to the parent actor for this new operator, which, in this example, is the distributor itself. 3. **Type**: The operator type. 4. **Status**: The status of the operator. 5. **Regional Settings**: Configuration regarding currency and timezone. 4. When finished, click **Save Information**. <Frame> <img /> </Frame> <Warning> **Actor Types** Note that when you create an actor directly below the distributor, there are only two types available: Institute or Operator. To create Routes, Area, or Location actor types, they must be below an actor with the Operator type. </Warning> ## Lynx API This process can also be done programmatically through Lynx API with a POST request to the following endpoint: <EndpointCard title="Create New Actor" href="/reference/lynx/actors/create-a-new-actor-1" method="post" /> <br /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ### Create operator request The [Create New Actor ](/reference/lynx/actors/create-a-new-actor-1)endpoint allows for registering a new operator in the Nayax system. See the example request in the code block below: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/actors/{ParentActorID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "ActorDescription": "Main Branch", "ActorCode": 1001, "ActorAddress": "123 Main Street, Metropolis", "ActorContact": "contact@branch.com", "ActorTypeID": 16, "ActorStatus": 1, "CurrencyID": 840, "CountryID": 840, "ActorMerchantBit": true, "ActorCreationDate": "2024-11-25T12:00:00Z", "ActorLanguageID": 7, "GeoCity": "Metropolis", "GeoLongitude": -77.0364, "GeoLatitude": 38.8951 }' ``` <Note> **Path Params** Change the `ParentActorID` with the unique identifier of the parent actor under which the new operator will be created. </Note> In the body parameters, fill in the following: | **Parameter** | `Type` | Description | | - | - | - | | **ParentActorID** | `int64/null` | The unique identifier of the parent actor is if this actor is a sub-entity. | | **ActorID** | `int64/null` | The unique identifier for the actor. | | **ActorDescription** | `string/null` | A brief description of the actor. | | **ActorCode** | `int64/null` | A code representing the actor is often used for identification or categorization. | | **ActorAddress** | `string/null` | The physical address associated with the actor. | | **ActorContact** | `string/null` | Contact information for the actor, such as a phone number or email. | | **ActorTypeID** | `int32/null` | The identifier represents the type of actor. | | **ActorStatus** | `int32/null` | The current status of the actor. | | **CurrencyID** | `int32/null` | The currency identifier used by the actor for transactions. | | **CountryID** | `int32/null` | The identifier for the country in which the actor is located. | | **ActorMerchantBit** | `boolean/null` | Indicates whether the actor is associated with a merchant. | | **ActorLanguageID** | `int32/null` | The language preference of the actor. | | **GeoCity** | `string/null` | The city where the actor is located. | | **GeoLongitude** | `double/null` | The geographic longitude of the actor's location. | | **GeoLatitude** | `double/null` | The geographic latitude of the actor's location. | | **ActorCreationDate** | `date-time/null` | The date and time when this actor was created. | A successful request will return a response with the created operator details. ## Verify creation You can check if your operator was correctly created in Nayax Core in the `Operators` menu. 1. Use the **Search** function to filter your operator. 2. Select it from the list. <Frame> <img /> </Frame> You can see all the operator information in the **Details** tab. # Nayax Hierarchy Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/operator/nayax-hierarchy Nayax uses a structured system to organize and manage entities, reflecting real-world business operations. This hierarchy is foundational for managing operators, machines, and other entities within the system. These entities are: * **Distributor**: The topmost entity in the hierarchy, representing a regional or country-level organization that manages multiple operators. Distributors oversee operations but cannot have a parent entity or be created via Lynx API. * **Operator**: A business or organization directly under a distributor. Operators manage their sub-hierarchies (areas, routes, machines) and handle inventory, machines, and user permissions. Operators cannot exist under another operator. * **Machine**: The physical vending machine containing inventory and sales data. Machines are assigned to specific routes or areas within the operator's hierarchy and are integral for tracking transactions and alerts. See an example of a hierarchy containing these entities in the following section. ## Hierarchy example The diagram below illustrates the hierarchy within Nayax, showing how entities are organized from the top level (Distributor) down to the lowest level (Machines). <Frame> <img alt="" /> </Frame> Where: * **Distributor**: The highest-level entity overseeing the entire structure. In this case, it manages two operators, Operator A and Operator B. * **Operator A** manages Areas A and B. Each contains routes that group machines for easier servicing. * Area A includes Route A with Machines 1 and 2 and Route B with Machines 3 and 4. * Area B includes Route C, managing Machine 5 and Machine 6. * **Operator B** manages Area C, which contains Route D with Machines 7 and 8. As you can see, machines are tied to specific routes, and routes are grouped under areas. Operators organize their hierarchy independently but remain under the Distributor’s oversight. <Note> **Lynx API Actors** In Nayax Core, the Operators and its types, such as "Area" and "Routes", are only nomenclatures that help you differentiate them. However, in Lynx API, they are all referred to as Actors, which are only differentiated by the `ActorTypeID`. </Note> ## Institutes Institutes in Nayax are unique entities parallel to operators, created directly under a distributor. They facilitate shared operations between multiple operators for specific locations or use cases, such as implementing unified prepaid card systems across multiple operators' machines. See the diagram below: <Frame> <img alt="" /> </Frame> Where: * At the top of the hierarchy, the Distributor oversees both institutes and operators. In this case, the distributor manages Operator A and a single Institute. * Institutes directly connect to the distributor and are not part of an operator's hierarchy. They are linked to locations, such as Location 1 (green) and Location 2 (red), which may contain machines serviced by one or more operators. Institutes enable machines from multiple operators to share a single prepaid card or payment system. For example, machines in Location 1 and another operator could use the same employee card system. This structure makes institutes valuable for collaborative operations between multiple operators, allowing flexibility and integration across locations. <br /> # Operator Actions Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/operator/operator-actions In Nayax Core, there are various actions that can be taken regarding Operators, such as updating or retrieving information of an operator, all of these are performed in the **Administration > Operators** menu. <Frame> <img /> </Frame> These actions can also be done through Lynx API programmatically using the following endpoints: <Columns> <EndpointCard title="Get Actor Details by ActorID" href="/reference/lynx/actors/get-actor-details-by-actorid" method="get" /> <EndpointCard title="Update Operator/Sub-Operator" href="/reference/lynx/actors/update-operatorsub-operator" method="put" /> </Columns> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens, and how to properly use it to authenticate your API requests. </Warning> ## Retrieve operator details [Get Actor Details by ActorID ](/reference/lynx/actors/get-actor-details-by-actorid)retrieves comprehensive information about a specific actor. This endpoint provides detailed attributes, including profile information and associated configurations, for the actor identified by the provided ActorID. <CodeGroup> ```sh Request theme={null} curl --request GET \ --url https://qa-lynx.nayax.com/operational/v1/actors/{ActorID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` ```json Response theme={null} { "ParentActorID": 0, "ActorID": 0, "ActorDescription": "string", "ActorCode": 0, "ActorAddress": "string", "ActorContact": "string", "ActorTypeID": 0, "ActorStatus": 0, "ActorHierarchyLevel": 0, "CurrencyID": 0, "LastUpdated": "2024-11-25T20:58:19.906Z", "RouteManagerName": "string", "RouteManagerMobile": "string", "TimeZoneKey": 0, "DayLightSavingsBit": true, "CountryID": 0, "DailyCCTransLimitPerCard": 0, "DailyPPTransLimitPerCard": 0, "DailyExternalPPTransLimitPerCard": 0, "DailyCCTransLimitPerCardPerOperator": 0, "OperatorActorID": 0, "DistributorActorID": 0, "AreaActorID": 0, "RouteActorID": 0, "ActorHierarchy": "string", "ActorHasChildrenBit": true, "ActorHasMachinesBit": true, "ActorImageURL": "string", "ActorContractInfo": "string", "ActorSQSID": 0, "UseProductGroupVATBit": true, "EreceiptTransactionEndEnableBit": true, "MaximumRevalueAmountLimit": 0, "ActorCreatedBy": 0, "ActorCreationDate": "2024-11-25T20:58:19.906Z", "UpdateBy": 0, "CultureID": 0, "RevaluePayoutByDistributor": true, "FiscalizationBit": true, "GeoCountryID": 0, "GeoState": "string", "GeoCity": "string", "GeoAddress": "string", "GeoStreetNumber": "string", "GeoLongitude": 0, "GeoLatitude": 0, "GeoZipCode": "string", "GeoZoom": 0, "ActorLanguageID": 2, "ActorMerchantBit": "string", "ActorMerchantNameForDescriptor": "string", "OverrideGeoInherritcanceBit": true, "AirportID": 0, "VerticalCustomJSON": "string", "FiscalizationActorID": 0, "SupportIncrementalAuth": true, "MaximumDefaultCredit": 0, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> <Note> **Path Params** Change `{ActorID}` with the actual Operator ID to retrieve the details from. </Note> The response will have the details of the requested operator. ## Update operator The [Update Operator/Sub-Operator](/reference/lynx/actors/update-operatorsub-operator) endpoint allows you to edit the information of the specified operator. <CodeGroup> ```sh Request theme={null} curl --request PUT \ --url https://qa-lynx.nayax.com/operational/v1/actors/{ActorID} \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ "ActorDescription": "Updated Main Branch", "ActorCode": 1002, "ActorAddress": "456 New Street, Metropolis", "ActorContact": "updated-contact@branch.com", "ActorTypeID": 16, "ActorStatus": 1, "CurrencyID": 840, "CountryID": 840, "GeoCity": "Metropolis", "GeoLongitude": -77.0364, "GeoLatitude": 38.8951 }' ``` ```json Response theme={null} { "ParentActorID": 0, "ActorID": 0, "ActorDescription": "string", "ActorCode": 0, "ActorAddress": "string", "ActorContact": "string", "ActorTypeID": 0, "ActorStatus": 0, "ActorHierarchyLevel": 0, "CurrencyID": 0, "LastUpdated": "2024-11-25T20:58:19.906Z", "RouteManagerName": "string", "RouteManagerMobile": "string", "TimeZoneKey": 0, "DayLightSavingsBit": true, "CountryID": 0, "DailyCCTransLimitPerCard": 0, "DailyPPTransLimitPerCard": 0, "DailyExternalPPTransLimitPerCard": 0, "DailyCCTransLimitPerCardPerOperator": 0, "OperatorActorID": 0, "DistributorActorID": 0, "AreaActorID": 0, "RouteActorID": 0, "ActorHierarchy": "string", "ActorHasChildrenBit": true, "ActorHasMachinesBit": true, "ActorImageURL": "string", "ActorContractInfo": "string", "ActorSQSID": 0, "UseProductGroupVATBit": true, "EreceiptTransactionEndEnableBit": true, "MaximumRevalueAmountLimit": 0, "ActorCreatedBy": 0, "ActorCreationDate": "2024-11-25T20:58:19.906Z", "UpdateBy": 0, "CultureID": 0, "RevaluePayoutByDistributor": true, "FiscalizationBit": true, "GeoCountryID": 0, "GeoState": "string", "GeoCity": "string", "GeoAddress": "string", "GeoStreetNumber": "string", "GeoLongitude": 0, "GeoLatitude": 0, "GeoZipCode": "string", "GeoZoom": 0, "ActorLanguageID": 2, "ActorMerchantBit": "string", "ActorMerchantNameForDescriptor": "string", "OverrideGeoInherritcanceBit": true, "AirportID": 0, "VerticalCustomJSON": "string", "FiscalizationActorID": 0, "SupportIncrementalAuth": true, "MaximumDefaultCredit": 0, "Refs": { "additionalProp": "string" } } ``` </CodeGroup> The body parameters are the same as used when [Creating an operator](/docs/manage-data-operations/lynx-api/operator/create-operator). <Note> **Path Params** Change `{ActorID}` with the actual Operator ID to update. </Note> The response will have the updated details of the requested operator. # Retrieve Hierarchy Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/operator/retrieve-hierarchy Nayax Core shows an operator's hierarchy in the **Operator** menu on the left sidebar. If you check its data, the **Company** section will detail its operator ID and Parent Operator. <Frame> <img /> </Frame> ## Lynx API You can also use Lynx API to programmatically retrieve the hierarchy of an Operator and its details by using the following endpoint: <EndpointCard title="Get Actor Hierarchy for Current User" href="/reference/lynx/actors/get-actor-hierarchy-for-current-user" method="get" /> ### Get operator hierarchy The [Get Actor Hierarchy for Current User](/reference/lynx/actors/get-actor-hierarchy-for-current-user) endpoint retrieves the hierarchy for the current user or a specified actor/operator and its child entities, such as areas, routes, and machines, by providing the `ActorID` in the query params of the request. See the example request in the code block below: ```sh theme={null} curl --request GET \ --url 'https://qa-lynx.nayax.com/operational/v1/actors/hierarchy?ActorID=<ID>' \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' ``` The available Query Params are: | Parameter | Description | | :- | :- | | `ActorID` | The unique ID of the operator or actor whose hierarchy you want to retrieve. | | `StatusID` | Filter the hierarchy to include only actors with a specific status. Use this to retrieve only active or inactive entities. | | `HierarchyLevelLimit` | Specify the maximum depth of the hierarchy to be returned. For example, 1 for immediate children and 2 for grandchildren. | <Note> **Lynx API Actors** In Nayax Core, the Operators and its types, such as "Area" and "Routes", are only nomenclatures that help you differentiate them. However, in Lynx API, they are all referred to as Actors, which are only differentiated by the `ActorTypeID`. </Note> ### Response With a successful request, the endpoint will return an array of Operator objects. See an example in the code block below: ```json theme={null} { "ParentActorID": 0, "ActorID": 12345, "ActorDescription": "Operator A", "ActorTypeID": 2, "ActorStatus": 1, "ActorHierarchyLevel": 0, "ActorChildren": [ { "ParentActorID": 12345, "ActorID": 23456, "ActorDescription": "Area A", "ActorTypeID": 3, "ActorStatus": 1, "ActorHierarchyLevel": 1, "ActorChildren": [ { "ParentActorID": 23456, "ActorID": 34567, "ActorDescription": "Route A", "ActorTypeID": 4, "ActorStatus": 1, "ActorHierarchyLevel": 2, "ActorChildren": [ { "ParentActorID": 34567, "ActorID": 45678, "ActorDescription": "Machine 1", "ActorTypeID": 5, "ActorStatus": 1, "ActorHierarchyLevel": 3, "ActorChildren": [] } ] } ] } ] } ``` As you can see above, this is the hierarchy for the Operator with the `ActorID: 12345` showing each of its children operators. The table below describes each of the response's body parameters: | Parameter | Description | | :- | :- | | `ParentActorID` | ID of the parent actor for the specified actor. | | `ActorID` | Unique ID of the current actor. | | `ActorDescription` | Description or name of the actor. | | `ActorTypeID` | Type of actor (e.g., Operator, Area, Route). | | `ActorStatus` | Status of the actor (e.g., active, inactive). | | `ActorHierarchyLevel` | The level of the actor within the hierarchy. | | `ActorChildren` | A list of child actor IDs or details for the current actor. | # FAQs Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/product-faqs This FAQ page addresses common questions and issues related to managing the product map and updates in the Lynx API. ## Why did updating only one product nullify the rest of my products? When you send an update request for a single product, it rewrites the entire product map. This means that if you don't include all the products and their current values in the request, the omitted products will be set to "null" or default values. To avoid this, you should always send the full list of products and make changes only to the specific product you want to update. ## Has the option to post product images been added? No, the option to post product images has not been added yet. However, it is still on the development roadmap and may be included in a future release. ## Will there be options for working with product map templates (creation, duplication, updates to machines)? Yes, options for working with product map templates are on the roadmap. However, these features will not be available in the near future. ## How can we reset/delete a machine’s product map through Lynx? The `MachineProductID` serves as the identifier for each line in the product map, allowing you to make changes to individual lines using it as a reference. However, you cannot "delete" or "reset" the entire product map technically. You can manually change the values for each line to your desired values, but the lines will still exist in the map. # Approve or Decline Refunds Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/refunds/approve-or-decline-a-refund When a refund is successfully requested, the transaction will remain in the **Pending** status until approved or declined. You can see this in Nayax Core by going to **Reports > Online Reports > Dynamic Transactions Monitor**. Follow the steps below: 1. Use the search feature to find the transaction. Then, choose **Refund Requested** to filter by **Status**. 2. Right-click the transaction in the list. 3. Click **Approve/Decline Refund**. <Frame> <img /> </Frame> 4. A pop-up window will appear. Click **Decline Refund** or **Approve Refund**. <Frame> <img /> </Frame> ## Lynx API This process can be done through the Lynx API using the endpoints below. <Columns> <EndpointCard title="Approve a Payment Refund" href="/reference/lynx/payment/approve-payment-refund" method="post" /> <EndpointCard title="Decline a Payment Refund" href="/reference/lynx/payment/decline-a-payment-refund" method="post" /> </Columns> <br /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> ### Approve request Use the Approve Payment Refund endpoint to approve the refund. The code block below shows the request object and its body parameters: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/payment/refund-approve \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "IsRefundedExternally": true, "RefundDocumentUrl": "string", "TransactionId": 0, "SiteId": 0, "MachineAuTime": "2024-10-10T16:30:37.179Z" } ' ``` See the table below for more details on each parameter: <table> <thead> <tr> <th> **Name** </th> <th> **Type** </th> <th> **Description** </th> </tr> </thead> <tbody> <tr> <td> **IsRefundedExternally** </td> <td> `boolean` </td> <td> It is used when the customer contacts the billing provider for a refund. In that case, this flag is set to true, and the file received by the billing provider is added to the `RefundedDocumentUrl`. </td> </tr> <tr> <td> **RefundDocumentUrl** </td> <td> `string` </td> <td> If `IsRefundedExternally` is set to `true`, the URL for the refund document from the billing provider needs to be added here. See [Upload Refund Documentation](/docs/manage-data-operations/lynx-api/refunds/upload-refund-document) for more details on uploading the document and getting the URL. </td> </tr> <tr> <td> **TransactionId** </td> <td> `int64` </td> <td> The unique identifier of the transaction for which the refund is being approved. </td> </tr> <tr> <td> **SiteId** </td> <td> `int32` </td> <td> The unique identifier of the site where the transaction occurred. </td> </tr> <tr> <td> **MachineAuTime** </td> <td> `date-time` </td> <td> The machine's authorization time is associated with the transaction </td> </tr> </tbody> </table> <Warning> The `TransactionId`, `SiteId` and `MachineAuTime` need to be the same as sent in the refund request. </Warning> ### Decline request To decline a refund, use the Decline a Payment Refund endpoint. The code block below displays the request object and its body parameters. ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/payment/refund-decline \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "DeclineReason": "string", "TransactionId": 0, "SiteId": 0, "MachineAuTime": "2024-10-10T16:30:37.179Z" } ' ``` See the table below for more details on each parameter: | **Name** | **Type** | **Description** | | - | - | - | | **DeclineReason** | `string` | The reason for declining the refund request. | | **TransactionId** | `int64` | The unique identifier of the transaction for which the refund is being declined. | | **SiteId** | `int32` | The unique identifier of the site where the transaction occurred. | | **MachineAuTime** | `date-time` | The machine's authorization time is associated with the transaction. | <Warning> The `TransactionId`, `SiteId` and `MachineAuTime` need to be the same as the one sent in the refund request. </Warning> ## Request status Once the request is approved or denied, the consumer will receive an email at the address provided in the refund request. The request status will also be updated. You can see this in Nayax Core by going to **Reports > Online Reports > Dynamic Transactions Monitor**. # Request Refunds Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/refunds/request-refunds The refund process begins by submitting a request with details such as the refund amount and reason. This notifies the customer that the refund is being processed. We will describe this process in more detail on this page. <Warning> **Credit Cards Only** Refunds can only be requested for transactions done through Credit Card. This option is not available for prepaid cards. </Warning> In Nayax Core, refunds can be requested through the **Dynamic Transactions Monitor**. Follow the steps below to do so. 1. Access **Reports > Online Reports > Dynamic Transactions Monitor**. 2. Search for the transaction to refund. You can use the filter feature to make this easier. 3. Right-click the transaction you want to refund. 4. Click **Request Refund** <Frame> <img /> </Frame> 5. A pop-up window will appear. In it, choose if the refund is complete or partial and write the reason for the refund. 6. Click **Request Refund**. <Frame> <img /> </Frame> ## Lynx API This process can be performed programmatically through the Lynx API. The following endpoint is used to process the refund. <EndpointCard title="Request a Payment Refund" href="/reference/lynx/payment/request-a-payment-refund" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> ### Initiating the request To start the request, use the [Request a Payment Refund](/reference/lynx/payment/request-a-payment-refund) endpoint to request a refund. Providing the attributes regarding the rebate in the body parameters of the request, as exemplified below: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/payment/refund-request \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "RefundAmount": 0, "RefundEmailList": "string", "RefundReason": "string", "TransactionId": 0, "SiteId": 0, "MachineAuTime": "2024-10-10T16:30:37.179Z" } ' ``` Below, you can see a description of each of the parameters: | **Name** | **Type** | **Description** | | :- | :- | :- | | **RefundAmount** | `double / null` | The amount to be refunded to the customer. | | **RefundEmailList** | `string / null` | A list of email addresses to notify about the refund, separated by commas. | | **RefundReason** | `string / null` | The reason for requesting the refund. | | **TransactionId** | `int64` | The unique identifier of the transaction for which the refund is requested. | | **SiteId** | `int32` | The unique identifier of the site where the transaction occurred. | | **MachineAuTime** | `date-time` | The machine's authorization time is associated with the transaction. | ### How to obtain TransactionID and SiteID Retrieve `TransactionId` and `SiteId` from the Lynx API using the [Get Last Sales for Machine](/reference/lynx/machines/get-last-sales-for-machine-by-machineid) endpoint with the `MachineID`. The response object includes both values. ## Request status Once you send the request, a notification email will be sent to the email address entered in the request parameters. The refund is now in the `pending` status and will need to be approved or declined. See [Approve or Decline a Refund](/docs/manage-data-operations/lynx-api/refunds/approve-or-decline-a-refund) for more details. # Upload Refund Documentation Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/refunds/upload-refund-document In cases where the customer contacts the billing provider directly for a refund, the `IsRefundedExternally` has to be set to `true` when accepting the refund and the file received by the billing provider added in the `RefundedDocumentUrl`. In Nayax Core, this is set when accepting or declining a refund by selecting **Refunded Externally**. You can upload the refund document. See the image below: <Frame> <img /> </Frame> ## Lynx API With Lynx API you can also upload the refund documentation to get the `RefundedDocumentUrl`. The endpoint below is used for this: <EndpointCard title="Upload Refund Documentation" href="/reference/lynx/payment/upload-refund-documentation" method="post" /> <Warning> **Authentication** Refer to the [Security & Token](/docs/manage-data-operations/lynx-api/security) page of this documentation to learn how to access your tokens and how to properly use them to authenticate your API requests. </Warning> Use the [Upload Refund Documentation](/reference/lynx/payment/upload-refund-documentation) endpoint to upload the file received by the billing provider. See the request example below: ```sh Request theme={null} curl --request POST \ --url https://qa-lynx.nayax.com/operational/v1/payment/upload-refund \ --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "FileName": "string", "FileData": "string", "TransactionId": 0, "SiteId": 0, "MachineAuTime": "2024-10-10T16:30:37.179Z" } ' ``` The table below details the body parameters of the request. | **Name** | **Type** | **Description** | | - | - | - | | FileName | string | The name of the file being uploaded. | | FileData | base64 | The base64-encoded content of the file being uploaded. You can use a [PDF to base 64 online convertor](https://base64.guru/converter/encode/pdf). | | TransactionId | int64 | The unique identifier of the transaction associated with the file. | | SiteId | int32 | The unique identifier of the site where the transaction occurred. | | MachineAuTime | date-time | The machine's authorization time is associated with the transaction. | <Note> The `TransactionId`, `SiteId` and `MachineAuTime` need to be the same as sent in the refund request. </Note> Once the request is done successfully, the response will contain a URL with the uploaded document. ```json Response theme={null} { "FileURL": "string" } ``` Now you can add this URL to the `RefundedDocumentUrl` flag when using the [Approve Refund](/docs/manage-data-operations/lynx-api/refunds/approve-or-decline-a-refund) endpoint. # Widgets ID List Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/available-widgets The **Widget Type ID** is a unique numeric identifier for each widget. It is the primary key required for all API data requests as the `widget_type_id` parameter specifies exactly which widget you want to pull data from within your application code. The tables below list all available widget IDs, organized by scope. Select your use case to find the ID you need. <Accordion title="Operator/actor level (multi-machine data)"> These widgets provide a "big picture" view of your entire business or specific groups of machines. | ID | Widget Name | | :- | :- | | `2` | Last 30 Days Sales Chart | | `3` | [Last Year vs This Year Monthly Sales](/docs/manage-data-operations/lynx-api/reports/widget-last-year-vs-this-year) | | `5` | Top Events For Period | | `6` | KeepAlives For Period | | `20` | Machines On Map | | `22` | [(Operator) 10 Most Popular Machines Sales/Vends](/docs/manage-data-operations/lynx-api/reports/widget-10-most-popular-machines) | | `23` | (Both) Machines Rating | | `24` | 10 Least Popular Machines Sales/Vends | | `33` | Sales/Vend By Products For Period | | `43` | Dashboard Active Machines Boxes | | `53` | [Dashboard Sales Table](/docs/manage-data-operations/lynx-api/reports/widget-dashboard-sales-table) | | `193` | [Sales By Period](/docs/manage-data-operations/lynx-api/reports/widget-sales-by-period) | | `244` | Machines Alert | | `331` | Gross Profit / Gross Margin | | `333` | Product Sales By Period | | `335` | Product Performance | | `350` | Machines Without Visit For Period | | `351` | Machines Without Cash Sale For Period | | `352` | Machines Without Cashless Sale For Period | | `353` | Machines Stock Level | | `355` | Prepaid Cards Summary | | `396` | New Existing Consumers | </Accordion> <Accordion title="Machine level (single machine data)"> These widgets focus on the "health" and performance of one specific unit. | ID | Widget Name | | :- | :- | | `4` | Machine Status | | `7` | Machine Last Visited KPI | | `8` | Machine Cashbox Level KPI | | `9` | Machine Stock Level - On Hand / PAR KPI | | `11` | Machine Days Since Last Cashless Transaction KPI | | `12` | Machine Days Since Last Cash Transaction KPI | | `13` | Machine Number of Empty Selections KPI | | `21` | (Machine) Vpos Existing / Requested FW Version KPI | | `23` | Last 24 Hourly Sales/Vends | | `26` | EV Machine Sales | | `27` | Ev Charger Status | | `31` | Sales Since Last Visit | | `32` | Sales/Vend By Products Since Last Visit | | `63` | Device Existing / Requested FW Version KPI | | `73` | Days Since Last DEX Read KPI | | `83` | Last Heartbeat KPI | | `93` | Change Tube Status KPI | | `103` | Time Since Last VMC Error KPI | | `330` | Product Map Suggestions | | `334` | Product Performance | | `376` | Products Heatmap | </Accordion> # Reports Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/index To monitor operational performance and financial metrics, such as sales trends and machine health, go to **Reports > Dashboard** in **[Nayax Core](https://qa.nayax.com/core/public/f?model=reports/dashboard)**. This page provides a customizable view of your business through various dashboards and data widgets. <Frame> <img /> </Frame> Widgets and dashboards serve two main levels within the Nayax Core platform: * **Actor (Operator) Level**: It consolidates data from all machines operated by a specific Actor or Operator. * **Machine Level**: It shows data relevant only to a single machine. <Check> You can also use the Lynx API to retrieve the raw data from these widgets in a structured format (JSON). See [Get Machine Widget Data Using the API](/docs/manage-data-operations/lynx-api/reports/retrieve-machine-widget-data) to learn more. </Check> <br /> # Revenue Per Machine: Integration Guide Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/integration-guide A step-by-step guide to retrieving revenue data broken down per machine, per day, and per month using the Widgets Dashboard API. The Widgets Dashboard API lets you retrieve revenue data broken down per machine, per day, and per month. For filter and field reference, see [Widget Filters Reference](/docs/manage-data-operations/lynx-api/reports/widget-filters). All requests require a valid access token in the `Authorization` header. See [Security & Token](/docs/manage-data-operations/lynx-api/security) to learn how to retrieve and use yours. ## Discover widget IDs Call the list-widgets endpoint to see all available widgets and their IDs: ```bash theme={null} curl -X GET "https://<host>/operational/v1/dashboard/widgets?screenTypeId=1" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` From the response, identify the `widgetTypeId` values for revenue-related widgets (look for names containing "Revenue", "Sales", or similar). ## Revenue per machine per day Use the `groupBy: day` filter with a date range to retrieve daily revenue totals: ```bash theme={null} curl -X POST "https://<host>/operational/v1/dashboard/get-widget-data" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "screenTypeId": 1, "widgetTypeId": 193, "entityId": <operatorId>, "filters": [ { "name": "startDate", "value": "2025-01-01", "type": "Date" }, { "name": "endDate", "value": "2025-01-31", "type": "Date" }, { "name": "groupBy", "value": "day", "type": "string" } ] }' ``` ## Revenue per machine per month Switch `groupBy` to `month` and widen the date range to retrieve monthly revenue totals: ```bash theme={null} curl -X POST "https://<host>/operational/v1/dashboard/get-widget-data" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "screenTypeId": 1, "widgetTypeId": 193, "entityId": <operatorId>, "filters": [ { "name": "startDate", "value": "2025-01-01", "type": "Date" }, { "name": "endDate", "value": "2025-12-31", "type": "Date" }, { "name": "groupBy", "value": "month", "type": "string" } ] }' ``` ## Revenue for a specific machine Pass the machine ID via `entityId` (if the widget is machine-scoped) or via the `MachineId` filter: ```bash theme={null} curl -X POST "https://<host>/operational/v1/dashboard/get-widget-data" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "screenTypeId": 1, "widgetTypeId": 193, "entityId": null, "filters": [ { "name": "startDate", "value": "2025-01-01", "type": "Date" }, { "name": "endDate", "value": "2025-12-31", "type": "Date" }, { "name": "MachineId", "value": "<machineId>","type": "int" }, { "name": "groupBy", "value": "day", "type": "string" } ] }' ``` <Note> The exact filter names and `groupBy` values supported by a widget depend on its stored procedure in Cortex Reports. If a filter name is not recognized, it is silently ignored. Test with and without each filter and compare responses. </Note> # Get Machine Widget Data (API) Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/retrieve-machine-widget-data The Widgets Dashboard APIs let you discover which widgets are available for a given screen and fetch the data for each individual widget. ## Prerequisites Before making calls to the Widget API, you need to have: * Access to the Lynx QA or Production environment * A valid API token (See [Security & Token](/docs/manage-data-operations/lynx-api/security)) * [Machines](/reference/lynx/machines/get-specific-machine-basic-info) or [Operator](/docs/manage-data-operations/lynx-api/operator/index) IDs ## Base URL ```text theme={null} https://<host>/v1/dashboard ``` <Note> If the server is configured with `UseBasePath: true`, all routes are prefixed with `/operational`: ```text theme={null} https://<host>/operational/v1/dashboard ``` </Note> ## Authentication All endpoints require authentication via JWT bearer token. Include the token in every request: ```text theme={null} Authorization: Bearer <YOUR_ACCESS_TOKEN> ``` See [Security & Token](/docs/manage-data-operations/lynx-api/security) for details on obtaining a token. ## Available endpoints The following endpoints are available. Select a card to view the full API reference. <CardGroup> <Card icon="grid" title="List widgets for a screen" href="/reference/lynx/report/get-available-widgets"> Returns all widgets configured for a given screen type, including their IDs, names, and configurations. </Card> <Card icon="chart-line" title="Retrieve widget data" href="/reference/lynx/report/retrieve-widget-data"> Fetches data for a specific widget with full filter support (date range, machine ID, etc.). **Recommended for most use cases.** </Card> </CardGroup> <Note> The GET simple variant (`GET /v1/dashboard/widget-data`) is not included in the API reference as it is not defined in the OpenAPI spec. Use the POST variant for filter support and full API reference coverage. </Note> ## Typical integration flow A standard integration follows three steps: discover available widgets, fetch their data with optional filters, then parse the response payload. ```text theme={null} 1. GET /v1/dashboard/widgets?screenTypeId=1 → Discover available widgets and their widgetTypeId values 2. POST /v1/dashboard/get-widget-data (recommended - supports filters) OR GET /v1/dashboard/widget-data (simple - no filter support) → Fetch widget data, optionally scoped by entity and filtered by date/machine 3. Parse the response: - widgetDetails.widgetConfig → rendering hints - data → actual data payload (structure varies per widget) ``` ## Error handling The following HTTP status codes may be returned by the widget endpoints: | HTTP Status | Cause | | - | - | | `400` | Missing required field, invalid parameter value | | `401` | Missing or expired bearer token | | `403` | Authenticated but missing the required permission key for this endpoint | | `500` | Backend error - common causes: wrong `Content-Type` header (use `application/json`), invalid `widgetTypeId`, or an unrecognized filter format | ## Permissions Each endpoint requires the authenticated user to have a specific menu permission assigned in Lynx. Permissions are checked by the `GetContext()` middleware on every request: | Endpoint | Permission Key | OAuth Scope | | - | - | - | | `GET /v1/dashboard/widgets` | `lynx_report_get_widgets` | `report:read` | | `POST /v1/dashboard/get-widget-data` | `lynx_report_get_widget_data` | `report:read` | | `GET /v1/dashboard/widget-data` | `lynx_report_get_widget` | `report:read` | <Note> `GET /v1/dashboard/widget-data` requires `lynx_report_get_widget`, which is separate from `lynx_report_get_widget_data` (the POST variant). If you have access to the POST endpoint but receive a `403` on the GET endpoint, request the `lynx_report_get_widget` permission in your Lynx role configuration. </Note> # 10 Most Popular Machines Sales/Vends Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widget-10-most-popular-machines A bar chart widget ranking the top-performing machines in your fleet by sales and vend volume. The **10 Most Popular Machines Sales/Vends** widget provides a ranking of the top-performing machines in your fleet. It allows operators to quickly identify high-traffic locations and the most profitable units based on their sales volume. <Frame> <img /> </Frame> This is the information available through this widget: 1. **Machine Name (Y-Axis)**: Lists the specific names or IDs of the top-performing machines. 2. **Sales Volume (X-Axis)**: A horizontal bar chart representing the comparative success of each machine. 3. **Time Period Label**: Shows the currently selected reporting window (e.g., Yesterday). <Accordion title="Filters"> * **Chart Style**: Choose the data visualization format, such as a bar chart. * **Category Axis Major Grid Line**: A toggle to show or hide vertical background lines for better readability. * **Include Cash**: A checkbox to add or remove physical cash transactions from the machine's totals. * **Time Period**: Defines the date range for the ranking, such as Yesterday, Last 7 Days, or Last 30 Days. <Frame> <img /> </Frame> </Accordion> # Dashboard Sales Table Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widget-dashboard-sales-table A table widget providing a numeric breakdown of revenue and transaction counts across standard reporting windows. The **Dashboard Sales Table** provides a detailed numeric breakdown of performance by period. It allows operators to see exact revenue and vend counts for specific timeframes at a glance. <Frame> <img /> </Frame> This is the information available through this widget: 1. **Time Period**: Breaks down data into standard reporting windows: Today, This Week, Last Week, This Month, Last Month, This Year, and Last Year. 2. **Sales**: Shows the monetary value earned, categorized by payment method (e.g., Credit Card) and a total for that period. 3. **Transactions**: Lists the total count of individual vends made, categorized by payment method, and a total for that period. # Widget Filters Reference Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widget-filters Field reference for widget parameters, filter names, and filter types used with the Widgets Dashboard API. This page covers the field reference for widget parameters and filters used when calling the Widgets Dashboard API endpoints. ## Field reference ### ScreenTypeId values `screenTypeId` identifies which dashboard screen context the widget belongs to: | Value | Screen | Description | | - | - | - | | `1` | Reports / Dashboard | The main operator-level reporting dashboard | | `2` | Operations / Machine | The machine-level operations screen | Use `screenTypeId=1` for revenue, sales, and summary widgets. Use `screenTypeId=2` for per-machine operational widgets. ### EntityId `entityId` scopes the widget data to a specific entity. The meaning depends on the widget type: * **Operator-level widgets**: pass the **Operator ID** (ActorID) * **Machine-level widgets**: pass the **Machine ID** * **Omit or pass `null`** to retrieve data across all entities the authenticated user has access to ### WidgetTypeId Obtain the list of valid widget type IDs for a given screen by calling: ```text theme={null} GET /v1/dashboard/widgets?screenTypeId=1 ``` Each item in the response array contains `widgetTypeId` and `widgetName`. Use the name to identify which widget you need, then use its ID in subsequent data requests. The IDs are defined in the Cortex Reports service database and may vary by environment. <Note> See the complete [Widgets ID List](/docs/manage-data-operations/lynx-api/reports/available-widgets) for a reference table of all known widget IDs. </Note> <Warning> The Devzone reference page for "Retrieve Widget Data" uses `widgetTypeId: 5` ("Top Events For Period") in its example, but presents it as if it were a revenue widget. This is incorrect. Use `GET /v1/dashboard/widgets` to discover the correct `widgetTypeId` for revenue widgets in your environment (commonly ID `19`). </Warning> ### Filter names Filter names are widget-specific. The following are commonly used across revenue and reporting widgets: | Name | Description | Example Value | | - | - | - | | `startDate` | Start of the date range (inclusive) | `"2025-01-01"` | | `endDate` | End of the date range (inclusive) | `"2025-12-31"` | | `TimePeriod` | Pre-defined time period in days (alternative to date range) | `"30"` | | `MachineId` | Filter data for a specific machine | `"98765"` | | `groupBy` | Grouping granularity | `"day"` / `"month"` | <Warning> `startDate`/`endDate` and `TimePeriod` are mutually exclusive - providing both may result in an error. Use one approach per request. </Warning> <Note> **MachineId via `entityId` vs filter**: Some widgets accept the machine ID through the `entityId` field; others accept it as a `MachineId` filter entry. If the widget is scoped to the machine screen (`screenTypeId=2`), prefer `entityId`. If it is a dashboard widget (`screenTypeId=1`), use the `MachineId` filter. The exact behavior depends on the widget's stored procedure implementation. </Note> ### Filter types The `type` field in a filter is a hint used by the backend to parse the `value` string: | Type | Description | | - | - | | `"Date"` | ISO 8601 date string (`YYYY-MM-DD`) | | `"int"` | Integer value | | `"string"` | Free-text string | ## Multiple filters in one request The `filters` field is an array - multiple filters can be combined in a single request. For example, filtering by date range, machine ID, and grouping in one call: ```json theme={null} { "screenTypeId": 1, "widgetTypeId": 19, "entityId": null, "filters": [ { "name": "startDate", "value": "2025-01-01", "type": "Date" }, { "name": "endDate", "value": "2025-12-31", "type": "Date" }, { "name": "MachineId", "value": "98765", "type": "int" }, { "name": "groupBy", "value": "day", "type": "string" } ] } ``` The filters are forwarded to the Cortex Reports service, which applies them in the stored procedure for that widget type. ## Notes * The shape of the `data` field in `WidgetDataResponseDto` is dynamic and varies per widget type. * Widget type IDs are defined in the Cortex Reports service database and map to screen types via the `widget_dashboard_compatibility` column (`ScreenTypeId`). * The Lynx API acts as an authenticated pass-through proxy to Cortex Reports. It does not modify or validate filter contents beyond basic deserialization. # Last Year vs This Year Monthly Sales Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widget-last-year-vs-this-year A chart widget comparing monthly sales performance between the current and previous year to track business growth and seasonal trends. The **Last Year vs This Year Monthly Sales** widget provides a high-level visual comparison of sales performance across two years. It helps operators track long-term business growth and seasonal trends. <Frame> <img /> </Frame> This is the information available through this widget: 1. **Timeframe (X-Axis)**: Shows a breakdown by month (e.g., Feb, Mar, Apr, etc.). 2. **Revenue Scale (Y-Axis)**: Shows the total value of sales in the local currency (e.g., zł - Polish złoty). 3. **Comparative Data**: Visualizes how current monthly performance stacks up against the same period in the previous year. <Accordion title="Filters"> * **Last 12 Months Chart Style**: Choose the data visualization format for the current period: line, column, or area. * **Previous Last 12 Months Chart Style**: Choose the data visualization format for the comparison period: line, column, or area. * **Category Axis Major Grid Line**: A toggle to show or hide vertical background grid lines. * **Value Axis Major Grid Lines**: A toggle to show or hide horizontal background grid lines for better value readability. * **Include Cash**: A checkbox to add or remove physical cash transactions from the totals. * **Payment Method**: A dropdown to filter the data by a specific provider or type, such as Credit Card, Prepaid Credit, or others. </Accordion> <Frame> <img /> </Frame> # Sales By Period Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widget-sales-by-period A bar chart widget showing revenue generated across your fleet or a specific set of machines over a selected time period. The **Sales By Period** widget shows a bar chart of revenue generated across your fleet or a specific set of machines. It allows operators to identify sales trends, peak performance days, and transaction volume at a glance. <Frame> <img /> </Frame> 1. **Time Dimension (X-Axis)**: Shows a daily breakdown of the selected timeframe, such as the last 30 days. 2. **Revenue Scale (Y-Axis)**: Shows the total value of sales in the local currency, such as zł - Polish złoty. 3. **Legend**: Categorizes sales by payment method. In this view, it is tracking Credit Card transactions (indicated by the blue bars). <Accordion title="Filters"> * **Chart Style**: Choose the data visualization format: column, area, or line. * **Category Axis Major Grid Line**: A toggle to show or hide vertical background lines for better readability. * **Include Cash**: A checkbox to add or remove physical cash transactions from the totals. * **Split Payment Method**: An option to see separate bars/lines for different payment types (Cash vs. Credit Card) rather than one combined total. * **Payment Method**: A dropdown to filter the entire widget by a specific provider or type. * **Time Period**: Defines the date range for the data, such as Last 30 Days. <Frame> <img /> </Frame> </Accordion> # Dashboard Widgets Overview Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/reports/widgets-overview Widgets are visual components on the Lynx Reports dashboard that display machine and operator data. Widgets are visual components that show specific customized data to meet your business needs. You can find these widgets on **Reports > Dashboard**. There are widgets available at two levels: * **Operator/Actor Level:** Widgets that gather data from multiple machines. * **Machine Level:** Widgets that show data specific to a single machine. <Note> Every widget has its own unique identifier (`widget_type_id`), filters, and other configuration options. See the [Widgets ID List](/docs/manage-data-operations/lynx-api/reports/available-widgets) for a full reference. </Note> ## Documented Widgets <CardGroup> <Card title="Sales By Period" href="/docs/manage-data-operations/lynx-api/reports/widget-sales-by-period"> Bar chart showing revenue generated across your fleet over a selected time period. </Card> <Card title="Dashboard Sales Table" href="/docs/manage-data-operations/lynx-api/reports/widget-dashboard-sales-table"> Numeric breakdown of revenue and transaction counts by reporting window. </Card> <Card title="Last Year vs This Year Monthly Sales" href="/docs/manage-data-operations/lynx-api/reports/widget-last-year-vs-this-year"> Visual comparison of monthly sales performance between the current and previous year. </Card> <Card title="10 Most Popular Machines Sales/Vends" href="/docs/manage-data-operations/lynx-api/reports/widget-10-most-popular-machines"> Ranking of the top-performing machines in your fleet by sales and vend volume. </Card> </CardGroup> ## General Widget Actions These options appear on the right side of every widget and offer additional controls. <Frame> <img /> </Frame> 1. The **Dropdown Arrow** button offers the following options: <Accordion title="Options"> * **Lock Widget**: Secures the widget in its current position on the dashboard to prevent accidental moving or resizing. * **Export**: Allows you to download the widget's raw data in PDF format for external reporting. * **Remove Widget**: Deletes the widget from your current dashboard view. </Accordion> 2. **Currency Toggle**: The bill/money icon opens a sub-menu that allows you to change the currency in the widget. 3. **Resize Tool**: Located in the bottom-right corner of the widget, this icon lets you click and drag to resize the widget on your dashboard. # Create Sandbox Account Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/request-access Submit the Lynx integration request form to receive your sandbox credentials and start building. To build with the Lynx API, you need a sandbox account provisioned by Nayax. ## Submit the request form You need an Operator ID in Nayax Core to complete the form. If you do not have access to Nayax Core, contact your Nayax case manager or sales representative. Go to [lynx-integration-request.nayax.com](https://lynx-integration-request.nayax.com) and complete the two-step form. <Steps> <Step title="Fill in your integration details"> Enter the following information: | Field | Description | | - | - | | **Country** | Your country of operation | | **First Name** | Your first name | | **Last Name** | Your last name | | **Email Address** | The email address for your developer account | | **Business Name** | Your company or organization name | | **Operator ID in Nayax Core** | Your numeric Operator ID | <Accordion title="How to find your Operator ID in Nayax Core"> 1. Open Nayax Core and go to **Operator** in the left sidebar. 2. Select an entry from the list and click **Search**. 3. Your ID is listed under **Company Info** as **Operator Id**. </Accordion> Check the box to confirm you agree to the [Privacy Policy](https://www.nayax.com/legal/nayax-general-privacy-policy/). Then return to the email field and click **Send Code**. Nayax sends a one-time verification code to the email address you entered. Enter the code to verify your email. Click **Continue to Terms & Conditions**. </Step> <Step title="Review and sign the terms and conditions"> Read the General Terms and Conditions for Professional Services (v. 1.05), then complete the signature section: | Field | Description | | - | - | | **Business Name** | Your company or organization name | | **Title** | Your job title | | **First Name and Last Name** | Your full name | | **Email Address** | The email address you verified in the previous step | | **Digital signature** | Your drawn or typed signature | Click **Sign and Submit** to complete the request. </Step> </Steps> Your request is submitted. If you have a problem with the form, email [integration-support@nayax.com](mailto:integration-support@nayax.com). ## What to expect after submitting Nayax processes your request automatically. After submitting, you will receive a welcome email containing: * Integration instructions for the Lynx API * Access credentials for the Nayax Core sandbox environment * Links to the sandbox Lynx platform Nayax provisions your sandbox account with a standalone hierarchy and full Lynx platform permissions. When the credentials arrive, use them to retrieve your access token. # Security & Token Source: https://devzone.nayax.com/docs/manage-data-operations/lynx-api/security The Lynx API requires an access token to authenticate requests securely. ## Choose a token type Which token you need depends on who's calling the API. | Token | Use it for | Scope | Get one | | - | - | - | - | | Access token | Your own requests to the Lynx API | Full account access | See [Access token](#access-token) below | | App token | Requests from your downstream customers or integrations | Limited by a Nayax admin to exactly what the integration needs | See [App Tokens (JWT)](/docs/manage-data-operations/lynx-api/app-tokens) | ## Access token An access token is a security credential used to authenticate API requests. Each request to the Lynx API must include a valid access token in the `Authorization` header. This access token is also known as an API key or API token, and appears as a User Token in Nayax Core. <Warning> **Keep your tokens safe** It is important to avoid sharing your secret tokens in public places like GitHub or Bitbucket since it can allow malicious API calls. </Warning> Follow these steps in the Nayax Back Office (Nayax Core) to find and copy an access token: <Steps> <Step title="Log in to Nayax Core"> Use your username and password. </Step> <Step title="Navigate to Account Settings"> Click your username in the top right corner, then select **Account Settings**. <Frame> <img /> </Frame> </Step> <Step title="Open the Security and Login tab"> It's the second tab, next to **Account**. <Frame> <img /> </Frame> </Step> <Step title="Find the User Tokens section"> It's below **Your Trusted Devices**. <Frame> <img /> </Frame> </Step> <Step title="Show and copy the token"> Click **Show Token** next to an existing token to reuse it, then copy it for use in API calls. If no token exists yet, click **Add Token** and select **Lynx Token** instead. <Frame> <img /> </Frame> </Step> </Steps> You now have an access token you can send as a Bearer credential on Lynx API requests. ## Use the token in API requests Include the access token in the `Authorization` header for each API request: ```sh theme={null} curl -X GET "https://qa-lynx.nayax.com/operational/v1/devices" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" ``` Replace `<YOUR_ACCESS_TOKEN>` with your actual token retrieved from Nayax Core. <Note> **Environments** This example uses the QA base URL. See [Environments](/docs/manage-data-operations/lynx-api/lynx-overview#environments) on the Lynx overview page for the full list of base URLs. </Note> ## See also * [Lynx overview](/docs/manage-data-operations/lynx-api/lynx-overview) for the full list of environment base URLs # Get Actor Details by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-details-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID} This endpoint retrieves comprehensive information about a single actor. You must specify the actor's unique identifier, `ActorID`, in the request path to obtain their full profile, including attributes. # Update Operator/Sub-Operator Source: https://devzone.nayax.com/reference/lynx/actors/update-operatorsub-operator /openapi/lynx.yaml put /v1/actors/{ActorID} Updates the details of an existing actor (operator or sub-operator) identified by `ActorID`. The request body must contain the updated attributes for the actor. # Actor Types Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/actor-types The `ActorTypeID` parameter specifies the type of sub-operator creation in the Nayax Lynx system. The following table lists the possible values: | Value | Actor Type | | - | - | | 5 | Area | | 6 | Route | | 7 | City | | 8 | State | | 9 | Province | | 10 | Region | | 11 | Client | | 12 | Facility Management | | 13 | Location (General) | | 14 | Customer (General) | | 15 | District | | 16 | Account | | 17 | Branch | | 18 | Terminal | | 19 | Floor | | 20 | Zone | | 21 | Airport | | 22 | Gate | | 23 | eCommerce | | 24 | Bus | | 25 | Train | | 26 | Tramway | | 27 | EV Infrastructure | # Cards Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/cards ## CardTypeID The `CardTypeID` parameter identifies the type of card being used. The following table lists the possible values: | Value | Description | | - | - | | 33 | Prepaid Card | | 31 | Technician Card | | 34 | Refund Card | | 30000616 | Discount Card | ## PhysicalTypeID The `PhysicalTypeID` parameter specifies the physical form of the card. The following table lists the possible values: | Value | Description | | - | - | | 30000528 | Swipe Card | | 30000529 | Contact Card | | 30000530 | Contactless Card | | 30000531 | Contactless Sticker | | 943237560 | QR Code | ## MemberTypeID The `MemberTypeID` parameter identifies the membership tier or type associated with a cardholder. The following table lists the possible values: | Value | Description | | - | - | | 800 | Bronze | | 801 | Silver | | 802 | Gold | | 803 | Platinum | | 804 | Diamond | | 805 | Emerald | | 812 | Personal | # Languages Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/languages The following table lists the `LanguageID` values and their corresponding languages supported in the Nayax Lynx API: | Value | Language | | - | - | | 62 | Arabic | | 81 | Bulgarian | | 22 | Chinese | | 52 | Czech | | 17 | Danish | | 21 | Dutch | | 7 | English | | 31 | English UK | | 42 | Estonian | | 54 | Finnish | | 8 | French | | 28 | German | | 30 | Greek | | 4 | Hebrew | | 23 | Hungarian | | 13 | Icelandic | | 16 | Italian | | 29 | Japanese | | 34 | Latvian | | 64 | Lithuanian | | 11 | Norwegian | | 18 | Polish | | 14 | Portuguese | | 9 | Romanian | | 12 | Russian | | 41 | Slovenian | | 15 | Spanish | | 10 | Swedish | | 27 | Thai | | 2 | Turkish | | 51 | Vietnamese | # Machine Types Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/machine-types The `MachineTypeID` parameter determines the icon displayed next to your virtual machine in Nayax Core. The following table lists the available values and their corresponding machine types: | Value | Machine Type | | - | - | | 555001 | Safe | | 555002 | Cash Register | | 555003 | Car Accessories | | 555004 | Donation Station | | 555005 | Transportation | | 555006 | Micro Markets | | 555007 | OCPP Electrical Vehicle | | 555008 | Parking | | 556017 | Windshield Washer Fluid | | 556018 | Canteen | | 30000514 | Hot Drinks | | 30000515 | Cold Drinks | | 30000516 | Snacks | | 30000517 | Ice Cream | | 30000518 | Milk Produce | | 30000519 | Sandwiches | | 30000520 | Food | | 30000521 | Amusement | | 30000522 | Alcohol | | 30000523 | Cigarettes | | 30000524 | Combo | | 30000525 | Air | | 30000526 | Electricity | | 30000527 | Other | | 30000561 | Recycling | | 30000578 | Car Wash Machine | | 30000579 | Laundry Machine | | 30000580 | Cellular Accessories | | 30000581 | Pharmacy | | 30000582 | TV And Internet Services | | 30000583 | PPE | | 30000602 | Massage Chairs | | 30000611 | Ice | | 30000612 | Photo Booth | | 30000617 | Pictures | | 30000618 | Photocopies | | 30000619 | Flowers | | 30000620 | Car Vacuum Cleaner | | 30000623 | Water Filling Station | | 176649542 | Access Control | | 227707459 | Golf Ball Dispenser | | 227707460 | Gaming | | 504059468 | Dog Wash | | 529079224 | Lockers | | 363311433 | Fresh Juice | | 244797254 | Weight | # AvailabilityCheck Source: https://devzone.nayax.com/reference/spark/transactions/availabilitycheck /openapi/spark.yaml post /AvailabilityCheck # CancelTransaction Source: https://devzone.nayax.com/reference/spark/transactions/canceltransaction /openapi/spark.yaml post /CancelTransaction The /CancelTransaction endpoint is a POST request that allows you to cancel a transaction currently in progress. This method is referred to as "Cancel" in the Pre-Authorization flow and "Void" in the Pre-Selection flow. # DeclineCallback Source: https://devzone.nayax.com/reference/spark/transactions/declinecallback /openapi/spark.yaml post /DeclineCallback The `DeclineCallback` API call is used to notify you of a failure in the Spark transaction process. It is typically triggered after a successful `/TriggerTransaction` response with a verdict of `Approved`, but when the flow subsequently fails for any reason before payment authorization. # ExternalCancel Source: https://devzone.nayax.com/reference/spark/transactions/externalcancel /openapi/spark.yaml post /ExternalCancel The `/ExternalCancel` method is used by the third-party server to cancel a transaction that has been authorized but not yet settled. Cancellation is necessary if a failure occurs during the interaction or on the third-party server. This process is vital for releasing any funds captured on the consumer's payment card. While the API method is always `/ExternalCancel`, the financial terminology depends on the machine flow type: * **Pre-Authorization Flow**: This method is called to as a **"Cancel"**. * **Pre-Selection Flow**: This the method is referred a **"Void"**. The request must specify the required cancellation type. ## Identifying the Transaction To successfully cancel a transaction, your request must include the three required identifiers that exactly match the original transaction data. * **NayaxTransactionID**: The unique ID generated during authorization. * **SiteID**: The identifier for the machine's location. * **MachineAuTime**: The exact authorization timestamp. Optional field but recommended * MachineAUTime is currently not available for Marshall machines due to Transfer Data not providing this information to the machine (hence the 3rd party servers would not have this information when trying to send the ExternalCancel) If any of these fields are missing or mismatched, the system will return a "Transaction not found" error. <Note> **Automatic Retries (AutoCancel):** In case the request fails, Nayax provides an **AutoCancel** feature, which means Nayax will automatically attempt to retry the cancellation later. The prerequisite is that the **AutoCancel** feature must be enabled for the specific operator. </Note> ## Troubleshooting Declined Cancellations If a cancellation request is declined, the response will return **ErrorCode 51**: "External Cancel Failed". * **Mandatory Use**: You must send an `ExternalCancel` immediately if you know no product or service will be provided. * **Consumer Impact**: If not canceled, consumer funds will remain captured, leading to a poor user experience and potential disputes. * **Audit Trail**: It is recommended to include a `ReasonCode` and `ReasonText` (e.g., "75 - Service not provided") to document why the transaction was voided. # ExternalSettlement Source: https://devzone.nayax.com/reference/spark/transactions/externalsettlement /openapi/spark.yaml post /ExternalSettlement The `/ExternalSettlement` method is called by the 3rd-party server to finalize a transaction after the payment provider has authorized the initial amount and the service or products have been provided to the consumer. This request must contain the final amount to be charged. To successfully settle a transaction, you must provide three mandatory identifiers that match the original authorization data exactly: * **NayaxTransactionID**: The unique identifier for the transaction in the Nayax system. * **SiteID**: The ID of the site where the machine is located. * **MachineAUTime**: The authorization timestamp from the terminal. Optional field but recommended. * MachineAUTime is not available for Marshall machines. However, as this field is optional, you can still use ExternalSettlement without it. ## Where to Find this Information Depending on your hardware, these identifiers are retrieved through different channels: * **OTI Devices**: Information is sent via the **CommerceAPI**. * **Marshall Devices**: Information is sent via **Transfer Data** * **Alternative**: All integrators can retrieve this data via **Amazon SQS**. ## Adding Digital Receipts (`EReceiptData`) If you use the Nayax eReceipt platform, you can use the `EReceiptData` field to add custom information to the digital receipt that isn't stored in the Nayax Backoffice. <Danger> Any information shared in this field will be visible to the consumer on their receipt. Avoid sharing sensitive data that is not relevant to the transaction. </Danger> The data must be sent as a JSON string containing: * **Section Naming**: To display fields without a section header, use a blank space for the section name: `{" ":[...]}`. * **Order**: Fields appear on the receipt in the exact order they are listed in the string. * **Characters**: Use escape characters (e.g., `\"`) for internal quotes within the JSON string. ## Reporting Products (`ProductInfo`) For operators who manage a **Products Map** in Nayax Core, the `ProductInfo` object allows you to report exactly which items were sold. This is an array of objects where each item requires: | Field | Type | Description | | - | - | - | | **Value** | Decimal | The price of a single unit of the product.<br /><br />\* The value is taken as is (Decimal place of 0), meaning if you send value of 6.50 the value that the consumer would be charged for is 6.50, and if you send 65 the value would be 65.00) | | **Code** | Integer | The Product Code as defined in your Nayax Products Map.<br /><br />\* The value is taken as is (Decimal place of 0) | | **Quantity** | Integer | The number of units of this product provided.<br /><br />\* The value is taken as is (Decimal place of 0) | **Example Format**: `[{"Value": 6.50, "Code": 12, "Quantity": 3}]` ## Troubleshooting Declined Settlements If a settlement request is declined, the response will include an **ErrorCode 50**: "External Settlement Failed". Common reasons for failure include: * **Missing Identifiers**: Mandatory fields like `SiteId` were missing from the request. * **Data Mismatch**: The IDs provided do not match the original authorization record. * **Time Limit**: The request was sent more than 48 hours after the transaction started. # Get Version Source: https://devzone.nayax.com/reference/spark/transactions/get-version /openapi/spark.yaml get /Version Returns the Spark API assembly version and build. # InfoQuery Source: https://devzone.nayax.com/reference/spark/transactions/infoquery /openapi/spark.yaml post /InfoQuery Nayax sends an `InfoQuery` API after a successful `StartSession` response. Its main purposes are to retrieve information to be shown on the POS device before payment begins and to check the availability status of the requested service station. # Settlement Source: https://devzone.nayax.com/reference/spark/transactions/settlement /openapi/spark.yaml post /Settlement The `Settlement` endpoint is used to finalize an approved transaction. After the session ends and the total amount is known, the integrator sends the final amount along with optional e-receipt information. This method is only relevant for transactions with Pre-Authorization. # StartAuthentication Source: https://devzone.nayax.com/reference/spark/transactions/startauthentication /openapi/spark.yaml post /StartAuthentication The `StartAuthentication` endpoint is the first step for any External Settlement. Use this to verify your server’s identity with Nayax and create a secure link for the transaction. <Card title="Try it: Spark Auth Tool" icon="bolt" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool"> Build and inspect the cipher and the `TransactionSignature` header for this endpoint in your browser, no code required. </Card> ## How to Build the Cipher You must send an encrypted string called a `cipher`. This string tells Nayax which transaction you are working on and proves the request is current. ### Step 1: Create the 64-character Plaintext Combine these four parts in the exact order and character positions shown below to make one long string: | Section | Type | Position | Description | | - | - | - | - | | **Spark Transaction ID** | String | 1-36 | Your unique GUID (with hyphens). | | **Separator** | Special | 37 | Must be the `=` symbol. | | **Random String** | String | 38-54 | A 17-character random alphanumeric string. | | **Timestamp** | Numeric | 55-64 | Current UTC time in `YYMMDDhhmm` format. | **Example:** `12c7cec2-c690-4425-9a1f-db0db60e2d8c=123456789qwertyui2602041044` ### Step 2: Get Your Encryption Key Nayax provides you with a **Secret Token** (usually 66 characters). To create your key, take only the **32 characters on the far right** of that token to create a 256-bit key. **Example:** * **Full token example:** `...wRvTVTkungMIKThTVbj_fiXdfoGclhn0` * **What your key will look like:** `wRvTVTkungMIKThTVbj_fiXdfoGclhn0` ### Step 3: Encrypt and Encode Encrypt the 64-character string from Step 1 using **AES (ECB mode)** with your key from Step 2. Then, encode the result into **Base64**. <Note> **Important Rules for Success:** * **5-Minute Window**: Nayax will reject any request if the timestamp in your cipher is more than 5 minutes old. This limit is controlled by the `CipherExpMinutes` variable. * **Double-Check Randomness**: The `Random` field in your JSON request must be exactly the same as the random string you put inside the cipher. * **Verify Nayax**: When the response arrives, it contains a `HashedSparkTransactionId`. You **must** hash your original Transaction ID using **SHA-256** and ensure it matches Nayax’s version to verify the response is authentic. </Note> ### Error Codes If your request is declined, look for these specific codes: | Error Code | Meaning | What to Check | | - | - | - | | **28** | Invalid Token | Check if your Token ID is correct, active, and associated with your account. | | **30** | Validation Failed | Your JSON `Random` field doesn't match the one in your cipher. | | **31** | Expired Request | Your timestamp is too old (longer than 5 minutes). Sync your server clock to UTC. | | **34** | Decryption Failure | Your cipher format is wrong or the `=` is missing from the 37th character. | # StartSession Source: https://devzone.nayax.com/reference/spark/transactions/startsession /openapi/spark.yaml post /StartSession This is the initial API call sent by Nayax. It initiates the transaction session by authenticating both parties and generating a `SparkTransactionId`, which will be echoed in all subsequent calls throughout the transaction's lifecycle. <Card title="Try it: Spark Auth Tool" icon="bolt" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool#startsession"> Build or inspect the `StartSession` cipher in your browser, no code required. Opens the tool on the StartSession tab. </Card> # StopCallback Source: https://devzone.nayax.com/reference/spark/transactions/stopcallback /openapi/spark.yaml post /StopCallback The `StopCallback` endpoint notifies the integrator that a consumer has presented a payment card to stop an ongoing session. # StopNotify Source: https://devzone.nayax.com/reference/spark/transactions/stopnotify /openapi/spark.yaml post /StopNotify The `StopNotify` endpoint enables Spark to determine whether a card presented at the payment terminal while idle is authorized to stop an ongoing session. A matching card should result in an `Approved` response; otherwise, the Spark integrator should return a `Declined` verdict. # TimeoutCallback Source: https://devzone.nayax.com/reference/spark/transactions/timeoutcallback /openapi/spark.yaml post /TimeoutCallback The `TimeoutCallback` API call notifies that the payment session has timed out due to inactivity or a failure to complete the expected flow within a defined period. # TransactionCallback Source: https://devzone.nayax.com/reference/spark/transactions/transactioncallback /openapi/spark.yaml post /TransactionCallback The terminal uses the `TransactionCallback` endpoint to notify the integrator about the result of a card tap. It is triggered automatically when a user presents a card, and an authorization flow is initiated with the payment provider. # TransactionNotify Source: https://devzone.nayax.com/reference/spark/transactions/transactionnotify /openapi/spark.yaml post /TransactionNotify The `TransactionNotify` endpoint is used to notify the integrator about the final details of a charging session, including charger availability, amount, and display information. # TriggerTransaction Source: https://devzone.nayax.com/reference/spark/transactions/triggertransaction /openapi/spark.yaml post /TriggerTransaction The `TriggerTransaction` endpoint initiates user interaction with the physical terminal by sending a wake-up signal to the specified device. # Add Actor Group Source: https://devzone.nayax.com/reference/lynx/actors/add-actor-group /openapi/lynx.yaml post /v1/actors/{ActorID}/roleGroups Adds a new actor group for a specific actor, identified by `ActorID`. # Add Machine Group Source: https://devzone.nayax.com/reference/lynx/actors/add-machine-group /openapi/lynx.yaml post /v1/actor/{ActorID}/machineGroups Adds a new machine group for a specific actor, identified by `ActorID`. # Create a New Actor Source: https://devzone.nayax.com/reference/lynx/actors/create-a-new-actor /openapi/lynx.yaml post /v2/actors/{ParentActorID} Creates a new actor under the specified parent actor. The parent actor is identified by the `ParentActorID` provided in the path. The request body must contain the details of the new actor. # Create Actor's Payment Methods Source: https://devzone.nayax.com/reference/lynx/actors/create-actors-payment-methods /openapi/lynx.yaml post /v1/actors/{ActorID}/paymentMethods Creates new payment methods for a specific actor, identified by the `ActorID`. # Decrypt Message by Encryption Version Source: https://devzone.nayax.com/reference/lynx/actors/decrypt-message-by-encryption-version /openapi/lynx.yaml put /v1/actors/DecryptionMessageByVer Decrypts a message using a specific encryption version for a given actor, identified by `actorID` and `encVer`. # Delete a Payment Method Source: https://devzone.nayax.com/reference/lynx/actors/delete-a-payment-method /openapi/lynx.yaml delete /v1/actors/{ActorID}/paymentMethods/{paymentMethodID} Deletes a specific payment method associated with a given actor, identified by `ActorID` and `paymentMethodID`. # Delete Actor Group Source: https://devzone.nayax.com/reference/lynx/actors/delete-actor-group /openapi/lynx.yaml delete /v1/actors/{ActorID}/roleGroups Deletes an actor group associated with a specific actor, identified by `ActorID`. # Generate Encryption Key Source: https://devzone.nayax.com/reference/lynx/actors/generate-encryption-key /openapi/lynx.yaml put /v1/actors/GenarateEncKey Generates a new encryption key for the specified actor, identified by `actorID`. # Get Actor by ActorCode Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-by-actorcode /openapi/lynx.yaml get /v1/actors Retrieves the details of an actor using their unique `ActorCode`. This is useful for fetching information about a specific actor when only their code is known. # Get Actor Hierarchy for Current User Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-hierarchy-for-current-user /openapi/lynx.yaml get /v1/actors/hierarchy Retrieves the actor hierarchy for the current user. Optionally, you can specify an `ActorID` to get the hierarchy for a specific actor, filter by `StatusID`, or limit the hierarchy levels returned. # Get All Actor Groups by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-all-actor-groups-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID}/roleGroups Retrieves all actor groups associated with a specific actor, identified by `ActorID`. # Get Encryption Keys by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-encryption-keys-by-actorid /openapi/lynx.yaml get /v1/actors/GetEncKeys Retrieves the encryption keys associated with a specific actor, identified by the `actorID` query parameter. # Get Operator EV Meter Dashboard Source: https://devzone.nayax.com/reference/lynx/actors/get-operator-ev-meter-dashboard /openapi/lynx.yaml get /v1/actors/{ActorID}/evDashboard Retrieves the EV meter dashboard for a specific operator, identified by `ActorID`. Optional query parameters allow filtering by date range, machine ID, time period, and machine number. # Get payment methods by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-payment-methods-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID}/paymentMethods Retrieves a list of payment methods associated with a specific actor, identified by the `ActorID`. # List All Machine Groups for Actor Source: https://devzone.nayax.com/reference/lynx/actors/list-all-machine-groups-for-actor /openapi/lynx.yaml get /v1/actor/{ActorID}/machineGroups Retrieves all machine groups associated with a specific actor, identified by `ActorID`. # Update Actor's Payment Methods Source: https://devzone.nayax.com/reference/lynx/actors/update-actors-payment-methods /openapi/lynx.yaml put /v1/actors/{ActorID}/paymentMethods Updates the payment methods associated with a specific actor, identified by the `ActorID`. # Update Machine Group Source: https://devzone.nayax.com/reference/lynx/actors/update-machine-group /openapi/lynx.yaml put /v1/actor/{ActorID}/machineGroups Updates the details of a machine group associated with a specific actor, identified by `ActorID`. # Add Credit to a Card Source: https://devzone.nayax.com/reference/lynx/cards/add-credit-to-a-card /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/credit/add Adds a specified amount to the credit of a card, identified by its unique identifier. # Add to the Card's Revalue Source: https://devzone.nayax.com/reference/lynx/cards/add-to-the-cards-revalue /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/revalue/add Adds a specified amount to the revalue of a card, identified by its unique identifier. # Create New Card Source: https://devzone.nayax.com/reference/lynx/cards/create-new-card /openapi/lynx.yaml post /v2/cards Creates a new card with the specified details. # Create Virtual Card Source: https://devzone.nayax.com/reference/lynx/cards/create-virtual-card /openapi/lynx.yaml post /v1/cards Creates a new virtual card with the provided details. # Get Card by ID Source: https://devzone.nayax.com/reference/lynx/cards/get-card-by-id /openapi/lynx.yaml get /v1/cards/uniqueIdentifier/{CardUniqueIdentifier} Retrieves card details associated with a specific unique identifier. # Get Card by the Cards Display Number Source: https://devzone.nayax.com/reference/lynx/cards/get-card-by-the-cards-display-number /openapi/lynx.yaml get /v1/cards/displayNumber/{CardDisplayNumber} Retrieves card details associated with a specific display number. # Get Card Group Source: https://devzone.nayax.com/reference/lynx/cards/get-card-group /openapi/lynx.yaml get /v1/cards/{cardId}/cardGroups Retrieves the group details associated with a specific card, identified by its card ID. # Get Cards Source: https://devzone.nayax.com/reference/lynx/cards/get-cards /openapi/lynx.yaml get /v1/cards Retrieves card details based on various query parameters. # Get Card's Revalue Source: https://devzone.nayax.com/reference/lynx/cards/get-cards-revalue /openapi/lynx.yaml get /v1/cards/{CardUniqueIdentifier}/revalue Retrieves the revalue amount associated with a specific card, identified by the card's unique identifier. # Get Credit Card's Latest Transactions Source: https://devzone.nayax.com/reference/lynx/cards/get-credit-cards-latest-transactions /openapi/lynx.yaml post /v1/cards/query Retrieves the latest transactions associated with a specific credit card number, identified by the SHA1 hash of the card number in base64 format. # Get Prepaid Card Source: https://devzone.nayax.com/reference/lynx/cards/get-prepaid-card /openapi/lynx.yaml get /v1/cards/{CardId}/prepaid Retrieves details of a prepaid card associated with a specific card ID. # Get the Credit from a Card Source: https://devzone.nayax.com/reference/lynx/cards/get-the-credit-from-a-card /openapi/lynx.yaml get /v1/cards/{CardUniqueIdentifier}/credit Retrieves the credit value associated with a specific card, identified by its unique identifier. # Transfer Revalue Between Cards Source: https://devzone.nayax.com/reference/lynx/cards/transfer-revalue-between-cards /openapi/lynx.yaml post /v1/cards/{FromCardUniqueIdentifier}/revalue/send/{ToCardUniqueIdentifier} Transfers a specified amount of revalue from one card to another, identified by their unique identifiers. # Update Card by ID Source: https://devzone.nayax.com/reference/lynx/cards/update-card-by-id /openapi/lynx.yaml put /v2/cards/{CardID} Updates the details of a card identified by its unique ID. # Update Card Details Source: https://devzone.nayax.com/reference/lynx/cards/update-card-details /openapi/lynx.yaml put /v1/cards Updates the details of an existing card. # Update Card Details by Display Number Source: https://devzone.nayax.com/reference/lynx/cards/update-card-details-by-display-number /openapi/lynx.yaml put /v1/cards/{CardDisplayNumber} Updates the details of a card identified by the card's display number. # Update Card Groups Source: https://devzone.nayax.com/reference/lynx/cards/update-card-groups /openapi/lynx.yaml put /v1/cards/{CardId}/cardGroups Updates the group details associated with a card, identified by the card's unique identifier. # Update Card Status Source: https://devzone.nayax.com/reference/lynx/cards/update-card-status /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/status/{CardStatus} Updates the status of a card, identified by its unique identifier. # Update Prepaid Card Source: https://devzone.nayax.com/reference/lynx/cards/update-prepaid-card /openapi/lynx.yaml put /v1/cards/{CardId}/prepaid Updates the details of a prepaid card associated with a specific card ID. # Validates Card for Machine Use Source: https://devzone.nayax.com/reference/lynx/cards/validates-card-for-machine-use /openapi/lynx.yaml get /v1/cards/validate-machine/{machineId} Validates whether a prepaid or discount card can be used with a specific machine. # Get All Devices Source: https://devzone.nayax.com/reference/lynx/devices/get-all-devices /openapi/lynx.yaml get /v1/devices Retrieve a list of devices with optional filters such as actor ID, connection status, serial number, and other device attributes. # Get Device by DeviceID Source: https://devzone.nayax.com/reference/lynx/devices/get-device-by-deviceid /openapi/lynx.yaml get /v1/devices/{DeviceID} Retrieve detailed information about a specific device using its `DeviceID`. The unique identifier of the device is provided in the path to ensure accurate retrieval of the device's data. # Move Devices to Actor ID Source: https://devzone.nayax.com/reference/lynx/devices/move-devices-to-actor-id /openapi/lynx.yaml put /v1/devices/move/{actorId} Assigns or moves a list of devices to a specified actor identified by `actorId`. The request body should include an array of device identifiers (e.g., serial numbers). # Update Device Source: https://devzone.nayax.com/reference/lynx/devices/update-device /openapi/lynx.yaml put /v1/devices/{DeviceID} Update the details of an existing device using its `DeviceID`. The unique identifier of the device is provided in the path to ensure that the correct device is updated. # Generate eReceipt for your Transaction Source: https://devzone.nayax.com/reference/lynx/ereceipt/generate-ereceipt-for-your-transaction /openapi/lynx.yaml post /v1/ereceipt/generate Generates an electronic receipt (eReceipt) for a specified transaction. The request body should include the transaction details necessary to generate the eReceipt. # Get All Actor Types Source: https://devzone.nayax.com/reference/lynx/lookups/get-all-actor-types /openapi/lynx.yaml get /v1/actorTypes Retrieves a list of all actor types, optionally filtered by a specific `ActorTypeID`. # Get Billing Providers Source: https://devzone.nayax.com/reference/lynx/lookups/get-billing-providers /openapi/lynx.yaml get /v1/billingProviders Retrieves a list of billing providers, optionally filtered by `BillingProviderID`. # Get Cities Source: https://devzone.nayax.com/reference/lynx/lookups/get-cities /openapi/lynx.yaml get /v1/cities Retrieves a list of cities within a specified country, optionally filtered by `CountryID`. # Get Countries Source: https://devzone.nayax.com/reference/lynx/lookups/get-countries /openapi/lynx.yaml get /v1/countries Retrieves a list of countries, optionally filtered by `CountryID` or `DialCode`. # Get Country by Code Source: https://devzone.nayax.com/reference/lynx/lookups/get-country-by-code /openapi/lynx.yaml get /v1/countries/{CountryCode} Retrieves the details of a specific country identified by `CountryCode`. # Get Currencies Source: https://devzone.nayax.com/reference/lynx/lookups/get-currencies /openapi/lynx.yaml get /v1/currencies Retrieves a list of currencies, optionally filtered by `CurrencyID`. # Get Currency by Code Source: https://devzone.nayax.com/reference/lynx/lookups/get-currency-by-code /openapi/lynx.yaml get /v1/currencies/{CurrencyCode} Retrieves the details of a specific currency identified by `CurrencyCode`. # Get Group Roles Source: https://devzone.nayax.com/reference/lynx/lookups/get-group-roles /openapi/lynx.yaml get /v1/group/{GroupID}/roles Retrieves a list of roles associated with a specific group identified by `GroupID`. # Get Groups Source: https://devzone.nayax.com/reference/lynx/lookups/get-groups /openapi/lynx.yaml get /v1/groups Retrieves a list of groups, optionally filtered by `GroupID`. # Get Lookup Types Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-types /openapi/lynx.yaml get /v1/lookupTypes Retrieves a list of lookup types, optionally filtered by a specific `LutTypeID`. # Get Lookup Value by Lookup ID Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-value-by-lookup-id /openapi/lynx.yaml get /v1/lookups/values/{LutID} Retrieves a specific lookup value identified by `LutID`. # Get Lookup Values by Lookup Type ID Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-values-by-lookup-type-id /openapi/lynx.yaml get /v1/lookupTypes/{LutTypeID}/values Retrieves a list of lookup values associated with a specific lookup type identified by `LutTypeID`. # Get Machine Models Source: https://devzone.nayax.com/reference/lynx/lookups/get-machine-models /openapi/lynx.yaml get /v1/lookupTypes/machineModels Retrieves a list of machine models, optionally filtered by a specific `MachineModeID`. # Get Payment Methods Source: https://devzone.nayax.com/reference/lynx/lookups/get-payment-methods /openapi/lynx.yaml get /v1/paymentMethods Retrieves a list of payment methods, optionally filtered by `PaymentMethodID`. # Get Regions Source: https://devzone.nayax.com/reference/lynx/lookups/get-regions /openapi/lynx.yaml get /v1/regions Retrieves a list of regions (states or provinces), optionally filtered by `CountryID` or `RegionID`. # Get States Source: https://devzone.nayax.com/reference/lynx/lookups/get-states /openapi/lynx.yaml get /v1/states Retrieves a list of regions (states or provinces) within a specified country, optionally filtered by `CountryID`. # Get Time Zones by Offset Source: https://devzone.nayax.com/reference/lynx/lookups/get-time-zones-by-offset /openapi/lynx.yaml get /v1/timeZones Retrieves a list of time zones based on the specified time zone offset. # Get Time Zones by Time Zone Key Source: https://devzone.nayax.com/reference/lynx/lookups/get-time-zones-by-time-zone-key /openapi/lynx.yaml get /v1/timeZones/{TimeZoneKey} Retrieves a specific time zone identified by `TimeZoneKey`. # Bulk Update Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/bulk-update-machine-attributes /openapi/lynx.yaml put /v1/machines/{MachineID}/attributes Performs a bulk update of machine attributes for the specified machine identified by `MachineID`. # Get All Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/get-all-machine-attributes /openapi/lynx.yaml get /v1/machines/{MachineID}/attributes Retrieves all attributes associated with a specific machine identified by `MachineID`. # Get Specific Machine Attribute Source: https://devzone.nayax.com/reference/lynx/machine-attribute/get-specific-machine-attribute /openapi/lynx.yaml get /v1/machines/{MachineID}/attributes/{DeviceAttributeID} Retrieves the details of a specific machine attribute identified by `MachineID` and `DeviceAttributeID`. # Insert/Update Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/insertupdate-machine-attributes /openapi/lynx.yaml post /v2/machines/attributes Allows bulk insertion or updating of machine attributes. The request body should include an array of machine attributes to be processed. # Update Machine Attribute to Current Configuration Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-machine-attribute-to-current-configuration /openapi/lynx.yaml post /v1/machines/{MachineID}/attributes/resendConfig Resends the current machine configuration, updating the machine attributes to match the latest configuration settings. # Update Machine Attribute to Model Defaults Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-machine-attribute-to-model-defaults /openapi/lynx.yaml post /v1/machines/{MachineID}/attributes/defaults Resets the machine attributes to the default values defined by the machine model. This operation is typically used to restore default configurations. # Update Specific Machine Attribute Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-specific-machine-attribute /openapi/lynx.yaml put /v1/machines/{MachineID}/attributes/{DeviceAttributeID} Updates the details of a specific machine attribute identified by `MachineID` and `DeviceAttributeID`. # Create Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/create-pick-list /openapi/lynx.yaml post /v1/machines/{MachineID}/pickList Generates a new pick list for a specific machine, with options to adjust the pick list based on various criteria. # Delete Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/delete-pick-list /openapi/lynx.yaml delete /v1/machines/{MachineID}/pickList Deletes the existing pick list for a specific machine identified by `MachineID`. # Empty Machine Products Inventory Source: https://devzone.nayax.com/reference/lynx/machine-inventory/empty-machine-products-inventory /openapi/lynx.yaml post /v1/machines/{MachineID}/inventory/empty Empties the inventory of all products in the specified machine, marking all product slots as empty. # Get Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/get-pick-list /openapi/lynx.yaml get /v1/machines/{MachineID}/pickList Retrieves the pick list associated with a specific machine identified by `MachineID`. # Set All Machine Bins as Full Source: https://devzone.nayax.com/reference/lynx/machine-inventory/set-all-machine-bins-as-full /openapi/lynx.yaml post /v1/machines/{MachineID}/inventory/full Marks all bins in the specified machine as fully stocked, indicating that all product slots are filled to capacity. # Update Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/update-pick-list /openapi/lynx.yaml put /v1/machines/inventory/picklists/update Updates the pick list for a specific machine, allowing changes to the quantity of products to be picked. # Create Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/create-machine-products /openapi/lynx.yaml post /v1/machines/{MachineID}/machineProducts Creates new products for the specified machine identified by `MachineID`. # Get a Machine Product Source: https://devzone.nayax.com/reference/lynx/machine-products/get-a-machine-product /openapi/lynx.yaml get /v1/machines/{MachineID}/machineProducts/{MachineProductID} Retrieves details of a specific machine product identified by `MachineProductID` within the machine identified by `MachineID`. # Get Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/get-machine-products /openapi/lynx.yaml get /v1/machines/{MachineID}/machineProducts Retrieves the list of products associated with a specific machine identified by `MachineID`. # Update a Machine Product Source: https://devzone.nayax.com/reference/lynx/machine-products/update-a-machine-product /openapi/lynx.yaml put /v1/machines/{MachineID}/machineProducts/{MachineProductID} Updates the details of a specific machine product identified by `MachineProductID` within the machine identified by `MachineID`. # Update Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/update-machine-products /openapi/lynx.yaml put /v1/machines/{MachineID}/machineProducts Updates the products associated with a specific machine identified by `MachineID`, with an option to avoid deletion. # Create New Machine Source: https://devzone.nayax.com/reference/lynx/machines/create-new-machine /openapi/lynx.yaml post /v1/machines Creates a new machine entry with the provided details. # Create Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/create-payment-methods-for-machine /openapi/lynx.yaml post /v1/machines/{MachineID}/paymentMethods Creates new payment methods for a specific machine, identified by MachineID. This operation allows users to add new payment options to the machine. # Delete Specific Payment Method for Machine Source: https://devzone.nayax.com/reference/lynx/machines/delete-specific-payment-method-for-machine /openapi/lynx.yaml delete /v1/machines/{MachineID}/paymentMethods/{paymentMethodID} Deletes a specific payment method associated with a machine, identified by the provided MachineID and paymentMethodID. This operation allows users to remove a payment option from the machine. # Get All Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/get-all-machine-basic-info /openapi/lynx.yaml get /v1/machines Retrieves basic information for all machines, with optional filtering by parameters. # Get Last Sales for Machine by MachineID Source: https://devzone.nayax.com/reference/lynx/machines/get-last-sales-for-machine-by-machineid /openapi/lynx.yaml get /v1/machines/{MachineID}/lastSales Retrieves the most recent sales transactions for a specific machine, identified by MachineID. This allows users to view the latest sales activity associated with the machine. # Get Machine Change Logs Source: https://devzone.nayax.com/reference/lynx/machines/get-machine-change-logs /openapi/lynx.yaml get /v1/machines/changeLogs Fetches the change logs for machines within a specified date range. Users can filter the logs by various parameters such as ActorID, StartDate, EndDate, MachineID, TimePeriod, and MachineNumber to retrieve the relevant changes. # Get Machine Last Alerts Source: https://devzone.nayax.com/reference/lynx/machines/get-machine-last-alerts /openapi/lynx.yaml get /v1/machines/{MachineID}/lastAlerts Retrieves the most recent alerts for a specific machine identified by the provided MachineID. This helps in monitoring recent issues or notifications related to the machine's operation. # Get Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/get-payment-methods-for-machine /openapi/lynx.yaml get /v1/machines/{MachineID}/paymentMethods Retrieves the list of payment methods associated with a specific machine, identified by MachineID. This allows users to view the available payment options configured for the machine. # Get Specific Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info /openapi/lynx.yaml get /v1/machines/{MachineID} Retrieves basic information about a specific machine identified by `MachineID`. # Get Specific Machine Basic Info by Device Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info-by-device /openapi/lynx.yaml get /v1/devices/{DeviceSerialNumber}/machine Retrieves the basic information of a specific machine associated with the provided device serial number. This allows users to fetch machine details by referencing the device it is connected to. # Get Specific Machine Basic Info by VPOS Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info-by-vpos /openapi/lynx.yaml get /v1/vpos/{VPOSSerial}/machine Retrieves the basic information of a specific machine associated with the provided VPOS serial number. This allows users to fetch machine details by referencing the VPOS device it is connected to. # Get Specific Machine Statistics Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-statistics /openapi/lynx.yaml get /v1/machines/{MachineID}/status Retrieves the current status and statistics of a specific machine identified by the provided MachineID. This includes details like operational status, performance metrics, and other relevant statistics. # Search Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/search-machine-basic-info /openapi/lynx.yaml post /v1/machines/search Retrieves a list of machines based on the search criteria provided in the request body. This allows users to filter and find specific machines or groups of machines by applying various parameters. # Update Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/update-payment-methods-for-machine /openapi/lynx.yaml put /v1/machines/{MachineID}/paymentMethods Updates the payment methods associated with a specific machine, identified by MachineID. This operation allows users to modify the existing payment options for the machine. # Update Specific Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/update-specific-machine-basic-info /openapi/lynx.yaml put /v1/machines/{MachineID} Updates the basic information of a specific machine identified by `MachineID`. # Get Event Rules Source: https://devzone.nayax.com/reference/lynx/metadata/get-event-rules /openapi/lynx.yaml get /v1/metadata/v1/event-rules Retrieves the event rules configured in the system. The response contains an array of event rules that are currently active. # Upload Picture Source: https://devzone.nayax.com/reference/lynx/metadata/upload-picture /openapi/lynx.yaml post /v1/metadata/upload-picture Uploads a picture to the server with associated metadata. The picture and its details are provided in the request body. # Approve Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/approve-payment-refund /openapi/lynx.yaml post /v1/payment/refund-approve Approves a previously requested payment refund. The request body includes details such as whether the refund was processed externally and any associated documentation. # Decline a Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/decline-a-payment-refund /openapi/lynx.yaml post /v1/payment/refund-decline Submits a request to decline a previously submitted payment refund request. The request body includes details such as the transaction ID and reason for declining the refund. # Request a Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/request-a-payment-refund /openapi/lynx.yaml post /v1/payment/refund-request Submits a request to refund a specific payment. The request body includes details such as the refund amount, reason, and transaction ID. # Upload Refund Documentation Source: https://devzone.nayax.com/reference/lynx/payment/upload-refund-documentation /openapi/lynx.yaml post /v1/payment/upload-refund Uploads a file related to a payment refund. The file could be documentation or other relevant data associated with the refund. # Get Product Group Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-group /openapi/lynx.yaml get /v1/productGroups/{ProductGroupID} Retrieves details of a specific product group identified by the ProductGroupID. The response includes information such as the product group name, code, and other related details. # Authentication Source: https://devzone.nayax.com/docs/core-extension/authentication Understand how Nayax delivers a JWT token to your Core Extension and how to use it for API calls. When a user opens your Core Extension, Nayax passes it a signed JWT token containing the user's identity and permissions. Your app uses this token to make Nayax API calls on behalf of the logged-in user. You do not manage login or sessions: Nayax handles authentication and hands your app a ready-to-use token at load time. For Screen, Button with Popup, and Tab extensions, the token arrives via `postMessage` from the parent frame. If you are building a Fullscreen extension, contact Nayax to confirm the delivery method. ## Receiving the token via postMessage For Screen, Button with Popup, and Tab extensions, listen for a `message` event on the window. Nayax posts an object containing the token, the Cortex base URL, and (for Button with Popup and Tab) the selection context. ```typescript theme={null} useEffect(() => { const handleMessage = (event: MessageEvent) => { const { token, cortexUrl, selection } = event.data; if (token) { setToken(token); setCortexUrl(cortexUrl); if (selection?.machineId) { setMachineId(selection.machineId); } } }; window.addEventListener("message", handleMessage); return () => window.removeEventListener("message", handleMessage); }, []); ``` The `selection` object is only present for Button with Popup and Tab extensions. Screen extensions receive `token` and `cortexUrl` only. Nayax can also pass context via the URL hash (for example, `/YourApp/index.html#machineId=12345`). ## Token payload The token is signed with RS256. Here is an example payload: ```json theme={null} { "id": "22", "name": "nayaxvend\\User", "actor": "27594", "OperatorId": "27594", "DistributorId": "27594", "IsAdmin": "True", "ActorHierarchy": "27594", "AppName": "cortex", "realUserId": "22", "email": "user@nayax.com", "nbf": 1768379518, "exp": 1768469518, "iat": 1768379518, "iss": "NayaxMomaApi", "aud": "moma2" } ``` ## Token claims | Claim | Description | | - | - | | `id` | User ID | | `name` | Username with domain | | `actor` | Actor ID | | `OperatorId` | Operator ID | | `DistributorId` | Distributor ID | | `IsAdmin` | Admin flag | | `ActorHierarchy` | Actor hierarchy chain | | `AppName` | Application name | | `realUserId` | Real user ID | | `email` | User email | | `nbf` | Not before (Unix timestamp) | | `exp` | Expiration (Unix timestamp) | | `iat` | Issued at (Unix timestamp) | | `iss` | Issuer | | `aud` | Audience | ## Validating the token Validate the JWT signature using the RSA public key for your environment. <Tabs> <Tab title="QA / Development"> ```text theme={null} -----BEGIN PUBLIC KEY----- MIIBCgKCAQEApd1+J2fE9kmt354EKyTqFLhPRgfzBU2vqpzZ5A2BAkhxcBs5/X5pB50Q6XVxibErAofqvv+zyEsPOnfAOKVu+s/mguYMiHuCJJ8Eu7X4VyaT/USYTA1sUI+cY+821RJ8zKhme+vDMStVE668C8Vwn7fZEPm7GU34HN1A+YQEe007ItwIx7tQtnrXql7gzlYU2zcHVrBToC3FaOdkrFX3zgzrJ+RCucAiAAjiK7TKc0YV+/uS8aXeQZD71TDGEcdbPYXogrZjIDudis4tmCLnqHC9m2ePdpjnpnVE/Vs56yK1ExOjkIlJ+kCR5WC3PZyVWv+oS7VMuFS4QaXsRSbHWQIDAQAB -----END PUBLIC KEY----- ``` </Tab> <Tab title="Production"> ```text theme={null} -----BEGIN PUBLIC KEY----- MIIBCgKCAQEAyUVRih9bb22lCTu/FEviqfJgPv3jwzWsXYDCdr+pz0i/BOAVAWUoA2xSBDbbmyUOT2KsEn1/WHhxpUS/ybi81VnhGkRocLuGxAV0LvvPOO774iAygRhlgzSedbt2z1qdgEs7d2c12Ae4LtCxQ2WV3Aaa1YVLWpeT8ZCdekgonzYFXvEK0ES+KFOaifnspMIQA7ek5K1BnojmjHQ7qI3DbYNydSOFqvhbnItFcXSqo+oiBx82HHqr0jAR6DatOfiV3zVXRbsJLaFK0pQFZPV9Ip6uarYofQV2mhlCudB5o+M/axYjnPf0wK4b3P6To9aM+lKpGq9LBnb8IyvpbSgVVQIDAQAB -----END PUBLIC KEY----- ``` </Tab> </Tabs> <Note> Use the QA key during sandbox development. Switch to the production key when you deploy to production. </Note> ## Scopes Scopes control which Nayax resources your app can access. Nayax injects them into the JWT token when your app is registered. There are two scope types: | Value | Type | Behavior | | - | - | - | | `scope` | Limiting | Your app can only access resources within both the user's permissions and the specified scopes. Use this to restrict access even when the user has broader permissions. | | `appScope` | Overriding | Your app receives the specified scopes regardless of the user's normal permissions. Use this to grant your app access that users might not otherwise have. | Scopes are configured by Nayax when your app is registered. Contact your Nayax representative to request the scopes your app requires. # Extension Types Source: https://devzone.nayax.com/docs/core-extension/extension-types Reference for the four Core Extension display types: Screen, Fullscreen, Button with Popup, and Tab. Your Core Extension appears in Nayax Core as one of four display types. The display type controls the layout, where your app sits in the UI, whether it receives element context, and how Nayax delivers the authentication token. Choose the type that fits your use case before you register your app with Nayax. ## Display types at a glance | Display type | Menu type | Layout | Receives context | Token delivery | | - | - | - | - | - | | Screen | App | Full page, Nayax menu visible | No | postMessage | | Fullscreen | App | Full page, no Nayax menu | No | See note | | Button with Popup | App Plugin | Modal over current screen | Yes | postMessage | | Tab | App Plugin | Tab within current screen | Yes | postMessage | <Note> Fullscreen extensions cannot receive the token via postMessage. Contact Nayax to confirm the token delivery method for your Fullscreen extension. </Note> ## Screen **Menu type:** App A Screen extension loads as a full page inside Nayax Core with the platform's navigation menu still visible. Users reach it by selecting it from the menu. **When to use:** Your app is a standalone tool or dashboard that does not need to react to a specific element selected in another screen. **Token delivery:** postMessage from the parent frame. Your app receives `token` and `cortexUrl`. No `selection` context is passed. <Frame> <img alt="The Screen extension type loads as a full page with the Nayax Core menu visible" /> </Frame> ## Fullscreen **Menu type:** App A Fullscreen extension loads as a full page and replaces the Nayax Core navigation entirely. Your app provides its own navigation. **When to use:** Your app has its own navigation structure and needs to own the full viewport. **Token delivery:** The Fullscreen type cannot use postMessage. Contact Nayax to confirm the token delivery method for your Fullscreen extension before building. <Frame> <img alt="The Fullscreen extension type loads as a full page without the Nayax Core navigation menu" /> </Frame> ## Button with popup **Menu type:** App Plugin A Button with Popup extension adds a button to an existing Nayax Core screen. Clicking the button opens your app in a modal overlay. **When to use:** Your app is a contextual action or tool that works on the element currently in focus (for example, a machine-specific diagnostic tool accessible from the Machines screen). **Token delivery:** postMessage from the parent frame. Your app receives `token`, `cortexUrl`, and a `selection` object containing context about the focused element. <Frame> <img alt="The Button with Popup extension type opens your app in a modal overlay" /> </Frame> **Container required:** You must specify a container ID to position the button on the parent screen. See [Available containers](#available-containers) below. ## Tab **Menu type:** App Plugin A Tab extension adds a tab to an existing Nayax Core screen. Your app loads inside that tab as an iframe. **When to use:** Your app is a view or panel that logically belongs alongside existing tabs on a screen (for example, a custom report tab on the machine detail screen). **Token delivery:** postMessage from the parent frame. Your app receives `token`, `cortexUrl`, and a `selection` object containing context about the focused element. <Frame> <img alt="The Tab extension type loads your app as a tab within an existing Nayax Core screen" /> </Frame> ## Configuration fields When you provide your app details to Nayax for registration, use these fields: | Field | Required | Description | | - | - | - | | **Title** | Yes | Display name shown in the Nayax Core menu or as the button/tab label | | **Menu Type** | Yes | `App` for Screen or Fullscreen. `App Plugin` for Button with Popup or Tab. | | **Parent Menu** | Conditional | The menu item or screen where your app appears. Required for App Plugin types. | | **Model** | No | The permission model identifier for your app. Used for scopes and role management. | | **Icon** | No | Icon file displayed in the menu or on the button | | **URL** | Yes | The hosted URL of your application | | **Type** | Yes | The display type: `Screen`, `Fullscreen`, `Button with Popup`, or `Tab` | | **Container** | Conditional | Required for App Plugin types. Specifies where the button appears on the parent screen. Leave empty for App types. | | **Scopes** | No | Limits or overrides the user's permissions for your app. See [Authentication](/docs/core-extension/authentication#scopes). | ### Configuration example: screen (external app) A full-page external app with the Nayax Core menu visible: | Field | Value | | - | - | | **Title** | FuelPoint | | **Menu Type** | App | | **Parent Menu** | Operations | | **Model** | app/fuelpoint | | **URL** | [https://fuelpoint.roseman.co.il/](https://fuelpoint.roseman.co.il/) | | **Type** | Screen | | **Container** | (empty) | ## Available containers App Plugin extensions (Button with Popup and Tab) require a container ID that positions the button on the parent screen. The following containers are available: | Container ID | Location | | - | - | | `btn_info` | Info section buttons | | `btn_actions` | Action section buttons | ## Quick reference | I want to... | Menu type | Display type | | - | - | - | | Add a full-page app with the Nayax menu | App | Screen | | Add a full-page app with my own navigation | App | Fullscreen | | Add a button that opens my app in a popup | App Plugin | Button with Popup | | Add my app as a tab on an existing screen | App Plugin | Tab | ## Next steps <CardGroup> <Card title="Authentication" icon="key" href="/docs/core-extension/authentication"> Learn how Nayax delivers the token for each display type. </Card> <Card title="Get started" icon="rocket" href="/docs/core-extension/get-started"> Walk through registering and testing your extension end to end. </Card> </CardGroup> # Get Started Source: https://devzone.nayax.com/docs/core-extension/get-started Walk through the full developer journey from sandbox access to a live Core Extension in production. This guide walks you through the end-to-end journey for building and deploying a Core Extension: from getting sandbox access, through building and testing your app, to certification and production deployment. By the end, you will have a working extension that loads inside Nayax Core and authenticates your users. ## What you'll need * A Nayax developer account with sandbox access (provided by Nayax after onboarding) * A hosted web application you control (your extension runs in an iframe inside Nayax Core) * Familiarity with the [Core Extension overview](/docs/core-extension/overview) and the [extension types](/docs/core-extension/extension-types) <Note> Core Extension is not available for self-registration. Nayax provisions your sandbox access and manually registers your app in Nayax Core. Contact your Nayax representative to begin the onboarding process. </Note> <Steps> <Step title="Get sandbox access"> Nayax sends you a welcome email with your sandbox credentials and environment details. The sandbox is a full Nayax Core environment where you can test your extension end-to-end before submitting for certification. Once you have access, verify that you can log in to the sandbox Nayax Core instance at the URL provided in the welcome email. </Step> <Step title="Choose your hosting approach"> Your extension runs as a web application hosted at a URL that Nayax Core loads in an iframe. You can host it on your own infrastructure or, in some cases, on Nayax-provided infrastructure. Host your application at a publicly accessible HTTPS URL. You will provide this URL to Nayax when your app is registered in the sandbox menu. </Step> <Step title="Implement the required integrations"> Before you can test your extension end-to-end, implement the four areas the App Framework requires. **[Authentication](/docs/core-extension/authentication):** Receive the JWT token Nayax passes to your app at load time and use it for all Nayax API calls. **[Extension Types](/docs/core-extension/extension-types):** Choose the display type that fits your use case (Screen, Fullscreen, Button with Popup, or Tab) and implement the matching token delivery method. **[Translations](/docs/core-extension/translations):** Wrap all user-visible text in the translation function so Nayax Core can serve your UI in the user's language. **[Role-Based UI Visibility](/docs/core-extension/role-based-visibility):** Register the UI elements your app exposes so Nayax Core administrators can control visibility by role. </Step> <Step title="Register your app in the sandbox"> Once your application is hosted and the integrations are in place, provide Nayax with: * The URL of your hosted application * The display type you are using (Screen, Fullscreen, Button with Popup, or Tab) * The menu location where your app should appear * The scopes your app requires (if any) Nayax registers your app in the Nayax Core sandbox menu manually. You will receive confirmation once your app is visible in the sandbox environment. </Step> <Step title="Test in sandbox"> With your app registered, log in to the sandbox Nayax Core as a user who has access to your menu item. Verify: * Your extension loads at the correct URL * You receive a valid JWT token (check your browser console or network tab) * API calls made with the token return the expected data * UI text displays in the correct language when you switch the Nayax Core language setting * Role-controlled elements show and hide correctly based on the user's role </Step> <Step title="Submit for certification"> When your extension passes testing in the sandbox, contact Nayax to request certification. Nayax reviews your app before approving it for production. </Step> <Step title="Deploy to production"> After certification, Nayax registers your app in the production Nayax Core environment. Deploy your application to your production hosting infrastructure and verify that it loads correctly with the production JWT public key. See [Authentication](/docs/core-extension/authentication) for the production public key and token validation details. </Step> </Steps> ## Summary You have walked through the full Core Extension lifecycle: sandbox access, implementation, sandbox registration and testing, certification, and production deployment. The next steps are to implement each technical area in detail using the guides below. <CardGroup> <Card title="Authentication" icon="key" href="/docs/core-extension/authentication"> Receive and validate the JWT token. </Card> <Card title="Extension types" icon="window-restore" href="/docs/core-extension/extension-types"> Choose and implement the right display type. </Card> <Card title="Translations" icon="language" href="/docs/core-extension/translations"> Expose your UI strings for multi-language support. </Card> <Card title="Role-based visibility" icon="shield-halved" href="/docs/core-extension/role-based-visibility"> Declare which UI elements are role-controllable. </Card> </CardGroup> # Overview Source: https://devzone.nayax.com/docs/core-extension/overview Learn how Core Extension lets you embed your application inside the Nayax back-office. Core Extension is the Nayax App Framework for external developers. It lets you build an application that loads directly inside the Nayax back-office (Nayax Core), giving your users a seamless experience without leaving the platform. ## How it works When a Nayax administrator adds your app to the menu, it appears to their users as a native part of Nayax Core. When a user opens it, Nayax passes your app a signed JWT token containing the user's identity and permissions. Your app uses that token to make Nayax API calls on behalf of the logged-in user. Nayax handles: * Registering your app in the menu * Delivering the authentication token * Routing API calls through the reverse proxy * Managing translations across languages * Controlling which user roles can see which parts of your UI You handle: * Building and hosting your application * Receiving the token and using it for API calls * Exposing your UI strings for translation * Declaring which UI elements are role-controllable ## Extension types How your app appears in Nayax Core depends on the display type configured by the Nayax administrator. Each type controls the layout, navigation, and how your app receives its token. * **Screen** — Full page with the Nayax Core navigation menu visible. No screen context passed. * **Fullscreen** — Full page without the Nayax menu; your app provides its own navigation. No screen context passed. * **Button with Popup** — A button in an existing screen that opens your app in a modal. Includes screen context (e.g. selected machine ID). * **Tab** — Your app loads as a tab within an existing Nayax Core screen. Includes screen context (e.g. selected machine ID). **Screen** and **Fullscreen** use the **App** menu type. **Button with Popup** and **Tab** use the **App Plugin** menu type. <Note> Fullscreen extensions cannot receive the token via postMessage. If your app uses the Fullscreen display type, contact Nayax to confirm the token delivery method. See [Authentication](/docs/core-extension/authentication) for details. </Note> ## What you implement Each of the four areas below has a dedicated guide: * [Authentication](/docs/core-extension/authentication) — Receive and validate the JWT token Nayax passes at load time. * [Extension Types](/docs/core-extension/extension-types) — Choose the right display type for your use case. * [Translations](/docs/core-extension/translations) — Expose your UI strings so Nayax Core can serve them in the user's language. * [Role-Based Visibility](/docs/core-extension/role-based-visibility) — Declare which UI elements admins can show or hide by role. ## Getting started To start building, follow the [Get Started guide](/docs/core-extension/get-started). It walks you through the developer journey from sandbox access to production deployment. # Implement Role-Based UI Visibility Source: https://devzone.nayax.com/docs/core-extension/role-based-visibility Let Nayax Core administrators show or hide parts of your Core Extension based on user roles. Nayax Core has a role management system that lets administrators control what users can see and do based on their role. You can connect your Core Extension to this system so that specific UI elements in your app (tabs, buttons, widgets, settings sections) are automatically shown or hidden based on the logged-in user's role. Your app fetches the list of hidden elements from Nayax at startup, then applies visibility throughout your UI. ## Prerequisites * Your Core Extension is registered with Nayax and has a model name (for example, `Apps/YourAppName`) * You have identified the UI elements in your app that should be role-controllable <Steps> <Step title="Define your UI element IDs"> Assign a string ID to each UI element you want to make role-controllable. Use this naming convention: ```text theme={null} {category}.{name} ``` * **Category:** one of `tab`, `widget`, `action`, `settings`, `sidebar`, `topMenu` * **Name:** camelCase identifier for the element Examples: ```text theme={null} tab.overview tab.settings action.restartDevice action.exportReport widget.salesSummary settings.notifications ``` Keep a list of all element IDs you define. You will provide this list to Nayax so administrators can configure role permissions for each one. <Note> Element IDs are case-sensitive. Use consistent casing throughout your app and in the list you submit to Nayax. </Note> </Step> <Step title="Fetch hidden elements at startup"> When your app loads, call the Nayax UI elements endpoint to get the list of elements that should be hidden for the current user: ```bash theme={null} GET /core/apps/ui-elements?model=Apps/YourAppName ``` The endpoint returns a JSON object with a `hide` array: ```json theme={null} { "hide": [ "action.restartDevice", "tab.settings", "widget.communication" ] } ``` Store the result as a set for fast lookup: ```typescript theme={null} async function fetchHiddenElements(model: string): Promise<Set<string>> { try { const response = await fetch( `/core/apps/ui-elements?model=${model}`, { credentials: "include" } ); if (!response.ok) { return new Set(); } const data: { hide: string[] } = await response.json(); return new Set(data.hide); } catch { return new Set(); } } ``` <Note> The endpoint returns an empty `hide` array for users who can see everything (for example, administrators). An empty array is a valid response, not an error. </Note> </Step> <Step title="Apply visibility in your UI"> Create a helper function that checks whether an element should be visible, then use it throughout your UI before rendering each role-controllable element: ```typescript theme={null} let hiddenElements: Set<string> = new Set(); function isVisible(elementId: string): boolean { return !hiddenElements.has(elementId); } ``` Call `fetchHiddenElements` at app startup and store the result before rendering: ```typescript theme={null} hiddenElements = await fetchHiddenElements("Apps/YourAppName"); ``` Then apply visibility checks in your UI: ```typescript theme={null} // Filter a tab list const visibleTabs = allTabs.filter(tab => isVisible(tab.elementId)); // Conditionally render a widget {isVisible("widget.salesSummary") && <SalesSummaryWidget />} // Filter an actions dropdown const visibleActions = allActions.filter(action => isVisible(action.elementId)); ``` </Step> <Step title="Handle the loading state"> The API call takes time. Decide how your app behaves while permissions are loading. The safest approach is to render nothing until the API call resolves, then apply visibility: ```typescript theme={null} let permissionsLoaded = false; async function initApp() { hiddenElements = await fetchHiddenElements("Apps/YourAppName"); permissionsLoaded = true; renderApp(); } ``` Alternatively, you can render all elements immediately and re-render after permissions load. Either approach is valid, but the first avoids a flash of visible content. </Step> <Step title="Provide your element IDs to Nayax"> Nayax administrators configure role permissions using your element IDs. You must provide Nayax with the complete list of element IDs your app exposes so they can be added to the role management system. </Step> </Steps> ## Element ID naming reference Use these categories when defining your element IDs: | Category | Use for | | - | - | | `tab` | Tabs in a tabbed view (for example, `tab.overview`, `tab.reports`) | | `action` | Buttons or menu items that trigger an operation (for example, `action.export`, `action.delete`) | | `widget` | Dashboard cards or data panels (for example, `widget.salesChart`) | | `settings` | Sections within a settings screen (for example, `settings.notifications`) | | `sidebar` | Sidebar navigation items (for example, `sidebar.filters`) | | `topMenu` | Items in a top navigation bar (for example, `topMenu.userMenu`) | ## Error handling The UI elements endpoint is designed to fail open. If the request fails for any reason (network error, authentication issue, server error), your app should show all elements rather than hiding everything. Hiding elements when you cannot confirm permissions would lock users out of your app. The example in [Step 2](#fetch-hidden-elements-at-startup) implements this behavior by returning an empty `Set` on any error. ## Troubleshooting If role-based visibility is not behaving as expected, use the table below to identify the cause. | Symptom | Likely cause | Fix | | - | - | - | | All elements visible despite role configuration | API returned empty array or request failed | Check browser DevTools network tab for the `/core/apps/ui-elements` response | | Specific element not hiding | Element ID not in the `hide` array | Verify your element ID matches exactly what Nayax configured (case-sensitive) | | API returns 404 | App not served through reverse proxy | Access your app through Nayax Core, not directly | | Element IDs not available in role management | IDs not submitted to Nayax | Provide your element ID list to Nayax for registration | ## What's next <CardGroup> <Card title="Translations" icon="language" href="/docs/core-extension/translations"> Expose your UI strings for multi-language support. </Card> <Card title="Authentication" icon="key" href="/docs/core-extension/authentication"> Understand the JWT token your app receives from Nayax. </Card> </CardGroup> # Support Translations Source: https://devzone.nayax.com/docs/core-extension/translations Expose your Core Extension's UI strings to Nayax so users see your app in their language. Nayax Core serves your extension to users in multiple languages. To participate in this system, your app calls the Nayax translation API at startup, retrieves the translated strings for the current user's language, and uses them throughout your UI. You do not manage language files: Nayax manages translations for all registered apps centrally. ## Prerequisites * Your Core Extension is registered with Nayax and has a model name (for example, `Apps/YourAppName`) * Your app is served through the Nayax Core reverse proxy (required for the translation API to be reachable; see [Reverse proxy requirement](#reverse-proxy-requirement)) <Steps> <Step title="Call the translation API at startup"> When your app loads, fetch translations from the Nayax Core translation endpoint: ```bash theme={null} GET /core/apps/translate?model=Apps/YourAppName ``` The endpoint returns a JSON object mapping original English strings to their translations in the user's language: ```json theme={null} { "Welcome": "ברוכים הבאים", "Save": "שמור", "Cancel": "ביטול", "No data available": "אין נתונים זמינים" } ``` If no translation exists for a string, the key is omitted. Your app falls back to the original string in that case. Here is an example implementation that fetches and stores translations at startup: ```typescript theme={null} async function loadTranslations(model: string): Promise<Record<string, string>> { const response = await fetch(`/core/apps/translate?model=${model}`); const data: Record<string, string> = await response.json(); const normalized: Record<string, string> = {}; for (const key of Object.keys(data)) { normalized[key.toLowerCase()] = data[key]; } return normalized; } ``` <Warning> The Nayax backend stores translation keys in lowercase, even if your original strings are mixed case. Always normalize stored keys and lookups to lowercase, or translations will not match. </Warning> </Step> <Step title="Implement a translation function"> Create a function that looks up a string in the loaded translations and falls back to the original if no translation is found: ```typescript theme={null} let translations: Record<string, string> = {}; function t(text: string): string { return translations[text.toLowerCase()] ?? text; } ``` Call `loadTranslations` at app startup and store the result so `t` can use it: ```typescript theme={null} translations = await loadTranslations("Apps/YourAppName"); ``` </Step> <Step title="Wrap your UI strings"> Every user-visible string in your UI must go through `t()`. This includes labels, buttons, table headers, placeholders, empty states, and error messages. ```typescript theme={null} t('Welcome') t('No data available') t('Save') t('Cancel') t('Search...') ``` **Wrap:** * Labels and headings: `t('Welcome')`, `t('No data available')` * Button text: `t('Save')`, `t('Cancel')` * Placeholders, empty states, and error messages: `t('Search...')` **Do not wrap:** * Status values used in code comparisons: `if (status === 'completed')` * CSS class names: `className="bg-green-500"` * Console or debug messages: `console.log('Debug info')` * Template literals with variables: `t(\`Machine \$\`)\` — dynamic keys cannot be matched reliably </Step> <Step title="Use your model name consistently"> The model name in your API call must exactly match the model registered with Nayax. If it does not match, the API still returns HTTP 200 but with an empty object — no error, no translations, and no indication of what went wrong. ```typescript theme={null} await loadTranslations("Apps/YourAppName"); ``` **Common mistakes:** | Wrong | Correct | | - | - | | `App/MyApp` | `Apps/MyApp` | | `apps/myapp` | `Apps/MyApp` | | `MyApp` | `Apps/MyApp` | If your app loads but all text shows in English, verify that your model name matches the one Nayax registered exactly, including capitalization. </Step> <Step title="Provide your strings to Nayax"> Nayax needs a list of all translatable strings from your app in order to add translations for each supported language. Provide this list to Nayax when you register your app or when you add new strings. </Step> </Steps> ## Reverse proxy requirement The translation endpoint uses an absolute path that resolves against your app's origin. Your app must be served through the Nayax Core reverse proxy for this to work. | How your app is accessed | Origin | Translation API resolves to | Works | | - | - | - | - | | Through Nayax Core reverse proxy | `dev.nayax.com` | `dev.nayax.com/core/apps/translate` | Yes | | Directly via your own domain | `your-app.example.com` | `your-app.example.com/core/apps/translate` | No, 404 | If the translation endpoint returns 404, the most likely cause is that your app is being accessed directly rather than through the Nayax Core reverse proxy. Contact Nayax to verify your reverse proxy configuration. ## Troubleshooting If translations are not working as expected, use the table below to identify the cause: | Symptom | Likely cause | Fix | | - | - | - | | API returns 404 | App not served through reverse proxy | Access your app through Nayax Core, not directly | | API returns empty object (`{}`) | Model name mismatch | Verify model name matches Nayax registration exactly | | Translations loaded but UI shows original language | Key case mismatch | Normalize keys and lookups to lowercase | | Some strings not translating | Strings not wrapped in `t()` | Audit your UI for hardcoded text | | Template literal strings not translating | Dynamic keys cannot be statically matched | Use static string arguments in `t()` | ## What's next <CardGroup> <Card title="Role-based visibility" icon="shield-halved" href="/docs/core-extension/role-based-visibility"> Declare which UI elements admins can show or hide by role. </Card> <Card title="Authentication" icon="key" href="/docs/core-extension/authentication"> Understand how your app receives the JWT token from Nayax. </Card> </CardGroup> # Prepaid Card Source: https://devzone.nayax.com/docs/cortina/cortina-faqs/cortina-prepaid-faq Find quick answers and step-by-step guides for the most common questions about **Nayax API integration**, device configuration, transaction tracking, and deployment processes. Navigate the categories below to find solutions and best practices. ### Are all of the calls directed to the same TCP port? <Accordion title="Answer" icon="info-circle"> Yes, that is the most common and standard setup for this type of integration. All communication calls discussed (e.g., StartSession, Sale, Authorization, etc.) are typically directed to the same TCP port on your server, as specified in the base URL provided to Nayax. </Accordion> ### How can we direct the calls to a particular port? <Accordion title="Answer" icon="info-circle"> You direct the calls to a specific port by appending the port number, preceded by a colon (`:`), to the customer's base URL. | Component | Example | | :- | :- | | **Customer URL** | `XXX.com` | | **Desired Port** | `1234` | | **Full URL Setup** | **`XXX.com:1234`** | This format ensures all calls (e.g., `StartSession`, `SaleEndNotification`, etc.) are directed to that specific port on the customer's server. </Accordion> ### How can we track a transaction? <Accordion title="Answer" icon="info-circle"> Your primary identifier for tracking a transaction on your system is the **Transaction ID** field. You can send us any Transaction ID you desire, provided it meets the following criteria: * It must be made up of **36 numeric characters**. * It must be included and encrypted in the `StartSession` response body. (For full details, please refer to the [Start Session authentication process](/docs/cortina/start-session/cortina-auth#/)). To see which Nayax internal ID matches your Transaction ID, refer to the subsequent requests, such as the `Sale` request. > **Example:** In the `Sale` request, you will find: > > * Your Transaction ID (in your system's context). > * Nayax's matching Transaction ID. <Frame> <img /> </Frame> </Accordion> ### How do I identify which of my machines the transaction is coming from? <Accordion title="Answer" icon="info-circle"> You can identify the machine from which the transaction originated by checking the **`Sale` request** data. ### 1. Recommended Method: `MachineInfo` The best method is to use the **`Id` field** found within the **`MachineInfo`** object in the request. * This `Id` represents your **virtual machine's ID**. * **Recommendation:** We suggest matching by the virtual machine ID because it is less likely to change than the physical device (e.g., if you swap a payment terminal). > **Action Item:** We recommend adding a column to your internal tracking table that correlates the `MachineInfo.Id` with the physical location of the device. ### 2. Alternative Method: `DeviceInfo` You can also identify the source using the physical device's serial number, which is sent within the **`DeviceInfo`** object. This is a less reliable long-term key if device swaps are common. <Frame> <img /> </Frame> <Frame> <img /> </Frame> </Accordion> ### What are the endpoints for each of the commands? <Accordion title="Answer" icon="info-circle"> Each method has its own endpoint, as specified in the URL provided to Nayax. The structure is: `(customer's URL)/Cortina/ followed by the command/integration path`. ### 1. Simple Commands (Session & Notification) These commands use a direct path structure: | Command | Endpoint Example | | :- | :- | | **StartSession** | `(customer's URL)/Cortina/StartSession` | | **SaleEndNotification** | `(customer's URL)/Cortina/SaleEndNotification` | *** ### 2. PrePaid Integration Commands These commands include the integration type (`PrePaid`) in the path: | Command | Endpoint Example | | :- | :- | | **Authorization** | `(customer's URL)/Cortina/PrePaid/Authorization` | | **Settlement** | `(customer's URL)/Cortina/PrePaid/Settlement` | | **Cancel** | `(customer's URL)/Cortina/PrePaid/Cancel` | | **Sale** | `(customer's URL)/Cortina/PrePaid/Sale` | | **Void** | `(customer's URL)/Cortina/PrePaid/Void` | </Accordion> ### Where do I get the consumer's card details? <Accordion title="Answer" icon="info-circle"> The consumer's card details are found within the **`CardData`** object, which is included in the **`Sale` request**. <Frame> <img /> </Frame> </Accordion> <br /> <br /> # StaticQR Source: https://devzone.nayax.com/docs/cortina/cortina-faqs/faq-2 Find quick answers and step-by-step guides for the most common questions about Nayax API integration, device configuration, transaction tracking, and deployment processes. Navigate the categories below to find solutions and best practices. ### How do I whitelist Nayax's IPs? <Accordion title="Answer" icon="info-circle"> To ensure that your system reliably receives communication from Nayax (such as `StartSession` and `SaleEndNotification` requests), you must configure your network firewall to **whitelist Nayax's server IP ranges**. You have two options for configuring these rules, both of which cover the same necessary range of addresses. ### Option 1: Full Range Whitelist (Recommended) This is the simplest method, using a single CIDR block that covers all current Nayax server IPs. This is the **recommended approach** for ease of maintenance. * **Single CIDR Block:** **`185.159.232.0/22`** ### Option 2: Server-Specific Whitelist Use this option if your firewall configuration requires more granular rules or if you need to segregate rules by geographic location. | Server Location | CIDR Block | | :- | :- | | **Israel (IL)** | `185.159.232.0/24` | | **Germany (DE)** | `185.159.234.0/24` | | **United States (US)** | `185.159.233.0/24` | </Accordion> ### What are the endpoints for each of the commands? <Accordion title="Answer" icon="info-circle"> Each command has its own endpoint, based on the URL you provided to Nayax. The format depends on the command. `SaleEndNotification` uses this format: | Command | Endpoint | | :- | :- | | **SaleEndNotification** | `(customer's URL)/Cortina/SaleEndNotification` | The other commands also include the integration type (`StaticQR`) in the path: | Command | Endpoint | | :- | :- | | **Authorization** | `(customer's URL)/Cortina/StaticQR/Authorization` | | **Settlement** | `(customer's URL)/Cortina/StaticQR/Settlement` | | **Cancel** | `(customer's URL)/Cortina/StaticQR/Cancel` | | **Sale** | `(customer's URL)/Cortina/StaticQR/Sale` | | **Void** | `(customer's URL)/Cortina/StaticQR/Void` | </Accordion> ### \[UniQR] how do I use the QR sticker that comes with the device to wake up the machine (instead of the device's SN)? <Accordion title="Answer" icon="info-circle"> First, connect the sticker to your device via the MOMA app. See [How to Connect Your Unattended Machine via the MoMa 2.0 App and Your QR Code Sticker](https://www.youtube.com/watch?v=DLaMQ-x-ra8) to learn more. Once connected, Nayax's servers establish a link between the scanned URL and the device: The Smart Sticker ID is matched to the device's virtual machine ID. When scanned, the QR code generates a long URL that contains the specific identifier required for the transaction. <Frame> <img /> </Frame> <Frame> <img /> </Frame> In the example above, the smart sticker ID is 907531, and when I hover my phone over the QR, I get the following URL: [https://preview.page.link/m.monyx.com/?link=https://m.monyx.com/?data%3D1;https://qr.nayax.com/v1/rWg\_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2\&apn=com.monyx.wallet\&isi=1455956409\&ibi=com.monyx.wallet](https://preview.page.link/m.monyx.com/?link=https://m.monyx.com/?data%3D1;https://qr.nayax.com/v1/rWg_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2\&apn=com.monyx.wallet\&isi=1455956409\&ibi=com.monyx.wallet) <Note> **Note:** You need to use only the part which starts with [http://qr.nayax.com/v1/x](http://qr.nayax.com/v1/x) (until the "&"), meaning in my case I'd use [https://qr.nayax.com/v1/rWg\_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2](https://qr.nayax.com/v1/rWg_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2). </Note> You would use "UniQR" field instead of "TerminalID", and insert the value of the QR code (Not the number written on it) as the value of it: <Frame> <img /> </Frame> </Accordion> ### Creating QRs of your own <Accordion title="Answer" icon="info-circle"> If you want to use a custom QR code that directs users to your own application, you must integrate a Nayax-provided HASH code into your URL. ```text theme={null} /{hashCode} ``` Nayax will provide a list of HASH details, including a unique UniQRCode (the HASH) for each machine. <Frame> <img /> </Frame> 1. Take your desired link (e.g., [https://YourApp.com](https://YourApp.com)) and append the HASH code to the end: <Frame> <img /> </Frame> 2. Use the MOMA app to scan and attach the original Nayax QR sticker to the desired virtual machine: **Actions > Attach a sticker > Scan the original QR**. <Frame> <img /> </Frame> 3. Now you can use the: ```text theme={null} /{hashCode} ``` Once linked, the UniQRNumber will appear in your virtual machine's Smart Sticker ID field, confirming the match. #### Example Let's say that I've got a customer who is named "MagicQR," and they want to generate their own QR code and have it be able to trigger their app, and they've got this UniQRNumber and UniQRCode: <Frame> <img /> </Frame> They would first need to link the UniQRCode to the MoMa app, as mentioned above (to get the UniQRNumber linked to the desired virtual machine), then link the hash. After the link was made, they would use the same hash in their own URL: [https://MagicQR.com/IzwdM76Sh3kIw9pCXk8SOsE3WcLO6jrslw\_eeT4yn3gUjg2](https://MagicQR.com/IzwdM76Sh3kIw9pCXk8SOsE3WcLO6jrslw_eeT4yn3gUjg2) This would mean that once a consumer has scanned this URL and MagicQR is ready to direct them for payment, they would need to take the hash at the end of the URL and revert it to the UniQRCode provided by Nayax, and then have "Start" include the URL in the "UniQR" field: <Frame> <img /> </Frame> ```json theme={null} { "AppUserID": "9999", "UniQR": "https://qr.nayax.com/v1/rWg_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2", "TransactionId": "123456", "SecretToken": "*****" } ``` </Accordion> # DynamicQR Source: https://devzone.nayax.com/docs/cortina/cortina-faqs/faq-3 Find quick answers and step-by-step guides for the most common questions about Nayax API integration, device configuration, transaction tracking, and deployment processes. Navigate the categories below to find solutions and best practices. ### How to upload the logo to the devices? <Accordion title="Answer" icon="info-circle"> The complete logo package is made up of **five separate files**, with each file serving a different purpose on the device (e.g., DQR payment method, brand selection screens). ### 1. File Delivery and Transfer 1. **Receive FTP Links:** After the logo files are finalized, you will receive **one unique FTP link per file**. 2. **Transfer Files Individually:** You must send **each file separately** to your device using its respective FTP link. 3. **Wait and Process:** You must **wait for the burning process to complete** on the device after sending one file before you send the next one. <Frame> <img /> </Frame> ### 2. Monitoring the Burning Process You can check the result of the file transfer and burning process in the **Last Alerts** section of your device management system. The result is indicated by the **Return Code (RC)** displayed in the top line of the alert. | Return Code | Status | Description | | :- | :- | :- | | **RC0** | **Successful** | The file was burned and installed successfully. | | **RC17** | Unsuccessful | The file already exists on the device. | | **RC41** | Unsuccessful | Bad or no response was received from our server. | | **Any other value** | Unsuccessful | Indicates a failure in the burning process. | The FTP links would be of the following format: ``` 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/CustomerName/PI/CustomerNameButton.png;;8b41;PI\CustomerNameButton.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/CustomerName/PI/CustomerNameLargerot.png;;5168;PI\CustomerNameLargerot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/CustomerName/PI/CustomerNameMediumrot.png;;624f;PI\CustomerNameMediumrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/CustomerName/PI/CustomerNameSmallrot.png;;f8c4;PI\CustomerNameSmallrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/CustomerName/QrLogo/CustomerNameSquare_105.png;;b290;QrLogo\CustomerNameSquare_105.png; ``` Should you have multiple channels, you would have places where there's "CustomerName" for each channel.\ For example, if I have 2 channels called "ChannelA" and "ChannelB" - you would get 10 files (5 images per channel) and the format would look something like this: ``` 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelA/PI/CustomerNameButton.png;;8b41;PI\ChannelAButton.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelA/PI/CustomerNameLargerot.png;;5168;PI\ChannelALargerot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelA/PI/CustomerNameMediumrot.png;;624f;PI\ChannelAMediumrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelA/PI/CustomerNameSmallrot.png;;f8c4;PI\ChannelASmallrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelA/QrLogo/CustomerNameSquare_105.png;;b290;QrLogo\ChannelASquare_105.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelB/PI/CustomerNameButton.png;;8b41;PI\ChannelBButton.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelB/PI/CustomerNameLargerot.png;;5168;PI\ChannelBLargerot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelB/PI/CustomerNameMediumrot.png;;624f;PI\ChannelBMediumrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelB/PI/CustomerNameSmallrot.png;;f8c4;PI\ChannelBSmallrot.png; 4010000;devicecoreftp.nayax.net;21;embeddedro;Ioh1Eqgv;/PaymentIcons/ChannelB/QrLogo/CustomerNameSquare_105.png;;b290;QrLogo\ChannelBSquare_105.png; ``` </Accordion> ### When should I send the logos? <Accordion title="Answer" icon="info-circle"> You only need to send the logo files **once per device**. Once you send the logos and confirm a **successful burn** (indicated by an **RC0** in **Last Alerts**), the files are permanently stored on that device. * The logos will **remain on the device** even if you perform a simple reset or a full reset-default of the machine. * You **do not need to send them again** unless the logo design itself changes, requiring a new file deployment. </Accordion> ### Which image type should you send us for the logo? <Accordion title="Answer" icon="info-circle"> To ensure the best possible display across all devices, we strongly prefer the image file type you should submit. ### 1. **Preferred Format: SVG (Scalable Vector Graphics)** * **Format:** **SVG** * **Key Advantage:** SVG is a **vector format**, meaning its resolution is independent of size. You can scale it infinitely without any loss of quality or pixelation, and its file size remains minimal. ### 2. **Alternative Format: PNG** * **Format:** **PNG** * **Requirement:** If SVG is not available, provide a **PNG** image of the **maximum size** and highest resolution possible. ### 3. **Image Reference** * **Format:** **Image Reference (URL/Source)** * **Use Case:** Sending a link or reference to the source image is also acceptable if a direct file submission is difficult. Once we receive your image(s) or references, we will process them internally to ensure they are optimized and displayed correctly on our devices. </Accordion> # Cortina FAQs Source: https://devzone.nayax.com/docs/cortina/cortina-faqs/index This FAQ section provides detailed technical information for integrating your system with Nayax's Cortina payment methods. Here you'll find solutions for setup, communication, and managing branding across our supported integrations. <CardGroup> <Card icon="wallet" title="Prepaid Card" href="/docs/cortina/cortina-faqs/cortina-prepaid-faq"> Quick answers on Cortina API endpoints, port setup, transaction tracking, and identifying the source machine. </Card> <Card icon="qrcode" title="StaticQR" href="/docs/cortina/cortina-faqs/faq-2"> IP whitelisting details, API endpoints (customer/Nayax initiated), and UniQR sticker integration process. </Card> <Card icon="rotate" title="DynamicQR" href="/docs/cortina/cortina-faqs/faq-3"> Instructions for uploading the 5-file logo package via FTP, required SVG/PNG file types, and checking the RC status. </Card> </CardGroup> <br /> # Integration Process Source: https://devzone.nayax.com/docs/cortina/cortina-integration Cortina's integration process follows several stages, ensuring the solution is implemented and tested before going live. The diagram below illustrates the integration process. <Frame> <img /> </Frame> The steps in this process are as follows: 1. **Kickoff**: The Integrator and Nayax teams hold an initial meeting to align expectations, define high-level goals, and introduce the stakeholders from the Integrator's project, the technical teams, the Nayax Integration Engineer, and the Product Team. 2. **Scoping**: The Integrator completes a detailed onboarding form that clearly defines the integration requirements, use cases, limitations, and any necessary project dependencies. 3. **Test Environment Setup**: The Nayax Integration Engineer establishes the internal setup according to the scoping form. They configure any required networking, such as a VPN, the testing device, and the corresponding machine on Nayax Core. 4. **Development**: The Integrator begins implementing the Cortina API. The Nayax Integration Engineer provides consultation and resolves any technical queries or issues that may arise. 5. **Testing & Certification**: The Integrator validates their solution by performing internal testing. The Integrator then completes the mandatory Cortina Certification tests to ensure the solution is implemented correctly. The Integrator must also finalize all required additional certifications, such as EMV L3. 6. **Production Setup**: Once Certification is approved, the Nayax Integration Engineer configures the approved integration on the Nayax Production server and completes any final networking requirements in the live environment.\ At this point the token used during the integration is replaced with a new one for production. 7. **Pilot**: The project launches a pilot with a limited number of active devices to verify real-world performance. This pilot runs for an agreed time or transaction volume, and the Integrator must resolve any issues discovered during this phase. 8. **Finalization**: Once both parties agree that all issues are resolved and the pilot results are satisfactory, the project transitions to ongoing support. Both sides share the contact details for their respective Production support, NOC, and operational teams. <br /> # Credit Card Source: https://devzone.nayax.com/docs/cortina/credit-card/cortina-credit-card-flows Cortina supports credit card payment processing. The process involves standard card verification steps, including pre-authorization, sale, cancellation (reversal), and void for card-present (swipe and chip) and card-not-present transactions. Cortina supports two types of Credit Card transaction flows: * Pre-selection * Pre-authorization Both flows involve interactions between components, including the Nayax Device, Nayax Engine, and Integrator. See the sections below for more details on each flow. ## Pre-selection The Pre-selection flow simplifies the payment process by merging the steps of product/service selection and authorization into a single transaction. This flow is typically used for low-value or quick transactions, where the consumer’s selection and payment authorization are handled in a single step. See the diagram below: <Frame> <img /> </Frame> The steps in this process are as follows: 1. The consumer presents a card (Insert, tap, or swipe) to the Nayax Device. 2. The Nayax Device sends a Begin Vending Session command to the Operator Service Machine. 3. The consumer selects a product, and the Operator Service Machine sends a Vend Request to the Nayax Device. 4. The Nayax Device sends an Authorization Command Request to the Nayax Server. 5. The Nayax Server sends a /Start Session request to the Payment Provider via the [Start Session](/reference/cortina/cortina/post-start-session) endpoint. 6. The Nayax Server sends a /Sale request to the Payment Provider via the [Credit Card Sale](/reference/cortina/cortina-credit-card/cortina-credit-card-sale) endpoint. 7. The Nayax Server returns an Authorization Command Response (Approved) to the Nayax Device. 8. The Nayax Device sends a Vend Approved command to the Operator Service Machine. 9. The product is dispensed, and the Operator Service Machine sends a Vend Success notification to the Nayax Device. 10. The Nayax Device sends a Settlement Command Request to the Nayax Server. 11. (Optional) The Nayax Server sends a /SaleEndNotification to the Payment Provider via the [Sale End Notification](/reference/cortina/cortina/post-sale-end-notification) endpoint. 12. The Nayax Server returns a Settlement Command Response (Always Approved) to the Nayax Device, which then displays a "Thank you" message. This response is typically always approved in this flow, as the authorization has already been granted. ### Exception Handling In the event of a failure at any critical junction (marked with a black circle in the diagram), the transaction is terminated. Since the **Sale** occurs before the product is dispensed in this flow, specific Void logic is required to ensure the cardholder is not charged for failed transactions. | Scenario | Diagram Step Reference | Technical Resolution | | :- | :- | :- | | **Selection Timeout** | 3.b | Occurs if the consumer fails to choose a valid product within the machine's allowed timeframe. The session ends before any payment request is made. | | **Start Session Failed** | 5.b | Occurs if the `/Start Session` request times out or returns an error. The process is aborted before the Sale request. | | **Sale Request Failed** | 6.b | If the `/Sale` request fails, returns an error, or receives a **`992`** response code, the session is aborted. In cases of a gateway timeout, the [Credit Card Void](/reference/cortina/cortina-credit-card/cortina-credit-card-void) endpoint is triggered with the flag `isGatewayTimeout: True`. | | **Vend Failed** | 9.b | If the machine fails to dispense the product (e.g., mechanical jam) after a successful sale, the Nayax Engine triggers the [Credit Card Void](/reference/cortina/cortina-credit-card/cortina-credit-card-void) endpoint to reverse the transaction. | | **Notification Failure** | 11.b | Occurs if the optional `/SaleEndNotification` fails. This is a non-critical reporting step; the consumer has already received the product, so the error is simply logged for reconciliation. | <Note> For a comprehensive list of financial response codes and authorization failures, refer to the [Credit Card Decline Reasons](/docs/cortina/credit-card/credit-card-decline-reasons) page. </Note> ## Pre-Authorization The Pre-authorization flow is used for transactions that require a two-step process. First, a session is initiated, followed by an authorization check. This flow ensures the transaction is valid and the consumer has sufficient funds before settlement. See the diagram below: <Frame> <img /> </Frame> Where: 1. The consumer presents a card (Insert, tap, or swipe) to the Nayax Device. 2. The Nayax Device sends an Authorization Command Request to the Nayax Server. 3. The Nayax Server sends a /Start Session request to the Payment Provider via the [Start Session](/reference/cortina/cortina/post-start-session) endpoint. 4. The Payment Provider returns a Start Session Response Success to the Nayax Server. 5. The Nayax Server sends an /Authorization request (default amount) to the Payment Provider via the [Credit Card Authorization](/reference/cortina/cortina-credit-card/cortina-credit-card-authorization) endpoint. 6. The Nayax Server returns an Authorization Command Response (Approved) to the Nayax Device. 7. The Nayax Device sends a Begin Vending Session command to the Operator Service Machine. 8. The consumer selects a product, and the Operator Service Machine sends a Vend Request (Code, price) to the Nayax Device. 9. The Nayax Device sends a Vend Approved (Always approved) response to the Operator Service Machine. 10. The product is dispensed, and the Operator Service Machine sends a Vend Success notification to the Nayax Device. 11. The Nayax Device sends a Settlement Command to the Nayax Server. 12. The Nayax Server sends a /Settlement request (Final Amount) to the Payment Provider via the [Credit Card Settlement](/reference/cortina/cortina-credit-card/cortina-credit-card-settlement) endpoint. 13. The Nayax Server returns a Settlement Command Response (Approved) to the Nayax Device, which then displays a "Thank you" message. ### Exception Handling In the event of a failure at any critical junction (marked with a black circle in the diagram), the transaction is terminated. Because a hold is placed on the cardholder's funds during the authorization step, specific cleanup actions (Cancellations) are required if the vend is not completed. | Scenario | Diagram Step Reference | Technical Resolution | | :- | :- | :- | | **Start Session Failed** | 4.b | Occurs if the `/Start Session` request times out or returns an error. The session is aborted before any funds are authorized. | | **Authorization Failed** | 5.b | Occurs if the provider denies the default credit amount. The transaction is terminated and the consumer is typically notified on the device. | | **Selection Timeout** | 8.b | Occurs if the consumer fails to choose a valid product within the machine's allowed timeframe. The session is closed. | | **Vend Failed** | 10.b | If the machine fails to dispense the product (e.g., mechanical jam), the system triggers the [Credit Card Cancel](/reference/cortina/cortina-credit-card/cortina-credit-card-cancel) endpoint to release the pre-authorized hold. | | **Settlement Failed** | 12.b | Occurs if the final settlement request fails or times out. This requires internal logging for manual reconciliation with the provider. | | **Timeout / 992 Code** | N/A | If no sale response is received within the timeout period, or a `992` code is returned, the [Credit Card Cancel](/reference/cortina/cortina-credit-card/cortina-credit-card-cancel) endpoint is called with the flag `isGatewayTimeout: True`. | <Note> For a comprehensive list of financial response codes and authorization failures, refer to the [Credit Card Decline Reasons](/docs/cortina/credit-card/credit-card-decline-reasons) page. </Note> # Credit Card Decline Reasons Source: https://devzone.nayax.com/docs/cortina/credit-card/credit-card-decline-reasons When a transaction is declined, the Cortina API returns a specific decline reason code that explains why the payment was not approved. These codes are essential for integrators and merchants to understand the cause of the decline and take appropriate action. The third-party integrator is responsible for returning the response, including the corresponding decline code from the list, based on the payment method used. The following decline reason codes are used when processing Credit Card transactions: | **Code** | **Description** | | - | - | | 1 | Refer to card issuer | | 2 | Refer to card issuer's special conditions | | 3 | Invalid merchant | | 4 | Pick-up | | 5 | Do not honor | | 6 | Error | | 7 | Pick-up card, special condition | | 8 | Honor with identification | | 9 | Request in progress | | 10 | Approved for partial amount | | 11 | Approved (VIP) | | 12 | Invalid transaction | | 13 | Invalid amount | | 14 | Invalid card number (no such number) | | 15 | No such issuer | | 16 | Approved, update track 3 | | 17 | Customer cancellation | | 18 | Customer dispute | | 19 | Re-enter transaction | | 20 | Invalid response | | 21 | No action taken | | 22 | Suspected malfunction | | 23 | Unacceptable transaction fee | | 24 | File update not supported by receiver | | 25 | Unable to locate record on file | | 26 | Duplicate file update record, old record replaced | | 27 | File update field edit error | | 28 | File update file locked out | | 29 | File update not successful, contact acquirer | | 30 | Format error | | 31 | Bank not supported by switch | | 32 | Completed partially | | 33 | Expired card | | 34 | Suspected fraud | | 35 | Card acceptor contact acquirer | | 36 | Restricted card | | 37 | Card acceptor call acquirer security | | 38 | Allowable PIN tries exceeded | | 39 | No credit account | | 40 | Requested function not supported | | 41 | Lost card | | 42 | No universal account | | 43 | Stolen card, pick-up | | 44 | No investment account | | 51 | Not sufficient funds | | 52 | No checking account | | 53 | No savings account | | 54 | Expired card | | 55 | Incorrect personal identification number | | 56 | No card record | | 57 | Transaction not permitted to cardholder | | 58 | Transaction not permitted to terminal | | 59 | Suspected fraud | | 60 | Card acceptor contact acquirer | | 61 | Exceeds withdrawal amount limit | | 62 | Restricted card | | 63 | Security violation | | 64 | Original amount incorrect | | 65 | Exceeds withdrawal frequency limit | | 66 | Card acceptor call acquirer's security department | | 67 | Hard capture (requires that card be picked up at ATM) | | 68 | Response received too late | | 75 | Allowable number of PIN tries exceeded | | 90 | Cutoff is in process | | 91 | Issuer or switch is inoperative | | 92 | Financial institution or intermediate network facility cannot be found for routing | | 93 | Transaction cannot be completed. Violation of law | | 94 | Duplicate transmission | | 95 | Reconcile error | | 96 | System malfunction | | 201 | Cardholder exceeded transaction amount limit | | 202 | Provider general system failure | | 203 | Request cannot be parsed (format error) by Provider | | 204 | Provider did not receive mandatory parameters | | 205 | Transaction is already refunded | | 206 | Refund amount cannot be greater than original amount | | 207 | Unknown Terminal ID | | 983 | SCA - Soft Decline | | 990 | CertificateFileName not found | | 991 | Failed to decipher message body | | 992 | Timeout exception | | 994 | Card Brand not supported | | 996 | Transaction ID Unknown / Duplicate Transaction ID (Start Session Error) | | 997 | Nayax did not receive mandatory parameters | | 998 | Validation / request cannot be parsed | | 999 | General exception | | 1010 | Public Key Certificate not found | | 1011 | Method not Implemented | | 1012 | Cardholder exceeded daily / weekly / monthly transaction count limit | | 1021 | SCA - Switch Interface | # EMV Response Tags Source: https://devzone.nayax.com/docs/cortina/credit-card/emv-response-tags When processing EMV contact credit card transactions, including the EMV response tags in your authorization/sale response is critical to ensure seamless communication between the issuer, terminal, and chip card. * **Mandatory** EMV Response tags: * Tag 8A: Authorization Response Code * Tag 91: Issuer Authentication Data * **Optional** EMV response tags: * Tag 71 & Tag 72: Issuer Scripts These tags carry issuer-provided instructions (scripts) that the terminal sends back to the card. They update card parameters or manage lifecycle events (e.g., block cards and update limits). Failing to return the mandatory EMV response tags in a contact transaction (8A and 91), or returning them incorrectly, may cause the transaction to fail during the second Generate AC step (Second GenAC) and be declined.\ In case the transaction is declined due to incorrect response tags, a Cortina Cancel/Void will be sent with `ReasonCode` as 17 or 18. ## How to implement Return the tag value to the relevant field in the "EMVTags" object for each contact transaction response. ```json theme={null} "EMVTags": { "Tag91": "A93381BFF8C5E9EC0012", "Tag8A": "3030", "Tag71": "860D8424000008D466284E10D1FF7C", "Tag72": "860D8424000008D466284E10D1FF7C"} ``` # Incremental Authorization Source: https://devzone.nayax.com/docs/cortina/credit-card/incremental-authorization-1 Incremental authorization is a payment feature that allows a merchant to request additional funds on a previously authorized transaction without requiring the customer to re-enter their payment credentials. <Note> **Enable Incremental Authorization** Incremental Authorization requires additional configuration on the Nayax side. If you wish to support it, please contact your assigned Nayax integration engineer. </Note> ## How to implement After a successful Authorization, if the merchant asks for Incremental, your endpoint will receive one or more [Cortina Credit Card Incremental Auth](/reference/cortina/cortina-credit-card/cortina-credit-card-incremental-auth) requests. The `BasicInfo.Amount` in this request will be the incremental amount. The `PaymentInfo` object will include the details for the linked authorization. The Response for this request is similar to a regular Authorization response. The final settlement amount will be sent in the Cortina Credit Card Settlement request in the `BasicInfo.Amount` field. # Partial Approval in Authorization Source: https://devzone.nayax.com/docs/cortina/credit-card/partial-approval This feature allows Payment Gateway to approve a lower authorization amount if the cardholder does not have enough balance to cover the full requested amount, increasing the integration's approval rate. The partially approved amount is the amount that can be used for purchase and will limit the settlement amount. ## How to implement In the Authorization endpoint response, set the attributes as follows:\ • `Status.Verdict` = Approved\ • `Status.Code` = 0\ • `PaymentInfo.AuthAmount` = Approve amount for pre-authorization. See the example below: ```json theme={null} {"Status": { "Verdict": "Approved", "Code": 0,}, "PaymentInfo": { "AuthAmount": 5} } ``` # Dynamic Key Exchange Source: https://devzone.nayax.com/docs/cortina/credit-card/pin-processing/dynamic-key-exchange Once a key needs to be renewed (the renewal interval will be discussed during project setup), a Cortina RenewKey request will be sent. The request will include all the details of the current key in the `CurrentKeyData` object. The Payment Gateway should send the new key data in the `NewKeyData` object of the response, as in the example below: ```json theme={null} "NewKeyData": { "EncryptedKeyValue": "D0112P0AB01N00008C27C2DD44ACF35513DCA16B10B7FB9AD47550091AF4FF37C01002E5BA04A1D05057291A4B0EBCA6EE46940224BCE55F", "Kcv": "BC4012", "ExternalKeyId": "376", "additionalProperties": {} } ``` Where: * **EncryptedKeyValue** = the encrypted Key Value, encrypted with the ZMK shared. * **Kcv** = the new Key Check value (content is bytes) * **ExternalKeyId** = The new External Key ID in the payment gateway system. # PIN Processing Source: https://devzone.nayax.com/docs/cortina/credit-card/pin-processing/index A PIN (Personal Identification Number) is a numerical code used to authorize and verify the cardholder in transactions done with debit and credit cards. To protect the PIN during transmission, it must be encrypted using a secure PIN encryption key, which is managed in accordance with PCI PIN Security standards. When a Cardholder enters their PIN at a terminal, the PIN is encrypted by the Nayax terminal using a DUKPT algorithm and sent to the Nayax Engine as a PIN block, which is the encrypted PIN string. Nayax engine sends the PIN Block to MyHSM (Nayax HSM provider) for decryption, then re-encrypts it with a key shared with the Payment Gateway (the integrator). <Note> **Master/Session Key** For Cortina, Nayax supports the Master/Session Key management method only. * **Master Key** is the key exchange key, also known as the Zone Master Key (ZMK). * **Session Key** refers to the PIN encryption key also known as the Zone PIN Key (ZPK). </Note> See the diagram below: <Frame> <img /> </Frame> ## Supported PIN Exchange Methods Nayax supports two methods for PIN key exchange and encryption: * **Manual Key Exchange (Static Key)**: In this approach, the PIN is encrypted using a long-term cryptographic key known as a Zone PIN Key (ZPK). The ZPK is securely exchanged during the setup phase and is manually loaded into the MyHSM system in accordance with PCI requirements. * **Dynamic Key Exchange (Master/Session)**: In this method, the PIN is encrypted using a temporary session key (ZPK), which is dynamically generated and shared via an API by the Payment Gateway. To ensure secure transmission, the session ZPK is encrypted with a static *Zone Master Key (ZMK)*. Like the static ZPK, the ZMK is securely exchanged and preloaded into MyHSM during the initial setup. The PIN exchange process will be initiated by Nayax using Cortina `Renew Key` endpoint, the interval in which the key is exchanged, is configurable and will be discussed during the setup stage of the integration. <Note> **PIN Encryption Algorithm** * Nayax supports TDEA, 2TDEA, 3TDEA, AES-128 and AES-256 * Nayax supports ISO 0-4 or ANSI PIN Block format. Please contact your Nayax Integrator for more details. </Note> # Receive the PIN Block Source: https://devzone.nayax.com/docs/cortina/credit-card/pin-processing/receiving-the-pin-block Nayax will send the encrypted PIN Block in the Authorization/Sale request under the `DukptInfo` object as in the example below: ```json theme={null} "DukptInfo": { "Algorithm": 1, "PINBlock": "xxxxxxxx", "PINBlockFormat": 48, "ExternalKeyId": "372"} ``` Where: * `Algorithm` = the algorithm used for encryption. * `1`: TDEA * `2`: 2TDEA * `3`: AES-128 * `4`: AES-256 * `5`: 3TDEA * `PINBlock` = The encrypted PIN Block * `PINBlockFormat` = The Pin block format used. * `1`: ISO\_0 * `5`: ISO\_1 * `34`: ISO\_2 * `47`: ISO\_3 * `48`: ISO\_4 * `ExternalKeyId` = The external ID of the key used in a Dynamic key exchange format. # Strong Customer Authentication (SCA) Source: https://devzone.nayax.com/docs/cortina/credit-card/pin-processing/strong-customer-authentication-sca Strong Customer Authentication (SCA) is a regulatory requirement under the EU’s PSD2 directive, designed to reduce fraud and enhance security during electronic payments. In a card-present transaction, SCA is typically performed through the Cardholder Verification Method (CVM), such as PIN entry, biometric verification (via mobile wallet), or signature, when the transaction amount exceeds the CVM limit. ## Soft decline In some cases, a transaction under the CVM limit will be declined with a Soft Decline. This occurs when a transaction is technically authorized by the issuer (i.e., the card is valid and has sufficient funds). Still, the issuer requests that Strong Customer Authentication (SCA) be performed before authorizing the payment. This is common in cases where the issuer suspects risk (e.g., a contactless tap without CVM after many prior low-value taps) or the transaction exceeds regulatory limits. ### Decline with PIN required In these cases, the acquirer receives a decline code indicating that an Online PIN is required for transaction approval. In that case, the Terminal will keep the transaction session and ask the cardholder to enter their PIN on the PIN pad. The Encrypted PIN will then be sent back to the acquirer for validation before the transaction can be settled. To implement it, return a `Verdict=Declined` with `Code 983` to the Authorization/Sale request. If a transaction were completed with an online PIN, the Nayax engine would return an echoed Authorization/Sale request with a PIN Block under the `DukptInfo` object. ```json theme={null} "Status": { "Verdict": "Declined", "Code": 983, "StatusMessage": "SCA- Soft Declined" } ``` ### Decline with switch interface In these cases, the acquirer receives a decline code indicating that the transaction must be initiated again, using the Contact Interface. In that case, the Terminal will prompt the user to insert his card and perform a transaction with PIN (offline or online). To implement it, return a `Verdict=Declined` with `Code 1021` to the Authorization/Sale request. If a transaction was completed with the contact interface, the Nayax engine will send a new Authorization/Sale request. If an online PIN was performed, the PIN Block will be sent under the `DukptInfo` object. ```json theme={null} "Status": { "Verdict": "Declined", "Code": 1021, "StatusMessage": "SCA- Switch Interface" } ``` # DynamicQR Source: https://devzone.nayax.com/docs/cortina/dynamicqr/cortina-dynamicqr DynamicQR codes enable customers to complete payments by scanning the code with their mobile device, but with an added layer of security generating a unique code for each transaction, ensuring the QR code cannot be reused, making it ideal for high-value or secure transactions. ## How it works The image below describes the typical usage flow of DynamicQR. <Frame> <img alt="" /> </Frame> Where: 1. The consumer starts by selecting a product. 2. The consumer chooses the QR payment option. 3. The device presents the generated QR code. 4. The consumer scans this code to initiate the payment. 5. The payment is processed and approved. <Warning> **Pre-Selection Only** Cortina Dynamic QR currently only supports Pre-Selection transaction types. </Warning> ## Pre-Selection Flow The Pre-selection flow simplifies the payment process by merging the steps of product/service selection and authorization into a single transaction. This flow is typically used for low-value or quick transactions, where the consumer’s selection and payment authorization are handled together in one step. See the diagram below (the numbers inside the brackets relate to the different sources of timeout): <Frame> <img /> </Frame> The steps in this process are as follows: 1. The consumer presents a means of payment at the machine, selecting QR. 2. The Nayax Device sends a Begin Vending Session (Default, credit...) command to the Operator Service Machine. 3. The consumer selects a product, and the Operator Service Machine sends a Vend Request (Code, price...) to the Nayax Device. 4. The Nayax Device sends a Cortina Transaction Initiation request to the Nayax Server. 5. The Nayax Server sends a /Start Session request to the Integrator via the [Start Session](/reference/cortina/cortina/post-start-session) endpoint, and the Integrator returns a Start Session Response Success. 6. The Nayax Server sends a GenerateQR (Amount, Channel) request to the Integrator using the [DynamicQR GenerateQR](/reference/cortina/dynamicqr/cortina-dynamicqr-generateqr) endpoint. 7. The Integrator returns a Response including the QR code data to the Nayax Server. 8. The Nayax Server sends the QR Command Response to the Nayax Device, which then shows the QR code. 9. Once the consumer scans the QR and confirms via mobile, the Nayax Device sends a QR Payment Command Request to the Nayax Server. 10. The Nayax Server sends an Inquiry (Transaction ID) to the Integrator using the [DynamicQR Inquiry](/reference/cortina/dynamicqr/cortina-dynamicqr-inquiry) endpoint. 11. The Integrator returns the Response Status (Approved/Pending) to the Nayax Server. 12. The Nayax Server sends the QR Payment Command Response to the Nayax Device. 13. The Nayax Device sends a Vend Approved command to the Operator Service Machine. 14. The Operator Service Machine dispenses the product and sends a Vend Success notification to the Nayax Device. 15. The Nayax Device sends the Settlement Command to the Nayax Server. 16. The Nayax Server returns the Settlement Command Response (Always Approved) to the Nayax Device, which then displays a "Thank you" message. # DynamicQR Decline Reasons Source: https://devzone.nayax.com/docs/cortina/dynamicqr/dynamicqr-decline-reasons When a transaction is declined, the Cortina API returns a specific decline reason code that explains why the payment was not approved. These codes are essential for integrators and merchants to understand the cause of the decline and take appropriate action. The third-party integrator is responsible for returning the response, including the corresponding decline code from the list, based on the payment method used. The following decline reason codes are used when processing DynamicQR transactions: | **Code** | **Description** | | - | - | | 1 | Insufficient funds | | 2 | Transaction ID unknown | | 3 | Cardholder exceeded daily/weekly/monthly transaction count limit | | 4 | The cardholder exceeded the transaction amount limit | | 5 | Suspected fraud | | 6 | General system failure | | 7 | Invalid amount | | 8 | Request cannot be parsed (format error) | | 9 | Transaction not allowed to cardholder | | 20 | No VPN or MQTT enabled | | 30 | The machine is not responding | | 40 | For Nayax internal use only | | 50 | Unknown machine Id | | 990 | CertificateFileName not found | | 991 | Failed to decipher message body | | 992 | Timeout exception | | 993 | Pending (relevant only for the Inquiry command) | | 994 | Card Brand not supported | | 996 | Transaction ID Unknown / Duplicate Transaction ID (Start Session Error) | | 997 | Missing mandatory parameters | | 998 | Validation/request cannot be parsed | | 999 | General exception | | 1010 | Public Key Certificate not found | | 1011 | Method not Implemented | # GenerateQR Source: https://devzone.nayax.com/docs/cortina/dynamicqr/dynamicqr-generateqr Cortina DQR uses the `GenerateQR` command to notify the integrator about the consumer's product selection in order for them to send the QR generation details.\ The command includes the transaction Id identification (Generated in /StartSession), required Amount, merchant, and Machine details (and more).\ The Cortina payment provider shall validate the information and respond with the Dynamic QR information to be displayed on the Nayax device accordingly. This command is essential for proceeding to the authorization process. ## Request Nayax's servers send a POST request to your configured `GenerateQR` endpoint, which would be of the following format: `(customer's URL)/Cortina/DynamicQR/GenerateQR` The payload includes the full result of the card scan operation: ```json theme={null} { "ChannelId": 19, "BasicInfo": { "TransactionId": "236584335969834429321847829253667359,", "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12 }, "DeviceInfo": null, "MachineInfo": { "Id": 869761713, "Name": "TestPayDynamicQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011 }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "Product": [ { "Code": 11, "Name": "Stella", "Price": 0.1, "UnitOfMeasurement": "USD", "Measurement": 1 }, { "Code": 456, "Name": "expensiveSprite", "Price": 600, "UnitOfMeasurement": "USD", "Measurement": 0 } ] } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & Status</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td><strong>Country/Region ISO Codes</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td><strong>Actor (Merchant/Operator) Details</strong></td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td><strong>Actor Geo Details</strong></td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td><strong>Product/Item Details</strong></td> </tr> <tr> <td>`Code`</td> <td>Int(16)</td> <td> **Code of the selected item**. </td> </tr> <tr> <td>`CatalogProductId`</td> <td>String(100)</td> <td> **External unique identifier** of the selected item (the product catalog number). </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Product name**. </td> </tr> <tr> <td>`Price`</td> <td>Double</td> <td> The **original Product Price** in the machine's currency. <ul> <li>**Note:** The transaction amount is the billing price after adjustments (e.g., surcharge, loyalty).</li> </ul> </td> </tr> <tr> <td>`UnitOfMeasurement`</td> <td>String(64)</td> <td> Product's **unit of measurement** (e.g., 'unit' or 'Liter'). </td> </tr> <tr> <td>`Measurement`</td> <td>Double</td> <td> Product's **quantity** in the unit of measurement. </td> </tr> <tr> <td>`Group`</td> <td>String(255)</td> <td> Product's **group name**. </td> </tr> <tr> <td>`ProductGroupId`</td> <td>String(255)</td> <td> Product's **group code**. </td> </tr> <tr> <td>`PulseLineNumber`</td> <td>Int(32)</td> <td> Used to support remote vend capability via pulse. Must be a **positive integer** $(\ge 0)$. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> </tbody> </table> ## Response The `GenerateQR` Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "QRCode": "QR_URL_to_be_presented_on_the_device's_screen", "QRData": { "ChannelId": "19", "RRN": "111111", "SrvTranId": "236584335969834429321847829253667359" }, "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "Cortina V2 Stub Tester" }, "additionalProperties": false } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Core Identifiers & Status</strong></td> </tr> <tr> <td>`QRCode`</td> <td>String</td> <td> The **QR URL** provided for the device display/interaction. </td> </tr> <tr> <td>`ChannelId`</td> <td>String</td> <td> **Conditional** for multi-channel integrations. An echo of the value provided by Nayax in the request. </td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Common codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and technical errors.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. <ul> <li>Used as External Transaction ID for external parties (e.g., Card schemes).</li> <li>Highly recommended to be visible to the **consumer/card holder** for support.</li> <li>This value must be **echoed** in the `/Inquiry` request.</li> </ul> </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>System & Conditional Flags</strong></td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> </tbody> </table> # Inquiry Source: https://devzone.nayax.com/docs/cortina/dynamicqr/dynamicqr-inquiry Cortina DQR uses the `Inquiry` to inquire the approval status of a Transaction ID. This call will include the transaction’s final amount and the transaction ID generated in the `GenerateQR` call.\ An “Approved” response to this call will usually attempt to vend/release the product.\ A “Decline” will terminate the transaction and a “Pending” response will trigger a subsequent `Inquiry` request after a predefined time. The Cortina payment provider shall validate the information and respond with the Dynamic QR information to be displayed on the Nayax device accordingly. This command is essential for the duration of the authorization process. ## Request Nayax's servers send a POST request to your configured `Inquiry` endpoint, which would be of the following format: `(customer's URL)/Cortina/DynamicQR/Inquiry` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": "236584335969834429321847829253667359", "Amount": 0.1, "Currency": "ILS", "SiteId": 1, "MachineAuTime": "230221101008" }, "Products": [ { "Code": 11, "Name": "Stella", "Price": 0.1, "UnitOfMeasurement": "Unit", "Measurement": 1 } ], "DeviceInfo": { "Id": 0, "HwSerial": "0434324119376524", "FWVersion": "4.0.0.12-RC1 - Sep 22 2020", "Type": "ONYX" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayDynamicQR V2", "TerminalId": "987654321", "DecimalPlace": 2, "Offset": "2.00", "CountryCode": "US", "CountryISOCode": "USA", "Country": "UNITED STATES", "City": "Abbeville", "Address": "TestPayDynamicQR V2", "ZipCode": "1223311" }, "ActorInfo": { "Id": 2001505522, "Name": "TanyaT_OP", "MerchantId": "123456789", "CountryCode": "US" }, "CustomData": { "Actor": "", "Machine": { "dynamic_qr_channels_rec_ids": "8,19" } }, "PaymentInfo": { "SrvTranId": "236584335969834429321847829253667359", "AuthAmount": 0.1, "SettAmount": 0, "RRN": "111111", "IsGatewayTimeout": false }, "Polling": { "IsLastPolling": false, "PollingAttemptCounter": 30 } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Currency Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Time & System Status</strong></td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`IsLastPolling`</td> <td>Bool</td> <td> Flag indicating the **last polling attempt**. </td> </tr> <tr> <td>`PollingAttemptCounter`</td> <td>Int(32)</td> <td> The **current polling attempt number**. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td><strong>Country & Actor Geo Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td><strong>Product & Item Details</strong></td> </tr> <tr> <td>`Code`</td> <td>Int(16)</td> <td> **Code of the selected item**. </td> </tr> <tr> <td>`CatalogProductId`</td> <td>String(100)</td> <td> **External unique identifier** of the selected item (the product catalog number). </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Product name**. </td> </tr> <tr> <td>`Price`</td> <td>Double</td> <td> The **original Product Price** in the machine's currency. <ul> <li>**Note:** The transaction amount is the billing price after adjustments.</li> </ul> </td> </tr> <tr> <td>`UnitOfMeasurement`</td> <td>String(64)</td> <td> Product's **unit of measurement** (e.g., 'unit' or 'Liter'). </td> </tr> <tr> <td>`Measurement`</td> <td>Double</td> <td> Product's **quantity** in the unit of measurement. </td> </tr> <tr> <td>`Group`</td> <td>String(255)</td> <td> Product's **group name**. </td> </tr> <tr> <td>`ProductGroupId`</td> <td>String(255)</td> <td> Product's **group code**. </td> </tr> <tr> <td>`PulseLineNumber`</td> <td>Int(32)</td> <td> Used to support remote vend capability via pulse. Must be a **positive integer** $(\ge 0)$. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> </tbody> </table> ## Response The `Inquiry` Response that the customer's payment method would send to Nayax's servers. Usually the response would be either "Approved" or "Declined" with code 993 which means "pending"- meaning the payment provider is still working on deciding on whether or not to approve the consumer (pending "Approved" or "Declined" response).\ In case of "pending" response, it will lead to Nayax's servers to keep polling until either a final response has been received ("Approved"/"Declined") or it reaches the limit as configured in Nayax Core. The payload should look as follows: <CodeGroup> ```json JSON theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "Cortina V2 Stub Tester" }, "PaymentInfo": { "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "Token": "Cortina V2 Stub Tester Token", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "555555", "AdditionalData": "" } } ``` ```json JSON-Pending theme={null} { "Status": { "Verdict": "Declined", "Code": 993, "StatusMessage": "Pending" }, "PaymentInfo": { "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "Token": "Cortina V2 Stub Tester Token", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "555555", "AdditionalData": "" } } ``` </CodeGroup> ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>**993:** Pending (relevant only for Inquiry)</li> <li>*See full list for other status and technical errors.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Highly recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>System & External Data</strong></td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> </tbody> </table> # Refund Source: https://devzone.nayax.com/docs/cortina/dynamicqr/dynamicqr-refund Cortina DQR uses the `Refund` command to notify the integrator about a refund request, so the integrator can start the refund with the Cortina payment provider. ## How a refund is triggered You can trigger the refund request in two ways: * From the Dynamic Transaction Monitor in Nayax Core. * Through the Lynx API. ### From the Dynamic Transaction Monitor <Warning> **Refunds Admin role required** Requesting and approving a refund from the Dynamic Transaction Monitor requires the Refunds Admin role. Ask your Integration Support Engineer to assign it. </Warning> <Steps> <Step title="Request the refund"> Right-click the relevant transaction and select **Request Refund**. <Frame> <img alt="Nayax Core transaction context menu with Request Refund highlighted" /> </Frame> </Step> <Step title="Approve the refund"> Right-click the same transaction again and select **Approve/Decline Refund**. <Frame> <img alt="Nayax Core transaction context menu with Approve/Decline Refund highlighted" /> </Frame> </Step> </Steps> Nayax then sends the `Refund` command to your endpoint, as described below. ### Through the Lynx API Call the [Request a Payment Refund](/reference/lynx/payment/request-a-payment-refund) endpoint, then the [Approve Payment Refund](/reference/lynx/payment/approve-payment-refund) endpoint. ## Request Nayax's servers send a POST request to your configured `Refund` endpoint, which would be of the following format: `(customer's URL)/Cortina/DynamicQR/Refund` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 0, "ReasonText": "string", "BasicInfo": { "TransactionId": "N99O4XURDQYJZIK4OTCAWF1RHHA40TZWVCRB", "NayaxTransactionId": 3584697384, "Amount": 5, "CurrencyCode": "ILS", "CurrencyNumeric": "376", "SiteId": 1, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true, "PaymentMethodID": 1, "BillingProviderId": 1, "AuditNumber": 342, "NayaxRRN": "111111", "IsDeferredAuthorization": true, "AgeLimitation": 18, "IsSoftDeclineCompletion": true, "TransitElement": { "TransitTransactionType": 1, "DenyListIndication": 0 } }, "DeviceInfo": { "HwSerial": "0434324119376526", "FWVersion": "4.0.0.22-RC01 - Aug 25 2021", "Type": "Onyx" }, "MachineInfo": { "Id": 106791869, "Name": "Itai_TestPayCC V2", "ExternalId": "OperatorExternalID", "Type": "machine type", "TerminalId": "8888888844", "DecimalPlace": 2, "Offset": "3.00", "GroupId": "String", "OperatorId": 2001537302, "Region": "EU", "City": "Abbeville", "ZipCode": "22448Z", "Country": { "Name": "UNITED STATES", "NumericCode": "840", "Alpha2Code": "US", "Alpha3Code": "USA", "Intra": "Europe" }, "GeoLocation": { "State": "Alabama", "City": "Zambezi", "CountryCode": "ZM", "ZipCode": "234234", "Address": "River", "Latitude": 51.0003431, "Longitude": 23.745245 } }, "ActorInfo": { "Id": 2001537302, "Name": "TestPayCC V2 OP", "OperatorId": 2001537302, "OperatorName": "TestPayCC V2 OP _ Sub Merchant", "MerchantId": 999999888885, "DynamicURL": "https://www.nayax.com/alternativeURL", "Country": { "Name": "UNITED STATES", "NumericCode": "840", "Alpha2Code": "US", "Alpha3Code": "USA", "Intra": "Europe" }, "GeoLocation": { "State": "Alabama", "City": "Zambezi", "CountryCode": "ZM", "ZipCode": "234234", "Address": "River", "Latitude": 51.0003431, "Longitude": 23.745245 }, "MCC": 455, "SubMerchantId": 999999888886 }, "CustomData": { "DirectActor": "String", "Operator": "String", "Distributor": "String", "Actor": "String", "Machine": "String", "SoftDecline": "String" }, "PaymentInfo": { "SrvTranId": "3584697388", "AuthCode": "333333", "AuthAmount": 5.5, "SettAmount": 5.5, "RRN": "111111", "Token": "string", "AuthDateTime": "071221133300", "SettDateTime": "071221133330", "TraceNumber": "4444", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": false, "ProviderExternalData": "string", "InitiateTranReference": 11223344, "IsRevalueCard": false } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>String</td> <td> **Conditional**: Reflects the original Nayax Transaction ID for prepaid loyalty card re-attempts. Provided as a String in **JSON format**. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types.</li> </ul> </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read by DOT</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td><strong>System & External Data</strong></td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> </tbody> </table> ## Response The Refund Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "string", "Code": 0, "StatusMessage": "string", "CustomDeclineCode": "string" }, "PaymentInfo": { "SrvTranId": "3584697388", "AuthCode": "333333", "AuthAmount": 5.5, "SettAmount": 5.5, "RRN": "111111", "Token": "string", "AuthDateTime": "071221133300", "SettDateTime": "071221133330", "TraceNumber": "4444", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": false, "ProviderExternalData": "string", "InitiateTranReference": 11223344, "IsRevalueCard": false } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/GenerateQR` request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in `/Settlement` or `/Sale` process. **Conditional** on `/Inquiry` request. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` or `/Sale` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>String</td> <td> The date and time the `/Settlement` or `/Sale` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. <ul> <li>Used as External Transaction ID for external parties (e.g., Card schemes).</li> <li>Highly recommended to be visible to the **consumer/card holder** for support.</li> <li>**Note:** The RRN must **match** the preceding value sent in the `/GenerateQR` response for an `/Inquiry` request.</li> </ul> </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Loyalty & System Details</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. </td> </tr> </tbody> </table> # Void Source: https://devzone.nayax.com/docs/cortina/dynamicqr/dynamicqr-void Cortina DQR uses the `Void` command to notify the integrator in order to initiate the cancellation process with the Cortina payment provider whenever one of the below scenarios takes place: 1. Issues during vending process (after an "Approved" `Inquiry` response)- Cancel button being pressed by the consumer/ vend failure (issue with product dispensing/service providing) by the machine. 2. No `Inquiry` Response until timeout. This command is essential for having the payment provider aware that the transaction was cancelled on Nayax's end (as well as from the consumer's POV), and is done in order for the payment provider to complete the cancellation on its end. ## Request Nayax's servers send a POST request to your configured `Void` endpoint, which would be of the following format: `(customer's URL)/Cortina/DynamicQR/Void` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 3, "ReasonText": "Cashless Cancelled by machine", "BasicInfo": { "TransactionId": "236584335969834429321847829253667359", "Amount": 0.1, "Currency": "ILS", "SiteId": 1, "MachineAuTime": "230221121009" }, "DeviceInfo": { "Id": 0, "HwSerial": "0434324119376524", "FWVersion": "", "Type": "ONYX" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayDynamicQR V2", "TerminalId": "987654321", "DecimalPlace": 2, "Offset": "2.00", "CountryCode": "US", "CountryISOCode": "USA", "Country": "UNITED STATES", "City": "Abbeville", "Address": "TestPayDynamicQR V2", "ZipCode": "1223311" }, "ActorInfo": { "Id": 2001187922, "Name": "TanyaT_OP", "MerchantId": "123456789" }, "CustomData": { "Actor": "", "Machine": { "dynamic_qr_channels_rec_ids": "18,19" } }, "PaymentInfo": { "SrvTranId": "236584335969834429321847829253667359", "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": "111111", "Token": "", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "55555", "IsGatewayTimeout": false } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types.</li> </ul> </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read by DOT</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID**. </td> </tr> <tr> <td>`Region`</td> <td>String(255)</td> <td> Machine **Region**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Machine **City**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name** (for machine location). </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> <tr> <td><strong>System & Response Flags</strong></td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> </tbody> </table> ## Response The Void Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "Cortina V2 Stub Tester" }, "PaymentInfo": { "SrvTranId": "236584335969834429321847829253667359", "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": "111111", "Token": "", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "55555", "IsGatewayTimeout": false } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Loyalty & System Details</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> </tbody> </table> # Cortina Network Requirements Source: https://devzone.nayax.com/docs/cortina/network-requirements Connection methods, VPN setup, and IP addresses to whitelist so Cortina terminals can reach Nayax. For communication between Nayax and the Integrator, we support the following methods: * HTTPS TLS 1.2/1.3 * VPN S2S (Site-to-Site VPN) If the integrator wishes to establish a VPN tunnel to the Nayax server, the VPN tunnels for Test and Production will be established during the initial setup stage. The integrator will be asked to complete a VPN request form and join a technical call. During the call, the tunnels will be created and tested. Integration testing will be performed only after the VPN is set up and working. <Note> **Authentication with a VPN** In cases where a VPN is established, the integrator may skip the `Start Session` authentication stage. However, Nayax recommends implementing it in all integrations. </Note> ## Whitelist IPs To ensure smooth communication, the Integrator must whitelist the following Nayax public IP addresses. | Environment | Region | IP Addresses | | :- | :- | :- | | Production | Germany (DE) | `137.221.37.126`, `185.159.234.2` | | Production | United States (US) | `72.28.118.100`, `72.28.111.132`, `185.159.233.2` | | Production | Israel (IL) | `185.159.232.2`, `84.110.125.194`, `82.102.172.206`, `212.179.76.198` | | QA | — | `31.154.55.2` | If required, the Integrator should also allow access from the Nayax QA environment so the Nayax QA team can conduct automation testing. ## See also * [Cortina Integration](/docs/cortina/cortina-integration) * [Start Session](/docs/cortina/start-session/cortina-auth) # Overview Source: https://devzone.nayax.com/docs/cortina/overview-cortina Cortina API allows third-party integrators, such as payment providers or Payment Gateways, to process payment transactions securely and efficiently. It acts as a communication layer that enables Nayax’s devices to interact with external payment platforms through well-defined request/response flows. <Card title="Set Up the MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Connect your AI assistant to Nayax documentation for instant answers. </Card> ## Transaction flow components Cortina API sits at the center of the payment flow and ensures each transaction is valid, secure, and fully processed. <Frame> <img /> </Frame> The flow involves four key components: 1. **Customer**: Customers initiate payment by presenting their payment method at the POS (Point of Sale) terminal. 2. **POS (Point of Sale)**: The POS terminal receives the credit card details and the transaction amount. It then sends the card and transaction details to the Nayax Server for further processing. 3. **Nayax**: Nayax receives the payment request and uses the Cortina API to verify the transaction. The API handles the transaction's authentication, authorization, and final settlement. 4. **Payment Gateway**: The Payment Gateway processes transaction details, authorizes payments, and clears funds. Nayax uses the Cortina API to authorize and clear the transaction, keeping the payment valid and secure. ## See also See the following pages to learn more about Cortina's payment methods and its integration and support resources. ### Payment methods Cortina supports four payment methods, each with its own transaction flow. <CardGroup> <Card icon="wallet" title="Prepaid card" href="/docs/cortina/prepaid-card/prepaid-card-flows"> Process prepaid card transactions using pre-selection or pre-authorization flows. </Card> <Card icon="credit-card" title="Credit card" href="/docs/cortina/credit-card/cortina-credit-card-flows"> Process credit card payments through pre-selection or pre-authorization flows. </Card> <Card icon="qrcode" title="StaticQR" href="/docs/cortina/staticqr/staticqr-flows"> Process wallet payments when customers scan a static QR code on the machine. </Card> <Card icon="rotate" title="DynamicQR" href="/docs/cortina/dynamicqr/cortina-dynamicqr"> Process QR payments using a unique code generated for each transaction. </Card> </CardGroup> ### Integration & support These pages cover the integration process, authentication, and other supporting resources for your Cortina integration. <CardGroup> <Card icon="list-check" title="Integration process" href="/docs/cortina/cortina-integration"> Follow Cortina's staged integration process from kickoff through the production pilot. </Card> <Card icon="lock" title="Authentication process" href="/docs/cortina/start-session/cortina-auth"> Encrypt and exchange tokens to authenticate each Cortina transaction session. </Card> <Card icon="network-wired" title="Network requirements" href="/docs/cortina/network-requirements"> Set up HTTPS or VPN connectivity and whitelist Nayax's IP addresses. </Card> <Card icon="circle-check" title="Sale end notification" href="/docs/cortina/sale-end-notification"> Notify your system when a Cortina transaction reaches completion. </Card> <Card icon="rotate-left" title="Refunds" href="/docs/cortina/refunds"> Return funds to customers for eligible transactions with full or partial refunds. </Card> <Card icon="circle-question" title="Cortina FAQs" href="/docs/cortina/cortina-faqs"> Find quick answers to common questions about Cortina integration, payments, and QR setups. </Card> </CardGroup> <br /> # Remaining Prepaid Balance Source: https://devzone.nayax.com/docs/cortina/prepaid-card/check-balance This feature allows Payment Gateway to report the cardholder's prepaid balance remaining after the current transaction, which is shown to the user at the end of the transaction. ## How to implement In the Settlement endpoint response or at the Sale endpoint response, set the Balance object as follows: * `RegularCreditType` = 1 * `RegularCredit` = Balance amount. See the example below: ```json theme={null} {"Balance": { "RegularCreditType": 1, "RegularCredit": 50.0}} ``` # Discounts Source: https://devzone.nayax.com/docs/cortina/prepaid-card/discount The discount feature allows Payment Gateways, implementing Cortina Prepaid API, to adjust the final settlement amount of a transaction to represent a Discount given to the cardholder by the (External) Prepaid Provider. ## How to implement To do so, the final amount (after the discount amount was deducted) should be sent in `SettAmount` fields, under the `PaymentInfo` object of the Settlement endpoint response or at the Sale endpoint response. The amount sent must be equal to or lower than the original amount and could never be higher than the original Authorization amount. The discounted amount will be reflected in the transaction settlement amount of the transaction record, which can be viewed in the transaction reports available in Nayax Core. Please note that this field is used for reporting purposes only and can only be used for cases where the Payment Gateway is covering the discount costs. See the example below: ```json theme={null} { "PaymentInfo": { "SettAmount": 0.1}} ``` # Partial Approval in Authorization Source: https://devzone.nayax.com/docs/cortina/prepaid-card/partial-approval-for-prepaid This feature allows a prepaid processor to approve a lower authorization amount if the cardholder does not have enough balance to cover the full requested amount, increasing the integration's approval rate. The partially approved amount can be used for purchase and will limit the settlement amount. ## How to implement In the Authorization endpoint response, set the attribute as follows: * `Status.Verdict` = Approved * `Status.Code` = 0 * `PaymentInfo.AuthAmount` = Approve amount for pre-authorization. See the example below: ```json theme={null} {"Status": { "Verdict": "Approved", "Code": 0,}, "PaymentInfo": { "AuthAmount": 5} } ``` # Authorization Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-authorization Cortina Prepaid uses the `Authorization` command to notify about the result of a card tap to initiate the authorization process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Authorization` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Authorization` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": "N99O4XURDQYJZIK4OTCAWF1RHHA40TZWVCRB", "NayaxTransactionId": 3584697384, "Amount": 5, "CurrencyCode": "ILS", "CurrencyNumeric": "376", "SiteId": 1, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true, "PaymentMethodID": 1, "BillingProviderId": 1, "AuditNumber": 342, "NayaxRRN": "111111", "IsDeferredAuthorization": true, "AgeLimitation": 18, "IsSoftDeclineCompletion": true, "TransitElement": { "TransitTransactionType": 1, "DenyListIndication": 0 } }, "DeviceInfo": { "HwSerial": "0434324119376526", "FWVersion": "4.0.0.22-RC01 - Aug 25 2021", "Type": "Onyx" }, "MachineInfo": { "Id": 106791869, "Name": "Itai_TestPayCC V2", "ExternalId": "OperatorExternalID", "Type": "machine type", "TerminalId": "8888888844", "DecimalPlace": 2, "Offset": "3.00", "GroupId": "String", "OperatorId": 2001537302, "Region": "EU", "City": "Abbeville", "ZipCode": "22448Z", "Country": { "Name": "UNITED STATES", "NumericCode": "840", "Alpha2Code": "US", "Alpha3Code": "USA", "Intra": "Europe" }, "GeoLocation": { "State": "Alabama", "City": "Zambezi", "CountryCode": "ZM", "ZipCode": "234234", "Address": "River", "Latitude": 51.0003431, "Longitude": 23.745245 } }, "ActorInfo": { "Id": 2001537302, "Name": "TestPayCC V2 OP", "OperatorId": 2001537302, "OperatorName": "TestPayCC V2 OP _ Sub Merchant", "MerchantId": 999999888885, "DynamicURL": "https://www.nayax.com/alternativeURL", "Country": { "Name": "UNITED STATES", "NumericCode": "840", "Alpha2Code": "US", "Alpha3Code": "USA", "Intra": "Europe" }, "GeoLocation": { "State": "Alabama", "City": "Zambezi", "CountryCode": "ZM", "ZipCode": "234234", "Address": "River", "Latitude": 51.0003431, "Longitude": 23.745245 }, "MCC": 455, "SubMerchantId": 999999888886 }, "CustomData": { "DirectActor": "String", "Operator": "String", "Distributor": "String", "Actor": "String", "Machine": "String", "SoftDecline": "String" }, "CardData": { "CardNumber": "****", "EntryMode": "MCR", "ExpYear": "23", "ExpMonth": "01", "EMVData": "string", "CVV2": "****", "IDNumber": "****", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "6", "PrimaryDescription": "VISA", "SecondaryId": "0", "SecondaryDescription": "string" }, "CardHolderName": "Test Card Holder", "IsDebitCard": true }, "PaymentInfo": { "SrvTranId": "3584697388", "AuthCode": "333333", "AuthAmount": 5.5, "SettAmount": 5.5, "RRN": "111111", "Token": "string", "AuthDateTime": "071221133300", "SettDateTime": "071221133330", "TraceNumber": "4444", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": false, "ProviderExternalData": "string", "InitiateTranReference": 11223344, "IsRevalueCard": false } } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The unique identifier for this transaction. <ul> <li>If `/StartSession` was used, this echoes the ID encrypted in 'TranIDCipher'.</li> <li>If `/StartSession` was not used, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique identifier** for the transaction. This ID is echoed in further related requests. </td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The payment amount (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`, 20 cents = `0.20`.</li> <li>Note: Currencies with no decimal places (e.g., JYN) are still represented as a double, e.g., 234 JYN = `234.0`.</li> </ul> </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> The currency represented by its **ISO 4217 Alpha-3** code (e.g., USD, EUR). </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> The currency represented by its **ISO 4217 Numeric-3** code (e.g., 840 for USD). </td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> The identifier for the **Nayax server region** hosting the transaction. </td> </tr> <tr> <td>`MachineAuTime`</td> <td>String</td> <td> The **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>Int(32)</td> <td> The **Nayax Server Timeout configuration**, specified in milliseconds. </td> </tr> <tr> <td>`IsProductSelected`</td> <td>Bool</td> <td> Indication of whether the product was **pre-selected** before the payment process began. </td> </tr> <tr> <td>`PaymentMethodID`</td> <td>Int(32)</td> <td> The **Nayax identifier** for the specific payment provider used. </td> </tr> <tr> <td>`BillingProviderId`</td> <td>Int(32)</td> <td> The **Nayax identifier** for the associated billing provider. </td> </tr> <tr> <td>`AuditNumber`</td> <td>Int(64)</td> <td> Field reserved **for Nayax internal use only**. </td> </tr> <tr> <td>`NayaxRRN`</td> <td>String</td> <td> A **Reference Number** used as an **External Transaction Identification** for external parties. <ul> <li>**Recommendation:** This ID should be visible to the **end consumer** and their bank/service provider.</li> <li>This value must be **repeated** in the subsequent `/Inquiry` request.</li> </ul> </td> </tr> <tr> <td>`IsDeferredAuthorization`</td> <td>Bool</td> <td> Boolean indicator. Further information is unavailable. </td> </tr> <tr> <td>`AgeLimitation`</td> <td>Int(16)</td> <td> The **minimum age required** to permit the transaction. </td> </tr> <tr> <td>`IsSoftDeclineCompletion`</td> <td>Bool</td> <td> Boolean indicator. Further information is unavailable. </td> </tr> <tr> <td>`TransitTransactionType`</td> <td>Int(32)</td> <td> The transaction type for transit payments (Enum values): <ul> <li>**1:** Prefunded</li> <li>**2:** Realtime Authorization</li> <li>**3:** Post-Authorization (Aggregated Transaction)</li> <li>**7:** Debt Recovery</li> </ul> </td> </tr> <tr> <td>`DenyListIndication`</td> <td>Int(32)</td> <td> Indicates the effect on the consumer's Deny List status (Enum values): <ul> <li>**0:** unknown/no effect</li> <li>**1:** Decline will cause the consumer to be **added** to the deny list.</li> <li>**2:** Approval shall cause the consumer to be **removed** from the deny list.</li> </ul> </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> The Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> The device **Firmware version** number. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> The **Nayax Device Type**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> The **unique machine entity ID** allocated in Nayax's back office system. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> The **Machine Name** as configured in Nayax's back office. </td> </tr> <tr> <td>`ExternalId`</td> <td>String(200)</td> <td> The Machine **External ID** (Machine number - operator) provided by the operator in Nayax's back office. </td> </tr> <tr> <td>`Type`</td> <td>String(50)</td> <td> The **Machine Type** as defined in Nayax's back office. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> The **Terminal identifier**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> The **decimal point location** for amounts used on this machine. <ul> <li>Example: Value of **`2`** means amounts like 123.45.</li> <li>Example: Value of **`0`** means amounts like 12345 (integer representation).</li> </ul> </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> The **UTC timezone offset** for the machine's location. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> Field reserved **for Nayax internal use only**. </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> The **Merchant ID** as defined in Nayax's back office. </td> </tr> <tr> <td>`Region`</td> <td>String(255)</td> <td> The **Region** as defined in Nayax's back office. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> The machine's **City** as defined in Nayax's back office. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> The machine's **Zip Code** as defined in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> The **Country Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> The **ISO-3166-1 Numeric-3 code** for the country (e.g., 840). </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> The **ISO-3166-1 Alpha-2 code** for the country (e.g., US). </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> The **ISO-3166-1 Alpha-3 code** for the country (e.g., USA). </td> </tr> <tr> <td>`Intra`</td> <td>String</td> <td> The **Intra Region** for geographical diversification. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> The Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> The **City** associated with the actor. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> The **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> The **Zip Code** associated with the actor. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> The **Address** associated with the actor. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> The Machine Location **Latitude**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> The Machine Location **Longitude**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> The **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> The **Direct Merchant Name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> The **Merchant Operator ID**. </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> The **Merchant Operator Name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> The **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DynamicURL`</td> <td>String</td> <td> The Actor level **URL configuration**. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> The **Country Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> The **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> The **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> The **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Intra`</td> <td>String</td> <td> The **Intra Region** for geographical diversification. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> The Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> The **City** associated with the actor. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> The **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> The **Zip Code** associated with the actor. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> The **Address** associated with the actor. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> The Machine Location **Latitude**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> The Machine Location **Longitude**. </td> </tr> <tr> <td>`MCC`</td> <td>Int(32)</td> <td> **Merchant Category Code**. Used to classify merchants by the type of goods or services provided. </td> </tr> <tr> <td>`SubMerchantId`</td> <td>String(255)</td> <td> The **Sub Merchant identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Custom data for the **Direct Actor** in JSON format. </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Custom data for the **Operator** in JSON format. </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Custom data for the **Distributor** in JSON format. </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Custom data for the **Actor** in JSON format. </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Custom data for the **Machine** in JSON format. </td> </tr> <tr> <td>`SoftDecline`</td> <td>String</td> <td> Custom data related to a **Soft Decline** in JSON format. </td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types (e.g., Refund, Settlement).</li> </ul> **Note:** The card details use the same format in which the device reads the card. For Mifare cards, the Track 2 data is in hexadecimal. For magnetic stripe cards, the Track 2 data is in ASCII. </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> Indicates how the card details were read. Common values include: <ul> <li>**MCR**: Magnetic Stripe Read (swipe).</li> <li>**CON**: Contact Chip Read (insert).</li> <li>**CLS**: Contactless Chip Read (tap).</li> <li>**NFC**: Phone/Mobile device contactless read.</li> <li>**QR**: Card number read from a QR code.</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> The card's expiration year (**YY** format). **Conditional:** Only sent when Interface is 1 or 10. </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> The card's expiration month (**MM** format). **Conditional:** Only sent when Interface is 1 or 10. </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> A string containing **EMV tags** in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`CVV2`</td> <td>String</td> <td> The Card Verification Value 2 (**CVV2**). </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> The **ID Number** associated with the cardholder or transaction. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> The **Primary Brand Id**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> The **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> The **Secondary Brand Id** (if applicable). </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> The **Secondary Brand Description** (if applicable). </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> The **Card Holder Name**. </td> </tr> <tr> <td>`IsDebitCard`</td> <td>Bool</td> <td> Indication if card is a **Debit** or **Prepaid** card. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional:** Only mandatory if `/StartSession` was **not** used.</li> <li>If `/StartSession` *was* used, this should be empty or echo the main Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> The **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Settlement` or `/Sale` process. Irrelevant for Authorization. </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number**. Highly recommended to be visible to the end consumer/card holder. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time string when the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The **Settlement Date/Time**. Irrelevant for Authorization. </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> The **Trace Number**. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax Internal use only**. </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data sent as a **JSON format string**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indication of whether a **gateway timeout** occurred. </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**. Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication of whether the card is **allowed to be revalued**. </td> </tr> </tbody> </table> </Accordion> ## Response The Authorization Response that the customer's payment method would send to Nayax's servers. The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string status of the request: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> **Conditional:** Only returned if `Verdict` is **Declined**. The mandatory decline codes: <ul> <li>**1:** Insufficient funds</li> <li>**2:** Transaction ID unknown</li> <li>**3:** Cardholder exceeded daily / weekly / monthly transaction count limit</li> <li>**4:** Cardholder exceeded transaction amount limit</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8:** Request cannot be parsed (format error)</li> <li>**9:** Transaction not allowed to cardholder</li> <li>**40:** For Nayax internal use only.</li> <li>**990:** CertificateFileName not found</li> <li>**991:** Failed to decipher message body</li> <li>**992:** Timeout exception</li> <li>**994:** Card Brand not supported</li> <li>**996:** Transaction ID Unknown / Duplicate Transaction ID (Start Session Error)</li> <li>**997:** Missing mandatory parameters</li> <li>**998:** Validation / request cannot be parsed</li> <li>**999:** General exception</li> <li>**1010:** Public Key Certificate not found</li> <li>**1011:** Method not Implemented</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> The transaction status message, provided as a free text field or for additional varying data. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used to specify a custom decline code (e.g., for Soft Decline or Switch Interface). This value may be the acquirer's response code or composed of other data. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional:** Only mandatory if `/StartSession` was **not** used.</li> <li>If `/StartSession` *was* used, this should be empty or echo the Transaction ID sent in the request.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> The **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Settlement` or `/Sale` process. Irrelevant for Authorization. </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number**. Highly recommended to be visible to the end consumer/card holder for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time string when the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The **Settlement Date/Time**. Irrelevant for Authorization. </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> The **Trace Number**. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax Internal use only**. </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data sent as a **JSON format string**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indication (valid in response) of whether a **gateway timeout** occurred. </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication of whether the card is **allowed to be revalued** (have funds added). </td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines what the `RegularCredit` field represents (Enum values): <ul> <li>**0:** The credit is counted in **transactions**.</li> <li>**1:** The credit is counted as an **amount**.</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The Regular Credit amount or number of transactions based on `RegularCreditType`. Decimal place 2. </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The Revalue Credit amount. **Only available if the card is configured as revalue-able**. Decimal place 2. </td> </tr> </tbody> </table> </Accordion> # Cancel Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-cancel Cortina Prepaid uses the `Cancel` command to notify the integrator in order to initiate the cancellation process with the Cortina payment provider whenever one of the below scenarios takes place: 1. Getting a failed `Authorization` Response (either due to timeout or having an error code in the `Authorization` Response). 2. Issues during product selection- inactivity of the consumer/Cancel button being pressed/invalid product selection by the consumer. 3. Vend failure (issue with product dispensing/service providing) by the machine This command is essential for having the payment provider aware that the transaction was cancelled on Nayax's end (as well as from the consumer's POV), and is done in order for the payment provider to complete the cancellation on its end. <Note> Note: This command is relevant for PreAuthorization only. Its equivalent in the PreSelection flow is the `Void` command. </Note> ## Request Nayax's servers send a POST request to your configured `Cancel` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Cancel` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 999, "ReasonText": "General exception", "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "0434324119376526", "FWVersion": "4.0.0.22-RC01 - Aug 25 2021", "Type": "Onyx" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string", "SecondaryDescription": "string" }, "CardHolderName": "Test Card Holder" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`ReasonCode`</td> <td>`Int(16)`</td> <td> The valid **cancellation or decline code**: <ul> <li>**1:** Insufficient funds</li> <li>**2:** Transaction ID unknown</li> <li>**3:** Cardholder exceeded daily/weekly/monthly transaction count limit</li> <li>**4:** Cardholder exceeded transaction amount limit</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Request cannot be parsed (format error) / Validation error</li> <li>**9:** Transaction not allowed to cardholder</li> <li>**40:** For Nayax internal use only.</li> <li>**990:** CertificateFileName not found</li> <li>**991:** Failed to decipher message body</li> <li>**992:** Timeout exception</li> <li>**994:** Card Brand not supported</li> <li>**996:** Transaction ID Unknown / Duplicate Transaction ID (Start Session Error)</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>**1010:** Public Key Certificate not found</li> <li>**1011:** Method not Implemented</li> </ul> </td> </tr> <tr> <td>`ReasonText`</td> <td>`String`</td> <td> The **verbal explanation** corresponding to the `ReasonCode`. </td> </tr> <tr> <td>`TransactionId`</td> <td>`String(36)`</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates the value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>`Int(64)`</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`Amount`</td> <td>`Double`</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places (e.g., JYN) are still represented as a double (e.g., `234.0`).</li> </ul> </td> </tr> <tr> <td>`CurrencyCode`</td> <td>`String(3)`</td> <td> The currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>`String(3)`</td> <td> The currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td>`SiteId`</td> <td>`Int(16)`</td> <td> The identifier for the **Nayax server region**. </td> </tr> <tr> <td>`MachineAuTime`</td> <td>`String`</td> <td> The **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>`Int(32)`</td> <td> Nayax Server **Timeout configuration** in milliseconds. </td> </tr> <tr> <td>`IsProductSelected`</td> <td>`Bool`</td> <td> Indication if the product was **pre-selected** before the payment process. </td> </tr> <tr> <td>`HwSerial`</td> <td>`String`</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>`String`</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>`String`</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>`Int(64)`</td> <td> **Machine entity unique ID** allocated in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>`String(255)`</td> <td> **Machine Name** as defined in Nayax's back office. </td> </tr> <tr> <td>`TerminalId`</td> <td>`String(255)`</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>`Int(64)`</td> <td> The **decimal point location** for amounts used on this machine. <ul> <li>Example: Value of **`2`** means amounts like 123.45.</li> </ul> </td> </tr> <tr> <td>`Offset`</td> <td>`String(255)`</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>`String`</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>`String(255)`</td> <td> **Merchant ID** as defined in Nayax's back office (String format). </td> </tr> <tr> <td>`Region`</td> <td>`String(255)`</td> <td> **Region** as defined in Nayax's back office. </td> </tr> <tr> <td>`City`</td> <td>`String(255)`</td> <td> Machine **City** as defined in Nayax's back office. </td> </tr> <tr> <td>`ZipCode`</td> <td>`String(255)`</td> <td> Machine **Zip Code** as defined in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>`String`</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>`String(3)`</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>`String(2)`</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>`String(3)`</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>`String`</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>`String(255)`</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>`String`</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>`String(255)`</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>`String(255)`</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>`String`</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>`String`</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td>`Id`</td> <td>`Int(64)`</td> <td> **Actor ID** (Direct Merchant/Operator). </td> </tr> <tr> <td>`Name`</td> <td>`String(255)`</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>`Int(64)`</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>`String`</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>`Int(64)`</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`Name`</td> <td>`String`</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>`String(3)`</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>`String(2)`</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>`String(3)`</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>`String`</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>`String(255)`</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>`String`</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>`String(255)`</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>`String(255)`</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Latitude`</td> <td>`String`</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td>`Longitude`</td> <td>`String`</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`DirectActor`</td> <td>`String`</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>`String`</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>`String`</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>`String`</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>`String`</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`CardNumber`</td> <td>`String`</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types (e.g., Refund, Settlement).</li> </ul> **Note:** The card details use the same format in which the device reads the card. For Mifare cards, the Track 2 data is in hexadecimal. For magnetic stripe cards, the Track 2 data is in ASCII. </td> </tr> <tr> <td>`EntryMode`</td> <td>`String(4)`</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip Read (insert)</li> <li>**CLS**: Contactless Chip Read (tap)</li> <li>**NFC**: Phone/Mobile device contactless read (phone tap)</li> <li>**QR**: Card number read from a QR code</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>`String`</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>`String`</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>`String`</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`IDNumber`</td> <td>`String`</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>`String`</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>`String`</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>`String`</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>`String`</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>`String`</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>`String`</td> <td> **Card Holder Name**. </td> </tr> <tr> <td>`SrvTranId`</td> <td>`String`</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Only mandatory if `/StartSession` was **not** used.</li> <li>If used, this should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>`String(40)`</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>`Double`</td> <td> The **original amount requested** in the `/Authorization` request. </td> </tr> <tr> <td>`SettAmount`</td> <td>`Double`</td> <td> The **original amount requested** in the `/Settlement` or `/Sale` process. Irrelevant for Authorization. </td> </tr> <tr> <td>`RRN`</td> <td>`String`</td> <td> **Reference Retrieval Number**. Highly recommended to be visible to the end consumer/Card holder. </td> </tr> <tr> <td>`Token`</td> <td>`String(256)`</td> <td> A unique token for the transaction. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>`String`</td> <td> The date and time string when the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>`Double`</td> <td> The Settlement Date/Time. Irrelevant for Authorization. </td> </tr> <tr> <td>`TraceNumber`</td> <td>`String`</td> <td> The Trace number. **For Nayax Internal use only**. </td> </tr> <tr> <td>`AuthSource`</td> <td>`String(5)`</td> <td> **For Nayax Internal use only**. </td> </tr> <tr> <td>`AdditionalData`</td> <td>`String`</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>`Bool`</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> </tbody> </table> </Accordion> ## Response The Cancel Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**2:** Transaction ID unknown</li> <li>**3:** Cardholder exceeded transaction count limit</li> <li>**4:** Cardholder exceeded transaction amount limit</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8:** Request cannot be parsed (format error)</li> <li>**9:** Transaction not allowed to cardholder</li> <li>**40:** For Nayax internal use only.</li> <li>**990:** CertificateFileName not found</li> <li>**991:** Failed to decipher message body</li> <li>**992:** Timeout exception</li> <li>**994:** Card Brand not supported</li> <li>**996:** Transaction ID Unknown / Duplicate Transaction ID (Start Session Error)</li> <li>**997:** Missing mandatory parameters</li> <li>**998:** Validation / request cannot be parsed</li> <li>**999:** General exception</li> <li>**1010:** Public Key Certificate not found</li> <li>**1011:** Method not Implemented</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. <ul> <li>**Only present** if the associated card is configured as revalue-able.</li> <li>**Uses Decimal place 2.**</li> </ul> </td> </tr> </tbody> </table> </Accordion> # Decline Reasons Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-decline-reasons When a transaction is declined, the Cortina API returns a specific decline reason code that explains why the payment was not approved. These codes are essential for integrators and merchants to understand the cause of the decline and take appropriate action. The third-party integrator is responsible for returning the response, including the corresponding decline code from the list, based on the payment method used. In addition to the standard decline reason codes, integrators can provide additional information through `StatusMessage` and `CustomDeclineCode` to offer more context about the issue. The following decline reason codes are used when processing Prepaid Card transactions: | Code | Description | | - | - | | 1 | Insufficient funds | | 2 | Transaction ID unknown | | 3 | Cardholder exceeded daily / weekly / monthly transaction count limit | | 4 | Cardholder exceeded transaction amount limit | | 5 | Suspected fraud | | 6 | General system failure | | 7 | Invalid amount | | 8 | Request cannot be parsed (format error) | | 9 | Transaction not allowed to cardholder | | 40 | For Nayax internal use only | | 990 | CertificateFileName not found | | 991 | Failed to decipher message body | | 992 | Timeout exception | | 994 | Card Brand not supported | | 996 | Transaction ID Unknown / Duplicate Transaction ID (Start Session Error) | | 997 | Missing mandatory parameters | | 998 | Validation / request cannot be parsed | | 999 | General exception | | 1010 | Public Key Certificate not found | | 1011 | Method not Implemented | # Prepaid Card Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-flows Prepaid card transactions work similarly to credit card payments but are used with pre-loaded cards. These cards do not require a connection to a bank account, making them ideal for closed-loop systems such as gift cards or loyalty cards. Prepaid cards are validated during the transaction, ensuring sufficient funds are available for the purchase. Cortina supports two types of prepaid card transaction flows: * Pre-selection * Pre-authorization Both flows involve interactions between various components, including the CardHolder, Nayax Device, Machine (MDB), Nayax Engine, and Integrator. See the sections below for more details on each flow. ## Pre-Selection The Pre-selection flow simplifies the payment process by merging the steps of product/service selection and authorization into a single transaction. This flow is typically used for low-value or quick transactions, where the consumer’s selection and payment authorization are handled together in one step. See the diagram below: <Frame> <img /> </Frame> The steps in this process are as follows: 1. The consumer presents a card (Insert, tap, or swipe) to the Nayax Device. 2. The Nayax Device sends a Begin Vending Session (Default, credit...) command to the Operator Service Machine. 3. The consumer selects a product, and the Operator Service Machine sends a Vend Request (Code, price...) to the Nayax Device. 4. The Nayax Device sends an Authorization Command Request to the Nayax Server. 5. The Nayax Server sends a /Start Session request to the Payment Provider via the [Start Session](/reference/cortina/cortina/post-start-session) endpoint. 6. The Nayax Server sends a /Sale request (default, credit...) to the Payment Provider via the [Prepaid Sale](/reference/cortina/cortina-prepaid/cortina-prepaid-sale) endpoint. 7. The Nayax Server returns an Authorization Command Response (Approved) to the Nayax Device. 8. The Nayax Device sends a Vend Approved command to the Operator Service Machine. 9. The Operator Service Machine dispenses the product and sends a Vend Success notification to the Nayax Device. 10. The Nayax Device sends a Settlement Command Request to the Nayax Server. 11. (Optional) The Nayax Server sends a /SaleEndNotification (TransactionID...) to the Payment Provider via the [Sale End Notification](/reference/cortina/cortina/post-sale-end-notification) endpoint. 12. The Nayax Server returns a Settlement Command Response (Always Approved) to the Nayax Device, which then displays a "Thank you" message. This response is typically always approved in this flow, as the authorization has already been granted. ### Exception Handling In the event of a failure at any critical junction (marked with a black circle in the diagram), the transaction is terminated. Because the payment occurs before the product is dispensed in this flow, specific Void logic is required to ensure customers are not charged for failed dispenses. | Scenario | Diagram Step Reference | Technical Resolution | | :- | :- | :- | | **Selection Timeout** | 3.b | Occurs if the consumer fails to choose a valid product within the machine's allowed timeframe. The session is closed before any payment is initiated. | | **Start Session Failed** | 5.b | Occurs if the `/Start Session` request fails or times out. The transaction is aborted before the Sale request. | | **Sale Request Failed** | 6.b | If the `/Sale` request fails, returns an error, or receives a **`992`** response code, the session is aborted. In cases of a gateway timeout, the [Prepaid Void](/reference/cortina/cortina-prepaid/cortina-prepaid-void) endpoint is triggered with the flag `isGatewayTimeout: True`. | | **Vend Failed** | 9.b | If the machine fails to dispense the product after payment is authorized, the Nayax Engine triggers the [Prepaid Void](/reference/cortina/cortina-prepaid/cortina-prepaid-void) endpoint to reverse the charge. | | **Notification Failure** | 11.b | Occurs if the optional `/SaleEndNotification` fails. As this is a reporting step, the transaction on the device is usually finalized, but the error is logged for reconciliation. | <Note> For a comprehensive list of financial response codes and authorization failures, refer to the [Prepaid Card Decline Reasons](/docs/cortina/prepaid-card/prepaid-card-decline-reasons) page. </Note> ## Pre-Authorization The Pre-authorization flow is used for transactions that require a two-step process. First, a session is initiated, followed by an authorization check. This flow ensures the transaction is valid and the consumer has sufficient funds on the prepaid card before settlement. See the diagram below: <Frame> <img /> </Frame> Where: 1. The consumer presents a card (Insert, tap, or swipe) to the Nayax Device. 2. The Nayax Device sends an Authorization Command Request to the Nayax Server. 3. The Nayax Server sends a /Start Session request to the Payment Provider via the [Start Session](/reference/cortina/cortina/post-start-session) endpoint. 4. The Payment Provider returns a Start Session Response Success to the Nayax Server. 5. The Nayax Server sends an /Authorization request (default amount) to the Payment Provider via the [Prepaid Authorization](/reference/cortina/cortina-prepaid/cortina-prepaid-authorization) endpoint. 6. The Nayax Server returns an Authorization Command Response (Approved) to the Nayax Device. 7. The Nayax Device sends a Begin Vending Session (Default Code...) command to the Operator Service Machine. 8. The consumer selects a product, and the Operator Service Machine sends a Vend Request (Code, price...) to the Nayax Device. 9. The Nayax Device sends a Vend Approved (Always approved) response to the Operator Service Machine. 10. The product is dispensed, and the Operator Service Machine sends a Vend Success notification to the Nayax Device. 11. The Nayax Device sends a Settlement Command to the Nayax Server. 12. The Nayax Server sends a /Settlement request (Final Amount) to the Payment Provider via the [Prepaid Settlement](/reference/cortina/cortina-prepaid/cortina-prepaid-settlement) endpoint. 13. The Nayax Server returns a Settlement Command Response (Approved) to the Nayax Device, which then displays a "Thank you" message. ### Exception Handling In the event of a failure at any critical junction (marked with a black circle in the diagram), the transaction is terminated. The following table outlines the recovery actions taken by the Nayax Engine: | Scenario | Diagram Step Reference | Technical Resolution | | :- | :- | :- | | **Start Session Failed** | 4.b | Occurs if the `/Start Session` request times out or returns an error. The session is aborted immediately. | | **Authorization Failed** | 5.b | Occurs if the provider denies the default credit amount. The transaction is terminated. | | **Selection Timeout** | 8.b | Occurs if the consumer fails to choose a valid product within the machine's allowed timeframe. | | **Vend Failed** | 10.b | If the machine fails to dispense (e.g., jam), the system triggers the [Prepaid Cancel](/reference/cortina/cortina-prepaid/cortina-prepaid-cancel) endpoint to release the Pre-Authorization and the transaction. | | **Settlement Failed** | 12.b | Occurs if the final settlement request fails or times out. This requires system logging for manual reconciliation. | | **Timeout / Void** | N/A | If no Sale Response is received within the timeout period, or a `992` response code is received- the [Prepaid Void](/reference/cortina/cortina-prepaid/cortina-prepaid-void) endpoint is triggered. | <Note> For a comprehensive list of financial response codes and authorization failures, refer to the [Prepaid Card Decline Reasons](/docs/cortina/prepaid-card/prepaid-card-decline-reasons) page. </Note> # Refund Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-refund Cortina Prepaid uses the `Refund` command to notify the integrator about a refund request, so the integrator can start the refund with the Cortina payment provider. ## How a refund is triggered You can trigger the refund request in two ways: * From the Dynamic Transaction Monitor in Nayax Core. * Through the Lynx API. ### From the Dynamic Transaction Monitor <Warning> **Refunds Admin role required** Requesting and approving a refund from the Dynamic Transaction Monitor requires the Refunds Admin role. Ask your Integration Support Engineer to assign it. </Warning> <Steps> <Step title="Request the refund"> Right-click the relevant transaction and select **Request Refund**. <Frame> <img alt="Nayax Core transaction context menu with Request Refund highlighted" /> </Frame> </Step> <Step title="Approve the refund"> Right-click the same transaction again and select **Approve/Decline Refund**. <Frame> <img alt="Nayax Core transaction context menu with Approve/Decline Refund highlighted" /> </Frame> </Step> </Steps> Nayax then sends the `Refund` command to your endpoint, as described below. ### Through the Lynx API Call the [Request a Payment Refund](/reference/lynx/payment/request-a-payment-refund) endpoint, then the [Approve Payment Refund](/reference/lynx/payment/approve-payment-refund) endpoint. ## Request Nayax's servers send a POST request to your configured `Refund` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Refund` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 999, "ReasonText": "General exception", "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "0434324119376526", "FWVersion": "4.0.0.22-RC01 - Aug 25 2021", "Type": "Onyx" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string", "SecondaryDescription": "string" }, "CardHolderName": "Test Card Holder" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Cancellation Codes</strong></td> </tr> <tr> <td>`ReasonCode`</td> <td>Int(16)</td> <td> The valid **cancellation or decline code**: <ul> <li>**1:** Insufficient funds</li> <li>**2:** Transaction ID unknown</li> <li>**3:** Cardholder exceeded daily/weekly/monthly transaction count limit</li> <li>**4:** Cardholder exceeded transaction amount limit</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Request cannot be parsed (format error) / Validation error</li> <li>**9:** Transaction not allowed to cardholder</li> <li>**40:** For Nayax internal use only.</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and technical errors (e.g., 990, 994, 1010).*</li> </ul> </td> </tr> <tr> <td>`ReasonText`</td> <td>String</td> <td> The **verbal explanation** corresponding to the `ReasonCode`. </td> </tr> <tr> <td><strong>Core Identifiers & Financial Details</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Highly recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique transaction token. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Timestamp & System Details</strong></td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`MachineAuTime`</td> <td>String</td> <td> **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>Int(32)</td> <td> Nayax Server **Timeout configuration** in milliseconds. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`IsProductSelected`</td> <td>Bool</td> <td> Indication if the product was **pre-selected**. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID**. </td> </tr> <tr> <td>`Region`</td> <td>String(255)</td> <td> Machine **Region**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Machine **City**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name** (for machine location). </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> </tbody> </table> </Accordion> ## Response The Refund Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full documentation for the complete list of error codes.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td><strong>Loyalty & Credit Information</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. <ul> <li>**Only present** if the associated card is configured as revalue-able.</li> <li>**Uses Decimal place 2.**</li> </ul> </td> </tr> </tbody> </table> </Accordion> # Sale Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-sale Cortina Prepaid uses the `Sale` command to notify the integrator about the result of a card tap after a product has been selected in order to initiate the authorization process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Sale` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Sale` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "string", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "string", "FWVersion": "string", "Type": "ONYX" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Type": "Food", "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string", "SecondaryDescription": "string" }, "CardHolderName": "Test Card Holder" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true }, "Products": [ { "Code": 11, "Name": "Stella", "Price": 0.1, "UnitOfMeasurement": "USD", "Measurement": false }, { "Code": 12, "Name": "expensiveSprite", "Price": 6, "UnitOfMeasurement": "USD", "Measurement": false } ] } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Core Identifiers</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full documentation for complete list of codes.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates the value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Only mandatory if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number**. External transaction ID for third parties. Highly recommended to be visible to the **consumer/card holder**. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique transaction token. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> The Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Financial Details, Card Information, & Timestamps</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>Currencies with no decimal places (e.g., JYN) are still represented as a double (e.g., `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The original amount requested in the **`/Sale`Request**. Conditional on `/Sale` Response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the **`/Sale`Request**. Conditional on `/Sale` Response. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Sale` took place. **Format:`ddMMyyHHmmss`**. Conditional on `/Sale` Response. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Conditional on `/Sale` Response. </td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types (e.g., Refund, Settlement).</li> </ul> **Note:** The card details use the same format in which the device reads the card. For Mifare cards, the Track 2 data is in hexadecimal. For magnetic stripe cards, the Track 2 data is in ASCII. </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**. Common values: <ul> <li>**MCR**: Magnetic Stripe Read</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`CVV2`</td> <td>String</td> <td> Card Verification Value 2 (**CVV2**). </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td>`IsDebitCard`</td> <td>Bool</td> <td> Indication if card is **Debit** or **Prepaid**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td><strong>Product & Item Details</strong></td> </tr> <tr> <td>`Code`</td> <td>Int(16)</td> <td> **Code of the selected item** as defined in the Nayax back office or vending machine. </td> </tr> <tr> <td>`CatalogProductId`</td> <td>String(100)</td> <td> **External unique identifier** of the selected item (the product catalog number). </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Product name** as defined in Nayax's back office. </td> </tr> <tr> <td>`Price`</td> <td>Double</td> <td> The **original Product Price** in the machine's currency. Note: The transaction amount is the billing price after adjustments. </td> </tr> <tr> <td>`UnitOfMeasurement`</td> <td>String(64)</td> <td> Product's **unit of measurement** (e.g., 'unit' or 'Liter'). </td> </tr> <tr> <td>`Measurement`</td> <td>Double</td> <td> Product's **quantity** in the unit of measurement. </td> </tr> <tr> <td>`Group`</td> <td>String(255)</td> <td> Product's **group name** as existing in the product map. </td> </tr> <tr> <td>`ProductGroupId`</td> <td>String(255)</td> <td> Product's **group code** as existing in the product map. </td> </tr> <tr> <td>`PulseLineNumber`</td> <td>Int(32)</td> <td> Used to support multiple machines via pulse for remote vend capability. Must be a **positive integer** $(\ge 0)$. </td> </tr> <tr> <td><strong>Machine & Actor Information</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`MachineAuTime`</td> <td>String</td> <td> **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>Int(32)</td> <td> Nayax Server **Timeout configuration** in milliseconds. </td> </tr> <tr> <td>`IsProductSelected`</td> <td>Bool</td> <td> Indication if the product was **pre-selected**. </td> </tr> <tr> <td>`PaymentMethodID`</td> <td>Int(32)</td> <td> Nayax identifier of the **payment provider**. </td> </tr> <tr> <td>`BillingProviderId`</td> <td>Int(32)</td> <td> Nayax identifier of the **billing provider**. </td> </tr> <tr> <td>`AuditNumber`</td> <td>Int(64)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`IsDeferredAuthorization`</td> <td>Bool</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`AgeLimitation`</td> <td>Int(16)</td> <td> **Minimum age required** to allow the transaction. </td> </tr> <tr> <td>`IsSoftDeclineCompletion`</td> <td>Bool</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`TransitTransactionType`</td> <td>Int(32)</td> <td> The Transit Transaction Type (Enum values): <ul> <li>**1:** Prefunded</li> <li>**2:** Realtime Authorization</li> <li>**3:** Post-Authorization / Aggregated Transaction</li> <li>**7:** Debt Recovery</li> </ul> </td> </tr> <tr> <td>`DenyListIndication`</td> <td>Int(32)</td> <td> Indicates the effect on the consumer's Deny List status (Enum values): <ul> <li>**0:** Unknown/no effect</li> <li>**1:** Decline causes consumer to be **added** to the deny list.</li> <li>**2:** Approval causes consumer to be **removed** from the deny list.</li> </ul> </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`ExternalId`</td> <td>String(200)</td> <td> **Machine External ID** (Machine number - operator). </td> </tr> <tr> <td>`Type`</td> <td>String(50)</td> <td> **Machine Type**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. <ul> <li>Example: **`2`** means amounts like 123.45.</li> </ul> </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td>`Region`</td> <td>String(255)</td> <td> Machine **Region**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Machine **City**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name** (for machine location). </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Intra`</td> <td>String</td> <td> The **Intra Region** (geographical diversification across countries). </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DynamicURL`</td> <td>String</td> <td> Actor level **URL configuration**. </td> </tr> <tr> <td>`MCC`</td> <td>Int(32)</td> <td> **Merchant Category Code (MCC)**, classifying the business type. </td> </tr> <tr> <td>`SubMerchantId`</td> <td>String(255)</td> <td> **Sub Merchant identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`SoftDecline`</td> <td>String</td> <td> Soft Decline **custom data** (String in **JSON format**). </td> </tr> </tbody> </table> </Accordion> ## Response The Sale Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Common codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and technical errors.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> The **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Sale` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Sale` Request. </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number**. External transaction ID for third parties. Highly recommended to be visible to the **consumer/card holder**. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> The Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> </tbody> </table> </Accordion> # Settlement Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-settlement Cortina Prepaid uses the `Settlement` command to notify the integrator about the result of a settlement process on the device's end (meaning a product has been vended) in order to initiate the settlement process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Settlement` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Settlement` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "string", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "string", "FWVersion": "string", "Type": "ONYX" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string" }, "CardHolderName": "Test Card Holder" }, "Products": [ { "Code": 11, "Name": "Stella", "Price": 0.1, "UnitOfMeasurement": "USD", "Measurement": false }, { "Code": 12, "Name": "expensiveSprite", "Price": 6, "UnitOfMeasurement": "USD", "Measurement": false } ], "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true }, "SecondaryDescription": "string" } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & Status</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>`String(36)`</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates the value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>`Int(64)`</td> <td> The **Nayax internal unique ID** for the transaction, echoed in subsequent requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>`String`</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID from the request.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>`String`</td> <td> **Reference Retrieval Number (RRN)**. <ul> <li>Used as the external transaction ID for third parties (e.g., Card Schemes).</li> <li>Recommended to be visible to the **consumer/cardholder**.</li> </ul> </td> </tr> <tr> <td>`Token`</td> <td>`String(256)`</td> <td> A unique transaction token. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>`String`</td> <td> The Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>`String(5)`</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial Details & Amounts</strong></td> </tr> <tr> <td>`Amount`</td> <td>`Double`</td> <td> The **payment amount**. <ul> <li>Decimal value (max 3 digits for cents).</li> <li>Currencies without decimals (e.g., JYN) are still represented as a double (e.g., `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>`Double`</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>`Double`</td> <td> The **original amount requested** in the `/Settlement` or `/Sale` process. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`CurrencyCode`</td> <td>`String(3)`</td> <td> The **currency code** in **ISO 4217 Alpha-3** format (e.g., USD, EUR). </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>`String(3)`</td> <td> The **currency code** in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>`Int(64)`</td> <td> The **decimal point location** for amounts on this machine. <ul> <li>Example: **`2`** means amounts like 123.45.</li> <li>Example: **`0`** means amounts like 12345 (integer representation).</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>`String(40)`</td> <td> The **External Authorization Code** (usually from the Card Issuer). </td> </tr> <tr> <td><strong>Timestamps & Flags</strong></td> </tr> <tr> <td>`MachineAuTime`</td> <td>`String`</td> <td> The **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>`Int(32)`</td> <td> Nayax Server **Timeout configuration in milliseconds**. </td> </tr> <tr> <td>`Offset`</td> <td>`String(255)`</td> <td> **UTC timezone offset** for the machine's location. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>`String`</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>`Double`</td> <td> The Settlement Date/Time. Relevant only for Settlement-related commands. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>`Bool`</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>`String`</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types (e.g., Refund, Settlement).</li> </ul> **Note:** The card details use the same format in which the device reads the card. For Mifare cards, the Track 2 data is in hexadecimal. For magnetic stripe cards, the Track 2 data is in ASCII. </td> </tr> <tr> <td>`EntryMode`</td> <td>`String(4)`</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magstripe (Swipe)</li> <li>**CON**: Contact Chip (Insert)</li> <li>**CLS**: Contactless Chip (Tap)</li> <li>**NFC**: Phone Tap</li> <li>**QR**: QR code read</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>`String`</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>`String`</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>`String`</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`IDNumber`</td> <td>`String`</td> <td> Cardholder ID/identification number. </td> </tr> <tr> <td>`RandomNumber`</td> <td>`String`</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>`String`</td> <td> **Primary Brand ID** (e.g., Visa, Mastercard). </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>`String`</td> <td> Primary Brand Description. </td> </tr> <tr> <td>`SecondaryId`</td> <td>`String`</td> <td> Secondary Brand ID (if applicable). </td> </tr> <tr> <td>`CardHolderName`</td> <td>`String`</td> <td> Name of the cardholder. </td> </tr> <tr> <td><strong>Product/Item Details</strong></td> </tr> <tr> <td>`IsProductSelected`</td> <td>`Bool`</td> <td> Indicates if the product was **pre-selected** before the payment process. </td> </tr> <tr> <td>`Code`</td> <td>`Int(16)`</td> <td> The **code of the selected item** as defined in Nayax's back office or the vending machine. </td> </tr> <tr> <td>`CatalogProductId`</td> <td>`String(100)`</td> <td> The **external unique identifier** of the selected item (the product catalog number). </td> </tr> <tr> <td>`Name`</td> <td>`String(255)`</td> <td> The **Product name** as defined in the Nayax back office. </td> </tr> <tr> <td>`Price`</td> <td>`Double`</td> <td> The original **Product Price** in the machine's currency. Note: `Amount` is the final billing price after adjustments. </td> </tr> <tr> <td>`UnitOfMeasurement`</td> <td>`String(64)`</td> <td> Product's **unit of measurement** (e.g., 'unit' or 'Liter'). </td> </tr> <tr> <td>`Measurement`</td> <td>`Double`</td> <td> Product's **quantity** in the specified unit of measurement. </td> </tr> <tr> <td>`Group`</td> <td>`String(255)`</td> <td> Product's **group name** as defined in the product map. </td> </tr> <tr> <td>`ProductGroupId`</td> <td>`String(255)`</td> <td> Product's **group code** as defined in the product map. </td> </tr> <tr> <td>`PulseLineNumber`</td> <td>`Int(32)`</td> <td> Used to support multiple machines via pulse for remote vend capability. Must be a **positive integer** $(\ge 0)$. </td> </tr> <tr> <td><strong>Machine & Device Information</strong></td> </tr> <tr> <td>`HwSerial`</td> <td>`String`</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>`String`</td> <td> Device **Firmware Version**. </td> </tr> <tr> <td>`Type`</td> <td>`String`</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>`Int(64)`</td> <td> **Machine Entity Unique ID** allocated in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>`String(255)`</td> <td> **Machine Name** as defined in Nayax's back office. </td> </tr> <tr> <td>`TerminalId`</td> <td>`String(255)`</td> <td> **Terminal identifier** as defined in Nayax's back office. </td> </tr> <tr> <td><strong>Machine Location</strong></td> </tr> <tr> <td>`SiteId`</td> <td>`Int(16)`</td> <td> **Region of the Nayax server** hosting the machine data. </td> </tr> <tr> <td>`Region`</td> <td>`String(255)`</td> <td> **Machine Region** as defined in Nayax's back office. </td> </tr> <tr> <td>`City`</td> <td>`String(255)`</td> <td> **Machine City** as defined in Nayax's back office. </td> </tr> <tr> <td>`ZipCode`</td> <td>`String(255)`</td> <td> **Machine Zip Code** as defined in Nayax's back office. </td> </tr> <tr> <td>`Latitude`</td> <td>`String`</td> <td> **Machine Location Latitude**. </td> </tr> <tr> <td>`Longitude`</td> <td>`String`</td> <td> **Machine Location Longitude**. </td> </tr> <tr> <td><strong>Actor (Merchant/Operator) Details</strong></td> </tr> <tr> <td>`Id`</td> <td>`Int(64)`</td> <td> **Actor ID** (Direct Merchant/Operator) defined in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>`String(255)`</td> <td> **Direct Merchant Name** as defined in Nayax's back office. </td> </tr> <tr> <td>`OperatorId`</td> <td>`String(255)`</td> <td> **Merchant ID** (Operator ID - String version) as defined in Nayax's back office. </td> </tr> <tr> <td>`OperatorId`</td> <td>`Int(64)`</td> <td> **Merchant Operator ID** (integer version). </td> </tr> <tr> <td>`OperatorName`</td> <td>`String`</td> <td> **Merchant Operator Name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>`Int(64)`</td> <td> **Merchant ID** as defined in Nayax's back office. </td> </tr> <tr> <td>`DynamicURL`</td> <td>`String`</td> <td> **Actor-level URL configuration**. </td> </tr> <tr> <td>`State`</td> <td>`String`</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>`String(255)`</td> <td> Actor geo **city**. </td> </tr> <tr> <td>`CountryCode`</td> <td>`String`</td> <td> Actor geo **country code** (ISO-3). </td> </tr> <tr> <td>`ZipCode`</td> <td>`String(255)`</td> <td> Actor geo **zip code**. </td> </tr> <tr> <td>`Address`</td> <td>`String(255)`</td> <td> Actor geo **address**. </td> </tr> <tr> <td><strong>Country Information (ISO 3166-1)</strong></td> </tr> <tr> <td>`Name`</td> <td>`String`</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>`String(3)`</td> <td> Country code in **ISO 3166-1 Numeric-3** format. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>`String(2)`</td> <td> Country code in **ISO 3166-1 Alpha-2** format. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>`String(3)`</td> <td> Country code in **ISO 3166-1 Alpha-3** format. </td> </tr> <tr> <td>`Intra`</td> <td>`String`</td> <td> The **Intra Region** (e.g., 'European Union') used for geographical diversification across countries. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`GroupId`</td> <td>`String`</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`DirectActor`</td> <td>`String`</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>`String`</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>`String`</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>`String`</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>`String`</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>`String`</td> <td> General custom data string in **JSON format**. </td> </tr> </tbody> </table> </Accordion> ## Response The Settlement Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Errors</strong></td> </tr> <tr> <td>`Verdict`</td> <td>`String`</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>`Int(32)`</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Common codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>`String(255)`</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>`String`</td> <td> Used for specifying a custom decline code. <ul> <li>Often related to **Soft Decline** or interface switching.</li> <li>May reflect the acquirer's response code or custom data.</li> </ul> </td> </tr> <tr> <td><strong>Loyalty & Credit Information</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>`Int(32)`</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>`Double`</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>`Int(32)`</td> <td> The **revalue credit amount**. <ul> <li>**Only present** if the associated card is configured as revalue-able.</li> <li>**Uses Decimal place 2.**</li> </ul> </td> </tr> </tbody> </table> </Accordion> # Void Source: https://devzone.nayax.com/docs/cortina/prepaid-card/prepaid-card-void Cortina Prepaid uses the `Void` command to notify the integrator in order to initiate the cancellation process with the Cortina payment provider whenever one of the below scenarios takes place: 1. Issues during vending process- Cancel button being pressed by the consumer/ vend failure (issue with product dispensing/service providing) by the machine. 2. No `Sale` Response until timeout. This command is essential for having the payment provider aware that the transaction was cancelled on Nayax's end (as well as from the consumer's POV), and is done in order for the payment provider to complete the cancellation on its end. <Note> Note: this command is relevant for PreSelection only. Its equivalent in the PreAuthorization flow is the `Cancel` command. </Note> ## Request Nayax's servers send a POST request to your configured `Void` endpoint, which would be of the following format: `(customer's URL)/Cortina/PrePaid/Void` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 999, "ReasonText": "General exception", "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "0434324119376526", "FWVersion": "4.0.0.22-RC01 - Aug 25 2021", "Type": "Onyx" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string", "SecondaryDescription": "string" }, "CardHolderName": "Test Card Holder" }, "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Core Identifiers & Financial Details</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique transaction token. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Timestamp & Status Flags</strong></td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`MachineAuTime`</td> <td>String</td> <td> **Machine Authorization Timestamp**. </td> </tr> <tr> <td>`TimeoutMS`</td> <td>Int(32)</td> <td> Nayax Server **Timeout configuration** in milliseconds. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types (e.g., Refund, Settlement).</li> </ul> **Note:** The card details use the same format in which the device reads the card. For Mifare cards, the Track 2 data is in hexadecimal. For magnetic stripe cards, the Track 2 data is in ASCII. </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**. Common values include: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`FWVersion`</td> <td>String</td> <td> Device **Firmware version**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. <ul> <li>Example: **`2`** means amounts like 123.45.</li> </ul> </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID**. </td> </tr> <tr> <td>`Region`</td> <td>String(255)</td> <td> Machine **Region**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Machine **City**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name** (for machine location). </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td><strong>Custom Data (JSON)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> </tbody> </table> </Accordion> ## Response The Void Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string" }, "PaymentInfo": { "SrvTranId": "236584335969834429321847829253667359", "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": "111111", "Token": "", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "55555", "IsGatewayTimeout": false }, "Balance": { "RegularCreditType": 0, "RegularCredit": 0, "RevalueCredit": 0 } } ``` ### Response parameters The following table describes the fields returned in the API response: <Accordion title="Reference fields"> <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8/998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full documentation for the complete list of error codes.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Identifier Fields</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for the Authorization command**. </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Highly recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> The Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>System & Conditional Flags</strong></td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> </tbody> </table> </Accordion> # Refunds Source: https://devzone.nayax.com/docs/cortina/refunds The Refund feature allows merchants to return funds to customers for eligible transactions directly through the system. It supports both full and partial refunds, helping to resolve disputes, handle cancellations, or correct errors efficiently. Refunds are triggered from either Nayax Core or Lynx API and are done as MOTO transactions (PAN and Expiry date only) with a negative amount. The refund request is a standalone action that includes details of the original transaction. Refunds are available for all Cortina integration types. <Note> **Enable Refunds** Refunds require additional configuration on the Nayax side. If you wish to support them, please contact your assigned Nayax integration engineer. </Note> ## How to implement A refund can be issued up to 180 days from the original transaction date using a [Cortina Refund request](/reference/cortina/cortina-credit-card/cortina-credit-card-refund) for the specific integration type used. * The refund amount will be sent in `BasicInfo.Amount`. * The `PaymentInfo` object will include the details for the original authorization. The response to this request is similar to a regular Sale response. # Sale End Notification Source: https://devzone.nayax.com/docs/cortina/sale-end-notification Cortina uses the `SaleEndNotification` command to notify the integrator about the completion of the transaction request with the Cortina payment provider. ## Request Nayax's servers send a POST request to your configured `SaleEndNotification` endpoint, which would be of the following format: `(customer's URL)/Cortina/SaleEndNotification` The payload includes the following details: ```json theme={null} { "BasicInfo": { "TransactionId": "N99O4XURDQYJZIK4OTCAWF1RHHA40TZWVCRB", "NayaxTransactionId": 3584697384, "Amount": 5, "CurrencyCode": "ILS", "CurrencyNumeric": "376", "SiteId": 1, "MachineAuTime": "071221132914", "TimeoutMS": 15000, "IsProductSelected": true, "PaymentMethodID": 1, "BillingProviderId": 1, "AuditNumber": 342, "NayaxRRN": "111111", "IsDeferredAuthorization": true, "AgeLimitation": 18, "IsSoftDeclineCompletion": true, "TransitElement": { "TransitTransactionType": 1, "DenyListIndication": 0 } }, "PaymentInfo": { "SrvTranId": "3584697388", "AuthCode": "333333", "AuthAmount": 5.5, "SettAmount": 5.5, "RRN": "111111", "Token": "string", "AuthDateTime": "071221133300", "SettDateTime": "071221133330", "TraceNumber": "4444", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": false, "ProviderExternalData": "string", "InitiateTranReference": 11223344, "IsRevalueCard": false }, "DynamicURL": "string", "CustomData": { "DirectActor": "String", "Operator": "String", "Distributor": "String", "Actor": "String", "Machine": "String", "SoftDecline": "String" } } ``` ### Request parameters The table below describes all the parameters of the request: <table> <thead> <tr> <th> Field </th> <th> Type </th> <th> Required </th> <th> Description </th> <th /> </tr> </thead> <tbody> <tr> <td> `BasicInfo` </td> <td> `TransactionId` </td> <td> String(36) </td> <td> Yes </td> <td> The unique identifier for this transaction. If /StartSession has been used then this will echo the transaction Id encrypted in 'TranIDCipher'.\ If /StartSession was not Used - Nayax Engine shall generate this Value. </td> </tr> <tr> <td /> <td> `NayaxTransactionId` </td> <td> Int(64) </td> <td> Yes </td> <td> Nayax Internal Unique identifier for the transaction which will be echoed in further requests. </td> </tr> <tr> <td /> <td> `Amount` </td> <td> Double </td> <td> Yes </td> <td> Decimal (max 3 digits for cents)\ The amount of the payment Example: 1 cent = 0.01, 20 cents = 0.20 * Note: Currencies with no Decimal Place shall be represented as double as well.\ Example: 234 JYN = 234.0. </td> </tr> <tr> <td /> <td> `CurrencyCode` </td> <td> String(3) </td> <td> Yes </td> <td> Currency according to ISO4217 Attribute format: Alpha-3. </td> </tr> <tr> <td /> <td> `CurrencyNumeric` </td> <td> String(3) </td> <td> Yes </td> <td> Currency according to ISO4217 Attribute format: Numeric-3. </td> </tr> <tr> <td /> <td> `SiteId` </td> <td> Int(16) </td> <td> No </td> <td> Region of the Nayax server. </td> </tr> <tr> <td /> <td> `MachineAuTime` </td> <td> String </td> <td> No </td> <td> Machine Authorization Timestamp </td> </tr> <tr> <td /> <td> `TimeoutMS` </td> <td> Int(32) </td> <td> No </td> <td> Nayax Server T/O configuration, in milliseconds </td> </tr> <tr> <td /> <td> `IsProductSelected` </td> <td> Bool </td> <td> No </td> <td> indication if the product was pre-selected </td> </tr> <tr> <td /> <td> `PaymentMethodID` </td> <td> Int(32) </td> <td> No </td> <td> Nayax identifier of the payment provider </td> </tr> <tr> <td /> <td> `BillingProviderId` </td> <td> Int(32) </td> <td> No </td> <td> Nayax identifier of the billing provider </td> </tr> <tr> <td /> <td> `AuditNumber` </td> <td> Int(64) </td> <td> No </td> <td> For Nayax internal use only. </td> </tr> <tr> <td /> <td> `NayaxRRN` </td> <td> String </td> <td> No </td> <td> Reference to generate Nayax Number, Used as External Transaction Identification for external parties (Usually Card schemes, or App service providers).\ From support perspective - It is highly recommended that this ID shall be the one visible to the end consumer/Card holder and the card's Issuer (e.g. Bank) or Application service provider (e.g. Alipay, WeChat).\ If none of the above is applicable, the Integrator shall generate an additional String. * This Value shall be echoed in the /Inquiry request. </td> </tr> <tr> <td /> <td> `IsDeferredAuthorization` </td> <td> Bool </td> <td> No </td> <td> Further information is unavailable. </td> </tr> <tr> <td /> <td> `AgeLimitation` </td> <td> Int(16) </td> <td> No </td> <td> Minimum age required to allow the transaction. </td> </tr> <tr> <td /> <td> `IsSoftDeclineCompletion` </td> <td> Bool </td> <td> No </td> <td> Further information is unavailable. </td> </tr> <tr> <td> `TransitElement` inside `BasicInfo` </td> <td> `TransitTransactionType` </td> <td> Int(32) </td> <td> No </td> <td> Enum: 1 2 3 7 1 - Prefunded 2 - Realtime Authorization 3 - Post-Authorization\ Aggregated Transaction 7 - Debt Recovery </td> </tr> <tr> <td> `TransitElement` inside `BasicInfo` </td> <td> `DenyListIndication` </td> <td> Int(32) </td> <td> No </td> <td> Enum: 0 1 2 0 - unknown/ no effect 1 - Decline will cause consumer\ to be added to the deny list 2 - Approval shall cause the consumer to be removed from deny list. </td> </tr> <tr> <td> `PaymentInfo` </td> <td> `SrvTranId` </td> <td> String </td> <td> No </td> <td> The Integrator's internal transaction id. Conditional, only if /StartSession was not Used. If /StartSession was used, this should be either empty or Echo the Transaction ID sent in the request. </td> </tr> <tr> <td /> <td> `AuthCode` </td> <td> String(40) </td> <td> No </td> <td> External (usually Card issuer's) Authorization Code </td> </tr> <tr> <td /> <td> `AuthAmount` </td> <td> Double </td> <td> No </td> <td> The original amount requested in /Authorization requested. </td> </tr> <tr> <td /> <td> `SettAmount` </td> <td> Double </td> <td> No </td> <td> The original amount requested in /Settlement or /Sale process. </td> </tr> <tr> <td /> <td> `RRN` </td> <td> String </td> <td> No </td> <td> Reference Retrieval Number, Used as External Transaction Identification for external parties (Usually Card schemes)\ From support perspective - It is highly recommended that this ID shall be the one visible to the end consumer/Card holder. </td> </tr> <tr> <td /> <td> `Token` </td> <td> String(256) </td> <td> No </td> <td> A unique token for the transaction. For Internal Nayax use only </td> </tr> <tr> <td /> <td> `AuthDateTime` </td> <td> String </td> <td> No </td> <td> The date time string of when the /Authorization took place Format: ddMMyyHHmmss </td> </tr> <tr> <td /> <td> `SettDateTime` </td> <td> Double </td> <td> No </td> <td> Irrelevant for the Authorization command. </td> </tr> <tr> <td /> <td> `TraceNumber` </td> <td> String </td> <td> No </td> <td> Trace number. For Internal Nayax use only </td> </tr> <tr> <td /> <td> `AuthSource` </td> <td> String(5) </td> <td> No </td> <td> For Internal Nayax use only </td> </tr> <tr> <td /> <td> `AdditionalData` </td> <td> String </td> <td> No </td> <td> String in JSON format.\ Contact Nayax TPOC on order define. </td> </tr> <tr> <td /> <td> `IsGatewayTimeout` </td> <td> Bool </td> <td> No </td> <td> Was there a gateway timeout (valid in response) </td> </tr> <tr> <td /> <td> `ProviderExternalData` </td> <td> String </td> <td> No </td> <td> String in JSON format. </td> </tr> <tr> <td /> <td> `InitiateTranReference` </td> <td> Int(64) </td> <td> No </td> <td> Conditional, in case of re-attempt of using a prepaid loyalty card on a terminal in a given transaction, this field will reflect which transaction (Nayax Transaction ID) this attempt originally belongs to. </td> </tr> <tr> <td /> <td> `IsRevalueCard` </td> <td> Bool </td> <td> No </td> <td> Indication if card is allowed revalue </td> </tr> <tr> <td> `BasicInfo` </td> <td> `DynamicURL` </td> <td> String </td> <td> No </td> <td> Actor level URL configuration </td> </tr> <tr> <td> `CustomData` </td> <td> `DirectActor` </td> <td> String </td> <td> No </td> <td> Direct actor custom data (String in json format) </td> </tr> <tr> <td /> <td> `Operator` </td> <td> String </td> <td> No </td> <td> Operator custom data (String in json format) </td> </tr> <tr> <td /> <td> `Distributor` </td> <td> String </td> <td> No </td> <td> Distributor custom data (String in json format) </td> </tr> <tr> <td /> <td> `Actor` </td> <td> String </td> <td> No </td> <td> Actor custom data (String in json format) </td> </tr> <tr> <td /> <td> `Machine` </td> <td> String </td> <td> No </td> <td> Machine custom data (String in json format) </td> </tr> <tr> <td /> <td> `SoftDecline` </td> <td> String </td> <td> No </td> <td> Soft Decline custom data (String in json format) </td> </tr> </tbody> </table> ## Response The `SaleEndNotification` Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "string", "Code": 0, "StatusMessage": "string", "CustomDeclineCode": "string" } } ``` ### Response parameters The table below describes all the parameters of the response: <table> <thead> <tr> <th> Field </th> <th> Type </th> <th> Required </th> <th> Description </th> </tr> </thead> <tbody> <tr> <td> `TranIDCipher` </td> <td> String(36) </td> <td> Yes </td> <td> The Integrator Generates transaction ID of 36 Chars (or 288 bits). The Integrator then appends the char = and RandomNumber to create the ciphertext of 64 chars Format TransactionId=RandomNumber The integrator encrypts the ciphertexts with the Secret Token in AES ECB. The AES key will be the last (right most) 256 bits (or 32 chars) of the Secret Token the matches the TokenID provided in the request. Nayax will AES ECB decrypt and extract transaction id The transaction Id value will then be used for all further requests. Information regarding how to generate the TranIDCipher (via encrypting the token alongside the Random Number and the customer's Transaction ID can be reviewed under [Start Session authentication process](/docs/cortina/start-session/cortina-auth#/) </td> </tr> <tr> <td> `Verdict` inside `Status` </td> <td> String </td> <td> Yes </td> <td> Const string.\ Status of the request ('Approved'/'Declined') </td> </tr> <tr> <td> `Code` inside `Status` </td> <td> Int(32) </td> <td> No </td> <td> Conditional - Only if verdict value is declined. Valid decline codes (must be a code from this list): <br /> 1 - Insufficient funds <br /> 2 - Transaction ID unknown <br /> 3 - Cardholder exceeded daily / weekly / monthly transaction count limit <br /> 4 - Cardholder exceeded transaction amount limit <br /> 5 - Suspected Fraud <br /> 6 - General system failure <br /> 7 - Invalid amount <br /> 8 - Request cannot be parsed (format error) <br /> 9 - Transaction not allowed to cardholder <br /> 40 - For Nayax internal use only. <br /> 990 - CertificateFileName not found <br /> 991 - Failed to decipher message body <br /> 992 - Timeout exception <br /> 994 - Card Brand not supported <br /> 996 - Transaction ID Unknown / Duplicate Transaction ID (Start Session Error) <br /> 997 - Missing mandatory parameters <br /> 998 - Validation / request cannot be parsed <br /> 999 - General exception <br /> 1010 - Public Key Certificate not found <br /> 1011 - Method not Implemented </td> </tr> <tr> <td> `StatusMessage` inside `Status` </td> <td> String(255) </td> <td> No </td> <td> Transaction status message free text field / additional varying data </td> </tr> <tr> <td> `CustomDeclineCode` inside `Status` </td> <td> String </td> <td> No </td> <td> This field is used for specifying a custom decline code (i.e. Soft Decline or Switch Interface). The value might be the same as the acquirer's response code or composed by other data. </td> </tr> </tbody> </table> # Authentication Process Source: https://devzone.nayax.com/docs/cortina/start-session/cortina-auth The authentication process in the Cortina API involves using the Start Session endpoint to send a pre-shared Token to the integrator, who will perform additional encryption steps to ensure secure communication between Nayax and the Integrator. ## Authentication process Below is a step-by-step breakdown of the authentication process, with examples to help you understand each part. 1. Before starting, Nayax and the Integrator agree on a shared Secret Token. This token is used for encryption and decryption. See the example token below: ``` mrV3U3nsgGFrE3w5-wnBo_WCLPce-pZ1awRvTVTkungMIKThTVbj_fiXdfoGclhn0 ``` 2. Nayax sends the Start Session Request with the Token ID and 27 char Random String. For example: ``` 123456789qwertyuioasdfghjkl ``` 3. The Integrator generates a Transaction ID of 36 Numeric Characters. For example: ``` 123456789012345678901234567890123456 ``` 4. The integrator prepares a Ciphertext by appending the Transaction ID and the received Random string with a “=” char separator to create a 64 char long ciphertext. For this example, it would be the following: ``` 123456789012345678901234567890123456=123456789qwertyuioasdfghjkl ``` 5. The Integrator generates an encryption key from the last 32 characters of the Secret Token (this is a 256-bit key). ``` wRvTVTkungMIKThTVbj_fiXdfoGclhn0 ``` 6. Using AES encryption in ECB mode (with `PKCS5` padding), the Integrator encrypts the Ciphertext. The encrypted result is then returned in the Start Session response to Nayax. In our example it would produce the following cipher: ``` a0Qnxm4fWMskzFXiMivn8BDiQVSL6be/NXIICC9HBoAiry6DUdKYPQh/YS1G8nObE6/0o9N4MFuYA7CTAxAnphuNJwBEjgBzKhhgpJ5ggnw= ``` 7. Nayax uses the same encryption key to decrypt the Ciphertext and validates that the Random String matches the one sent in the request and that the format is correct. 8. Once the Transaction ID is decrypted, Nayax uses it for subsequent requests such as GenerateQR, Inquiry, Sale, and Authorization. You can use the following website to ensure you've encrypted the TranIDCipher correctly: [https://www.devglan.com/online-tools/aes-encryption-decryption](https://www.devglan.com/online-tools/aes-encryption-decryption) For the example above: <Frame> <img /> </Frame> You can also use this site to decipher your encryption, in order to ensure that the encryption was valid- in order for Nayax's servers to be able to decrypt it.\ For the example above: <Frame> <img /> </Frame> The Integrator must validate that the Transaction ID in requests like `GenerateQR`, `Sale`, `Authorization`, and `Inquiry` was created in a previous `Start Session` request and is still valid.\ It is recommended that the Transaction ID remain valid for no longer than 10 minutes for these requests. <Warning> **Expired Requests** Requests like `Settlement`, `Void`, `Cancel`, and `Refund` can still be processed even after the Transaction ID has expired, as these might be required after the original `Authorization`, `Sale`, or `Inquiry` request. </Warning> # Start Session Source: https://devzone.nayax.com/docs/cortina/start-session/index Cortina uses the `Start Session` command to notify the integrator about the initialization of the transaction request with the Cortina payment provider. <Note> **Important:** For **Cortina Static QR (SQR)**, the `Start` command is being used instead of StartSession, and `Start` is sent from the Cortina payment provider to Nayax, not the other way around (as mentioned here). </Note> More on that in [Static QR- Start](/docs/cortina/staticqr/static-qr-start#/). ## Request Nayax's servers send a POST request to your configured `StartSession` endpoint, which would be of the following format: `(customer's URL)/Cortina/StartSession` The payload includes the following details: ```json theme={null} { "TokenId": "123456", "RandomNumber": "123456789qwertyuioasdfghjkl", "DynamicURL": "string", "CustomData": { "DirectActor": "String", "Operator": "String", "Distributor": "String", "Actor": "String", "Machine": "String", "SoftDecline": "String" } } ``` ### Request Parameters The following table describes all the parameters of the request: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Required</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`TokenId`</td> <td>String</td> <td>**Yes**</td> <td> The **3rd party Secret Token** reference number. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td>**Yes**</td> <td> A unique **27-character random number** generated by Nayax. </td> </tr> <tr> <td>`DynamicURL`</td> <td>String(255)</td> <td>No</td> <td> The **Actor-level URL configuration**. Supports routing to different URLs. </td> </tr> <tr> <td> <strong>Custom Data Fields (String in JSON format)</strong> </td> </tr> <tr> <td>`DirectActor` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data for the **Direct Actor** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`Operator` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data for the **Operator** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`Distributor` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data for the **Distributor** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`Actor` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data for the **Actor** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`Machine` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data for the **Machine** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> <tr> <td>`SoftDecline` Inside `CustomData`</td> <td>String</td> <td>No</td> <td> Custom data related to a **Soft Decline** in **JSON format**. Contact Nayax TPOC for definition. </td> </tr> </tbody> </table> ## Response The `StartSession` Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "TranIDCipher": "a0Qnxm4fWMskzFXiMivn8BDiQVSL6be/NXIICC9HBoAiry6DUdKYPQh/YS1G8nObE6/0o9N4MFuYA7CTAxAnphuNJwBEjgBzKhhgpJ5ggnw=", "Status": { "Verdict": "Approved", "Code": 0, "StatusMessage": "string", "CustomDeclineCode": "string" } } ``` ### Response Parameters The following table describes all the parameters of the response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Required</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>`TranIDCipher`</td> <td>String(36)</td> <td>Yes</td> <td> The **encrypted transaction ID** used for authentication in the `/StartSession` request. <ul> <li>**Integrator's Role:** Generate transaction ID (36 chars/288 bits), append `=` and `RandomNumber` to form the cipher text (64 chars). Encrypt this string using **AES ECB**.</li> <li>**AES Key:** The rightmost 256 bits (32 chars) of the Secret Token that matches the `TokenID`.</li> <li>**Nayax's Role:** Decrypt the cipher text to extract the transaction ID, which is then used for all subsequent requests.</li> </ul> </td> </tr> <tr> <td>`Verdict` inside `Status`</td> <td>String</td> <td>Yes</td> <td> Constant string representing the final **status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code` inside `Status`</td> <td>Int(32)</td> <td>No</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid decline codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full documentation for the complete list of error codes.*</li> </ul> </td> </tr> <tr> <td>`StatusMessage` inside `Status`</td> <td>String(255)</td> <td>No</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode` inside `Status`</td> <td>String</td> <td>No</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> </tbody> </table> # On Screen QR Display Source: https://devzone.nayax.com/docs/cortina/staticqr/on-screen-qr-display Each device has a QR code generated by default (Monyx QR), which includes its device ID. The QR code may be displayed on the screen in idle mode or as a carousel, among other payment methods, cycling on the device's screen.\ A logo of your brand could also be added alongside the QR. Extracting the device ID from the entire QR string should be performed by the mobile application or its backend. The mobile application backend should perform the Cortina calls with the device ID extracted from the QR image.\ In order for the QR to appear in idle, you must do the following: * Ensure that you've got Monyx Balance on the Payment page (under the relevant virtual machine): <Frame> <img /> </Frame> * Set "QR" as one of your Idle Mode Screens: <Frame> <img /> </Frame> See the image below for an example of how it would look: <Frame> <img /> </Frame> # Product Remote Vend Source: https://devzone.nayax.com/docs/cortina/staticqr/remote-vend Remote Vend allows the integrator to initiate a transaction with the selected product using the `Start` call. The selected product can be sent as a product code for MDB or Marshal machines, or a specific pulse line ID for Pulse machines. <Warning> This functionality is <u>only supported for the following protocols</u>: * MDB level 3 (needs both the physical machine to support MDB level 3 as well as have matching configurations on Nayax Core) * Pulse **NOT** supported for: * MDB level 1 / 2 * Marshall </Warning> <Note> This functionality is currently supported only with `VPOS\ONYX` device. </Note> ## Virtual machine configurations <Frame> <img alt="" /> </Frame> <Warning> **Pulse machines** Leave `MDB Level 3 Optional Features` empty on Pulse machines. `Enable Remote Vend` and `Enable "Always Idle" state` are MDB features, and they can cause issues on Pulse machines. </Warning> ## How to implement When sending the Start request, add a "Products" attribute with an array with one or more products as follows: ### Pulse machine #### Starting from which firmware is it supported? 4.0.10.23 #### What is the format of the call? The selected product goes inside the `Products` array of the Start request. Pulse machines use either `Code` or `PulseLineNumber`, depending on how the machine is configured. See [Remote vend: product selection](/docs/cortina/staticqr/static-qr-start#remote-vend-product-selection) for which field to send and how the numbering works. ### Not pulse (MDB, Marshall etc.) * MDB- note that Remote Vend is supported on MDB machines with level 3 only (a protocol limitation) #### What is the format of the call? **Cortina V1 (relevant for old integrations only):** ```json theme={null} { "AppUserId": "260760", "TerminalId": "0456789456789456", "TransactionId": "12345129", "SecretToken": "1234qgODDqYgkJbSU-Vxw0MkZM1XjHvbQeSTnHmhwltUM_5kB-ZSgofkCxNk3ZN0", "Products": [ { "ProductCode": 2 } ] } ``` **Cortina V2:** ```json theme={null} { "AppUserId": "260760", "TerminalId": "0456789456789456", "TransactionId": "12345129", "SecretToken": "1234OqgODDqYgkJbSU-Vxw0MkZM1XjHvbQeSTnHmhwltUM_5kB-ZSgofkCxNk3ZN0", "Products": [ { "Code": 2 } ] } ``` # Authorization Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-authorization Cortina SQR uses the `Authorization` command to notify the integrator about the result of a card tap in order to initiate the authorization process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Authorization` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Authorization` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": "236584335969834429321847829253667359,", "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12 }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011 }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & Financial Details</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Machine & Device Information</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`HwSerial`</td> <td>String</td> <td> Nayax Device **Hardware serial number**. </td> </tr> <tr> <td>`Type`</td> <td>String</td> <td> Nayax Device Type. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID** allocated in Nayax's back office. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. <ul> <li>Example: `2` means amounts like 123.45.</li> </ul> </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Machine **Zip Code**. </td> </tr> <tr> <td><strong>Country & Actor Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name** (for machine location). </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> </tbody> </table> ## Response The Authorization Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "Cortina V2 Stub Tester" }, "PaymentInfo": { "SrvTranId": "string", "AuthCode": "string", "AuthAmount": 0, "SettAmount": 0, "RRN": "string", "Token": "string", "AuthDateTime": "string", "SettDateTime": "string", "TraceNumber": "string", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The final status of the request. Must be one of the constant string values: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Highly recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>System & External Data</strong></td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> </tbody> </table> # Cancel Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-cancel Cortina SQR uses the `Cancel` command to notify the integrator in order to initiate the cancellation process with the Cortina payment provider whenever one of the below scenarios takes place: 1. Getting a failed `Authorization` Response (either due to timeout or having an error code in the `Authorization` Response). 2. Issues during product selection- inactivity of the consumer/Cancel button being pressed/invalid product selection by the consumer. 3. Vend failure (issue with product dispensing/service providing) by the machine This command is essential for having the payment provider aware that the transaction was cancelled on Nayax's end (as well as from the consumer's POV), and is done in order for the payment provider to complete the cancellation on its end. * Note- this command is relevant for PreAuthorization only. Its equivalent in the PreSelection flow is the `Void` command. ## Request Nayax's servers send a POST request to your configured `Cancel` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Cancel` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 2, "ReasonText": "Cashless cancelled by consumer", "BasicInfo": { "TransactionId": "236584335969834429321847829253667359,", "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12 }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011 }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "PaymentInfo": { "SrvTranId": "string", "AuthCode": "string", "AuthAmount": 0, "SettAmount": 0, "RRN": "string", "Token": "string", "AuthDateTime": "string", "SettDateTime": "string", "TraceNumber": "string", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td><strong>Country & Actor Geo Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings) & System Flags</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> </tbody> </table> ## Response The Cancel Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "Cortina V2 Stub Tester" } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td><strong>Loyalty & Credit Information</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. **Uses Decimal place 2.** </td> </tr> </tbody> </table> # Refund Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-refund Cortina SQR uses the `Refund` command to notify the integrator about a refund request, so the integrator can start the refund with the Cortina payment provider. ## How a refund is triggered You can trigger the refund request in two ways: * From the Dynamic Transaction Monitor in Nayax Core. * Through the Lynx API. ### From the Dynamic Transaction Monitor <Warning> **Refunds Admin role required** Requesting and approving a refund from the Dynamic Transaction Monitor requires the Refunds Admin role. Ask your Integration Support Engineer to assign it. </Warning> <Steps> <Step title="Request the refund"> Right-click the relevant transaction and select **Request Refund**. <Frame> <img alt="Nayax Core transaction context menu with Request Refund highlighted" /> </Frame> </Step> <Step title="Approve the refund"> Right-click the same transaction again and select **Approve/Decline Refund**. <Frame> <img alt="Nayax Core transaction context menu with Approve/Decline Refund highlighted" /> </Frame> </Step> </Steps> Nayax then sends the `Refund` command to your endpoint, as described below. ### Through the Lynx API Call the [Request a Payment Refund](/reference/lynx/payment/request-a-payment-refund) endpoint, then the [Approve Payment Refund](/reference/lynx/payment/approve-payment-refund) endpoint. ## Request Nayax's servers send a POST request to your configured `Refund` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Refund` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 999, "ReasonText": "General exception", "BasicInfo": { "TransactionId": "236584335969834429321847829253667359,", "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12 }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011 }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "PaymentInfo": { "SrvTranId": "string", "AuthCode": "string", "AuthAmount": 0, "SettAmount": 0, "RRN": "string", "Token": "string", "AuthDateTime": "string", "SettDateTime": "string", "TraceNumber": "string", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types.</li> </ul> </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read by DOT</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`CVV2`</td> <td>String</td> <td> Card Verification Value 2 (**CVV2**). </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td><strong>System & External Data</strong></td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> Additional data string in **JSON format**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> </tbody> </table> ## Response The Refund Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "Cortina V2 Stub Tester" } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td><strong>Loyalty & Credit Information</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. **Uses Decimal place 2.** </td> </tr> </tbody> </table> # Sale Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-sale Cortina SQR uses the `Sale` command to notify the integrator about the result of a card tap after a product has been selected in order to initiate the authorization process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Sale` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Sale` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": "105603", "NayaxTransactionId": 6890622040, "Amount": 2.0, "CurrencyCode": "GBP", "CurrencyNumeric": "826", "SiteId": 6, "MachineAuTime": "041125210717", "TimeoutMS": 15000, "PaymentMethodID": 233, "BillingProviderId": 0, "NayaxRRN": "104210717194" }, "MachineInfo": { "Id": 968382276, "Name": "1844-PEPPA PIG 3 SEATER CAROUSEL-PARK CENTRE - BELFAST", "ExternalId": "0612133524110088", "Type": "Amusement", "TerminalId": "", "DecimalPlace": 2, "Offset": "0.00", "City": "Belfast", "ZipCode": "BT12 6HN", "Country": { "Name": "UNITED KINGDOM", "NumericCode": "826", "Alpha2Code": "GB", "Alpha3Code": "GBR" }, "GeoLocation": { "State": "Northern Ireland", "City": "Belfast", "CountryCode": "GB", "ZipCode": "BT12 6HN", "Address": "Donegall Road", "Latitude": 54.5886358, "Longitude": -5.9645663 } }, "ActorInfo": { "Id": 2001384616, "Name": "ABCD", "Country": { "Name": "UNITED KINGDOM", "NumericCode": "826", "Alpha2Code": "GB", "Alpha3Code": "GBR" }, "GeoLocation": { "State": "Northern Ireland", "City": "Banbridge", "CountryCode": "GB", "ZipCode": "BT32 3QD", "Address": "abcde" }, "MCC": 5813 }, "CustomData": { "Actor": "", "Machine": "" }, "DeviceInfo": { "HwSerial": "0123456123456123", "FWVersion": "4.1.24.4-RC01 - Jun 24 2024", "Type": "ONYX" }, "Products": [ { "Code": -1, "CatalogProductId": "", "Name": "Unknown", "Price": 2.0, "UnitOfMeasurement": "Unit", "Measurement": 1.0, "Group": "Unknown", "ProductGroupId": "52" } ] } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & Status</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td><strong>Country & Actor Geo Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`Intra`</td> <td>String</td> <td> The **Intra Region** (e.g., 'European Union') used for geographical diversification across countries. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DynamicURL`</td> <td>String</td> <td> Actor level **URL configuration**. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings) & System Flags</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types.</li> </ul> </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read by DOT</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`CVV2`</td> <td>String</td> <td> Card Verification Value 2 (**CVV2**). </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> </tbody> </table> ## Response The Sale Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "transaction approved" }, "PaymentInfo": { "SrvTranId": "string", "AuthCode": "string", "AuthAmount": 0, "SettAmount": 0, "RRN": "string", "Token": "string", "AuthDateTime": "string", "SettDateTime": "string", "TraceNumber": "string", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Sale` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Sale` Request. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Loyalty & System Details</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> </tbody> </table> # Settlement Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-settlement Cortina SQR uses the `Settlement` command to notify the integrator about the result of a settlement process on the device's end (meaning a product has been vended) in order to initiate the settlement process with the Cortina payment provider. This command is essential for proceeding to transaction confirmation or rejection handling. ## Request Nayax's servers send a POST request to your configured `Settlement` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Settlement` The payload includes the full result of the card scan operation: ```json theme={null} { "BasicInfo": { "TransactionId": 2.3658433596983443e+35, "NayaxTransactionId": 0, "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12, "MachineAuTime": "string", "TimeoutMS": 15000, "IsProductSelected": true }, "DeviceInfo": { "HwSerial": "string", "FWVersion": "string", "Type": "ONYX" }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "Region": "string", "City": "string", "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011, "Country": { "Name": "string", "NumericCode": "string", "Alpha2Code": "string", "Alpha3Code": "string" }, "GeoLocation": { "State": "string", "City": "string", "CountryCode": "string", "ZipCode": "string", "Address": "string", "Longitude": 34.998819, "Latitude": 32.8198988 } }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "CardData": { "CardNumber": "string", "EntryMode": "string", "ExpYear": "string", "ExpMonth": "string", "EMVData": "string", "IDNumber": "string", "RandomNumber": "string", "BrandInfo": { "PrimaryId": "string", "PrimaryDescription": "string", "SecondaryId": "string" }, "CardHolderName": "Test Card Holder" }, "Products": [ { "Code": 11, "Name": "Stella", "Price": 0.1, "UnitOfMeasurement": "USD", "Measurement": false }, { "Code": 12, "Name": "expensiveSprite", "Price": 6, "UnitOfMeasurement": "USD", "Measurement": false } ], "PaymentInfo": { "SrvTranId": 2.3658433596983443e+35, "AuthCode": 333333, "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": 111111, "Token": "string", "AuthDateTime": 230221101008, "SettDateTime": 230221101009, "TraceNumber": 4444, "AuthSource": 555555, "AdditionalData": "string", "IsGatewayTimeout": true }, "SecondaryDescription": "string" } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td><strong>Country & Actor Geo Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Actor ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Direct Merchant name**. </td> </tr> <tr> <td>`OperatorId`</td> <td>Int(64)</td> <td> **Merchant operator ID** (Integer format). </td> </tr> <tr> <td>`OperatorName`</td> <td>String</td> <td> **Merchant operator name**. </td> </tr> <tr> <td>`MerchantId`</td> <td>Int(64)</td> <td> **Merchant ID**. Contact Nayax TPOC to define. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings)</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> </tbody> </table> ## Response The Settlement Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Declined", "Code": 1, "StatusMessage": "Insufficient balance" } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Loyalty & Credit Information</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. </td> </tr> </tbody> </table> # Start Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-start ## Request The Cortina payment method would send a `Start` command to Nayax's servers in order to notify them about starting a transaction. The call would be of the following format: `https://lynx.nayax.com/payment/v2/transactions/cortina/(payment method's name)/start` The payload includes the following details: <CodeGroup> ```json JSON-TerminalID theme={null} { "AppUserID": "19", "TerminalId": "0456789456789456", "TransactionId": "123456789qwertyuioasdfghjkl", "SecretToken": "mrV3U3nsgGFrE3w5-wnBo_WCLPce-pZ1awRvTVTkungMIKThTVbj_fiXdfoGclhn0" } ``` ```json JSON-UniQR theme={null} { "AppUserID": "19", "UniQR": "https://qr.nayax.com/v1/rWg_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2", "TransactionId": "123456789qwertyuioasdfghjkl", "SecretToken": "mrV3U3nsgGFrE3w5-wnBo_WCLPce-pZ1awRvTVTkungMIKThTVbj_fiXdfoGclhn0" } ``` ```json Product selection (relevant only for PreSelection flow) theme={null} { "AppUserID": "19", "UniQR": "https://qr.nayax.com/v1/rWg_p6pZh1pwjvbkGrmBLy3KgwSz3dq-y63r5FPxk2NOWw2", "TransactionId": "123456789qwertyuioasdfghjkl", "SecretToken": "mrV3U3nsgGFrE3w5-wnBo_WCLPce-pZ1awRvTVTkungMIKThTVbj_fiXdfoGclhn0" "Products": [ { "Code":2 } ] } ``` </CodeGroup> ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>User & Security Identifiers</strong></td> </tr> <tr> <td>`AppUserID`</td> <td>String(40)</td> <td> The consumer's **user ID on the 3rd party's app**. </td> </tr> <tr> <td>`TransactionId`</td> <td>String(40)</td> <td> The **unique identifier for the transaction**. <ul> <li>Will be echoed in all further requests and responses.</li> <li>Minimum length of **8 characters**.</li> </ul> </td> </tr> <tr> <td>`SecretToken`</td> <td>String(64)</td> <td> The **unique secret key** for your system, provided by Nayax in advance. **Must be kept secret.** </td> </tr> <tr> <td>`Balance`</td> <td>Double</td> <td> The **balance of the user's account**. Decimal value (max 3 digits for cents). </td> </tr> <tr> <td><strong>Machine Identification (One is Required)</strong></td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> The **Unique Identifier for the vending machine** (HW-Serial of the device). <ul> <li>**Conditional**: Must be sent if `UniQR` is **not** sent.</li> </ul> </td> </tr> <tr> <td>`UniQR`</td> <td>String</td> <td> The **QR code value** linked to the machine. <ul> <li>**Conditional**: Must be sent if `TerminalId` is **not** sent.</li> </ul> </td> </tr> <tr> <td><strong>Product Selection (`Products` Array)</strong></td> </tr> <tr> <td>`Products` Array</td> <td>\*\*\*</td> <td> The array is **optional**, but if provided, some inner fields are mandatory. Only relevant for the **PreSelection flow**. </td> </tr> <tr> <td>`Code` inside `Products`</td> <td>Int(16)</td> <td> The **Code of the selected item**. <ul> <li>**Conditional**: Mandatory if the machine is **not** a Pulse machine.</li> </ul> </td> </tr> <tr> <td>`PulseLineNumber` inside `Products`</td> <td>Int(32)</td> <td> The pulse line number for remote vend capability. <ul> <li>**Conditional**: Mandatory if the machine is a **Pulse machine**.</li> <li>Must be a **positive integer** ($\ge 0$).</li> </ul> </td> </tr> <tr> <td>`Name` inside `Products`</td> <td>String(255)</td> <td> The **Product name** as defined in the Nayax back office. </td> </tr> <tr> <td>`Price` inside `Products`</td> <td>Double</td> <td> The **original Product price** in the machine's currency. <ul> <li>**Conditional**: Mandatory if the machine does **not** have a price setup for the product code.</li> <li>Note: The transaction amount is the final billing price after adjustments.</li> </ul> </td> </tr> <tr> <td>`UnitOfMeasurement` inside `Products`</td> <td>String(64)</td> <td> Product's **unit of measurement** (e.g., 'unit' or 'Liter'). </td> </tr> </tbody> </table> ### Remote vend: product selection The following applies to the **PreSelection flow** only. To specify which product to vend, include a `"code"` field inside the `"Products"` array with the corresponding product index. **Pulse machine code numbering** <u>For Pulse array machines</u> (any Pulse configuration except Pulse Line), the `"code"` numbering starts from 0.<br />For example, in case of: <Frame> <img alt="Image" /> </Frame> * `"Code": 0` → **"Ultimate"** product * `"Code": 1` → **"Superior"** product * `"Code": 2` → **"Regular"** product If you send a number outside the scope of the virtual machine's array, our servers will select the first item in the list (`Code: 0`). <u>For Pulse 1–6 configurations</u> (Pulse Line), use `"PulseLineNumber"` instead of `"code"`, and the counting starts from 1 (not 0). <Frame> <img alt="Image" /> </Frame> ## Response The `Start` Response that Nayax's servers would send to the payment method.<br />The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "Cortina V2 Stub Tester" } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict` inside `Status`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code` inside `Status`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage` inside `Status`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode` inside `Status`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> </tbody> </table> # Void Source: https://devzone.nayax.com/docs/cortina/staticqr/static-qr-void Cortina SQR uses the `Void` command to notify the integrator in order to initiate the cancellation process with the Cortina payment provider whenever one of the below scenarios takes place: 1. Issues during vending process- Cancel button being pressed by the consumer/ vend failure (issue with product dispensing/service providing) by the machine. 2. No `Sale` Response until timeout. This command is essential for having the payment provider aware that the transaction was cancelled on Nayax's end (as well as from the consumer's POV), and is done in order for the payment provider to complete the cancellation on its end. * Note- this command is relevant for PreSelection only. Its equivalent in the PreAuthorization flow is the `Cancel` command. ## Request Nayax's servers send a POST request to your configured `Void` endpoint, which would be of the following format: `(customer's URL)/Cortina/StaticQR/Void` The payload includes the full result of the card scan operation: ```json theme={null} { "ReasonCode": 0, "ReasonText": "string", "BasicInfo": { "TransactionId": "236584335969834429321847829253667359,", "Amount": 0.1, "CurrencyCode": "USD", "CurrencyNumeric": 376, "SiteId": 12 }, "MachineInfo": { "Id": 869761713, "Name": "TestPayStaticQR V2", "TerminalId": 987654321, "DecimalPlace": 2, "Offset": 2, "GroupId": "Beverages", "OperatorId": 12345, "ZipCode": 10001, "Country": { "Name": "United States of America", "NumericCode": 840, "Alpha2Code": "US", "Alpha3Code": "USA" } }, "ActorInfo": { "Id": 2001102296, "Name": "Far East Dev Zone", "OperatorId": 2000305191, "OperatorName": "TanyaT_OP", "MerchantId": 10011 }, "CustomData": { "DirectActor": 12312312, "Operator": 123121434134, "Distributor": "superDistributor", "Actor": 12312312, "Machine": 131231348 }, "PaymentInfo": { "SrvTranId": "string", "AuthCode": "string", "AuthAmount": 0, "SettAmount": 0, "RRN": "string", "Token": "string", "AuthDateTime": "string", "SettDateTime": "string", "TraceNumber": "string", "AuthSource": "string", "AdditionalData": "string", "IsGatewayTimeout": true } } ``` ### Request parameters The following table describes the parameters included in the request body: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`TransactionId`</td> <td>String(36)</td> <td> The **unique identifier** for this transaction. <ul> <li>Echoes the encrypted ID from `/StartSession` if used.</li> <li>Otherwise, the **Nayax Engine** generates this value.</li> </ul> </td> </tr> <tr> <td>`NayaxTransactionId`</td> <td>Int(64)</td> <td> The **Nayax internal unique ID** for the transaction, echoed in further requests. </td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`Amount`</td> <td>Double</td> <td> The **payment amount** (Decimal with max 3 digits for cents). <ul> <li>Example: 1 cent = `0.01`.</li> <li>**Note:** Currencies with no decimal places are still represented as a double (e.g., 234 JYN = `234.0`).</li> </ul> </td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` request. Conditional on `/Authorization` response. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td>`CurrencyCode`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Alpha-3** format. </td> </tr> <tr> <td>`CurrencyNumeric`</td> <td>String(3)</td> <td> Currency code in **ISO 4217 Numeric-3** format. </td> </tr> <tr> <td><strong>Card & Payment Details</strong></td> </tr> <tr> <td>`CardNumber`</td> <td>String</td> <td> Card details provided based on transaction type: <ul> <li>Full **Track 2** for card-present Authorization/Sale.</li> <li>Card **PAN only** for other transaction types.</li> </ul> </td> </tr> <tr> <td>`EntryMode`</td> <td>String(4)</td> <td> **How the card details were read**: <ul> <li>**MCR**: Magnetic Stripe Read (swipe)</li> <li>**CON**: Contact Chip (insert)</li> <li>**CLS**: Contactless Chip (tap)</li> <li>**NFC**: Phone/Mobile contactless</li> <li>**QR**: QR code read by DOT</li> <li>*Consult Nayax POC for specific edge cases.*</li> </ul> </td> </tr> <tr> <td>`ExpYear`</td> <td>String</td> <td> Card expiration year (**YY** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`ExpMonth`</td> <td>String</td> <td> Card expiration month (**MM** format). **Conditional** (only when Interface is 1 or 10). </td> </tr> <tr> <td>`EMVData`</td> <td>String</td> <td> EMV tags data in **TLV (Tag-Length-Value) format**. </td> </tr> <tr> <td>`CVV2`</td> <td>String</td> <td> Card Verification Value 2 (**CVV2**). </td> </tr> <tr> <td>`IDNumber`</td> <td>String</td> <td> Cardholder **ID Number**. </td> </tr> <tr> <td>`RandomNumber`</td> <td>String</td> <td> Further information is unavailable. </td> </tr> <tr> <td>`PrimaryId`</td> <td>String</td> <td> **Primary Brand ID**. </td> </tr> <tr> <td>`PrimaryDescription`</td> <td>String</td> <td> **Primary Brand Description**. </td> </tr> <tr> <td>`SecondaryId`</td> <td>String</td> <td> **Secondary Brand ID**. </td> </tr> <tr> <td>`SecondaryDescription`</td> <td>String</td> <td> **Secondary Brand Description**. </td> </tr> <tr> <td>`CardHolderName`</td> <td>String</td> <td> **Card Holder Name**. </td> </tr> <tr> <td><strong>Machine & Location Details</strong></td> </tr> <tr> <td>`SiteId`</td> <td>Int(16)</td> <td> Region of the **Nayax server**. </td> </tr> <tr> <td>`Id`</td> <td>Int(64)</td> <td> **Machine entity unique ID**. </td> </tr> <tr> <td>`Name`</td> <td>String(255)</td> <td> **Machine Name**. </td> </tr> <tr> <td>`TerminalId`</td> <td>String(255)</td> <td> **Terminal identifier**. Contact Nayax TPOC to define. </td> </tr> <tr> <td>`DecimalPlace`</td> <td>Int(64)</td> <td> **Decimal point location** for amounts. </td> </tr> <tr> <td>`Offset`</td> <td>String(255)</td> <td> **UTC timezone offset**. </td> </tr> <tr> <td>`GroupId`</td> <td>String</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`OperatorId`</td> <td>String(255)</td> <td> **Merchant ID** (String format). </td> </tr> <tr> <td><strong>Country & Actor Geo Details</strong></td> </tr> <tr> <td>`Name`</td> <td>String</td> <td> Country **Full Name**. </td> </tr> <tr> <td>`NumericCode`</td> <td>String(3)</td> <td> **ISO-3166-1 Numeric-3 code**. </td> </tr> <tr> <td>`Alpha2Code`</td> <td>String(2)</td> <td> **ISO-3166-1 Alpha-2 code**. </td> </tr> <tr> <td>`Alpha3Code`</td> <td>String(3)</td> <td> **ISO-3166-1 Alpha-3 code**. </td> </tr> <tr> <td>`State`</td> <td>String</td> <td> Actor geo **state code**. </td> </tr> <tr> <td>`City`</td> <td>String(255)</td> <td> Actor geo **City**. </td> </tr> <tr> <td>`CountryCode`</td> <td>String</td> <td> Actor geo **Country code (ISO3)**. </td> </tr> <tr> <td>`ZipCode`</td> <td>String(255)</td> <td> Actor geo **Zip code**. </td> </tr> <tr> <td>`Address`</td> <td>String(255)</td> <td> Actor geo **Address**. </td> </tr> <tr> <td>`Longitude`</td> <td>String</td> <td> Machine Location **Longitude**. </td> </tr> <tr> <td>`Latitude`</td> <td>String</td> <td> Machine Location **Latitude**. </td> </tr> <tr> <td><strong>Custom Data (JSON Strings) & System Flags</strong></td> </tr> <tr> <td>`DirectActor`</td> <td>String</td> <td> Direct actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Operator`</td> <td>String</td> <td> Operator **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Distributor`</td> <td>String</td> <td> Distributor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Actor`</td> <td>String</td> <td> Actor **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`Machine`</td> <td>String</td> <td> Machine **custom data** (String in **JSON format**). </td> </tr> <tr> <td>`AdditionalData`</td> <td>String</td> <td> General custom data string in **JSON format**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> </tbody> </table> ## Response The Void Response that the customer's payment method would send to Nayax's servers.\ The payload should look as follows: ```json theme={null} { "Status": { "Verdict": "Approved", "StatusMessage": "Cortina V2 Stub Tester" }, "PaymentInfo": { "SrvTranId": "236584335969834429321847829253667359", "AuthCode": "333333", "AuthAmount": 0.1, "SettAmount": 0.1, "RRN": "111111", "Token": "", "AuthDateTime": "230221101008", "SettDateTime": "230221101009", "TraceNumber": "4444", "AuthSource": "55555", "IsGatewayTimeout": false } } ``` ### Response parameters The following table describes the fields returned in the API response: <table> <thead> <tr> <th>Field</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Transaction Status & Error Codes</strong></td> </tr> <tr> <td>`Verdict`</td> <td>String</td> <td> The constant string representing the **final status of the request**: <ul> <li>**`Approved`**</li> <li>**`Declined`**</li> </ul> </td> </tr> <tr> <td>`Code`</td> <td>Int(32)</td> <td> The **Decline Code**. **Conditional**—only present if `Verdict` is 'Declined'. Valid codes include: <ul> <li>**1:** Insufficient funds</li> <li>**5:** Suspected Fraud</li> <li>**6:** General system failure</li> <li>**7:** Invalid amount</li> <li>**8 / 998:** Format/parsing error or Validation error</li> <li>**992:** Timeout exception</li> <li>**997:** Missing mandatory parameters</li> <li>**999:** General exception</li> <li>*See full list for other status and internal errors (e.g., 40, 990, 1011).*</li> </ul> </td> </tr> <tr> <td>`StatusMessage`</td> <td>String(255)</td> <td> A free text field containing the **transaction status message** or additional varying data regarding the outcome. </td> </tr> <tr> <td>`CustomDeclineCode`</td> <td>String</td> <td> Used for specifying a **custom decline code** (e.g., related to Soft Decline or Switch Interface). May reflect the acquirer's response code. </td> </tr> <tr> <td><strong>Financial & Time Details</strong></td> </tr> <tr> <td>`AuthAmount`</td> <td>Double</td> <td> The **original amount requested** in the `/Authorization` Request. </td> </tr> <tr> <td>`SettAmount`</td> <td>Double</td> <td> The original amount requested in the `/Settlement` or `/Sale` process. **Irrelevant for Authorization**. </td> </tr> <tr> <td>`AuthDateTime`</td> <td>String</td> <td> The date and time the `/Authorization` took place. **Format:`ddMMyyHHmmss`**. </td> </tr> <tr> <td>`SettDateTime`</td> <td>Double</td> <td> The Settlement Date/Time. Irrelevant for the Authorization command. </td> </tr> <tr> <td><strong>Transaction Identifiers & References</strong></td> </tr> <tr> <td>`SrvTranId`</td> <td>String</td> <td> The **Integrator's internal transaction ID**. <ul> <li>**Conditional**: Required if `/StartSession` was **not** used.</li> <li>If used, it should be empty or echo the Transaction ID.</li> </ul> </td> </tr> <tr> <td>`AuthCode`</td> <td>String(40)</td> <td> **External Authorization Code** (usually from the Card Issuer's bank). </td> </tr> <tr> <td>`RRN`</td> <td>String</td> <td> **Reference Retrieval Number (RRN)**. Recommended to be visible to the **consumer/card holder** for support. </td> </tr> <tr> <td>`Token`</td> <td>String(256)</td> <td> A unique token for the transaction. **For Nayax internal use only.** </td> </tr> <tr> <td>`TraceNumber`</td> <td>String</td> <td> Trace number. **For Nayax internal use only.** </td> </tr> <tr> <td>`AuthSource`</td> <td>String(5)</td> <td> **For Nayax internal use only.** </td> </tr> <tr> <td>`InitiateTranReference`</td> <td>Int(64)</td> <td> **Conditional**: Reflects the **original Nayax Transaction ID** for prepaid loyalty card re-attempts. </td> </tr> <tr> <td><strong>Loyalty & System Details</strong></td> </tr> <tr> <td>`RegularCreditType`</td> <td>Int(32)</td> <td> Defines the unit of measure for `RegularCredit` (Enum values): <ul> <li>**0:** Credit is counted in **transactions** (count).</li> <li>**1:** Credit is counted as an **amount** (currency).</li> </ul> </td> </tr> <tr> <td>`RegularCredit`</td> <td>Double</td> <td> The regular credit value (amount or transaction count) based on the `RegularCreditType`. **Uses Decimal place 2.** </td> </tr> <tr> <td>`RevalueCredit`</td> <td>Int(32)</td> <td> The **revalue credit amount**. **Only present** if the associated card is configured as revalue-able. </td> </tr> <tr> <td>`IsRevalueCard`</td> <td>Bool</td> <td> Indication if card is **allowed revalue**. </td> </tr> <tr> <td>`IsGatewayTimeout`</td> <td>Bool</td> <td> Indicates if a **gateway timeout** occurred (valid in the response). </td> </tr> <tr> <td>`ProviderExternalData`</td> <td>String</td> <td> External data from the provider in **JSON format string**. </td> </tr> </tbody> </table> # StaticQR Decline Reasons Source: https://devzone.nayax.com/docs/cortina/staticqr/staticqr-decline-reasons When a transaction is declined, the Cortina API returns a specific decline reason code that explains why the payment was not approved. These codes are essential for integrators and merchants to understand the cause of the decline and take appropriate action. The third-party integrator is responsible for returning the response, including the corresponding decline code from the list, based on the payment method used. The following decline reason codes are used when processing StaticQR transactions: | **Code** | **Description** | | - | - | | 1 | Insufficient funds | | 2 | Transaction ID unknown | | 3 | Cardholder exceeded daily / weekly / monthly transaction count limit | | 4 | Cardholder exceeded transaction amount limit | | 5 | Suspected fraud | | 6 | General system failure | | 7 | Invalid amount | | 8 | Request cannot be parsed (format error) | | 9 | Transaction not allowed to cardholder | | 20 | No VPN or MQTT enabled | | 30 | Machine is not responding | | 40 | For Nayax internal use only | | 50 | Unknown machine Id | | 990 | CertificateFileName not found | | 991 | Failed to decipher message body | | 992 | Timeout exception | | 994 | Card Brand not supported | | 996 | Transaction ID Unknown / Duplicate Transaction ID (Start Session Error) | | 997 | Missing mandatory parameters | | 998 | Validation / request cannot be parsed | | 999 | General exception | | 1010 | Public Key Certificate not found | | 1011 | Method not Implemented | # StaticQR Source: https://devzone.nayax.com/docs/cortina/staticqr/staticqr-flows Static QR codes provide a straightforward, secure way to process payments via wallet applications, enabling customers to scan a code displayed on a vending machine or terminal. ## How it works Before selecting a product, the consumer scans the QR code displayed on the machine, as in the image below. <Frame> <img alt="" /> </Frame> Once scanned, the consumer’s mobile device interacts with the payment system to process the transaction, providing a seamless payment experience without requiring additional hardware. ## Transaction Flows Cortina supports two types of StaticQR transaction flows: * Pre-selection * Pre-authorization Learn more in the sections below. ### Pre-selection The Pre-selection flow simplifies the payment process by merging the steps of product/service selection and authorization into a single transaction. This flow is typically used for low-value or quick transactions, where the consumer’s selection and payment authorization are handled in a single step. See the diagram below: <Frame> <img /> </Frame> The steps in this process are as follows: 1. The consumer scans the QR code or enters the machine number into their mobile app. 2. The Mobile App establishes a connection with the Integrator's backend server. 3. The Integrator sends a /Notify (TerminalID) request to the Nayax Server via the [StaticQR Start](/reference/cortina/staticqr/cortina-staticqr-start) endpoint. 4. The Nayax Server sends a WakeUpDevice Request to the Nayax Device. 5. The Nayax Device returns a WakeUp Device Response to the Nayax Server. 6. The Nayax Server sends a Notify success message back to the Integrator. 7. The Nayax Device sends a Begin vending session command to the Service Machine. 8. The consumer selects a product on the Service Machine. 9. The Service Machine sends a Vend Request to the Nayax Device. 10. The Nayax Device sends an Authorization response to the Nayax Server. 11. The Nayax Server sends the /Sale (Final amount) request to the Integrator via the [StaticQR Sale](/reference/cortina/staticqr/cortina-staticqr-sale) endpoint. 12. (Optional) The Integrator may display a prompt to the consumer on their mobile device. 13. The Integrator sends a Sale response success back to the Nayax Server. 14. The Nayax Server sends an Authorization approved message to the Nayax Device. 15. The Nayax Device sends a Vend Approve response to the Service Machine. 16. The Service Machine dispenses the product successfully. 17. The Service Machine sends a Vend Success notification to the Nayax Device. 18. The Nayax Device displays a "Thank you" message. 19. The Nayax Device sends the Settlement Command to the Nayax Server. 20. (Optional) The Nayax Server sends the /Sale End Notification (TransactionId) to the Integrator via the [Sale End Notification](/reference/cortina/cortina/post-sale-end-notification) endpoint. 21. (Optional) The Integrator may display a final prompt to the consumer on their mobile device. 22. The Integrator sends a Response Acknowledge Success to the Nayax Server. This response is typically always approved in this flow, as the authorization has already been granted. <Warning> **Void** In case the product fails to be dispensed to client or no Sale Response until timeout, the Nayax Engine uses the [StaticQR Void](https://devzone.nayax.com/docs/cortina/staticqr/static-qr-void) endpoint to void the payment request. </Warning> ### Pre-Authorization The Pre-authorization Flow for Static QR involves several key steps to authenticate and authorize a payment using a static QR code. This flow ensures the transaction is valid before dispensing the product or service. See the diagram below: <Frame> <img /> </Frame> Where: 1. The consumer scans the QR code or enters the machine number into their mobile app. 2. The Mobile App establishes a connection with the Integrator's backend server. 3. The Integrator sends a /Notify (TerminalID) request to the Nayax Server via the [StaticQR Start](/reference/cortina/staticqr/cortina-staticqr-start) endpoint. 4. The Nayax Server sends a WakeUpDevice Request to the Nayax Device. 5. The Nayax Device returns a WakeUp Device Response to the Nayax Server. 6. The Nayax Server sends a Notify success message back to the Integrator. 7. The Nayax Device sends an Authorization request to the Nayax Server. 8. The Nayax Server sends an /Authorization (Default amount) request to the Integrator via the [StaticQR Authorization](/reference/cortina/staticqr/cortina-staticqr-authorization) endpoint. 9. (Optional) The Integrator may display a prompt to the consumer on their mobile device. 10. The Integrator sends an Authorization response success back to the Nayax Server. 11. The Nayax Server sends an Authorization approved message to the Nayax Device. 12. The Nayax Device sends a Begin vending session command to the Service Machine. 13. The consumer selects the desired product on the Service Machine. 14. The Service Machine sends a Vend Request to the Nayax Device. 15. The Nayax Device sends a Vend Approve response to the Service Machine. 16. The Service Machine dispenses the product successfully. 17. The Service Machine sends a Vend Success notification to the Nayax Device. 18. The Nayax Device displays a "Thank you" message. 19. The Nayax Device sends the Settlement Command to the Nayax Server. 20. The Nayax Server sends the /Settlement (Final amount) request to the Integrator via the [StaticQR Settlement](/reference/cortina/staticqr/cortina-staticqr-settlement) endpoint. 21. (Optional) The Integrator may display a final prompt to the consumer on their mobile device. 22. The Integrator sends a Settlement Response success to the Nayax Server. <Warning> **Cancellation** In case the product fails to be dispensed to client or no Authorization Response until timeout, the Nayax Engine uses the [StaticQR Cancel](/reference/cortina/staticqr/cortina-staticqr-cancel) endpoint to cancel the Pre Authorization and the transaction. </Warning> # Cortina Credit Card Authorization Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-authorization /openapi/cortina.yaml post /Cortina/CreditCard/Authorization Initiates a credit card pre-authorization transaction. This POST endpoint verifies the card's validity and available balance while handling security protocols like EMV, DUKPT, and 3-D Secure (SCA). It returns an authorization verdict, issuer authentication data (EMV tags), or a redirection URL if further user authentication is required. # Cortina Credit Card Cancel Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-cancel /openapi/cortina.yaml post /Cortina/CreditCard/Cancel Stops a transaction that hasn't finished yet. This endpoint cancels a credit card payment that was authorized but not yet finalized. It stops the process, releases the held funds back to the customer, and records the reason for the cancellation. # Cortina Credit Card Incremental Auth Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-incremental-auth /openapi/cortina.yaml post /Cortina/CreditCard/IncrementalAuth Increases the approved amount for an active transaction. This endpoint requests permission to charge additional funds on a card that has already been authorized. It is used to raise the total transaction amount before the payment is finalized. # Cortina Credit Card Inquiry3DS Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-inquiry3ds /openapi/cortina.yaml post /Cortina/CreditCard/Inquiry3DS Verifies 3-D Secure authentication status. This endpoint checks if the cardholder has successfully authenticated their identity using 3-D Secure (Strong Customer Authentication). It returns the final authentication status (e.g., completed, failed, or frictionless flow applied) to allow the transaction to proceed safely. # Cortina Credit Card Refund Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-refund /openapi/cortina.yaml post /Cortina/CreditCard/Refund Returns money to the customer after a transaction is complete. This endpoint processes a refund for a transaction that has already been settled (finalized). It sends funds back to the cardholder, logging the reason for the refund and updating the batch status. # Cortina Credit Card Sale Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-sale /openapi/cortina.yaml post /Cortina/CreditCard/Sale Processes a complete payment in one step. This endpoint authorizes and charges the credit card in a single action (combining Authorization and Settlement). It handles all card checks and security verification (like 3DS) and captures funds immediately if approved. # Cortina Credit Card Settlement Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-settlement /openapi/cortina.yaml post /Cortina/CreditCard/Settlement Finalizes and captures the funds for an authorized credit card transaction. This POST endpoint completes the payment lifecycle by submitting the final transaction details for settlement. It validates the original authorization using `PaymentInfo`, processes the charge, and returns the settlement status along with relevant `Batch` information for reconciliation. # Cortina Credit Card Void Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-void /openapi/cortina.yaml post /Cortina/CreditCard/Void Cancels a payment that hasn't been settled yet. This endpoint reverses a transaction that was authorized but not yet finalized. It removes the temporary hold on the customer's funds and requires a reason code for the action. # Cortina Age Verification Source: https://devzone.nayax.com/reference/cortina/cortina/cortina-age-verification /openapi/cortina.yaml post /Cortina/AgeVerification Cortina Age Verification # Post Renew Key Source: https://devzone.nayax.com/reference/cortina/cortina/post-renew-key /openapi/cortina.yaml post /Cortina/RenewKey Rotates the encryption key used for secure operations. This POST endpoint requests a key refresh from the provider. It submits the `CurrentKeyData` and returns the `NewKeyData` (including the new PIN encryption key encrypted under the Zone Master Key), along with its ID and Key Check Value (KCV). # Post Sale End Notification Source: https://devzone.nayax.com/reference/cortina/cortina/post-sale-end-notification /openapi/cortina.yaml post /Cortina/SaleEndNotification Receives a notification indicating the successful completion of a sale transaction. This POST endpoint is triggered by Nayax to inform the integrator that a sale has ended successfully. It accepts transaction details including `BasicInfo` and `PaymentInfo`, and returns a verdict acknowledging the receipt of the notification. # Post Start Session Source: https://devzone.nayax.com/reference/cortina/cortina/post-start-session /openapi/cortina.yaml post /Cortina/StartSession Validates the client and initializes a secure transaction session. This POST endpoint performs the initial handshake using a `TokenId` and `RandomNumber`. It returns a `Verdict` indicating if the session is approved and establishes the encryption and transaction ID context required for all subsequent operations. # Cortina DynamicQR GenerateQR Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-generateqr /openapi/cortina.yaml post /Cortina/DynamicQR/GenerateQR Generates a QR code for the customer to scan. This endpoint receives transaction details (such as the amount and machine ID) and generates the specific QR code data to be displayed on the payment terminal screen for the user to scan. # Cortina DynamicQR Inquiry Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-inquiry /openapi/cortina.yaml post /Cortina/DynamicQR/Inquiry Checks if the QR code payment is complete. This endpoint verifies if the customer has successfully paid after scanning the QR code. It tells the machine to dispense the product if approved, stop if the payment fails, or wait and check again if the process is still pending. # Create New Product Groups Source: https://devzone.nayax.com/reference/lynx/product-groups/create-new-product-groups /openapi/lynx.yaml post /v1/productGroups Creates new product groups based on the details provided in the request body. The request includes information such as the product group name, code, and associated actor. # Create Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/create-product-group-tax /openapi/lynx.yaml post /v1/productGroups/{ProductGroupID}/tax Creates new tax details for a specific product group, identified by the ProductGroupID. The request body contains the tax information to be added. # Delete Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/delete-product-group-tax /openapi/lynx.yaml delete /v1/productGroups/{ProductGroupID}/tax/{TaxRowID} Deletes a specific tax entry associated with a product group, identified by both ProductGroupID and TaxRowID. This operation removes the specified tax row from the product group. # Get All Product Groups Source: https://devzone.nayax.com/reference/lynx/product-groups/get-all-product-groups /openapi/lynx.yaml get /v1/productGroups Retrieves a list of all product groups. The response includes details of each product group such as the name, code, and associated actor. # Get Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-group-tax /openapi/lynx.yaml get /v1/productGroups/{ProductGroupID}/tax Retrieves the tax details associated with a specific product group, identified by the ProductGroupID. Optionally, a specific tax row can be retrieved using the TaxRowID query parameter. # Get Product Groups by Actor Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-groups-by-actor /openapi/lynx.yaml get /v1/operators/{ActorID}/productGroups Retrieves a list of product groups associated with a specific actor, identified by the ActorID. The response includes details of each product group. # Update Product Group Source: https://devzone.nayax.com/reference/lynx/product-groups/update-product-group /openapi/lynx.yaml put /v1/productGroups/{ProductGroupID} Updates the details of a specific product group identified by the ProductGroupID. The request body should include the updated information such as the product group name, code, and category. # Update Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/update-product-group-tax /openapi/lynx.yaml put /v1/productGroups/{ProductGroupID}/tax Updates the tax details for a specific product group, identified by the ProductGroupID. The request body contains the updated tax information. # Create New Operator Product Source: https://devzone.nayax.com/reference/lynx/products/create-new-operator-product /openapi/lynx.yaml post /v1/operators/{OperatorID}/products Creates a new product associated with a specific operator, identified by the OperatorID. The request body contains the details of the product to be created. # Get Specific Operator Products Source: https://devzone.nayax.com/reference/lynx/products/get-specific-operator-products /openapi/lynx.yaml get /v1/operators/{OperatorID}/products Retrieves a list of products associated with a specific operator, identified by the OperatorID. The response includes details of each product. # Get Specific Product Source: https://devzone.nayax.com/reference/lynx/products/get-specific-product /openapi/lynx.yaml get /v1/products/{NayaxProductID} Retrieves the details of a specific product identified by the NayaxProductID. The response includes all relevant information about the product. # Update Specific Product Source: https://devzone.nayax.com/reference/lynx/products/update-specific-product /openapi/lynx.yaml put /v1/products/{NayaxProductID} Updates the details of a specific product identified by the NayaxProductID. The request body should contain the updated product information. # Get Available Widgets Source: https://devzone.nayax.com/reference/lynx/report/get-available-widgets /openapi/lynx.yaml get /v1/dashboard/widgets Retrieves a list of available dashboard widgets, optionally filtered by the screen type ID. # Retrieve Widget Data Source: https://devzone.nayax.com/reference/lynx/report/retrieve-widget-data /openapi/lynx.yaml post /v1/dashboard/get-widget-data Fetches analytical data for a specific dashboard widget based on the provided filters and widget ID. # Add New Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/add-new-driver /openapi/lynx.yaml post /v1/Scheduling/drivers Adds a new driver to the scheduling system. The request body should include the details of the driver to be added. # Assign Machine to Route Source: https://devzone.nayax.com/reference/lynx/scheduling/assign-machine-to-route /openapi/lynx.yaml post /v1/Scheduling/route-machines Assigns a machine to a specific route. The request body should include the details of the machine to be assigned. # Create Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/create-machine-tasks /openapi/lynx.yaml post /v1/Scheduling/schedule/machine-tasks Creates new scheduled tasks for machines. The request body should include details of the tasks to be scheduled. # Create New Route Source: https://devzone.nayax.com/reference/lynx/scheduling/create-new-route /openapi/lynx.yaml post /v1/Scheduling/routes Creates a new route for the specified operator. The request body should include the details of the route to be created. # Create Visit Orders Source: https://devzone.nayax.com/reference/lynx/scheduling/create-visit-orders /openapi/lynx.yaml post /v1/Scheduling/schedule/visit-order Creates new visit orders for machines. The request body should include the details of the machines to be visited. # Delete Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/delete-driver /openapi/lynx.yaml delete /v1/Scheduling/drivers Deletes a driver identified by DriverId from the scheduling system. # Delete Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/delete-machine-tasks /openapi/lynx.yaml delete /v1/Scheduling/schedule/machine-tasks Deletes scheduled tasks for machines based on the provided query parameters such as SchedulingIds, MachineID, and date. # Get Drivers Source: https://devzone.nayax.com/reference/lynx/scheduling/get-drivers /openapi/lynx.yaml get /v1/Scheduling/drivers Retrieves a list of drivers based on various query parameters, such as ActorId, DriverStatusId, and multiple search options (e.g., by DriverId, UserId, Fullname, etc.). # Get Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/get-machine-tasks /openapi/lynx.yaml get /v1/Scheduling/schedule/machine-tasks Retrieves a list of scheduled machine tasks based on various query parameters such as date range, machine, driver, route, and other filters. # Get Route Machines Source: https://devzone.nayax.com/reference/lynx/scheduling/get-route-machines /openapi/lynx.yaml get /v1/Scheduling/route-machines Retrieves a list of machines assigned to a specific route, identified by RouteId, and optionally filtered by MachineId. # Get Routes Source: https://devzone.nayax.com/reference/lynx/scheduling/get-routes /openapi/lynx.yaml get /v1/Scheduling/routes Retrieves a list of routes based on various query parameters, such as OperatorId, DriverId, Status, and multiple search options (e.g., by Name, Code, Notes, etc.). # Get Visit Orders Source: https://devzone.nayax.com/reference/lynx/scheduling/get-visit-orders /openapi/lynx.yaml get /v1/Scheduling/schedule/visit-order Retrieves a list of visit orders based on various query parameters such as VisitDate, MachineId, DriverId, RouteId, and ActorId. # Remove Machine from Route Source: https://devzone.nayax.com/reference/lynx/scheduling/remove-machine-from-route /openapi/lynx.yaml delete /v1/Scheduling/route-machines Removes a machine from a specific route, identified by RouteId and MachineId. # Update Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/update-driver /openapi/lynx.yaml put /v1/Scheduling/drivers Updates the details of an existing driver identified by DriverId. The request body should include the updated driver information. # Update Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/update-machine-tasks /openapi/lynx.yaml put /v1/Scheduling/schedule/machine-tasks Updates existing scheduled tasks for machines. The request body should include the updated task details. # Update Route Source: https://devzone.nayax.com/reference/lynx/scheduling/update-route /openapi/lynx.yaml put /v1/Scheduling/routes Updates the details of an existing route identified by routeId. The request body should include the updated route information. # Sign In Source: https://devzone.nayax.com/reference/lynx/sign-in/sign-in /openapi/lynx.yaml get /signin # User Sign In Source: https://devzone.nayax.com/reference/lynx/sign-in/user-sign-in /openapi/lynx.yaml post /v1/signin Authenticates a user with the provided credentials (username and password). # Build with AI on Nayax Source: https://devzone.nayax.com/docs/get-started/build-with-ai Bring AI assistants into your Nayax integration with the MCP server for live documentation access. The Nayax DevZone lets your AI assistant search and read the full developer portal in real time through the MCP server, so you get accurate answers about any Nayax API, SDK, or integration flow. ## Get started Connect your tools with the setup guide: <CardGroup> <Card title="Connect to the Nayax MCP Server" icon="robot" href="/docs/get-started/mcp-setup"> Give your AI assistant live search access to the full developer portal. </Card> </CardGroup> # Security Certifications Source: https://devzone.nayax.com/docs/get-started/certifications Nayax's PCI DSS, ISO/IEC 27001, and SOC 2 Type 2 certifications, what each one means, and where to verify them. Nayax maintains independently validated certifications for payment security, information security management, and internal controls. This page explains what each certification means and how you can verify it. ## PCI DSS The Payment Card Industry Data Security Standard (PCI DSS) is the security standard maintained by the PCI Security Standards Council (PCI SSC) for organizations that store, process, or transmit payment card data. The PCI SSC does not issue certifications itself: compliance is validated through an assessment by an accredited PCI Qualified Security Assessor (QSA), who confirms the organization meets the standard's requirements and issues an Attestation of Compliance. You can view [Nayax's current PCI DSS v4.0.1 Attestation of Compliance](https://www.nayax.com/wp-content/uploads/2026/07/Nayax_PCI-SCC-v4.0.1-Certificate-of-compliance-by-nabu_30-June-2026_signed.pdf). ## ISO/IEC 27001 ISO/IEC 27001 is the international standard for an Information Security Management System (ISMS). It sets requirements for establishing, implementing, maintaining, and continually improving a risk-based approach to protecting the confidentiality, integrity, and availability of information. An accredited, independent certification body issues the certificate after an audit. The certificate is valid for three years, and the certification body carries out annual surveillance audits to confirm the ISMS still meets the standard. You can view [Nayax's current ISO/IEC 27001:2022 certificate](https://www.nayax.com/wp-content/uploads/2026/03/ISOIEC-270012022_2025-12-25.pdf). ## SOC 2 type 2 Nayax holds a SOC 2 Type 2 certification with no exceptions noted by the auditor. SOC 2 (System and Organization Controls 2) is a reporting framework maintained by the American Institute of Certified Public Accountants (AICPA). Independent, licensed CPA auditors examine an organization's controls against the framework and issue the report. A Type 2 report goes further than a Type 1: instead of assessing controls at a single point in time, it evaluates whether those controls operated effectively over an extended audit period. ## See also * [Privacy Policy](https://www.nayax.com/legal/nayax-general-privacy-policy/) * [Terms of Service](/docs/get-started/terms-of-service) # Connect to the Nayax MCP Server Source: https://devzone.nayax.com/docs/get-started/mcp-setup [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI coding assistants connect to external data sources and tools. The Nayax developer portal includes an MCP server. Connect your AI assistant to it, and it can read and search Nayax documentation in real time, giving you accurate answers about Nayax APIs, SDKs, and integration flows without leaving your editor. ## Prerequisites Before you begin, you'll need an MCP-compatible AI tool to act as the client host. Common options include Claude desktop, Claude Code, Cursor, and VS Code with GitHub Copilot (Agent mode). ## Connect to the Nayax MCP server See how you can connect to our MCP server through different tools: <Tabs> <Tab title="Claude"> <Steps> <Step title="Open connectors settings"> In Claude, go to [**Settings** → **Connectors**](https://claude.ai/settings/integrations) and select **Add custom connector**. </Step> <Step title="Enter the server details"> Set the name to `nayax` and the URL to `https://devzone.nayax.com/mcp`, then click **Add**. </Step> <Step title="Attach the server in chat"> To attach the server to your conversation: 1. Start a new conversation. 2. Select the attachments icon (the plus icon next to the input). 3. Choose the `nayax` connector. </Step> <Step title="Verify the connection"> Ask a Nayax-related question such as: ``` What authentication method does the Lynx API use? ``` Claude should respond with information pulled directly from the Nayax developer portal. </Step> </Steps> </Tab> <Tab title="Claude Code"> <Steps> <Step title="Add the server via the CLI"> Run the following command in your terminal: ```bash theme={null} claude mcp add --transport http nayax https://devzone.nayax.com/mcp ``` This registers the server globally across all your Claude Code sessions. For more on managing MCP servers in Claude Code, see the [Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp). </Step> <Step title="Verify the connection"> Start a Claude Code session and ask a Nayax-related question. To confirm the server is registered, run: ```bash theme={null} claude mcp list ``` The `nayax` server should appear in the output. </Step> </Steps> </Tab> <Tab title="Cursor"> <Steps> <Step title="Open MCP settings"> 1. Press `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Windows/Linux) to open the command palette. 2. Search for **Open MCP settings**. 3. Select **Add custom MCP**. This opens the `mcp.json` file. For more details, see the [Cursor MCP documentation](https://cursor.com/docs/context/mcp). </Step> <Step title="Add the Nayax MCP server"> In `mcp.json`, add the following configuration. If you already have other servers configured, add the `nayax` entry inside the existing `mcpServers` object. ```json ~/.cursor/mcp.json theme={null} { "mcpServers": { "nayax": { "url": "https://devzone.nayax.com/mcp" } } } ``` </Step> <Step title="Save and restart cursor"> Save the file. Cursor detects the new server automatically on the next start. </Step> <Step title="Verify the connection"> To verify the connection, open Cursor Chat and ask a Nayax-related question. The server name `nayax` appears in the tool list when MCP is active. </Step> </Steps> </Tab> <Tab title="VS Code"> <Steps> <Step title="Open your workspace MCP configuration"> In your project root (the top-level folder of your project), create or open a file called `.vscode/mcp.json`. </Step> <Step title="Add the Nayax MCP server"> Paste the following configuration: ```json .vscode/mcp.json theme={null} { "servers": { "nayax": { "type": "http", "url": "https://devzone.nayax.com/mcp" } }, "inputs": [] } ``` </Step> <Step title="Reload the window"> Press `Ctrl+Shift+P` (Windows/Linux) or `Cmd+Shift+P` (macOS), then run **Developer: Reload Window**. </Step> <Step title="Verify the connection"> Open your AI assistant in VS Code and ask a question about a Nayax API, such as: ``` How do I start a session with the Marshall SDK? ``` Your assistant should answer using content from the Nayax developer portal. <Note> If you are using GitHub Copilot, make sure you are in [**Agent mode**](https://code.visualstudio.com/docs/copilot/chat/mcp-servers). You can switch to it by selecting it from the dropdown at the bottom of the chat input. </Note> </Step> </Steps> </Tab> </Tabs> ## What you can do with the MCP server Once connected, your AI assistant can: * Search and retrieve content from any page in the Nayax developer portal * Answer questions about specific API endpoints, request parameters, and response fields * Explain integration flows, payment sessions, and SDK configuration options * Surface code examples from guides such as Marshall, Cortina, EMV Core, and the eCom SDK <Tip> For best results, be specific in your prompts. For example, ask "How do I handle a declined transaction in the Cortina prepaid card flow?" rather than a broad question like "Tell me about Cortina." </Tip> ## Troubleshooting These are some common errors you might encounter while setting up the Nayax MCP and how to solve them: <AccordionGroup> <Accordion title="The MCP server does not appear in my tool list."> Confirm that: * The JSON in your configuration file is valid (no trailing commas, all braces closed). * You reloaded or restarted the editor after saving the file. * Your network can reach `https://devzone.nayax.com`. </Accordion> <Accordion title="The assistant returns outdated or incorrect information."> The MCP server reflects the published state of the Nayax developer portal. If documentation was recently updated, try starting a new conversation so the assistant fetches a fresh context. </Accordion> <Accordion title="I see an authentication error."> The Nayax MCP server does not require authentication. If you see an auth error, check whether a proxy or firewall is intercepting HTTPS requests to `devzone.nayax.com`. </Accordion> </AccordionGroup> # Get Version Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/get-version /openapi/cortina.yaml get /Version Retrieves the current Commerce API version and build information. This GET endpoint provides metadata about the deployed Commerce system, returning the ApiVersion, ProductVersion, and Copyright details for diagnostic purposes. # Onboard Actor Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/onboard-actor /openapi/cortina.yaml post /OnboardActor Registers or updates a merchant (Actor) in the system. This endpoint handles the onboarding process for new merchants, distributors, or operators. It accepts their profile details and configuration settings and returns an onboarding status (e.g., Success, Pending, Failed) along with credentials such as API keys or merchant IDs. # Onboard Machine Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/onboard-machine /openapi/cortina.yaml post /OnboardMachine Registers or updates a vending machine's configuration in the system. This endpoint manages the onboarding of specific machines by linking them to an operator and distributor. It configures the machine's details and returns its unique credentials (such as TerminalId or QrString) along with the final setup status. # Cortina Prepaid Authorization Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-authorization /openapi/cortina.yaml post /Cortina/Prepaid/Authorization Checks the balance and authorizes a prepaid card. This endpoint verifies if a prepaid card is valid and has enough funds (or credits) for the purchase. It returns the approval decision along with the card's current balance or remaining uses. # Cortina Prepaid Cancel Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-cancel /openapi/cortina.yaml post /Cortina/Prepaid/Cancel Cancels a prepaid transaction before it's finished. This endpoint stops an authorized prepaid payment that hasn't been settled yet. It releases any held funds or credits back to the card and returns the balance to its original status. # Cortina Prepaid Refund Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-refund /openapi/cortina.yaml post /Cortina/Prepaid/Refund Returns funds or credits to a prepaid card. This endpoint processes a refund for a prepaid transaction that was already completed. It adds the refunded amount (or credit count) back to the user's card balance and records the reason for the return. # Cortina Prepaid Sale Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-sale /openapi/cortina.yaml post /Cortina/Prepaid/Sale Cancels a prepaid transaction before it's finished. This endpoint stops an authorized prepaid payment that hasn't been settled yet. It releases any held funds or credits back to the card and returns the balance to its original status. # Cortina Prepaid Settlement Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-settlement /openapi/cortina.yaml post /Cortina/Prepaid/Settlement Deducts funds and finalizes a prepaid purchase. This endpoint captures the payment from the prepaid card, reducing the user's balance or credit count. It confirms the final amount charged and returns the updated balance. # Cortina Prepaid Void Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-void /openapi/cortina.yaml post /Cortina/Prepaid/Void Reverses an authorized prepaid payment. This endpoint cancels a transaction that was approved but not finalized. It releases the hold on the prepaid funds or credits, immediately updating the card's balance to reflect the reversal. # Cortina DynamicQR Refund Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-refund /openapi/cortina.yaml post /Cortina/DynamicQR/Refund Returns a full or partial refund for a completed QR payment. This endpoint sends money back to the customer after a transaction completes successfully. It is typically triggered by a customer complaint (via the Nayax web system) and allows for specific refund reasons to be recorded. # Cortina DynamicQR Void Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-void /openapi/cortina.yaml post /Cortina/DynamicQR/Void Cancels a QR payment if the product wasn't dispensed. This endpoint reverses a successful QR transaction when the machine fails to release the item or times out. It ensures the customer is not charged since they did not receive their product. # Cortina StaticQR Authorization Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-authorization /openapi/cortina.yaml post /Cortina/StaticQR/Authorization Holds funds for a transaction where the final amount isn't known yet. Nayax calls this endpoint to validate the customer's account and temporarily reserve funds (pre-authorization) before the actual usage is calculated. It must be followed later by a settlement or cancellation. # Cortina StaticQR Cancel Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-cancel /openapi/cortina.yaml post /Cortina/StaticQR/Cancel Finalizes and charges the customer after the product is dispensed. Nayax triggers this endpoint to complete the transaction once the machine has successfully released the item. It captures the final amount from the user's account. # Cortina StaticQR Refund Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-refund /openapi/cortina.yaml post /Cortina/StaticQR/Refund Returns a full or partial refund for a completed Static QR payment. This endpoint sends money back to the customer after a transaction completes successfully. It is typically triggered by a customer complaint (via the Nayax web system) and allows for specific refund reasons to be recorded. # Cortina StaticQR Sale Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-sale /openapi/cortina.yaml post /Cortina/StaticQR/Sale Charges the customer immediately for a specific amount. This endpoint processes a complete Static QR payment in one step (Auth + Settlement) when the price is already known (pre-selection). It validates and charges the user's account instantly. # Cortina StaticQR Settlement Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-settlement /openapi/cortina.yaml post /Cortina/StaticQR/Settlement Upon successful dispense of a product/service by the operator's machine, Nayax will call this method to complete and capture the transaction with the integrator.This call will include the transaction's final amount to be cleared by the integrator. # Cortina StaticQR Start Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-start /openapi/cortina.yaml post /Cortina/{integratorName}/start Starts the transaction when a customer scans a static QR code. This endpoint notifies Nayax that a user is at the machine and ready to pay. It links the user ID to the machine ID using a secret token to begin the process. # Cortina StaticQR Void Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-void /openapi/cortina.yaml post /Cortina/StaticQR/Void Cancels a payment if the machine fails to dispense. This endpoint reverses a Static QR transaction when the vending machine encounters an error or times out. It ensures the customer is not charged for a product they did not receive. # Actor Types Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/actor-types The `ActorTypeID` parameter specifies the type of sub-operator creation in the Nayax Lynx system. The following table lists the possible values: | Value | Actor Type | | - | - | | 5 | Area | | 6 | Route | | 7 | City | | 8 | State | | 9 | Province | | 10 | Region | | 11 | Client | | 12 | Facility Management | | 13 | Location (General) | | 14 | Customer (General) | | 15 | District | | 16 | Account | | 17 | Branch | | 18 | Terminal | | 19 | Floor | | 20 | Zone | | 21 | Airport | | 22 | Gate | | 23 | eCommerce | | 24 | Bus | | 25 | Train | | 26 | Tramway | | 27 | EV Infrastructure | # Cards Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/cards ## CardTypeID The `CardTypeID` parameter identifies the type of card being used. The following table lists the possible values: | Value | Description | | - | - | | 33 | Prepaid Card | | 31 | Technician Card | | 34 | Refund Card | | 30000616 | Discount Card | ## PhysicalTypeID The `PhysicalTypeID` parameter specifies the physical form of the card. The following table lists the possible values: | Value | Description | | - | - | | 30000528 | Swipe Card | | 30000529 | Contact Card | | 30000530 | Contactless Card | | 30000531 | Contactless Sticker | | 943237560 | QR Code | ## MemberTypeID The `MemberTypeID` parameter identifies the membership tier or type associated with a cardholder. The following table lists the possible values: | Value | Description | | - | - | | 800 | Bronze | | 801 | Silver | | 802 | Gold | | 803 | Platinum | | 804 | Diamond | | 805 | Emerald | | 812 | Personal | # Machine Types Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/machine-types The `MachineTypeID` parameter determines the icon displayed next to your virtual machine in Nayax Core. The following table lists the available values and their corresponding machine types: | Value | Machine Type | | - | - | | 555001 | Safe | | 555002 | Cash Register | | 555003 | Car Accessories | | 555004 | Donation Station | | 555005 | Transportation | | 555006 | Micro Markets | | 555007 | OCPP Electrical Vehicle | | 555008 | Parking | | 556017 | Windshield Washer Fluid | | 556018 | Canteen | | 30000514 | Hot Drinks | | 30000515 | Cold Drinks | | 30000516 | Snacks | | 30000517 | Ice Cream | | 30000518 | Milk Produce | | 30000519 | Sandwiches | | 30000520 | Food | | 30000521 | Amusement | | 30000522 | Alcohol | | 30000523 | Cigarettes | | 30000524 | Combo | | 30000525 | Air | | 30000526 | Electricity | | 30000527 | Other | | 30000561 | Recycling | | 30000578 | Car Wash Machine | | 30000579 | Laundry Machine | | 30000580 | Cellular Accessories | | 30000581 | Pharmacy | | 30000582 | TV And Internet Services | | 30000583 | PPE | | 30000602 | Massage Chairs | | 30000611 | Ice | | 30000612 | Photo Booth | | 30000617 | Pictures | | 30000618 | Photocopies | | 30000619 | Flowers | | 30000620 | Car Vacuum Cleaner | | 30000623 | Water Filling Station | | 176649542 | Access Control | | 227707459 | Golf Ball Dispenser | | 227707460 | Gaming | | 504059468 | Dog Wash | | 529079224 | Lockers | | 363311433 | Fresh Juice | | 244797254 | Weight | # AvailabilityCheck Source: https://devzone.nayax.com/reference/spark/transactions/availabilitycheck /openapi/spark.yaml post /AvailabilityCheck # CancelTransaction Source: https://devzone.nayax.com/reference/spark/transactions/canceltransaction /openapi/spark.yaml post /CancelTransaction The /CancelTransaction endpoint is a POST request that allows you to cancel a transaction currently in progress. This method is referred to as "Cancel" in the Pre-Authorization flow and "Void" in the Pre-Selection flow. # DeclineCallback Source: https://devzone.nayax.com/reference/spark/transactions/declinecallback /openapi/spark.yaml post /DeclineCallback The `DeclineCallback` API call is used to notify you of a failure in the Spark transaction process. It is typically triggered after a successful `/TriggerTransaction` response with a verdict of `Approved`, but when the flow subsequently fails for any reason before payment authorization. # ExternalCancel Source: https://devzone.nayax.com/reference/spark/transactions/externalcancel /openapi/spark.yaml post /ExternalCancel The `/ExternalCancel` method is used by the third-party server to cancel a transaction that has been authorized but not yet settled. Cancellation is necessary if a failure occurs during the interaction or on the third-party server. This process is vital for releasing any funds captured on the consumer's payment card. While the API method is always `/ExternalCancel`, the financial terminology depends on the machine flow type: * **Pre-Authorization Flow**: This method is called to as a **"Cancel"**. * **Pre-Selection Flow**: This the method is referred a **"Void"**. The request must specify the required cancellation type. ## Identifying the Transaction To successfully cancel a transaction, your request must include the three required identifiers that exactly match the original transaction data. * **NayaxTransactionID**: The unique ID generated during authorization. * **SiteID**: The identifier for the machine's location. * **MachineAuTime**: The exact authorization timestamp. Optional field but recommended * MachineAUTime is currently not available for Marshall machines due to Transfer Data not providing this information to the machine (hence the 3rd party servers would not have this information when trying to send the ExternalCancel) If any of these fields are missing or mismatched, the system will return a "Transaction not found" error. <Note> **Automatic Retries (AutoCancel):** In case the request fails, Nayax provides an **AutoCancel** feature, which means Nayax will automatically attempt to retry the cancellation later. The prerequisite is that the **AutoCancel** feature must be enabled for the specific operator. </Note> ## Troubleshooting Declined Cancellations If a cancellation request is declined, the response will return **ErrorCode 51**: "External Cancel Failed". * **Mandatory Use**: You must send an `ExternalCancel` immediately if you know no product or service will be provided. * **Consumer Impact**: If not canceled, consumer funds will remain captured, leading to a poor user experience and potential disputes. * **Audit Trail**: It is recommended to include a `ReasonCode` and `ReasonText` (e.g., "75 - Service not provided") to document why the transaction was voided. # ExternalSettlement Source: https://devzone.nayax.com/reference/spark/transactions/externalsettlement /openapi/spark.yaml post /ExternalSettlement The `/ExternalSettlement` method is called by the 3rd-party server to finalize a transaction after the payment provider has authorized the initial amount and the service or products have been provided to the consumer. This request must contain the final amount to be charged. To successfully settle a transaction, you must provide three mandatory identifiers that match the original authorization data exactly: * **NayaxTransactionID**: The unique identifier for the transaction in the Nayax system. * **SiteID**: The ID of the site where the machine is located. * **MachineAUTime**: The authorization timestamp from the terminal. Optional field but recommended. * MachineAUTime is not available for Marshall machines. However, as this field is optional, you can still use ExternalSettlement without it. ## Where to Find this Information Depending on your hardware, these identifiers are retrieved through different channels: * **OTI Devices**: Information is sent via the **CommerceAPI**. * **Marshall Devices**: Information is sent via **Transfer Data** * **Alternative**: All integrators can retrieve this data via **Amazon SQS**. ## Adding Digital Receipts (`EReceiptData`) If you use the Nayax eReceipt platform, you can use the `EReceiptData` field to add custom information to the digital receipt that isn't stored in the Nayax Backoffice. <Danger> Any information shared in this field will be visible to the consumer on their receipt. Avoid sharing sensitive data that is not relevant to the transaction. </Danger> The data must be sent as a JSON string containing: * **Section Naming**: To display fields without a section header, use a blank space for the section name: `{" ":[...]}`. * **Order**: Fields appear on the receipt in the exact order they are listed in the string. * **Characters**: Use escape characters (e.g., `\"`) for internal quotes within the JSON string. ## Reporting Products (`ProductInfo`) For operators who manage a **Products Map** in Nayax Core, the `ProductInfo` object allows you to report exactly which items were sold. This is an array of objects where each item requires: | Field | Type | Description | | - | - | - | | **Value** | Decimal | The price of a single unit of the product.<br /><br />\* The value is taken as is (Decimal place of 0), meaning if you send value of 6.50 the value that the consumer would be charged for is 6.50, and if you send 65 the value would be 65.00) | | **Code** | Integer | The Product Code as defined in your Nayax Products Map.<br /><br />\* The value is taken as is (Decimal place of 0) | | **Quantity** | Integer | The number of units of this product provided.<br /><br />\* The value is taken as is (Decimal place of 0) | **Example Format**: `[{"Value": 6.50, "Code": 12, "Quantity": 3}]` ## Troubleshooting Declined Settlements If a settlement request is declined, the response will include an **ErrorCode 50**: "External Settlement Failed". Common reasons for failure include: * **Missing Identifiers**: Mandatory fields like `SiteId` were missing from the request. * **Data Mismatch**: The IDs provided do not match the original authorization record. * **Time Limit**: The request was sent more than 48 hours after the transaction started. # Get Version Source: https://devzone.nayax.com/reference/spark/transactions/get-version /openapi/spark.yaml get /Version Returns the Spark API assembly version and build. # InfoQuery Source: https://devzone.nayax.com/reference/spark/transactions/infoquery /openapi/spark.yaml post /InfoQuery Nayax sends an `InfoQuery` API after a successful `StartSession` response. Its main purposes are to retrieve information to be shown on the POS device before payment begins and to check the availability status of the requested service station. # Settlement Source: https://devzone.nayax.com/reference/spark/transactions/settlement /openapi/spark.yaml post /Settlement The `Settlement` endpoint is used to finalize an approved transaction. After the session ends and the total amount is known, the integrator sends the final amount along with optional e-receipt information. This method is only relevant for transactions with Pre-Authorization. # StartAuthentication Source: https://devzone.nayax.com/reference/spark/transactions/startauthentication /openapi/spark.yaml post /StartAuthentication The `StartAuthentication` endpoint is the first step for any External Settlement. Use this to verify your server’s identity with Nayax and create a secure link for the transaction. <Card title="Try it: Spark Auth Tool" icon="bolt" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool"> Build and inspect the cipher and the `TransactionSignature` header for this endpoint in your browser, no code required. </Card> ## How to Build the Cipher You must send an encrypted string called a `cipher`. This string tells Nayax which transaction you are working on and proves the request is current. ### Step 1: Create the 64-character Plaintext Combine these four parts in the exact order and character positions shown below to make one long string: | Section | Type | Position | Description | | - | - | - | - | | **Spark Transaction ID** | String | 1-36 | Your unique GUID (with hyphens). | | **Separator** | Special | 37 | Must be the `=` symbol. | | **Random String** | String | 38-54 | A 17-character random alphanumeric string. | | **Timestamp** | Numeric | 55-64 | Current UTC time in `YYMMDDhhmm` format. | **Example:** `12c7cec2-c690-4425-9a1f-db0db60e2d8c=123456789qwertyui2602041044` ### Step 2: Get Your Encryption Key Nayax provides you with a **Secret Token** (usually 66 characters). To create your key, take only the **32 characters on the far right** of that token to create a 256-bit key. **Example:** * **Full token example:** `...wRvTVTkungMIKThTVbj_fiXdfoGclhn0` * **What your key will look like:** `wRvTVTkungMIKThTVbj_fiXdfoGclhn0` ### Step 3: Encrypt and Encode Encrypt the 64-character string from Step 1 using **AES (ECB mode)** with your key from Step 2. Then, encode the result into **Base64**. <Note> **Important Rules for Success:** * **5-Minute Window**: Nayax will reject any request if the timestamp in your cipher is more than 5 minutes old. This limit is controlled by the `CipherExpMinutes` variable. * **Double-Check Randomness**: The `Random` field in your JSON request must be exactly the same as the random string you put inside the cipher. * **Verify Nayax**: When the response arrives, it contains a `HashedSparkTransactionId`. You **must** hash your original Transaction ID using **SHA-256** and ensure it matches Nayax’s version to verify the response is authentic. </Note> ### Error Codes If your request is declined, look for these specific codes: | Error Code | Meaning | What to Check | | - | - | - | | **28** | Invalid Token | Check if your Token ID is correct, active, and associated with your account. | | **30** | Validation Failed | Your JSON `Random` field doesn't match the one in your cipher. | | **31** | Expired Request | Your timestamp is too old (longer than 5 minutes). Sync your server clock to UTC. | | **34** | Decryption Failure | Your cipher format is wrong or the `=` is missing from the 37th character. | # StartSession Source: https://devzone.nayax.com/reference/spark/transactions/startsession /openapi/spark.yaml post /StartSession This is the initial API call sent by Nayax. It initiates the transaction session by authenticating both parties and generating a `SparkTransactionId`, which will be echoed in all subsequent calls throughout the transaction's lifecycle. <Card title="Try it: Spark Auth Tool" icon="bolt" href="/docs/integrate-pos-device/spark/security-authentication/spark-auth-tool#startsession"> Build or inspect the `StartSession` cipher in your browser, no code required. Opens the tool on the StartSession tab. </Card> # StopCallback Source: https://devzone.nayax.com/reference/spark/transactions/stopcallback /openapi/spark.yaml post /StopCallback The `StopCallback` endpoint notifies the integrator that a consumer has presented a payment card to stop an ongoing session. # StopNotify Source: https://devzone.nayax.com/reference/spark/transactions/stopnotify /openapi/spark.yaml post /StopNotify The `StopNotify` endpoint enables Spark to determine whether a card presented at the payment terminal while idle is authorized to stop an ongoing session. A matching card should result in an `Approved` response; otherwise, the Spark integrator should return a `Declined` verdict. # TimeoutCallback Source: https://devzone.nayax.com/reference/spark/transactions/timeoutcallback /openapi/spark.yaml post /TimeoutCallback The `TimeoutCallback` API call notifies that the payment session has timed out due to inactivity or a failure to complete the expected flow within a defined period. # TransactionCallback Source: https://devzone.nayax.com/reference/spark/transactions/transactioncallback /openapi/spark.yaml post /TransactionCallback The terminal uses the `TransactionCallback` endpoint to notify the integrator about the result of a card tap. It is triggered automatically when a user presents a card, and an authorization flow is initiated with the payment provider. # TransactionNotify Source: https://devzone.nayax.com/reference/spark/transactions/transactionnotify /openapi/spark.yaml post /TransactionNotify The `TransactionNotify` endpoint is used to notify the integrator about the final details of a charging session, including charger availability, amount, and display information. # TriggerTransaction Source: https://devzone.nayax.com/reference/spark/transactions/triggertransaction /openapi/spark.yaml post /TriggerTransaction The `TriggerTransaction` endpoint initiates user interaction with the physical terminal by sending a wake-up signal to the specified device. # Add Actor Group Source: https://devzone.nayax.com/reference/lynx/actors/add-actor-group /openapi/lynx.yaml post /v1/actors/{ActorID}/roleGroups Adds a new actor group for a specific actor, identified by `ActorID`. # Add Machine Group Source: https://devzone.nayax.com/reference/lynx/actors/add-machine-group /openapi/lynx.yaml post /v1/actor/{ActorID}/machineGroups Adds a new machine group for a specific actor, identified by `ActorID`. # Create a New Actor Source: https://devzone.nayax.com/reference/lynx/actors/create-a-new-actor /openapi/lynx.yaml post /v2/actors/{ParentActorID} Creates a new actor under the specified parent actor. The parent actor is identified by the `ParentActorID` provided in the path. The request body must contain the details of the new actor. # Create Actor's Payment Methods Source: https://devzone.nayax.com/reference/lynx/actors/create-actors-payment-methods /openapi/lynx.yaml post /v1/actors/{ActorID}/paymentMethods Creates new payment methods for a specific actor, identified by the `ActorID`. # Decrypt Message by Encryption Version Source: https://devzone.nayax.com/reference/lynx/actors/decrypt-message-by-encryption-version /openapi/lynx.yaml put /v1/actors/DecryptionMessageByVer Decrypts a message using a specific encryption version for a given actor, identified by `actorID` and `encVer`. # Delete a Payment Method Source: https://devzone.nayax.com/reference/lynx/actors/delete-a-payment-method /openapi/lynx.yaml delete /v1/actors/{ActorID}/paymentMethods/{paymentMethodID} Deletes a specific payment method associated with a given actor, identified by `ActorID` and `paymentMethodID`. # Delete Actor Group Source: https://devzone.nayax.com/reference/lynx/actors/delete-actor-group /openapi/lynx.yaml delete /v1/actors/{ActorID}/roleGroups Deletes an actor group associated with a specific actor, identified by `ActorID`. # Generate Encryption Key Source: https://devzone.nayax.com/reference/lynx/actors/generate-encryption-key /openapi/lynx.yaml put /v1/actors/GenarateEncKey Generates a new encryption key for the specified actor, identified by `actorID`. # Get Actor by ActorCode Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-by-actorcode /openapi/lynx.yaml get /v1/actors Retrieves the details of an actor using their unique `ActorCode`. This is useful for fetching information about a specific actor when only their code is known. # Get Actor Details by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-details-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID} This endpoint retrieves comprehensive information about a single actor. You must specify the actor's unique identifier, `ActorID`, in the request path to obtain their full profile, including attributes. # Get Actor Hierarchy for Current User Source: https://devzone.nayax.com/reference/lynx/actors/get-actor-hierarchy-for-current-user /openapi/lynx.yaml get /v1/actors/hierarchy Retrieves the actor hierarchy for the current user. Optionally, you can specify an `ActorID` to get the hierarchy for a specific actor, filter by `StatusID`, or limit the hierarchy levels returned. # Get All Actor Groups by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-all-actor-groups-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID}/roleGroups Retrieves all actor groups associated with a specific actor, identified by `ActorID`. # Get Encryption Keys by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-encryption-keys-by-actorid /openapi/lynx.yaml get /v1/actors/GetEncKeys Retrieves the encryption keys associated with a specific actor, identified by the `actorID` query parameter. # Get Operator EV Meter Dashboard Source: https://devzone.nayax.com/reference/lynx/actors/get-operator-ev-meter-dashboard /openapi/lynx.yaml get /v1/actors/{ActorID}/evDashboard Retrieves the EV meter dashboard for a specific operator, identified by `ActorID`. Optional query parameters allow filtering by date range, machine ID, time period, and machine number. # Get payment methods by ActorID Source: https://devzone.nayax.com/reference/lynx/actors/get-payment-methods-by-actorid /openapi/lynx.yaml get /v1/actors/{ActorID}/paymentMethods Retrieves a list of payment methods associated with a specific actor, identified by the `ActorID`. # List All Machine Groups for Actor Source: https://devzone.nayax.com/reference/lynx/actors/list-all-machine-groups-for-actor /openapi/lynx.yaml get /v1/actor/{ActorID}/machineGroups Retrieves all machine groups associated with a specific actor, identified by `ActorID`. # Update Actor's Payment Methods Source: https://devzone.nayax.com/reference/lynx/actors/update-actors-payment-methods /openapi/lynx.yaml put /v1/actors/{ActorID}/paymentMethods Updates the payment methods associated with a specific actor, identified by the `ActorID`. # Update Machine Group Source: https://devzone.nayax.com/reference/lynx/actors/update-machine-group /openapi/lynx.yaml put /v1/actor/{ActorID}/machineGroups Updates the details of a machine group associated with a specific actor, identified by `ActorID`. # Update Operator/Sub-Operator Source: https://devzone.nayax.com/reference/lynx/actors/update-operatorsub-operator /openapi/lynx.yaml put /v1/actors/{ActorID} Updates the details of an existing actor (operator or sub-operator) identified by `ActorID`. The request body must contain the updated attributes for the actor. # Add Credit to a Card Source: https://devzone.nayax.com/reference/lynx/cards/add-credit-to-a-card /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/credit/add Adds a specified amount to the credit of a card, identified by its unique identifier. # Add to the Card's Revalue Source: https://devzone.nayax.com/reference/lynx/cards/add-to-the-cards-revalue /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/revalue/add Adds a specified amount to the revalue of a card, identified by its unique identifier. # Create New Card Source: https://devzone.nayax.com/reference/lynx/cards/create-new-card /openapi/lynx.yaml post /v2/cards Creates a new card with the specified details. # Create Virtual Card Source: https://devzone.nayax.com/reference/lynx/cards/create-virtual-card /openapi/lynx.yaml post /v1/cards Creates a new virtual card with the provided details. # Get Card by ID Source: https://devzone.nayax.com/reference/lynx/cards/get-card-by-id /openapi/lynx.yaml get /v1/cards/uniqueIdentifier/{CardUniqueIdentifier} Retrieves card details associated with a specific unique identifier. # Get Card by the Cards Display Number Source: https://devzone.nayax.com/reference/lynx/cards/get-card-by-the-cards-display-number /openapi/lynx.yaml get /v1/cards/displayNumber/{CardDisplayNumber} Retrieves card details associated with a specific display number. # Get Card Group Source: https://devzone.nayax.com/reference/lynx/cards/get-card-group /openapi/lynx.yaml get /v1/cards/{cardId}/cardGroups Retrieves the group details associated with a specific card, identified by its card ID. # Get Cards Source: https://devzone.nayax.com/reference/lynx/cards/get-cards /openapi/lynx.yaml get /v1/cards Retrieves card details based on various query parameters. # Get Card's Revalue Source: https://devzone.nayax.com/reference/lynx/cards/get-cards-revalue /openapi/lynx.yaml get /v1/cards/{CardUniqueIdentifier}/revalue Retrieves the revalue amount associated with a specific card, identified by the card's unique identifier. # Get Credit Card's Latest Transactions Source: https://devzone.nayax.com/reference/lynx/cards/get-credit-cards-latest-transactions /openapi/lynx.yaml post /v1/cards/query Retrieves the latest transactions associated with a specific credit card number, identified by the SHA1 hash of the card number in base64 format. # Get Prepaid Card Source: https://devzone.nayax.com/reference/lynx/cards/get-prepaid-card /openapi/lynx.yaml get /v1/cards/{CardId}/prepaid Retrieves details of a prepaid card associated with a specific card ID. # Get the Credit from a Card Source: https://devzone.nayax.com/reference/lynx/cards/get-the-credit-from-a-card /openapi/lynx.yaml get /v1/cards/{CardUniqueIdentifier}/credit Retrieves the credit value associated with a specific card, identified by its unique identifier. # Transfer Revalue Between Cards Source: https://devzone.nayax.com/reference/lynx/cards/transfer-revalue-between-cards /openapi/lynx.yaml post /v1/cards/{FromCardUniqueIdentifier}/revalue/send/{ToCardUniqueIdentifier} Transfers a specified amount of revalue from one card to another, identified by their unique identifiers. # Update Card by ID Source: https://devzone.nayax.com/reference/lynx/cards/update-card-by-id /openapi/lynx.yaml put /v2/cards/{CardID} Updates the details of a card identified by its unique ID. # Update Card Details Source: https://devzone.nayax.com/reference/lynx/cards/update-card-details /openapi/lynx.yaml put /v1/cards Updates the details of an existing card. # Update Card Details by Display Number Source: https://devzone.nayax.com/reference/lynx/cards/update-card-details-by-display-number /openapi/lynx.yaml put /v1/cards/{CardDisplayNumber} Updates the details of a card identified by the card's display number. # Update Card Groups Source: https://devzone.nayax.com/reference/lynx/cards/update-card-groups /openapi/lynx.yaml put /v1/cards/{CardId}/cardGroups Updates the group details associated with a card, identified by the card's unique identifier. # Update Card Status Source: https://devzone.nayax.com/reference/lynx/cards/update-card-status /openapi/lynx.yaml post /v1/cards/{CardUniqueIdentifier}/status/{CardStatus} Updates the status of a card, identified by its unique identifier. # Update Prepaid Card Source: https://devzone.nayax.com/reference/lynx/cards/update-prepaid-card /openapi/lynx.yaml put /v1/cards/{CardId}/prepaid Updates the details of a prepaid card associated with a specific card ID. # Validates Card for Machine Use Source: https://devzone.nayax.com/reference/lynx/cards/validates-card-for-machine-use /openapi/lynx.yaml get /v1/cards/validate-machine/{machineId} Validates whether a prepaid or discount card can be used with a specific machine. # Get All Devices Source: https://devzone.nayax.com/reference/lynx/devices/get-all-devices /openapi/lynx.yaml get /v1/devices Retrieve a list of devices with optional filters such as actor ID, connection status, serial number, and other device attributes. # Get Device by DeviceID Source: https://devzone.nayax.com/reference/lynx/devices/get-device-by-deviceid /openapi/lynx.yaml get /v1/devices/{DeviceID} Retrieve detailed information about a specific device using its `DeviceID`. The unique identifier of the device is provided in the path to ensure accurate retrieval of the device's data. # Move Devices to Actor ID Source: https://devzone.nayax.com/reference/lynx/devices/move-devices-to-actor-id /openapi/lynx.yaml put /v1/devices/move/{actorId} Assigns or moves a list of devices to a specified actor identified by `actorId`. The request body should include an array of device identifiers (e.g., serial numbers). # Update Device Source: https://devzone.nayax.com/reference/lynx/devices/update-device /openapi/lynx.yaml put /v1/devices/{DeviceID} Update the details of an existing device using its `DeviceID`. The unique identifier of the device is provided in the path to ensure that the correct device is updated. # Generate eReceipt for your Transaction Source: https://devzone.nayax.com/reference/lynx/ereceipt/generate-ereceipt-for-your-transaction /openapi/lynx.yaml post /v1/ereceipt/generate Generates an electronic receipt (eReceipt) for a specified transaction. The request body should include the transaction details necessary to generate the eReceipt. # Get All Actor Types Source: https://devzone.nayax.com/reference/lynx/lookups/get-all-actor-types /openapi/lynx.yaml get /v1/actorTypes Retrieves a list of all actor types, optionally filtered by a specific `ActorTypeID`. # Get Billing Providers Source: https://devzone.nayax.com/reference/lynx/lookups/get-billing-providers /openapi/lynx.yaml get /v1/billingProviders Retrieves a list of billing providers, optionally filtered by `BillingProviderID`. # Get Cities Source: https://devzone.nayax.com/reference/lynx/lookups/get-cities /openapi/lynx.yaml get /v1/cities Retrieves a list of cities within a specified country, optionally filtered by `CountryID`. # Get Countries Source: https://devzone.nayax.com/reference/lynx/lookups/get-countries /openapi/lynx.yaml get /v1/countries Retrieves a list of countries, optionally filtered by `CountryID` or `DialCode`. # Get Country by Code Source: https://devzone.nayax.com/reference/lynx/lookups/get-country-by-code /openapi/lynx.yaml get /v1/countries/{CountryCode} Retrieves the details of a specific country identified by `CountryCode`. # Get Currencies Source: https://devzone.nayax.com/reference/lynx/lookups/get-currencies /openapi/lynx.yaml get /v1/currencies Retrieves a list of currencies, optionally filtered by `CurrencyID`. # Get Currency by Code Source: https://devzone.nayax.com/reference/lynx/lookups/get-currency-by-code /openapi/lynx.yaml get /v1/currencies/{CurrencyCode} Retrieves the details of a specific currency identified by `CurrencyCode`. # Get Group Roles Source: https://devzone.nayax.com/reference/lynx/lookups/get-group-roles /openapi/lynx.yaml get /v1/group/{GroupID}/roles Retrieves a list of roles associated with a specific group identified by `GroupID`. # Get Groups Source: https://devzone.nayax.com/reference/lynx/lookups/get-groups /openapi/lynx.yaml get /v1/groups Retrieves a list of groups, optionally filtered by `GroupID`. # Get Lookup Types Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-types /openapi/lynx.yaml get /v1/lookupTypes Retrieves a list of lookup types, optionally filtered by a specific `LutTypeID`. # Get Lookup Value by Lookup ID Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-value-by-lookup-id /openapi/lynx.yaml get /v1/lookups/values/{LutID} Retrieves a specific lookup value identified by `LutID`. # Get Lookup Values by Lookup Type ID Source: https://devzone.nayax.com/reference/lynx/lookups/get-lookup-values-by-lookup-type-id /openapi/lynx.yaml get /v1/lookupTypes/{LutTypeID}/values Retrieves a list of lookup values associated with a specific lookup type identified by `LutTypeID`. # Get Machine Models Source: https://devzone.nayax.com/reference/lynx/lookups/get-machine-models /openapi/lynx.yaml get /v1/lookupTypes/machineModels Retrieves a list of machine models, optionally filtered by a specific `MachineModeID`. # Get Payment Methods Source: https://devzone.nayax.com/reference/lynx/lookups/get-payment-methods /openapi/lynx.yaml get /v1/paymentMethods Retrieves a list of payment methods, optionally filtered by `PaymentMethodID`. # Get Regions Source: https://devzone.nayax.com/reference/lynx/lookups/get-regions /openapi/lynx.yaml get /v1/regions Retrieves a list of regions (states or provinces), optionally filtered by `CountryID` or `RegionID`. # Get States Source: https://devzone.nayax.com/reference/lynx/lookups/get-states /openapi/lynx.yaml get /v1/states Retrieves a list of regions (states or provinces) within a specified country, optionally filtered by `CountryID`. # Get Time Zones by Offset Source: https://devzone.nayax.com/reference/lynx/lookups/get-time-zones-by-offset /openapi/lynx.yaml get /v1/timeZones Retrieves a list of time zones based on the specified time zone offset. # Get Time Zones by Time Zone Key Source: https://devzone.nayax.com/reference/lynx/lookups/get-time-zones-by-time-zone-key /openapi/lynx.yaml get /v1/timeZones/{TimeZoneKey} Retrieves a specific time zone identified by `TimeZoneKey`. # Bulk Update Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/bulk-update-machine-attributes /openapi/lynx.yaml put /v1/machines/{MachineID}/attributes Performs a bulk update of machine attributes for the specified machine identified by `MachineID`. # Get All Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/get-all-machine-attributes /openapi/lynx.yaml get /v1/machines/{MachineID}/attributes Retrieves all attributes associated with a specific machine identified by `MachineID`. # Get Specific Machine Attribute Source: https://devzone.nayax.com/reference/lynx/machine-attribute/get-specific-machine-attribute /openapi/lynx.yaml get /v1/machines/{MachineID}/attributes/{DeviceAttributeID} Retrieves the details of a specific machine attribute identified by `MachineID` and `DeviceAttributeID`. # Insert/Update Machine Attributes Source: https://devzone.nayax.com/reference/lynx/machine-attribute/insertupdate-machine-attributes /openapi/lynx.yaml post /v2/machines/attributes Allows bulk insertion or updating of machine attributes. The request body should include an array of machine attributes to be processed. # Update Machine Attribute to Current Configuration Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-machine-attribute-to-current-configuration /openapi/lynx.yaml post /v1/machines/{MachineID}/attributes/resendConfig Resends the current machine configuration, updating the machine attributes to match the latest configuration settings. # Update Machine Attribute to Model Defaults Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-machine-attribute-to-model-defaults /openapi/lynx.yaml post /v1/machines/{MachineID}/attributes/defaults Resets the machine attributes to the default values defined by the machine model. This operation is typically used to restore default configurations. # Update Specific Machine Attribute Source: https://devzone.nayax.com/reference/lynx/machine-attribute/update-specific-machine-attribute /openapi/lynx.yaml put /v1/machines/{MachineID}/attributes/{DeviceAttributeID} Updates the details of a specific machine attribute identified by `MachineID` and `DeviceAttributeID`. # Create Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/create-pick-list /openapi/lynx.yaml post /v1/machines/{MachineID}/pickList Generates a new pick list for a specific machine, with options to adjust the pick list based on various criteria. # Delete Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/delete-pick-list /openapi/lynx.yaml delete /v1/machines/{MachineID}/pickList Deletes the existing pick list for a specific machine identified by `MachineID`. # Empty Machine Products Inventory Source: https://devzone.nayax.com/reference/lynx/machine-inventory/empty-machine-products-inventory /openapi/lynx.yaml post /v1/machines/{MachineID}/inventory/empty Empties the inventory of all products in the specified machine, marking all product slots as empty. # Get Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/get-pick-list /openapi/lynx.yaml get /v1/machines/{MachineID}/pickList Retrieves the pick list associated with a specific machine identified by `MachineID`. # Set All Machine Bins as Full Source: https://devzone.nayax.com/reference/lynx/machine-inventory/set-all-machine-bins-as-full /openapi/lynx.yaml post /v1/machines/{MachineID}/inventory/full Marks all bins in the specified machine as fully stocked, indicating that all product slots are filled to capacity. # Update Pick List Source: https://devzone.nayax.com/reference/lynx/machine-inventory/update-pick-list /openapi/lynx.yaml put /v1/machines/inventory/picklists/update Updates the pick list for a specific machine, allowing changes to the quantity of products to be picked. # Create Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/create-machine-products /openapi/lynx.yaml post /v1/machines/{MachineID}/machineProducts Creates new products for the specified machine identified by `MachineID`. # Get a Machine Product Source: https://devzone.nayax.com/reference/lynx/machine-products/get-a-machine-product /openapi/lynx.yaml get /v1/machines/{MachineID}/machineProducts/{MachineProductID} Retrieves details of a specific machine product identified by `MachineProductID` within the machine identified by `MachineID`. # Get Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/get-machine-products /openapi/lynx.yaml get /v1/machines/{MachineID}/machineProducts Retrieves the list of products associated with a specific machine identified by `MachineID`. # Update a Machine Product Source: https://devzone.nayax.com/reference/lynx/machine-products/update-a-machine-product /openapi/lynx.yaml put /v1/machines/{MachineID}/machineProducts/{MachineProductID} Updates the details of a specific machine product identified by `MachineProductID` within the machine identified by `MachineID`. # Update Machine Products Source: https://devzone.nayax.com/reference/lynx/machine-products/update-machine-products /openapi/lynx.yaml put /v1/machines/{MachineID}/machineProducts Updates the products associated with a specific machine identified by `MachineID`, with an option to avoid deletion. # Get Specific Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info /openapi/lynx.yaml get /v1/machines/{MachineID} Retrieves basic information about a specific machine identified by `MachineID`. # Languages Source: https://devzone.nayax.com/reference/manage-data-operations/lynx-api/languages The following table lists the `LanguageID` values and their corresponding languages supported in the Nayax Lynx API: | Value | Language | | - | - | | 62 | Arabic | | 81 | Bulgarian | | 22 | Chinese | | 52 | Czech | | 17 | Danish | | 21 | Dutch | | 7 | English | | 31 | English UK | | 42 | Estonian | | 54 | Finnish | | 8 | French | | 28 | German | | 30 | Greek | | 4 | Hebrew | | 23 | Hungarian | | 13 | Icelandic | | 16 | Italian | | 29 | Japanese | | 34 | Latvian | | 64 | Lithuanian | | 11 | Norwegian | | 18 | Polish | | 14 | Portuguese | | 9 | Romanian | | 12 | Russian | | 41 | Slovenian | | 15 | Spanish | | 10 | Swedish | | 27 | Thai | | 2 | Turkish | | 51 | Vietnamese | # Create New Machine Source: https://devzone.nayax.com/reference/lynx/machines/create-new-machine /openapi/lynx.yaml post /v1/machines Creates a new machine entry with the provided details. # Create Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/create-payment-methods-for-machine /openapi/lynx.yaml post /v1/machines/{MachineID}/paymentMethods Creates new payment methods for a specific machine, identified by MachineID. This operation allows users to add new payment options to the machine. # Delete Specific Payment Method for Machine Source: https://devzone.nayax.com/reference/lynx/machines/delete-specific-payment-method-for-machine /openapi/lynx.yaml delete /v1/machines/{MachineID}/paymentMethods/{paymentMethodID} Deletes a specific payment method associated with a machine, identified by the provided MachineID and paymentMethodID. This operation allows users to remove a payment option from the machine. # Get All Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/get-all-machine-basic-info /openapi/lynx.yaml get /v1/machines Retrieves basic information for all machines, with optional filtering by parameters. # Get Last Sales for Machine by MachineID Source: https://devzone.nayax.com/reference/lynx/machines/get-last-sales-for-machine-by-machineid /openapi/lynx.yaml get /v1/machines/{MachineID}/lastSales Retrieves the most recent sales transactions for a specific machine, identified by MachineID. This allows users to view the latest sales activity associated with the machine. # Get Machine Change Logs Source: https://devzone.nayax.com/reference/lynx/machines/get-machine-change-logs /openapi/lynx.yaml get /v1/machines/changeLogs Fetches the change logs for machines within a specified date range. Users can filter the logs by various parameters such as ActorID, StartDate, EndDate, MachineID, TimePeriod, and MachineNumber to retrieve the relevant changes. # Get Machine Last Alerts Source: https://devzone.nayax.com/reference/lynx/machines/get-machine-last-alerts /openapi/lynx.yaml get /v1/machines/{MachineID}/lastAlerts Retrieves the most recent alerts for a specific machine identified by the provided MachineID. This helps in monitoring recent issues or notifications related to the machine's operation. # Get Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/get-payment-methods-for-machine /openapi/lynx.yaml get /v1/machines/{MachineID}/paymentMethods Retrieves the list of payment methods associated with a specific machine, identified by MachineID. This allows users to view the available payment options configured for the machine. # Get Specific Machine Basic Info by Device Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info-by-device /openapi/lynx.yaml get /v1/devices/{DeviceSerialNumber}/machine Retrieves the basic information of a specific machine associated with the provided device serial number. This allows users to fetch machine details by referencing the device it is connected to. # Get Specific Machine Basic Info by VPOS Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-basic-info-by-vpos /openapi/lynx.yaml get /v1/vpos/{VPOSSerial}/machine Retrieves the basic information of a specific machine associated with the provided VPOS serial number. This allows users to fetch machine details by referencing the VPOS device it is connected to. # Get Specific Machine Statistics Source: https://devzone.nayax.com/reference/lynx/machines/get-specific-machine-statistics /openapi/lynx.yaml get /v1/machines/{MachineID}/status Retrieves the current status and statistics of a specific machine identified by the provided MachineID. This includes details like operational status, performance metrics, and other relevant statistics. # Search Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/search-machine-basic-info /openapi/lynx.yaml post /v1/machines/search Retrieves a list of machines based on the search criteria provided in the request body. This allows users to filter and find specific machines or groups of machines by applying various parameters. # Update Payment Methods for Machine Source: https://devzone.nayax.com/reference/lynx/machines/update-payment-methods-for-machine /openapi/lynx.yaml put /v1/machines/{MachineID}/paymentMethods Updates the payment methods associated with a specific machine, identified by MachineID. This operation allows users to modify the existing payment options for the machine. # Update Specific Machine Basic Info Source: https://devzone.nayax.com/reference/lynx/machines/update-specific-machine-basic-info /openapi/lynx.yaml put /v1/machines/{MachineID} Updates the basic information of a specific machine identified by `MachineID`. # Get Event Rules Source: https://devzone.nayax.com/reference/lynx/metadata/get-event-rules /openapi/lynx.yaml get /v1/metadata/v1/event-rules Retrieves the event rules configured in the system. The response contains an array of event rules that are currently active. # Upload Picture Source: https://devzone.nayax.com/reference/lynx/metadata/upload-picture /openapi/lynx.yaml post /v1/metadata/upload-picture Uploads a picture to the server with associated metadata. The picture and its details are provided in the request body. # Approve Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/approve-payment-refund /openapi/lynx.yaml post /v1/payment/refund-approve Approves a previously requested payment refund. The request body includes details such as whether the refund was processed externally and any associated documentation. # Decline a Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/decline-a-payment-refund /openapi/lynx.yaml post /v1/payment/refund-decline Submits a request to decline a previously submitted payment refund request. The request body includes details such as the transaction ID and reason for declining the refund. # Request a Payment Refund Source: https://devzone.nayax.com/reference/lynx/payment/request-a-payment-refund /openapi/lynx.yaml post /v1/payment/refund-request Submits a request to refund a specific payment. The request body includes details such as the refund amount, reason, and transaction ID. # Upload Refund Documentation Source: https://devzone.nayax.com/reference/lynx/payment/upload-refund-documentation /openapi/lynx.yaml post /v1/payment/upload-refund Uploads a file related to a payment refund. The file could be documentation or other relevant data associated with the refund. # Create New Product Groups Source: https://devzone.nayax.com/reference/lynx/product-groups/create-new-product-groups /openapi/lynx.yaml post /v1/productGroups Creates new product groups based on the details provided in the request body. The request includes information such as the product group name, code, and associated actor. # Create Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/create-product-group-tax /openapi/lynx.yaml post /v1/productGroups/{ProductGroupID}/tax Creates new tax details for a specific product group, identified by the ProductGroupID. The request body contains the tax information to be added. # Delete Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/delete-product-group-tax /openapi/lynx.yaml delete /v1/productGroups/{ProductGroupID}/tax/{TaxRowID} Deletes a specific tax entry associated with a product group, identified by both ProductGroupID and TaxRowID. This operation removes the specified tax row from the product group. # Get All Product Groups Source: https://devzone.nayax.com/reference/lynx/product-groups/get-all-product-groups /openapi/lynx.yaml get /v1/productGroups Retrieves a list of all product groups. The response includes details of each product group such as the name, code, and associated actor. # Get Product Group Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-group /openapi/lynx.yaml get /v1/productGroups/{ProductGroupID} Retrieves details of a specific product group identified by the ProductGroupID. The response includes information such as the product group name, code, and other related details. # Get Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-group-tax /openapi/lynx.yaml get /v1/productGroups/{ProductGroupID}/tax Retrieves the tax details associated with a specific product group, identified by the ProductGroupID. Optionally, a specific tax row can be retrieved using the TaxRowID query parameter. # Get Product Groups by Actor Source: https://devzone.nayax.com/reference/lynx/product-groups/get-product-groups-by-actor /openapi/lynx.yaml get /v1/operators/{ActorID}/productGroups Retrieves a list of product groups associated with a specific actor, identified by the ActorID. The response includes details of each product group. # Update Product Group Source: https://devzone.nayax.com/reference/lynx/product-groups/update-product-group /openapi/lynx.yaml put /v1/productGroups/{ProductGroupID} Updates the details of a specific product group identified by the ProductGroupID. The request body should include the updated information such as the product group name, code, and category. # Update Product Group Tax Source: https://devzone.nayax.com/reference/lynx/product-groups/update-product-group-tax /openapi/lynx.yaml put /v1/productGroups/{ProductGroupID}/tax Updates the tax details for a specific product group, identified by the ProductGroupID. The request body contains the updated tax information. # Create New Operator Product Source: https://devzone.nayax.com/reference/lynx/products/create-new-operator-product /openapi/lynx.yaml post /v1/operators/{OperatorID}/products Creates a new product associated with a specific operator, identified by the OperatorID. The request body contains the details of the product to be created. # Get Specific Operator Products Source: https://devzone.nayax.com/reference/lynx/products/get-specific-operator-products /openapi/lynx.yaml get /v1/operators/{OperatorID}/products Retrieves a list of products associated with a specific operator, identified by the OperatorID. The response includes details of each product. # Get Specific Product Source: https://devzone.nayax.com/reference/lynx/products/get-specific-product /openapi/lynx.yaml get /v1/products/{NayaxProductID} Retrieves the details of a specific product identified by the NayaxProductID. The response includes all relevant information about the product. # Update Specific Product Source: https://devzone.nayax.com/reference/lynx/products/update-specific-product /openapi/lynx.yaml put /v1/products/{NayaxProductID} Updates the details of a specific product identified by the NayaxProductID. The request body should contain the updated product information. # Get Available Widgets Source: https://devzone.nayax.com/reference/lynx/report/get-available-widgets /openapi/lynx.yaml get /v1/dashboard/widgets Retrieves a list of available dashboard widgets, optionally filtered by the screen type ID. # Retrieve Widget Data Source: https://devzone.nayax.com/reference/lynx/report/retrieve-widget-data /openapi/lynx.yaml post /v1/dashboard/get-widget-data Fetches analytical data for a specific dashboard widget based on the provided filters and widget ID. # Add New Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/add-new-driver /openapi/lynx.yaml post /v1/Scheduling/drivers Adds a new driver to the scheduling system. The request body should include the details of the driver to be added. # Assign Machine to Route Source: https://devzone.nayax.com/reference/lynx/scheduling/assign-machine-to-route /openapi/lynx.yaml post /v1/Scheduling/route-machines Assigns a machine to a specific route. The request body should include the details of the machine to be assigned. # Create Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/create-machine-tasks /openapi/lynx.yaml post /v1/Scheduling/schedule/machine-tasks Creates new scheduled tasks for machines. The request body should include details of the tasks to be scheduled. # Create New Route Source: https://devzone.nayax.com/reference/lynx/scheduling/create-new-route /openapi/lynx.yaml post /v1/Scheduling/routes Creates a new route for the specified operator. The request body should include the details of the route to be created. # Create Visit Orders Source: https://devzone.nayax.com/reference/lynx/scheduling/create-visit-orders /openapi/lynx.yaml post /v1/Scheduling/schedule/visit-order Creates new visit orders for machines. The request body should include the details of the machines to be visited. # Delete Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/delete-driver /openapi/lynx.yaml delete /v1/Scheduling/drivers Deletes a driver identified by DriverId from the scheduling system. # Delete Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/delete-machine-tasks /openapi/lynx.yaml delete /v1/Scheduling/schedule/machine-tasks Deletes scheduled tasks for machines based on the provided query parameters such as SchedulingIds, MachineID, and date. # Get Drivers Source: https://devzone.nayax.com/reference/lynx/scheduling/get-drivers /openapi/lynx.yaml get /v1/Scheduling/drivers Retrieves a list of drivers based on various query parameters, such as ActorId, DriverStatusId, and multiple search options (e.g., by DriverId, UserId, Fullname, etc.). # Get Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/get-machine-tasks /openapi/lynx.yaml get /v1/Scheduling/schedule/machine-tasks Retrieves a list of scheduled machine tasks based on various query parameters such as date range, machine, driver, route, and other filters. # Get Route Machines Source: https://devzone.nayax.com/reference/lynx/scheduling/get-route-machines /openapi/lynx.yaml get /v1/Scheduling/route-machines Retrieves a list of machines assigned to a specific route, identified by RouteId, and optionally filtered by MachineId. # Get Routes Source: https://devzone.nayax.com/reference/lynx/scheduling/get-routes /openapi/lynx.yaml get /v1/Scheduling/routes Retrieves a list of routes based on various query parameters, such as OperatorId, DriverId, Status, and multiple search options (e.g., by Name, Code, Notes, etc.). # Get Visit Orders Source: https://devzone.nayax.com/reference/lynx/scheduling/get-visit-orders /openapi/lynx.yaml get /v1/Scheduling/schedule/visit-order Retrieves a list of visit orders based on various query parameters such as VisitDate, MachineId, DriverId, RouteId, and ActorId. # Remove Machine from Route Source: https://devzone.nayax.com/reference/lynx/scheduling/remove-machine-from-route /openapi/lynx.yaml delete /v1/Scheduling/route-machines Removes a machine from a specific route, identified by RouteId and MachineId. # Update Driver Source: https://devzone.nayax.com/reference/lynx/scheduling/update-driver /openapi/lynx.yaml put /v1/Scheduling/drivers Updates the details of an existing driver identified by DriverId. The request body should include the updated driver information. # Update Machine Tasks Source: https://devzone.nayax.com/reference/lynx/scheduling/update-machine-tasks /openapi/lynx.yaml put /v1/Scheduling/schedule/machine-tasks Updates existing scheduled tasks for machines. The request body should include the updated task details. # Update Route Source: https://devzone.nayax.com/reference/lynx/scheduling/update-route /openapi/lynx.yaml put /v1/Scheduling/routes Updates the details of an existing route identified by routeId. The request body should include the updated route information. # Sign In Source: https://devzone.nayax.com/reference/lynx/sign-in/sign-in /openapi/lynx.yaml get /signin # User Sign In Source: https://devzone.nayax.com/reference/lynx/sign-in/user-sign-in /openapi/lynx.yaml post /v1/signin Authenticates a user with the provided credentials (username and password). # Cortina Credit Card Authorization Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-authorization /openapi/cortina.yaml post /Cortina/CreditCard/Authorization Initiates a credit card pre-authorization transaction. This POST endpoint verifies the card's validity and available balance while handling security protocols like EMV, DUKPT, and 3-D Secure (SCA). It returns an authorization verdict, issuer authentication data (EMV tags), or a redirection URL if further user authentication is required. # Cortina Credit Card Cancel Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-cancel /openapi/cortina.yaml post /Cortina/CreditCard/Cancel Stops a transaction that hasn't finished yet. This endpoint cancels a credit card payment that was authorized but not yet finalized. It stops the process, releases the held funds back to the customer, and records the reason for the cancellation. # Cortina Credit Card Incremental Auth Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-incremental-auth /openapi/cortina.yaml post /Cortina/CreditCard/IncrementalAuth Increases the approved amount for an active transaction. This endpoint requests permission to charge additional funds on a card that has already been authorized. It is used to raise the total transaction amount before the payment is finalized. # Cortina Credit Card Inquiry3DS Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-inquiry3ds /openapi/cortina.yaml post /Cortina/CreditCard/Inquiry3DS Verifies 3-D Secure authentication status. This endpoint checks if the cardholder has successfully authenticated their identity using 3-D Secure (Strong Customer Authentication). It returns the final authentication status (e.g., completed, failed, or frictionless flow applied) to allow the transaction to proceed safely. # Cortina Credit Card Refund Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-refund /openapi/cortina.yaml post /Cortina/CreditCard/Refund Returns money to the customer after a transaction is complete. This endpoint processes a refund for a transaction that has already been settled (finalized). It sends funds back to the cardholder, logging the reason for the refund and updating the batch status. # Cortina Credit Card Sale Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-sale /openapi/cortina.yaml post /Cortina/CreditCard/Sale Processes a complete payment in one step. This endpoint authorizes and charges the credit card in a single action (combining Authorization and Settlement). It handles all card checks and security verification (like 3DS) and captures funds immediately if approved. # Cortina Credit Card Settlement Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-settlement /openapi/cortina.yaml post /Cortina/CreditCard/Settlement Finalizes and captures the funds for an authorized credit card transaction. This POST endpoint completes the payment lifecycle by submitting the final transaction details for settlement. It validates the original authorization using `PaymentInfo`, processes the charge, and returns the settlement status along with relevant `Batch` information for reconciliation. # Cortina Credit Card Void Source: https://devzone.nayax.com/reference/cortina/cortina-credit-card/cortina-credit-card-void /openapi/cortina.yaml post /Cortina/CreditCard/Void Cancels a payment that hasn't been settled yet. This endpoint reverses a transaction that was authorized but not yet finalized. It removes the temporary hold on the customer's funds and requires a reason code for the action. # Get Version Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/get-version /openapi/cortina.yaml get /Version Retrieves the current Commerce API version and build information. This GET endpoint provides metadata about the deployed Commerce system, returning the ApiVersion, ProductVersion, and Copyright details for diagnostic purposes. # Onboard Actor Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/onboard-actor /openapi/cortina.yaml post /OnboardActor Registers or updates a merchant (Actor) in the system. This endpoint handles the onboarding process for new merchants, distributors, or operators. It accepts their profile details and configuration settings and returns an onboarding status (e.g., Success, Pending, Failed) along with credentials such as API keys or merchant IDs. # Onboard Machine Source: https://devzone.nayax.com/reference/cortina/cortina-onboarding/onboard-machine /openapi/cortina.yaml post /OnboardMachine Registers or updates a vending machine's configuration in the system. This endpoint manages the onboarding of specific machines by linking them to an operator and distributor. It configures the machine's details and returns its unique credentials (such as TerminalId or QrString) along with the final setup status. # Cortina Prepaid Authorization Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-authorization /openapi/cortina.yaml post /Cortina/Prepaid/Authorization Checks the balance and authorizes a prepaid card. This endpoint verifies if a prepaid card is valid and has enough funds (or credits) for the purchase. It returns the approval decision along with the card's current balance or remaining uses. # Cortina Prepaid Cancel Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-cancel /openapi/cortina.yaml post /Cortina/Prepaid/Cancel Cancels a prepaid transaction before it's finished. This endpoint stops an authorized prepaid payment that hasn't been settled yet. It releases any held funds or credits back to the card and returns the balance to its original status. # Cortina Prepaid Refund Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-refund /openapi/cortina.yaml post /Cortina/Prepaid/Refund Returns funds or credits to a prepaid card. This endpoint processes a refund for a prepaid transaction that was already completed. It adds the refunded amount (or credit count) back to the user's card balance and records the reason for the return. # Cortina Prepaid Sale Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-sale /openapi/cortina.yaml post /Cortina/Prepaid/Sale Cancels a prepaid transaction before it's finished. This endpoint stops an authorized prepaid payment that hasn't been settled yet. It releases any held funds or credits back to the card and returns the balance to its original status. # Cortina Prepaid Settlement Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-settlement /openapi/cortina.yaml post /Cortina/Prepaid/Settlement Deducts funds and finalizes a prepaid purchase. This endpoint captures the payment from the prepaid card, reducing the user's balance or credit count. It confirms the final amount charged and returns the updated balance. # Cortina Prepaid Void Source: https://devzone.nayax.com/reference/cortina/cortina-prepaid/cortina-prepaid-void /openapi/cortina.yaml post /Cortina/Prepaid/Void Reverses an authorized prepaid payment. This endpoint cancels a transaction that was approved but not finalized. It releases the hold on the prepaid funds or credits, immediately updating the card's balance to reflect the reversal. # Cortina Age Verification Source: https://devzone.nayax.com/reference/cortina/cortina/cortina-age-verification /openapi/cortina.yaml post /Cortina/AgeVerification Cortina Age Verification # Post Renew Key Source: https://devzone.nayax.com/reference/cortina/cortina/post-renew-key /openapi/cortina.yaml post /Cortina/RenewKey Rotates the encryption key used for secure operations. This POST endpoint requests a key refresh from the provider. It submits the `CurrentKeyData` and returns the `NewKeyData` (including the new PIN encryption key encrypted under the Zone Master Key), along with its ID and Key Check Value (KCV). # Post Sale End Notification Source: https://devzone.nayax.com/reference/cortina/cortina/post-sale-end-notification /openapi/cortina.yaml post /Cortina/SaleEndNotification Receives a notification indicating the successful completion of a sale transaction. This POST endpoint is triggered by Nayax to inform the integrator that a sale has ended successfully. It accepts transaction details including `BasicInfo` and `PaymentInfo`, and returns a verdict acknowledging the receipt of the notification. # Post Start Session Source: https://devzone.nayax.com/reference/cortina/cortina/post-start-session /openapi/cortina.yaml post /Cortina/StartSession Validates the client and initializes a secure transaction session. This POST endpoint performs the initial handshake using a `TokenId` and `RandomNumber`. It returns a `Verdict` indicating if the session is approved and establishes the encryption and transaction ID context required for all subsequent operations. # Cortina DynamicQR GenerateQR Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-generateqr /openapi/cortina.yaml post /Cortina/DynamicQR/GenerateQR Generates a QR code for the customer to scan. This endpoint receives transaction details (such as the amount and machine ID) and generates the specific QR code data to be displayed on the payment terminal screen for the user to scan. # Cortina DynamicQR Inquiry Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-inquiry /openapi/cortina.yaml post /Cortina/DynamicQR/Inquiry Checks if the QR code payment is complete. This endpoint verifies if the customer has successfully paid after scanning the QR code. It tells the machine to dispense the product if approved, stop if the payment fails, or wait and check again if the process is still pending. # Cortina DynamicQR Refund Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-refund /openapi/cortina.yaml post /Cortina/DynamicQR/Refund Returns a full or partial refund for a completed QR payment. This endpoint sends money back to the customer after a transaction completes successfully. It is typically triggered by a customer complaint (via the Nayax web system) and allows for specific refund reasons to be recorded. # Cortina DynamicQR Void Source: https://devzone.nayax.com/reference/cortina/dynamicqr/cortina-dynamicqr-void /openapi/cortina.yaml post /Cortina/DynamicQR/Void Cancels a QR payment if the product wasn't dispensed. This endpoint reverses a successful QR transaction when the machine fails to release the item or times out. It ensures the customer is not charged since they did not receive their product. # Cortina StaticQR Authorization Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-authorization /openapi/cortina.yaml post /Cortina/StaticQR/Authorization Holds funds for a transaction where the final amount isn't known yet. Nayax calls this endpoint to validate the customer's account and temporarily reserve funds (pre-authorization) before the actual usage is calculated. It must be followed later by a settlement or cancellation. # Cortina StaticQR Cancel Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-cancel /openapi/cortina.yaml post /Cortina/StaticQR/Cancel Finalizes and charges the customer after the product is dispensed. Nayax triggers this endpoint to complete the transaction once the machine has successfully released the item. It captures the final amount from the user's account. # Cortina StaticQR Refund Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-refund /openapi/cortina.yaml post /Cortina/StaticQR/Refund Returns a full or partial refund for a completed Static QR payment. This endpoint sends money back to the customer after a transaction completes successfully. It is typically triggered by a customer complaint (via the Nayax web system) and allows for specific refund reasons to be recorded. # Cortina StaticQR Sale Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-sale /openapi/cortina.yaml post /Cortina/StaticQR/Sale Charges the customer immediately for a specific amount. This endpoint processes a complete Static QR payment in one step (Auth + Settlement) when the price is already known (pre-selection). It validates and charges the user's account instantly. # Cortina StaticQR Settlement Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-settlement /openapi/cortina.yaml post /Cortina/StaticQR/Settlement Upon successful dispense of a product/service by the operator's machine, Nayax will call this method to complete and capture the transaction with the integrator.This call will include the transaction's final amount to be cleared by the integrator. # Cortina StaticQR Start Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-start /openapi/cortina.yaml post /Cortina/{integratorName}/start Starts the transaction when a customer scans a static QR code. This endpoint notifies Nayax that a user is at the machine and ready to pay. It links the user ID to the machine ID using a secret token to begin the process. # Cortina StaticQR Void Source: https://devzone.nayax.com/reference/cortina/staticqr/cortina-staticqr-void /openapi/cortina.yaml post /Cortina/StaticQR/Void Cancels a payment if the machine fails to dispense. This endpoint reverses a Static QR transaction when the vending machine encounters an error or times out. It ensures the customer is not charged for a product they did not receive.