Processing a transaction with a terminal

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

Nexio's API allows you to process card present (EMV) transactions using a terminal, either via the retail iframe or directly through the API. In order to do this, you must have completed the steps in the Configuring your terminal for USAePay tutorial or through using the Pair terminal endpoint.

Follow the steps below, depending on your gateway.

USAePay

In order to process a card present transaction with a terminal through USAePay, you need to set up your terminal and then pair it and process the transaction either via iframe or via API.

Processing transaction with the iframe

In order to process a transaction via iframe, you must have completed setup and paired your terminal via iframe.

  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 terminal to use. If the terminal does not appear in the Terminal menu, it may not be paired, 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.

Processing transaction with the API

In order to process a transaction via API, you must have completed setup and paired your terminal via API.

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

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

  2. 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",
    
    }
    

  3. 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.

  4. Complete the transaction at the terminal.

  5. 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.

Zeamster

  1. Send a GET request to the View terminal list endpoint.

    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"
      }
    ]
    

  2. Copy the terminalId from the response above. You will use it in step 3.

  3. Send a POST request with the transaction details and terminalId to the Process transaction from terminal endpoint.

    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"
      },
      "terminalId": "eyJtZXJjaGFudElkIjoiMTAxMDM5IiwiZ2F0ZXdheUxhYmVsIjoiLi4uMmUyMSwuLi41ZWU3IiwidGVybWluYWwiOnsiaWQiOiIxMWU5MDIxMGNmZTdmNmFlOWVkNWUwYTgiLCJsb2NhdGlvbklkIjoiMTFlOGNkNmE4YjQ0YzUzZWFkNmFkY2UxIn19"
    }'
    

    A successful response returns a terminalRequestId. You can use the terminalRequestId to check the status of the transaction.

    {
      "terminalRequestId": "64ea267f-2766-49b8-9e0e-aeb91b2fe722",
      "terminalRequestStatus": "initialized"
    }
    

  4. Optionally, check the Transaction Status. Send a GET request with the terminalRequestId to the View terminal transaction status endpoint.

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

    {
      "gatewayResponse": {
        "gatewayName": "yourGateway"
      },
      "terminalRequestId": "64ea267f-2766-49b8-9e0e-aeb91b2fe722",
      "terminalRequestStatus": "initialized"
    }
    

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.