Processing a transaction with a terminal

Background
Before starting this tutorial, make sure you understand the following topics from the Quick start section:

👍

Prerequisites

In order to process a transaction with a terminal, you must have completed the configuration steps for the gateway/connection for a terminal:

Nexio's API allows you to process card present transactions using a terminal through either of the following methods:

📘

Note

Kount verification is not available for terminal transactions.

Via the retail iframe

The retail iframe stores the last terminal used to process a payment, which includes the API credentials used to load the iframe and the merchant ID (Processing Account) used, on the computer or workstation that accessed the iframe.

In order to process a transaction with a terminal through the retail iframe, do the following:

  1. Decide which authentication method to use:

    • By using Simple login for trusted users. You will include the simpleLogin key and value in the src of the iframe in the following steps.
    • By requiring users to enter their Nexio user credentials when they access the https://retail.nexiopaysandbox.com page. You will not include the simpleLogin key in the src of the iframe.
  2. Load the retail iframe with the default options or customize it with additional parameters and options. The following are examples of how to build the URL with simple login or without. Also, when not using simple login, you could include the URL directly in the src instead of using JavaScript or another language to dynamically set the value.

    <html>
      <head>
        <title>Retail Transaction</title>
        <link rel="stylesheet" href="mystyle.css">
      </head>
      <body>
        <script>
          function getSimpleLogin() {
            fetch('http://localhost:3000/', {
                method: 'GET'
            }).then(function (response) {
                return response.json();
            }).then((objData) => {
                console.log('------->response Data', objData);
    
                // Define your complex settings JSON object
                let settings = {
                    "card": {
                        "cardHolderName": "John H. Doe"
                    },
                    "data": {
                        "customer": {
                            "customerRef": "customer123",
                            "birthDate": "2000-01-01"
                        }
                    },
                    "uiOptions": {
                        "hideCustomerInfo": false,
                        "hideBilling": false,
                        "hideShipping": false
                    }
                };
    
                // Convert the JSON object to a string and URL-escape it
                let settingsEscaped = encodeURIComponent(JSON.stringify(settings, null, 2)); // The '2' argument adds indentation to the JSON string
    
                // Append the simple login and escaped settings string to your URL
                let iframe = document.getElementById('myIframe');
                iframe.src = 'https://retail.nexiopaysandbox.com/?simpleLogin=' + objData.key + '&settings=' + settingsEscaped;
            });
          }
    
          getSimpleLogin();      
        </script>
        <div>
          <h3>Retail Transaction</h3>
          <p>Complete all required information:</p>      
          <iframe id="myIframe" name="myIframe" src=""></iframe>
        </div>
      </body>
    </html>
    
    <html>
      <head>
        <title>Retail Transaction</title>
        <link rel="stylesheet" href="mystyle.css">
      </head>
      <body>
        <script>
          function buildUrl() {
            // Define your complex settings JSON object
            let settings = {
                "card": {
                    "cardHolderName": "John H. Doe"
                },
                "data": {
                    "customer": {
                        "customerRef": "customer123",
                        "birthDate": "2000-01-01"
                    }
                },
                "uiOptions": {
                    "hideCustomerInfo": false,
                    "hideBilling": false,
                    "hideShipping": false
                }
            };
    
            // Convert the JSON object to a string and URL-escape it
            let settingsEscaped = encodeURIComponent(JSON.stringify(settings, null, 2)); // The '2' argument adds indentation to the JSON string
    
            // Append the simple login and escaped settings string to your URL
            let iframe = document.getElementById('myIframe');
            iframe.src = 'https://retail.nexiopaysandbox.com/?settings=' + settingsEscaped;
          }
    
        	buildUrl();      
        </script>
        <div>
          <h3>Retail Transaction</h3>
          <p>Complete all required information:</p>     
        	<iframe id="myIframe" name="myIframe" src=""></iframe>
        </div>
      </body>
    </html>
    
    <html>
      <head>
        <title>Retail Transaction</title>
        <link rel="stylesheet" href="mystyle.css">
      </head>
      <body>
        <div>
          <h3>Retail Transaction</h3>
          <p>Complete all required information:</p>      
        	<iframe id="myIframe" name="myIframe" src="https://retail.nexiopaysandbox.com/?settings=%7B%22card%22%3A%7B%22cardHolderName%22%3A%22John%20H.%20Doe%22%7D%2C%22data%22%3A%7B%22customer%22%3A%7B%22nationalIdentificationNumber%22%3A%22123-45-6789%22%2C%22birthDate%22%3A%222000-01-01%22%7D%7D%2C%22uiOptions%22%3A%7B%22hideCustomerInfo%22%3Afalse%2C%22hideBilling%22%3Afalse%2C%22hideShipping%22%3Afalse%7D%7D"></iframe>
        </div>
      </body>
    </html>
    

  3. Create an event listener on the frontend webpage to monitor actions in the iframe. This listener keeps your code updated on what is happening inside the iframe. You handle the success, error, and loading states here.
    See our Iframe events table for a list of possible events.

    window.addEventListener('message', function messageListener(event) {
        if (event.origin === iframeUrl) {
            // switch on event.data properties
            // (e.g. loaded, formValidations, error)
        }
    });
    

  4. The user who will be accessing the iframe page needs to make sure the terminal is awake and connected before proceeding.

  5. When your trusted user accesses the webpage, the user sees the retail iframe for running a transaction.

  6. The user then selects the appropriate value from the Processing Account field before selecting the "Card (terminal)" option from the Payment Method field.

    📘

    Note

    If you do not see the Payment Method field, your account is not configured for retail transactions.

    If this is the case, contact Integrations Support for help getting set up before proceeding.

  7. The retail iframe for running a transaction with the terminal displays, as shown here:

Retail iframe for terminal

Retail iframe for terminal

  1. The user selects the appropriate currency and amount for the transaction.
  2. Then, the user selects the paired/registered terminal to use. If the terminal does not appear in the Terminal menu, it may not be paired/registered, or the terminal may have gone to sleep per the manufacturer's settings. Wake the terminal then reload the iframe.
  3. The user then clicks Submit to send the payment to the terminal.
  4. The customer then completes the transaction at the terminal. When complete, the terminal posts a response to the iframe.

Directly through the API

Rather than using the retail iframe, you can create your own interface and use the Nexio API to run a transaction through a terminal.

In order to process a transaction with a terminal through the Nexio API, do the following:

  1. If you do not know the currently connected terminals for the merchant account, send a GET request to the View terminal list endpoint.

  2. curl -X GET https://api.nexiopaysandbox.com/pay/v3/getTerminalList \
      -H 'Accept: application/json' \
      -H 'Authorization: Basic [Base64_encoded_login]'
    

    A successful request returns an array of terminal objects. These are the terminals currently enabled on your merchant ID.

    [
      {
        "gatewayLabel": "...2e21,...5ee7",
        "gatewayName": "yourGateway",
        "gatewayType": 110,
        "merchantId": "103002",
        "merchantName": "Test Merchant",
        "terminalId": "eyJtZXJjaGFudElkIjoiMTAxMDM5IiwiZ2F0ZXdheUxhYmVsIjoiLi4uMmUyMSwuLi41ZWU3IiwidGVybWluYWwiOnsiaWQiOiIxMWU5MDIxMGNmZTdmNmFlOWVkNWUwYTgiLCJsb2NhdGlvbklkIjoiMTFlOGNkNmE4YjQ0YzUzZWFkNmFkY2UxIn19",
        "terminalName": "Terminal 1",
        "terminalSerialNumber": "84937213"
      }
    ]
    

    You can then use the returned terminalId for the transaction, or present users with a list of terminals to choose from.

  3. Send a POST request with the transaction amount and terminalId to the Process transaction from terminal endpoint. You can optionally send a value for the saveCardToken parameter.

    curl -X POST https://api.nexiopaysandbox.com/pay/v3/processFromTerminal \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Basic [Base64_encoded_login]'
      -d '{
      "data": {
        "amount": "13.45"
      },
      "processingOptions": {
        "saveCardToken": true
      },
      "terminalId": "eyJtZXJjaGFudElkIjoiMTAxMDM5IiwiZ2F0ZXdheUxhYmVsIjoiLi4uMmUyMSwuLi41ZWU3IiwidGVybWluYWwiOnsiaWQiOiIxMWU5MDIxMGNmZTdmNmFlOWVkNWUwYTgiLCJsb2NhdGlvbklkIjoiMTFlOGNkNmE4YjQ0YzUzZWFkNmFkY2UxIn19"
    }'
    

    A successful request returns a terminalRequestStatus of initialized.

    {
      "terminalRequestId": "8524beee-70f1-4890-9382-3d5bb8871a4c",
      "terminalRequestStatus": "initialized",
    
    }
    

  4. After submitting the request to process from terminal, the terminal displays the amount that was in the request and an image indicating that it is ready for you to present the card.

  5. Complete the transaction at the terminal.

  6. Using the returned terminalRequestId, send a request to the View terminal transaction status endpoint as frequently as once per second until the terminalRequestStatus returns as success. You may see a pending status before the success status. This means that it was submitted but the transaction with the gateway is not complete.

Next steps

After running a transaction, you can check the status of the transaction or transactions with the APIs:

  • If this was an auth only transaction, the next step is to capture the transaction. You can use the Capture a transaction endpoint or go to your Nexio dashboard to locate the transaction and capture it there.
  • View transaction by payment ID - Because you get the paymentId (as id) in the response for a transaction, this endpoint is useful for quickly getting transaction information and updates.
  • View transaction by transaction ID - You can use this endpoint instead of View transactions when you only need to get information about a single transaction and in order to get all response parameters related to the transaction without needing to request them specifically.
  • View transactions - For viewing information about one or more transactions and being able to filter the results based on specified parameters.