Introduction

The new generation of Handpoint APIs and SDKs are engineered to make your life simpler, happier.

Awesomely simple
Created for humans, coders, geeks, no need of dark and complex knowledge of the payment industry.
Superly secure
We take care of the PCI side so you don't have to spend months becoming compliant.
The Handpoint card reader encrypts all sensitive cardholder data so your app does not have to deal with it.
Working with the SDK
The Handpoint Windows SDK is compatible with .NET Framework Version 4.6.1.

1. Download the SDK.
2. Create a new windows form project in Visual Studio 2010 (or above) using .Net Framework Version 4.6.1.
3. Add the HandpointSDK NuGet Package to your project.
If you have a DEBUG device (How to identify DEBUG devices) please use the package version -beta (prerelease): Example 3.0.0-beta
4. Follow the getting started guide, to get you up and running or dive into the documentation.

If you have any questions, do not hesitate to contact us.

version

Get the SDK

API overview

How to implement a Sale Transaction

The below flow chart shows the interaction between the SDK, the payment terminal and your application. The orange arrows represent methods (requests) that need to be invoked to communicate with the Handpoint SDK's. The dark arrows represent events that need to be integrated in your code in order to retrieve information from the SDK´s and the card reader.


How to implement a Sale Transaction with Recovery feature

At some point, the connection between the SDK and the card reader can become unstable. For example, the Bluetooth connection can be cut in the middle of a sale transaction if the smartphone runs out of battery. If this happens, you need to have implemented the “transaction recovery feature” in order to get the receipts from the previous transaction and knowing if it was successful despite the connection problem.



Supported functionality

  • Discovery of remote BT and CLOUD devices.
  • Connect to remote BT and CLOUD device.
  • Physical connection to HiPro external accessory.
  • Automatic or manual reconnection to the card reader.
  • Executing financial transaction.
  • Reporting status of transactions.
  • Control and access to device logs.
  • Barcode scanner with HiPro card readers.
  • Limited card reader simulation.

Processing Payments Simulation

Your test payments are sent against a test server on the Handpoint side which simulates the behavior of an acquiring bank. Funds are not moved and sensitive data from the card is fully encrypted. You can use trigger amounts to generate some specific responses from our server:

Sale amounts
Amount Behaviour
37.79 Issuer response code = 01 (Refer to issuer)
37.84 Issuer response code = 05 (Not authorized)
37.93 Issuer response code = 04 (Pick up card)
37.57 Request is partially approved
37.68 Request timeout


Integration Guide

Hilite & Hi5 - Bluetooth Integration

Introduction

This tutorial is guiding you through all the steps to create a basic payment application for Windows devices integrated with a Datecs terminal.

The new generation of Handpoint SDK's is designed to make your life easier. Simple and created for humans, it does not require any specific knowledge of the payment industry to be able to start accepting credit/debit card transactions.

At Handpoint we take care of securing every transaction so you don´t have to worry about it while creating your application. We encrypt data from the payment terminal to the bank with our point-to-point encryption solution. Our platform is always up to the latest PCI-DSS security requirements.

Let's start programming!

  1. Create a C# class
  2. Create a new C# class called MyClass and include com.handpoint.api as a dependency :

    
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass
        {
        }
    }
                
  3. Initialize the API
  4. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass
        {
            Hapi api;
    
            public MyClass()
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
                // The api is now initialized. Yay! we've even set a default shared secret!
                // The shared secret is a unique string shared between the card reader and your mobile application.
                // It prevents other people to connect to your card reader.
                // You should replace this default shared secret by the one sent by our support team.
            }
        }
    }
                
  5. Implement the mandatory Events(Events.Required) and per recommendation Status events (Events.Status)
  6. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
    
            public MyClass()
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
                // Here you get a list of Bluetooth payment terminals paired with your computer
            }
    
            public void EndOfTransaction(TransactionResult transactionResult, Device device)
            {
              // The TransactionResult object holds details about the transaction as well as the receipts.
              // Useful information can be accessed through this object like the transaction ID, the amount, etc.
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                // The ConnectionStatus object holds details about the status regarding the connection to the target device.
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                // The StatusInfo object holds details about the status and step taken during the transaction.
            }
    
            public void SignatureRequired(SignatureRequest signatureRequest, Device device)
            {
                // You'll be notified here if a sale process needs a signature verification
                // A signature verification is needed if the cardholder uses an MSR or a chip & signature card
                // This method will not be invoked if a transaction is made with a Chip & PIN card
    
                api.SignatureResult(true); // This line means that the cardholder ALWAYS accepts to sign the receipt.
                // A specific line will be displayed on the merchant receipt for the cardholder to be able to sign it
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                // Ignore, legacy event, will be deleted in future version.
            }
        }
    }
                
  7. Add a method to discover surrounding devices and connect to the card reader
  8. Ensure that the card reader and PC are correctly paired via bluetooth.

    
    public void DiscoverDevices()
    {
        api.ListDevices(ConnectionMethod.BLUETOOTH);
        // This triggers the search for all the bluetooth devices around.
        // You can also search for USB and Serial as a connection method
    }
    
    public void DeviceDiscoveryFinished(List<Device> devices)
    {
        foreach (Device device in devices)
        {
            if (device.Name != null)
            {
                if (device.Name.Equals("PP0513901435"))
                // Put the name of your device, find it by doing C then up arrow on your card reader keypad
                {
                    this.device = device;
                    //We'll remember the device for this session, it is nice if you would do that too
                    api.Connect(this.device);
                    //Connection to the device is handled automatically in the API
                }
            }
        }
    }
                
  9. Add a method to connect directly to the card reader
  10. Instead of discovering the surrounding devices you can also directly connect to the card reader by implementing the following method:

    
    public void DirectConnect()
    {
        Device device = new Device("PP0513901435", "68:AA:D2:00:D5:27", "", ConnectionMethod.BLUETOOTH);
        //new Device("name", "address", "port", ConnectionMethod);
        //The address always has to be written in UPPER CASE
        api.Connect(device);
    }
                
  11. Add a method to take payments
  12. 
    public bool Pay()
    {
        return api.Sale(new BigInteger(1000), Currency.GBP);
        // Let´s start our first payment of 10 pounds
    }
                
  13. Add a method to disconnect from the card reader
  14. 
    public void Disconnect()
    {
        api.Disconnect();
    }
                
  15. Eventually, MyClass.cs must look like this after implementing all the necessary methods :
  16. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
    
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
    
            public MyClass(Form1 form1)
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
            }
    
            public void DiscoverDevices()
            {
                api.SearchDevices(ConnectionMethod.BLUETOOTH);
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
                foreach (Device device in devices)
                {
                    if (device.Name != null)
                    {
                        if (device.Name.Equals("PP0513901435"))
                        {
                            this.device = device;
                            api.Connect(this.device);
                        }
                    }
                }
            }
    
            public void DirectConnect()
            {
                Device device = new Device("PP0513901435", "68:AA:D2:00:D5:27", "", ConnectionMethod.BLUETOOTH);
                api.Connect(device);
            }
    
            public bool Pay()
            {
                return api.Sale(new BigInteger(1000), Currency.GPB);
            }
    
            public void Disconnect()
            {
                api.Disconnect();
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                Console.WriteLine("*** ConnectionStatus *** " + status);
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
            }
    
            public void SignatureRequired(SignatureRequest signatureRequest, Device device)
            {
                    api.SignatureResult(true);
            }
            
            public void EndOfTransaction(TransactionResult result, Device device)
            {
                Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                //Ignore
            }
        }
    }
                

Let's create a User Interface!

  1. Create buttons
    • Go to your user interface (usually Form1.cs[Design])
    • Select View > Toolbox
    • In the toolbox, under “Common Controls” drag and drop 3 button items to the user interface
    • Select "button1" > Right-Click > Properties
    • Change the attribute "Name" from "button1" to "PayButton"
    • Change the attribute "text" from "button1" to "Pay Now"
    • Change the attribute "Name" from "button2" to "ConnectButton"
    • Change the attribute "text" from "button2" to "Connect To Card reader"
    • Change the attribute "Name" from "button3" to "DisconnectButton"
    • Change the attribute "text" from "button3" to "Disconnect From Card Reader"
    • Select View > Toolbox > Common Controls > Label
    • Change the attribute "Name" from "label1" to "ConnectionLabel"
    • Change the attribute "text" from "label1" to "Disconnected"
    • Change the attribute "backColor" from "label1" to "Red"

  2. Create WebBrowsers
  3. Now that we have our 3 buttons, let´s create two webBrowsers items to display the merchant receipt as well as the cardholder´s receipt at the end of the transaction.

    • Select View > Toolbox > Common Controls > WebBrowser
    • Drag and drop two web browsers to the user interface
    • Select View > Toolbox > Common Controls > Label
    • Drag and drop two labels to the user interface in order to identify the webBrowser items
    • Change the attribute "Name" from the left webBrowser to "MerchantReceiptBrowser"
    • Change the attribute "Name" from the right webBrowser to "CardholderReceiptBrowser"
    • Change the attribute "Name" from "label2" to "MerchantReceiptLabel"
    • Change the attribute "text" from "label2" to "Merchant Receipt :"
    • Change the attribute "Name" from "label3" to "CardholderReceiptLabel"
    • Change the attribute "text" from "label3" to "Cardholder Receipt :"

Let's link our user interface with methods!

  1. Referencing the user interface(Form1.cs) in MyClass
  2. In MyClass.cs, create an instance of Form1 called UIClass and initialize it. Instantiate MyClass and add form1 as a parameter for the Class.

    
    class MyClass : Events.Required, Events.Status
    {
        Hapi api;
        Device myDevice;
        private Form1 uIClass;
    
        public MyClass(Form1 form1)
        {
            uIClass = form1;
            InitApi();
        }
        
        [...]
    }
                
  3. Referencing Myclass in Form1.cs and link methods to the user interface
  4. Go to Form1.cs[Design] and double click on the button "Pay Now". By Double Clicking on it you created a method called PayButton_Click. Create a new instance of MyClass called "my" in Form1.cs then, inside the new method PayButton_Click call the Pay() method from MyClass.

    
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace GettingStartedApp
    {
        public partial class Form1 : Form
        {
            MyClass my;
            public Form1()
            {
                InitializeComponent();
                my = new MyClass(this);
            }
            private void PayButton_Click(object sender, EventArgs e)
            {
                my.Pay();
            }
        }
    }
                

    Go back to Form1.cs[Design] and double click on each of the other buttons to automatically generate an OnClick method in Form1.cs. Link each of the buttons to the correct methods in MyClass.cs.

    
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace GettingStartedApp
    {
        public partial class Form1 : Form
        {
            MyClass my;
            public Form1()
            {
                InitializeComponent();
                my = new MyClass(this);
            }
    
            private void PayButton_Click(object sender, EventArgs e)
            {
                my.Pay();
            }
    
            private void ConnectButton_Click(object sender, EventArgs e)
            {
                //my.DiscoverDevices();
                my.DirectConnect();
            }
    
            private void DisconnectButton_Click(object sender, EventArgs e)
            {
                my.Disconnect();
            }
        }
    }
                

Let´s notify the user when the app is connected and ready to send the transaction

  1. Update the ConnectionLabel to notify the user of the connection status
  2. Get the connection status from the method ConnectionStatusChanged in MyClass.cs.

    
    public void ConnectionStatusChanged(ConnectionStatus status, Device device)
    {
        Console.WriteLine("*** ConnectionStatus *** " + status);
        if (status == ConnectionStatus.Connected)
        {
            uIClass.UpdateLabel(true);
        }
        else
        {
            uIClass.UpdateLabel(false);
        }
    }
    
    public void CurrentTransactionStatus(StatusInfo info, Device device)
    {
        //Let also console log the status during the transaction
        Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
    }
                
  3. Create the UpdateLabel method in Form1.cs
  4. 
    public delegate void UpdateConnectionLabel(bool Connected);
    public void UpdateLabel(bool Connected)
    {
        //Only need to check for one of the webbrowsers
        if (ConnectionLabel.InvokeRequired)
        {
            UpdateConnectionLabel d = new UpdateConnectionLabel(UpdateLabel);
            this.Invoke(d, new object[] { Connected });
        }
        else
        {
            if (Connected)
            {
                ConnectionLabel.Text = "Connected";
                ConnectionLabel.BackColor = Color.Green;
            }
            else {
                ConnectionLabel.Text = "Disconnected";
                ConnectionLabel.BackColor = Color.Red;
            }
        }
    }
                

Let´s display the receipts at the end of a transaction!

  1. Fetch the cardholder's and merchant receipts from the method EndOfTransaction in MyClass
  2. At this point all the buttons are connected but we are still missing to display the receipts in the webBrowsers. First, let´s get the receipts from the method EndOfTransaction in myClass.cs.

    
    public void EndOfTransaction(TransactionResult transactionResult, Device device)
    {
        Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
        uIClass.DisplayReceipts(result.MerchantReceipt, result.CustomerReceipt);
    }
                
  3. Create the DisplayReceipts method in form1.cs
  4. 
    public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
    public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
    {
        //Only need to check for one of the webbrowsers
        if (MerchantReceiptBrowser.InvokeRequired)
        {
            UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
            this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
        }
        else
        {
            MerchantReceiptBrowser.DocumentText = MerchantReceipt;
            CardholderReceiptBrowser.DocumentText = CustomerReceipt;
        }
    }
                

Final Result!

Here is how MyClass.cs and Form1.cs must eventually look like :

  1. MyClass.cs :
  2. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
    
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
            private Form1 uIClass;
    
            public MyClass(Form1 form1)
            {
                uIClass = form1;
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
            }
    
            public void DiscoverDevices()
            {
                api.SearchDevices(ConnectionMethod.BLUETOOTH);
            }
    
            public void DirectConnect()
            {
                Device device = new Device("PP0513901435", "68:AA:D2:00:D5:27", "", ConnectionMethod.BLUETOOTH);
                 api.Connect(device);
            }
    
            public bool Pay()
            {
                return api.Sale(new BigInteger(1000), Currency.GBP);
            }
    
            public void Disconnect()
            {
                api.Disconnect();
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                Console.WriteLine("*** ConnectionStatus *** " + status);
                if (status == ConnectionStatus.Connected)
                {
                    uIClass.UpdateLabel(true);
                }
                else
                {
                    uIClass.UpdateLabel(false);
                }
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                //Let's log also the status during the transaction
                Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
                foreach (Device device in devices)
                {
                    if (device.Name != null)
                    {
                        if (device.Name.Equals("PP0513901435"))
                        {
                            this.device = device;
                            api.Connect(this.device);
                        }
                    }
                }
            }
    
            public void EndOfTransaction(TransactionResult result, Device device)
            {
                Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
                uIClass.DisplayReceipts(result.MerchantReceipt, result.CustomerReceipt);
            }
    
            public void SignatureRequired(SignatureRequest signatureRequest, Device device)
            {
                api.SignatureResult(true); // This line means that the cardholder ALWAYS accepts to sign the receipt.
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                //Ignore
            }
        }
    }
                
  3. Form1.cs :
  4. 
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace GettingStartedApp
    {
        public partial class Form1 : Form
        {
            MyClass my;
            public Form1()
            {
                InitializeComponent();
                my = new MyClass(this);
            }
    
            private void PayButton_Click(object sender, EventArgs e)
            {
                my.Pay();
            }
    
            private void ConnectButton_Click(object sender, EventArgs e)
            {
                my.DirectConnect();
            }
    
            private void DisconnectButton_Click(object sender, EventArgs e)
            {
                my.Disconnect();
            }
    
            public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
            public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
            {
                //Only need to check for one of the webbrowsers
                if (MerchantReceiptBrowser.InvokeRequired)
                {
                    UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
                    this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
                }
                else
                {
                    MerchantReceiptBrowser.DocumentText = MerchantReceipt;
                    CardholderReceiptBrowser.DocumentText = CustomerReceipt;
                }
            }
    
            public delegate void UpdateConnectionLabel(bool connected);
    
            public void UpdateLabel(bool Connected)
            {
                //Only need to check for one of the webbrowsers
                if (ConnectionLabel.InvokeRequired)
                {
                    UpdateConnectionLabel d = new UpdateConnectionLabel(UpdateLabel);
                    this.Invoke(d, new object[] { Connected });
                }
                else
                {
                    if (Connected)
                    {
                        ConnectionLabel.Text = "Connected";
                        ConnectionLabel.BackColor = Color.Green;
                    }
                    else {
                        ConnectionLabel.Text = "Disconnected";
                        ConnectionLabel.BackColor = Color.Red;
                    }
                }
            }
    
        }
    }
                

Let's run our program!

Run the program by clicking the "play" button :

  1. Click on "Connect To Card Reader", this can take a little bit of time (10 sec max) due to the fact that we are looking for all the devices around before connecting to a specific one
  2. Click "Pay Now"
  3. Follow the instructions on the card reader
  4. When the transaction is finished, the receipts should be displayed in the webBrowsers
  5. Click on "Disconnect From Card Reader" to stop the connection with the card reader

PAX & Telpo - Cloud Integration

Introduction

This tutorial is guiding you through all the required steps to create a basic payment application for Windows integrated with a PAX or Telpo payment terminal.

The new generation of Handpoint SDK's is designed to make your life easier. Simple and created for humans, it does not require any specific knowledge of the payment industry to be able to start accepting credit/debit card transactions.

At Handpoint we take care of securing every transaction so you don´t have to worry about it while creating your application. We encrypt data from the payment terminal to the bank with our point-to-point encryption solution. Our platform is always up to the latest PCI-DSS security requirements.

Let's start programming!

  1. Create a C# class
  2. Create a new C# class called MyClass and include com.handpoint.api as a dependency :

    
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass
        {
        }
    }
                
  3. Initialize the API
  4. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass
        {
            Hapi api;
    
            public MyClass()
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                string apikey = "This-is-my-api-key-provided-by-Handpoint";
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret, apikey));
                // The api is now initialized. Yay! we've even set default credentials.
                // The shared secret is a unique string shared between the payment terminal and your application, it is a free field.
                // The Api key is a unique key per merchant used to authenticate the terminal against the Cloud.
                // You should replace the API key with the one sent by the Handpoint support team.
            }
        }
    }
                
  5. Implement the mandatory Events(Events.Required) and per recommendation Status events (Events.Status)
  6. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
                        
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
    
            public MyClass()
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                string apikey = "This-is-my-api-key-provided-by-Handpoint"
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret, apikey));
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
              // here you get a list of payment terminals associated with the api key.
            }
    
            public void EndOfTransaction(TransactionResult transactionResult, Device device)
            {
              // The TransactionResult object holds details about the transaction as well as the receipts.
              // Useful information can be accessed through this object like the transaction ID, the amount, etc.
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                // The ConnectionStatus object holds details about the status regarding the connection to the target device.
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                // The StatusInfo object holds details about the status and step taken during the transaction.
            }
    
            public void SignatureRequired(SignatureRequest request, Device device)
            {
                // Ignore for a PAX/Telpo integration. The complete signature capture process
                // is already handled in the sdk, a dialog will prompt the user for a signature if required.
                // If a signature was entered, it should be printed on the receipts.
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                // Ignore, legacy event, will be deleted in future version.
            }
        }
    }
                
  7. Add a method to list the terminals of your merchant and connect to one of them
  8. Ensure that the card reader and PC are correctly paired via Cloud connection.

    
    public void DiscoverDevices()
    {
        // This triggers the search for all the cloud devices related to your Api Key.
        api.SearchDevices(ConnectionMethod.CLOUD);
    }
    
    public void DeviceDiscoveryFinished(List<Device> devices)
    {
        foreach (Device device in devices)
        {
            if (device.Name != null)
            {
                if (device.Name.Equals("9822032398-PAXA920"))
                // Put the name of your device, it is the composition of: serial number - device model.
                // Example for a PAX A920 device: serial_number - model -> 9822032398-PAXA920
                {
                    this.myDevice = device;
                  //We'll remember the device for this session, it is nice if you would do that too
                  api.Connect(this.myDevice);
                  //Connection to the device is handled automatically by the api
                }
            }
        }
    }
                
  9. Add a method to connect directly to the payment terminal
  10. Instead of discovering terminals you can also connect directly to one of them:

    
    public void DirectConnect()
    {
        Device device = new Device("CloudDevice", "9822032398-PAXA920", "", ConnectionMethod.CLOUD);
        // new Device("name", "address", "port (optional)", ConnectionMethod);
        // The address always has to be written in UPPER CASE
        // It is the composition of the serial number and model ot the payment terminal.
        // Example for a PAX A920 device: serial_number - model  -> 9822032398-PAXA920
        api.Connect(device);
    }
                
  11. Add a method to take payments
  12. 
    public bool Pay()
    {
        return api.Sale(new BigInteger(1000), Currency.EUR);
        // Let´s start our first transaction for 10 euros
        // The amount should always be in the minor unit of the currency
    }
                
  13. Add a method to disconnect from the card reader
  14. 
    public void Disconnect()
    {
        api.Disconnect();
    }
                
  15. Eventually, MyClass.cs must look like this after implementing all the necessary methods :
  16. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
    
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
    
            public MyClass(Form1 form1)
            {
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                string apikey = "This-is-my-api-key-provided-by-Handpoint"
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret, apikey));
            }
    
            public void DiscoverDevices()
            {
                api.SearchDevices(ConnectionMethod.CLOUD);
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
                foreach (Device device in devices)
                {
                    if (device.Name != null)
                    {
                        if (device.Name.Equals("9822032398-PAXA920"))
                        {
                            this.myDevice = device;
                            api.Connect(this.myDevice);
                        }
                    }
                }
            }
    
            public void DirectConnect()
            {
                Device device = new Device("CloudDevice", "9822032398-PAXA920", "", ConnectionMethod.CLOUD);
                api.Connect(device);
            }
    
            public bool Pay()
            {
                return api.Sale(new BigInteger(1000), Currency.EUR);
            }
    
            public void Disconnect()
            {
                api.Disconnect();
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                Console.WriteLine("*** ConnectionStatus *** " + status);
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
            }
    
            public void EndOfTransaction(TransactionResult result, Device device)
            {
                Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                //Ignore
            }
    
            public void SignatureRequired(SignatureRequest request, Device device)
            {
                //Ignore
            }
        }
    }
                

Let's create a User Interface!

  1. Create buttons and labels
    • Go to your user interface (usually Form1.cs[Design])
    • Select View > Toolbox
    • In the toolbox, under “Common Controls” drag and drop 3 button items to the user interface
    • Select "button1" > Right-Click > Properties
    • Change the attribute "Name" from "button1" to "PayButton"
    • Change the attribute "text" from "button1" to "Pay Now"
    • Change the attribute "Name" from "button2" to "ConnectButton"
    • Change the attribute "text" from "button2" to "Connect To Card reader"
    • Change the attribute "Name" from "button3" to "DisconnectButton"
    • Change the attribute "text" from "button3" to "Disconnect From Card Reader"
    • Select View > Toolbox > Common Controls > Label
    • Change the attribute "Name" from "label1" to "ConnectionLabel"
    • Change the attribute "text" from "label1" to "Disconnected"
    • Change the attribute "backColor" from "label1" to "Red"

  2. Create WebBrowsers
  3. Now that we have our 3 buttons, let´s create two webBrowsers items to display the merchant receipt as well as the cardholder´s receipt at the end of the transaction.

    • Select View > Toolbox > Common Controls > WebBrowser
    • Drag and drop two web browsers to the user interface
    • Select View > Toolbox > Common Controls > Label
    • Drag and drop two labels to the user interface in order to identify the webBrowser items
    • Change the attribute "Name" from the left webBrowser to "MerchantReceiptBrowser"
    • Change the attribute "Name" from the right webBrowser to "CardholderReceiptBrowser"
    • Change the attribute "Name" from "label2" to "MerchantReceiptLabel"
    • Change the attribute "text" from "label2" to "Merchant Receipt :"
    • Change the attribute "Name" from "label3" to "CardholderReceiptLabel"
    • Change the attribute "text" from "label3" to "Cardholder Receipt :"

Let's link our user interface with methods!

  1. Referencing the user interface(Form1.cs) in MyClass
  2. In MyClass.cs, create an instance of Form1 called UIClass and initialize it. Instantiate MyClass and add form1 as a parameter for the Class.

    
    class MyClass : Events.Required, Events.Status
    {
        Hapi api;
        Device myDevice;
        private Form1 uIClass;
    
        public MyClass(Form1 form1)
        {
            uIClass = form1;
            InitApi();
        }
        
        [...]
    }
                
  3. Referencing Myclass in Form1.cs and link methods to the user interface
  4. Go to Form1.cs[Design] and double click on the button "Pay Now". By Double Clicking on it you created a method called PayButton_Click. Create a new instance of MyClass called "my" in Form1.cs then, inside the new method PayButton_Click call the Pay() method from MyClass.

    
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace GettingStartedApp
    {
        public partial class Form1 : Form
        {
            MyClass my;
            public Form1()
            {
                InitializeComponent();
                my = new MyClass(this);
            }
            private void PayButton_Click(object sender, EventArgs e)
            {
                my.Pay();
            }
        }
    }
                

    Go back to Form1.cs[Design] and double click on each of the other buttons to automatically generate an OnClick method in Form1.cs. Link each of the buttons to the correct methods in MyClass.cs.

    
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace GettingStartedApp
    {
        public partial class Form1 : Form
        {
            MyClass my;
            public Form1()
            {
                InitializeComponent();
                my = new MyClass(this);
            }
    
            private void PayButton_Click(object sender, EventArgs e)
            {
                my.Pay();
            }
    
            private void ConnectButton_Click(object sender, EventArgs e)
            {
                //my.DiscoverDevices();
                my.DirectConnect();
            }
    
            private void DisconnectButton_Click(object sender, EventArgs e)
            {
                my.Disconnect();
            }
        }
    }
                

Let´s notify the user when the app is connected and ready to send the transaction

  1. Update the ConnectionLabel to notify the user of the connection status
  2. Get the connection status from the method ConnectionStatusChanged in MyClass.cs.

    
    public void ConnectionStatusChanged(ConnectionStatus status, Device device)
    {
        Console.WriteLine("*** ConnectionStatus *** " + status);
        if (status == ConnectionStatus.Connected)
        {
            uIClass.UpdateLabel(true);
        }
        else
        {
            uIClass.UpdateLabel(false);
        }
    }
    
    public void CurrentTransactionStatus(StatusInfo info, Device device)
    {
        //Let also console log the status during the transaction
        Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
    }
                
  3. Create the UpdateLabel method in Form1.cs
  4. 
    public delegate void UpdateConnectionLabel(bool Connected);
    public void UpdateLabel(bool Connected)
    {
        //Only need to check for one of the webbrowsers
        if (ConnectionLabel.InvokeRequired)
        {
            UpdateConnectionLabel d = new UpdateConnectionLabel(UpdateLabel);
            this.Invoke(d, new object[] { Connected });
        }
        else
        {
            if (Connected)
            {
                ConnectionLabel.Text = "Connected";
                ConnectionLabel.BackColor = Color.Green;
            }
            else {
                ConnectionLabel.Text = "Disconnected";
                ConnectionLabel.BackColor = Color.Red;
            }
        }
    }
                

Let´s display the receipts at the end of a transaction!

  1. Fetch the cardholder's and merchant receipts from the method EndOfTransaction in MyClass
  2. At this point all the buttons are connected but we are still missing to display the receipts in the webBrowsers. First, let´s get the receipts from the method EndOfTransaction in myClass.cs.

    
    public void EndOfTransaction(TransactionResult transactionResult, Device device)
    {
        Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
        uIClass.DisplayReceipts(result.MerchantReceipt, result.CustomerReceipt);
    }
                
  3. Create the DisplayReceipts method in Form1.cs
  4. 
    public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
    public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
    {
        //Only need to check for one of the webbrowsers
        if (MerchantReceiptBrowser.InvokeRequired)
        {
            UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
            this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
        }
        else
        {
            MerchantReceiptBrowser.DocumentText = MerchantReceipt;
            CardholderReceiptBrowser.DocumentText = CustomerReceipt;
        }
    }
                

Final Result!

Here is how MyClass.cs and Form1.cs must eventually look like:

  1. MyClass.cs :
  2. 
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using com.handpoint.api;
    
    namespace GettingStartedApp
    {
        class MyClass : Events.Required, Events.Status
        {
            Hapi api;
            Device myDevice;
            private Form1 uIClass;
    
            public MyClass(Form1 form1)
            {
                uIClass = form1;
                InitApi();
            }
    
            public void InitApi()
            {
                string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                string apikey = "This-is-my-api-key-provided-by-Handpoint"
                api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret, apikey));
            }
    
            public void DiscoverDevices()
            {
                api.SearchDevices(ConnectionMethod.CLOUD);
            }
    
            public void DirectConnect()
            {
                Device device = new Device("CloudDevice", "0821032398-PAXA920", "", ConnectionMethod.CLOUD);
                api.Connect(device);
            }
    
            public bool Pay()
            {
                return api.Sale(new BigInteger(1000), Currency.EUR);
            }
    
            public void Disconnect()
            {
                api.Disconnect();
            }
    
            public void ConnectionStatusChanged(ConnectionStatus status, Device device)
            {
                Console.WriteLine("***ConnectionStatus*** " + status);
                if (status == ConnectionStatus.Connected)
                {
                    uIClass.UpdateLabel(true);
                }
                else
                {
                    uIClass.UpdateLabel(false);
                }
            }
    
            public void CurrentTransactionStatus(StatusInfo info, Device device)
            {
                //Let's log also the status during the transaction
                Console.WriteLine("*** CurrentTransactionStatus *** " + info.Status.ToString());
            }
    
            public void DeviceDiscoveryFinished(List<Device> devices)
            {
                foreach (Device device in devices)
                {
                    if (device.Name != null)
                    {
                        if (device.Name.Equals("0821032398-PAXA920"))
                        {
                            this.myDevice = device;
                            api.Connect(this.myDevice);
                        }
                    }
                }
            }
    
            public void EndOfTransaction(TransactionResult result, Device device)
            {
                Console.WriteLine("*** EndOfTransaction *** " + result.ToJSON());
                uIClass.DisplayReceipts(result.MerchantReceipt, result.CustomerReceipt);
            }
    
            public void HardwareStatusChanged(HardwareStatus status, ConnectionMethod hardware)
            {
                //Ignore
            }
    
            public void SignatureRequired(SignatureRequest request, Device device)
            {
                //Ignore
            }
        }
    }
                
  3. Form1.cs :
  4. 
        using System;
        using System.Drawing;
        using System.Windows.Forms;
        
        namespace GettingStartedApp
        {
            public partial class Form1 : Form
            {
                MyClass my;
                public Form1()
                {
                    InitializeComponent();
                    my = new MyClass(this);
                }
        
                private void PayButton_Click(object sender, EventArgs e)
                {
                    my.Pay();
                }
        
                private void ConnectButton_Click(object sender, EventArgs e)
                {
                    my.DirectConnect();
                }
        
                private void DisconnectButton_Click(object sender, EventArgs e)
                {
                    my.Disconnect();
                }
        
                public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
                public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
                {
                    //Only need to check for one of the webbrowsers
                    if (MerchantReceiptBrowser.InvokeRequired)
                    {
                        UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
                        this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
                    }
                    else
                    {
                        MerchantReceiptBrowser.DocumentText = MerchantReceipt;
                        CardholderReceiptBrowser.DocumentText = CustomerReceipt;
                    }
                }
        
                public delegate void UpdateConnectionLabel(bool connected);
        
                public void UpdateLabel(bool Connected)
                {
                    //Only need to check for one of the webbrowsers
                    if (ConnectionLabel.InvokeRequired)
                    {
                        UpdateConnectionLabel d = new UpdateConnectionLabel(UpdateLabel);
                        this.Invoke(d, new object[] { Connected });
                    }
                    else
                    {
                        if (Connected)
                        {
                            ConnectionLabel.Text = "Connected";
                            ConnectionLabel.BackColor = Color.Green;
                        }
                        else {
                            ConnectionLabel.Text = "Disconnected";
                            ConnectionLabel.BackColor = Color.Red;
                        }
                    }
                }
        
            }
        }
                

Let's run our program!

Run the program by clicking the "play" button :

  1. Click on "Connect To Card Reader", this can take a little bit of time (10 sec max) due to the fact that we are looking for all the devices around before connecting to a specific one
  2. Click "Pay Now"
  3. Follow the instructions on the card reader
  4. When the transaction is finished, the receipts should be displayed in the webBrowsers
  5. Click on "Disconnect From Card Reader" to stop the connection with the card reader

Terminal Simulator Integration

Introduction

This tutorial is guiding you through all the steps to create a basic payment application for Windows using a card reader simulator. The simulator only has limited capabilities and we highly recommend that you order a development kit if you want to carry a full integration. The development kit contains a card reader as well as a test card and will allow you to test your integration from end to end.

The new generation of Handpoint SDK's is designed to make your life easier. Simple and created for humans, it does not require any specific knowledge of the payment industry to be able to start accepting credit/debit card transactions.

At Handpoint we take care of securing every transaction so you don´t have to worry about it while creating your application. We encrypt data from the payment terminal to the bank with our point-to-point encryption solution. Our platform is always up to the latest PCI-DSS security requirements.

Connecting to the simulator

The SDK offers a method in which you will need to specify the card reader to be used:


hapi.useDevice(new Device("Name", "Port", "Address", ConnectionMethod.****))
                

Simply set the ConnectionMethod to Simulator, i.e. ConnectionMethod.Simulator. The SDK does the rest. You don't need to search via bluetooth for surrounding card readers when using the simulator.


hapi.useDevice(new Device("Name", "Port", "Address", ConnectionMethod.Simulator))
            

Controlling responses

The simulator mimics the card reader as much as possible regarding information flow from the SDK interface to your application. It will return all the transaction statuses, transaction results and receipts.

Results of a transaction are controlled by the amount sent into the sale function:
The 3rd position from the right sets the desired financial status, 0 = Authorized and 1 = Declined.
The 4th position from the right sets the desired verification method, 0 = Signature and 1 = PIN.

hapi.Sale(X10XX, Currency.GBP); // amount = X 10 XX - where X represents an integer [0;9]

  • X 00 XX = Signature authorized
  • X 01 XX = Signature declined
  • X 10 XX = Pin authorized
  • X 11 XX = Pin declined

Let's start programming!

  1. Create a C# class
  2. Create a new C# class called MyClass and include com.handpoint.api as a dependency :

    
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using com.handpoint.api;
    
        namespace GettingStartedWithSimulator
        {
            class MyClass
            {
            }
        }
                        
  3. Initialize the API
  4. 
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using com.handpoint.api;
    
        namespace GettingStartedWithSimulator
        {
            class MyClass
            {
                Hapi api;
    
                public MyClass()
                {
                    InitApi();
                }
                public void InitApi()
                {
                    string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                    api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
                    // The api is now initialized. Yay! we've even set a default shared secret!
                    // The shared secret is a unique string shared between the card reader and your mobile application.
                    // It prevents other people to connect to your card reader.
                }
            }
        }
                        
  5. Implement the mandatory Events(Events.Required)
  6. 
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using com.handpoint.api;
    
        namespace GettingStartedWithSimulator
        {
            class MyClass : Events.Required
            {
                Hapi api;
    
                public MyClass()
                {
                    InitApi();
                }
    
                public void InitApi()
                {
                    string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                    api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
                    // The api is now initialized. Yay! we've even set a default shared secret!
                    // The shared secret is a unique string shared between the card reader and your mobile application
                    // It prevents other people to connect to your card reader
                }
    
                public void DeviceDiscoveryFinished(List<Device> devices)
                {
                    // Only needed when using a payment terminal
                    //here you get a list of Bluetooth payment terminals paired with your PC
                    // You can also get a list of serial / USB payment terminals attached to your computer
    
                }
    
                public void SignatureRequired(SignatureRequest signatureRequest, Device device)
                {
                    // You'll be notified here if a sale process needs a signature verification
                    // A signature verification is needed if the cardholder uses an MSR or a chip & signature card
                    // This method will not be invoked if a transaction is made with a Chip & PIN card
    
                    api.SignatureResult(true); // This line means that the cardholder ALWAYS accepts to sign the receipt
                    // A specific line will be displayed on the merchant receipt for the cardholder to be able to sign it
                }
    
                public void EndOfTransaction(TransactionResult transactionResult, Device device)
                {
                    // The object TransactionResult holds the different receipts
                    // Other information can be accessed through this object like the transaction ID, the amount...
                }
            }
        }
                        
  7. Add a method to connect to the simulator
  8. 
        public void Connect()
        {
            Device device = new Device("Name", "Address", "Port", ConnectionMethod.SIMULATOR);
            api.UseDevice(device);
        }
                        
  9. Add a method to take payments with the simulator
  10. The simulator mimics the card reader as much as possible regarding the information flow from the SDK interface to your application. The results of the transaction (declined, authorized) and the type of verification method (PIN, signature) will depend on the amount used.

    You can get different responses from the simulator by setting different values for the amount parameter, e.g. for a Sale function :

    
        api.Sale(X10XX, Currency.GBP); // amount = X 10 XX - where X represents an integer [0;9]
                        

    Amount Values

    • X00XX = Signature authorized
    • X01XX = Signature declined
    • X10XX = PIN authorized
    • X11XX = PIN declined

    The 3rd number from right sets desired financial status, Authorized or Declined. Default status is Authorized.
    The 4th number from right sets desired verification method, Signature or PIN. Default method is Signature.

    Let´s add 4 methods to MyClass in order to represent the 4 cases above :

    
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using com.handpoint.api;
    
        namespace GettingStartedWithSimulator
        {
            class MyClass : Events.Required
            {
                Hapi api;
    
                public MyClass()
                {
                    InitApi();
                }
    
                public void InitApi()
                {
                    string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                    api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
                    // The api is now initialized. Yay! we've even set a default shared secret!
                    // The shared secret is a unique string shared between the card reader and your mobile application.
                    // It prevents other people to connect to your card reader.
                }
    
                public void DeviceDiscoveryFinished(List <Device> devices)
                {
                     // Only needed when using a payment terminal
                     //Here you get a list of Bluetooth payment terminals paired with your PC
                     // You can also get a list of serial / USB payment terminals attached to your computer
    
                }
    
                public void Connect()
                {
                    Device device = new Device("Name", "Address", "Port", ConnectionMethod.SIMULATOR);
                    api.UseDevice(device);
                }
    
                public bool PayWithSignatureAuthorized()
                {
                    return api.Sale(new BigInteger("10000"), Currency.GBP);
                    // amount X00XX where X represents an integer [0;9] --> Signature authorized
                }
    
                public bool PayWithSignatureDeclined()
                {
                    return api.Sale(new BigInteger("10100"), Currency.GBP);
                    // amount X01XX where X represents an integer [0;9] --> Signature declined
                }
    
                public bool PayWithPinAuthorized()
                {
                    return api.Sale(new BigInteger("11000"), Currency.GBP);
                    // amount X10XX where X represents an integer [0;9] --> PIN authorized
                }
                public bool PayWithPinDeclined()
                {
                    return api.Sale(new BigInteger("11100"), Currency.GBP);
                    // amount X11XX where X represents an integer [0;9] --> PIN declined
                }
    
                public void SignatureRequired(SignatureRequest signatureRequest, Device device)
                {
                    // You'll be notified here if a sale process needs a signature verification
                    // A signature verification is needed if the cardholder uses an MSR or a chip & signature card
                    // This method will not be invoked if a transaction is made with a Chip & PIN card
    
                    api.SignatureResult(true); // This line means that the cardholder ALWAYS accepts to sign the receipt.
                    // A specific line will be displayed on the merchant receipt for the cardholder to be able to sign it
                }
    
                public void EndOfTransaction(TransactionResult transactionResult, Device device)
                {
                    // The object TransactionResult stores the different receipts
                    // Other information can be accessed through this object like the transaction ID, the amount...
                }
            }
        }
                        

Let's create a User Interface!

  1. Create buttons
    • Go to your user interface (usually Form1.cs[Design])
    • Select View > Toolbox
    • In the toolbox, under “Common Controls” drag and drop 5 button items to the user interface
    • Select "button1" > Right-Click > Properties
    • Change the attribute "Name" from "button1" to "ConnectToSimulator"
    • Change the attribute "text" from "button1" to "Connect To Simulator"
    • Change the attribute "Name" from "button2" to "PayWithSignatureAuthorized"
    • Change the attribute "text" from "button2" to "Pay With Signature Authorized"
    • Change the attribute "Name" from "button3" to "PayWithSignatureDeclined"
    • Change the attribute "text" from "button3" to "Pay With Signature Declined"
    • Change the attribute "Name" from "button4" to "PayWithPinAuthorized"
    • Change the attribute "text" from "button4" to "Pay With Pin Authorized"
    • Change the attribute "Name" from "button5" to "PayWithPinDeclined"
    • Change the attribute "text" from "button5" to "Pay With Pin Declined"

  2. Create WebBrowsers
  3. Now that we have our 5 buttons let´s create two webBrowsers items to display the merchant receipt as well as the cardholder´s receipt at the end of the transaction.

    • Select View > Toolbox > Common Controls > WebBrowser
    • Drag and drop two web browsers to the user interface
    • Select View > Toolbox > Common Controls > Label
    • Drag and drop two labels to the user interface in order to identify the webBrowser items
    • Change the attribute "Name" from the left webBrowser to "MerchantReceiptBrowser"
    • Change the attribute "Name" from the right webBrowser to "CardholderReceiptBrowser"
    • Change the attribute "Name" from "label1" to "MerchantReceiptLabel"
    • Change the attribute "text" from "label1" to "Merchant Receipt :"
    • Change the attribute "Name" from "label2" to "CardholderReceiptLabel"
    • Change the attribute "text" from "label2" to "Cardholder Receipt :"

Let's link our user interface with methods!

  1. Referencing the user interface(Form1.cs) in MyClass
  2. In MyClass.cs, create an instance of Form1 called UIClass and initialize it. Instantiate MyClass and add form1 as a parameter for the Class.

    
        class MyClass : Events.Required
            {
                Hapi api;
                private Form1 UIClass;
    
                public MyClass(Form1 form1)
                {
                    InitApi();
                    UIClass = form1;
                }
                        
  3. Referencing Myclass in Form1.cs and link methods to the user interface
  4. Go to Form1.cs[Design] and double click on the button "Connect To Simulator". By Double Clicking on the "Connect To Simulator" button you created a method called ConnectToSimulator_Click. Create a new instance of MyClass called "my" in Form1.cs then, inside the new method ConnectToSimulator_Click call the Connect() method from MyClass.

    
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        namespace GettingStartedWithSimulator
        {
            public partial class Form1 : Form
            {
                MyClass my;
    
                public Form1()
                {
                    InitializeComponent();
                    my = new MyClass(this);
                }
                private void ConnectToSimulator_Click(object sender, EventArgs e)
                {
                    my.Connect();
                }
            }
        }
                        

    Go back to Form1.cs[Design] and double click on each of the other buttons to automatically generate an OnClick method in Form1.cs. Link each of the buttons to the correct methods in MyClass.cs.

    
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        namespace GettingStartedWithSimulator
        {
            public partial class Form1 : Form
            {
                MyClass my;
                public Form1()
                {
                    InitializeComponent();
                    my = new MyClass(this);
                }
                private void ConnectToSimulator_Click(object sender, EventArgs e)
                {
                    my.Connect();
                }
                private void PayWithSignatureAuthorized_Click(object sender, EventArgs e)
                {
                    my.PayWithSignatureAuthorized();
                }
                private void PayWithSignatureDeclined_Click(object sender, EventArgs e)
                {
                    my.PayWithSignatureDeclined();
                }
                private void PayWithPinAuthorized_Click(object sender, EventArgs e)
                {
                    my.PayWithPinAuthorized();
                }
                private void PayWithPinDeclined_Click(object sender, EventArgs e)
                {
                    my.PayWithPinDeclined();
                }
            }
        }
                        

Let´s display the receipts at the end of a transaction!

  1. Fetch the cardholder's and merchant receipts from the method EndOfTransaction in MyClass
  2. At this point all the buttons are connected but we are still missing to display the receipts in the webBrowsers. First, let´s get the receipts from the method EndOfTransaction in myClass.cs.

    
        public void EndOfTransaction(TransactionResult transactionResult, Device device)
                {
                    UIClass.DisplayReceipts(transactionResult.MerchantReceipt, transactionResult.CustomerReceipt);
                }
                        
  3. Create the DisplayReceipts method in form1.cs
  4. 
        public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
                public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
                {
                    //Only need to check for one of the webBrowsers
                    if (MerchantReceiptBrowser.InvokeRequired)
                    {
                        UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
                        this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
                    }
                    else
                    {
                        MerchantReceiptBrowser.DocumentText = MerchantReceipt;
                        CardholderReceiptBrowser.DocumentText = CustomerReceipt;
                    }
                }
                        

Final Result!

Here is how MyClass.cs and Form1.cs must eventually look like :

  1. MyClass.cs :
  2. 
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using com.handpoint.api;
        namespace GettingStartedWithSimulator
        {
            class MyClass : Events.Required
            {
                Hapi api;
                private Form1 UIClass;
                public MyClass(Form1 form1)
                {
                    InitApi();
                    UIClass = form1;
                }
    
                public void InitApi()
                {
                    string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
                    api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
                    // The api is now initialized. Yay! we've even set a default shared secret!
                    // The shared secret is a unique string shared between the card reader and your mobile application.
                    // It prevents other people to connect to your card reader.
                }
    
                public void DeviceDiscoveryFinished(List<Device> devices)
                {
                    // Only needed when using a payment terminal
                    //Here you get a list of Bluetooth payment terminals paired with your PC
                    // You can also get a list of serial / USB payment terminals attached to your computer
    
                }
    
                public void Connect()
                {
                    Device device = new Device("Name", "Address", "Port", ConnectionMethod.SIMULATOR);
                    api.UseDevice(device);
                }
    
                public bool PayWithSignatureAuthorized()
                {
                    return api.Sale(new BigInteger("10000"), Currency.GBP);
                    // amount X00XX where X represents an integer [0;9] --> Signature authorized
                }
    
                public bool PayWithSignatureDeclined()
                {
                    return api.Sale(new BigInteger("10100"), Currency.GBP);
                    // amount X01XX where X represents an integer [0;9] --> Signature declined
                }
    
                public bool PayWithPinAuthorized()
                {
                    return api.Sale(new BigInteger("11000"), Currency.GBP);
                    // amount X10XX where X represents an integer [0;9] --> PIN authorized
                }
                public bool PayWithPinDeclined()
                {
                    return api.Sale(new BigInteger("11100"), Currency.GBP);
                    // amount X11XX where X represents an integer [0;9] --> PIN declined
                }
    
                public void SignatureRequired(SignatureRequest signatureRequest, Device device)
                {
                    // You'll be notified here if a sale process needs a signature verification
                    // A signature verification is needed if the cardholder uses an MSR or a chip & signature card
                    // This method will not be invoked if a transaction is made with a Chip & PIN card
    
    
                    api.SignatureResult(true); // This line means that the cardholder ALWAYS accepts to sign the receipt.
                    // A specific line will be displayed on the merchant receipt for the cardholder to be able to sign it
                }
    
                public void EndOfTransaction(TransactionResult transactionResult, Device device)
                {
                    UIClass.DisplayReceipts(transactionResult.MerchantReceipt, transactionResult.CustomerReceipt);
                }
            }
        }
                        
  3. Form1.cs :
  4. 
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        namespace GettingStartedWithSimulator
        {
            public partial class Form1 : Form
            {
                MyClass my;
                public Form1()
                {
                    InitializeComponent();
                    my = new MyClass(this);
                }
                private void ConnectToSimulator_Click(object sender, EventArgs e)
                {
                    my.Connect();
                }
                private void PayWithSignatureAuthorized_Click(object sender, EventArgs e)
                {
                    my.PayWithSignatureAuthorized();
                }
                private void PayWithSignatureDeclined_Click(object sender, EventArgs e)
                {
                    my.PayWithSignatureDeclined();
                }
                private void PayWithPinAuthorized_Click(object sender, EventArgs e)
                {
                    my.PayWithPinAuthorized();
                }
                private void PayWithPinDeclined_Click(object sender, EventArgs e)
                {
                    my.PayWithPinDeclined();
                }
    
                public delegate void UpdateReceiptsCallback(string MerchantReceipt, string CustomerReceipt);
                public void DisplayReceipts(string MerchantReceipt, string CustomerReceipt)
                {
                    //Only need to check for one of the webbrowsers
                    if (MerchantReceiptBrowser.InvokeRequired)
                    {
                        UpdateReceiptsCallback d = new UpdateReceiptsCallback(DisplayReceipts);
                        this.Invoke(d, new object[] { MerchantReceipt, CustomerReceipt });
                    }
                    else
                    {
                        MerchantReceiptBrowser.DocumentText = MerchantReceipt;
                        CardholderReceiptBrowser.DocumentText = CustomerReceipt;
                    }
                }
            }
        }
                        

Let's run our program!

Run the program by clicking the "play" button, click on "Connect to simulator" and then Click on one of the payment types available and have a look at the receipts! Voila!

Transactions

Sale

method Available since 1.1.7

Sale

A sale initiates a payment operation to the card reader. In it's simplest form you only have to pass the amount and currency but it also accepts a map with extra parameters.

Parameters

Parameter Notes
amount *
BigInteger
Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency *
Currency
Currency of the charge
map
Map
A map including extra optional transaction parameters.
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry')
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiate a sale for 10.00 Pounds
api.Sale(new BigInteger(1000),Currency.GBP);

Sale And Tokenize Card

method Available since 2.1.0

SaleAndTokenizeCard

A sale that returns the tokenized version of the card used if successful. (not available for all acquirers, please check with Handpoint to know if tokenization is supported for your acquirer of choice)

Parameters

Parameter Notes
amount *
BigInteger
Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency *
Currency
Currency of the charge
map
Map
A map including extra optional transaction parameters.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry').
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiate a sale for 10.00 in Great British Pounds
api.SaleAndTokenizeCard(new BigInteger("1000"),Currency.GBP);

Sale Reversal

method Available since 1.1.7

SaleReversal

A sale Reversal, also called sale VOID allows the user to reverse a previous sale operation. This operation reverts (if possible) a specific sale identified with a transaction id. In it's simplest form you only have to pass the amount, currency and originalTransactionID but it also accepts a map with extra parameters. Note that transactions can only be reversed within the same day as the transaction was made.

Parameters

Parameter Notes
amount *
BigInteger
Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency *
Currency
Currency of the charge
originalTransactionID *
String
As received from the card reader (EFTTransactionID)
map
Map
A map including extra optional transaction parameters.
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry')
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiate a reversal for 10.00 Pounds
api.SaleReversal(new BigInteger(1000),Currency.GBP,"00000000-0000-0000-0000-000000000000");

Refund

method Available since 3.1.0

Refund

A refund initiates a refund operation to the card reader. This operation moves funds from the merchant account to the cardholder´s credit card. In it's simplest form you only have to pass the amount and currency but it also accepts a map with extra parameters.

Parameters

Parameter Notes
amount *
BigInteger
Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency *
Currency
Currency of the charge
originalTransactionID
String
References the ID of a previous sale. If present, forces the refund to use the same card as the one in the original sale.
map
Map
A map including extra optional transaction parameters.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry')
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiate a refund for 10.00 in Great British Pounds
api.Refund(new BigInteger(1000),Currency.GBP,"00000000-0000-0000-0000-000000000000");

Refund reversal

method Available since 1.1.7

RefundReversal

A Refund Reversal, also called Refund VOID allows the merchant to reverse a previous refund operation. This operation reverts (if possible) a specific refund identified with a transaction id. In it's simplest form you only have to pass the amount, currency and originalTransactionID but it also accepts a map with extra parameters. Note that transactions can only be reversed within the same day as the transaction was made.

Parameters

Parameter Notes
amount *
BigInteger
Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency *
Currency
Currency of the charge
originalTransactionID *
String
As received from the card reader (EFTTransactionID)
map
Map
A map including extra optional transaction parameters.
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry')
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiate a refund reversal for 10.00 in Great British Pounds
api.RefundReversal(new BigInteger(1000),Currency.GBP,"00000000-0000-0000-0000-000000000000");

Print Receipt

method Available since 3.0.0

PrintReceipt

Print on demand functionality allowing the merchant to print any HTML formatted receipt. Available for CLOUD connections

Parameters

Parameter Notes
receipt *
String
HTML receipt or url to locate the receipt, it can be found in the response of a financial operation, in the fields merchantReceipt or customerReceipt. The receipt must match the following HTML Print Format


Returns

Boolean
true if the receipt was sent to the printer, false otherwise

Code example

// string validReceipt = '...';
bool success = api.PrintReceipt(validReceipt);

Signature result

method Available since 3.0.0

SignatureResult

A signatureRequired event is invoked during transaction when signature verification is needed (f.ex when payment is done with a magstripe card). The merchant is required to ask the cardholder for signature and approve (or disapprove) the signature. signatureResult tells the card reader if the signature was approved by passing true in the method. To disapprove then false is passed. Integrations with PAX or Telpo devices DO NOT need the implementation of this event.

Parameters

Parameter Notes
accepted *
Boolean
pass true if merchant accepts customer signature
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry')
endOfTransaction
Invoked when the card reader finishes processing the transaction

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Receiving a SignatureRequest from the SDK.
public void SignatureRequired(SignatureRequest signatureRequest, Device device)
{
    //If you accept the signature
    api.SignatureResult(true);
}

Tip Adjustment

method Available since 1.3.1

TipAdjustment

A tip adjustment operation allows merchants to adjust the tip amount of a sale transaction before the batch of transactions is settled by the processor at the end of the day.
Note: This functionality is only available for the restaurant industry in the United States and the processors currently supporting this functionality are TSYS and VANTIV.

Parameters

Parameter Notes
tipAmount *
BigInteger
Tip amount added to the original (base) transaction amount - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
originalTransactionID *
String
Unique id of the original sale transaction as received from the card reader (EFTTransactionID)


Returns

FinancialStatus

Result of the tip adjustment transaction, this is an asynchronous method that returns a task called <FinancialStatus>, the possible values are :

- FinancialStatus.AUTHORISED (tip adjustment approved by the processor)
- FinancialStatus.FAILED (system error or timeout)
- FinancialStatus.DECLINED (tip adjustment declined by the processor)

If two tip adjustments are sent for the same sale transaction, the second tip adjustment will override the first one. In case the transaction fails (not declined) we recommend that you prompt the user of the POS to retry the adjustment.

Code example

//Initiate a tip adjustment for $10.00
Task<FinancialStatus> result = hapi.TipAdjustment(BigInteger.Parse("1000"), "2bc23910-c3b3-11e6-9e62-07b2a5f091ec");
FinancialStatus status = result.Result;
if (status != FinancialStatus.FAILED)
{
	if (status == FinancialStatus.AUTHORISED)
	{
		//Success!
	}
	else
	{
		//Declined
	}
}

Tokenize Card

method Available since 2.3.0

TokenizeCard

Returns the tokenized version of the card used if successful (not available for all acquirers, please check with Handpoint to know if tokenization is supported for your acquirer of choice).

Parameters

Parameter Notes
map
Map
A map including extra optional transaction parameters.


Events invoked

currentTransactionStatus
Invoked during a transaction, it fetches statuses coming from the card reader (ex : 'waiting for card' or 'waiting for PIN entry').
signatureRequired
Invoked if card verification requires signature.
endOfTransaction
Invoked when the card reader finishes processing the transaction.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Initiates a card tokenization operation.
api.TokenizeCard();

Device management

Connect

method Available since 3.0.0

Connect

Configures the device as the preferred device and tries to connect to it. Everytime a new connection is started the SDK will make 3 attempts to reestablish the connection. If those attempts fail, the connection is considered dead.

Parameters

Parameter Notes
device *
Device
This parameter specifies to the system which device you want to use for the operations.


Events invoked

ConnectionStatusChanged
Each time the card reader state changes (ex : going from Connected to Disconnected) the ConnectionStatusChanged event is called. It causes the connection manager to invoke this event with the appropriate information.

Returns

Boolean
true if the operation was successful.

Code example

//Connect to a CLOUD device
Device device = new Device("CloudDevice", "9822032398-PAXA920", "", ConnectionMethod.Cloud);
// The address is the composition of the serial number and model ot the target device.
//Example for a PAX A920 device: serial_number - model  -> 9822032398-PAXA920
api.UseDevice(device);

//Connect to a device
Device device = new Device("CardReader7", "08:00:69:02:01:FC", "1", ConnectionMethod.BLUETOOTH);
api.UseDevice(device);

Disconnect

method Available since 1.1.7

Disconnect

Disconnect will stop the active connection (and reconnection process). Please note that the method does NOT ignore the current state of the card reader. This means that if a disconnect is attempted during a transaction it will not be successful and the method will return false. If a transaction is not in progress the disconnect will take 1-3 seconds to successfully finish and will then return true.

Parameters

Parameter Notes
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

ConnectionStatusChanged
Each time the card reader state changes (ex : going from Connected to Disconnected) the ConnectionStatusChanged event is called. It causes the connection manager to invoke this event with the appropriate information.

Returns

Boolean
true if the operation was successful.

Code example

//Disconnect from current device
api.Disconnect();

Set shared secret

method Available since 1.1.7

SetSharedSecret

Validates the app for this session, thus enabling financial transactions

Parameters

Parameter Notes
sharedSecret *
String
The shared secret is a key provided by Handpoint when you get your account that enables you to perform live operations with the card reader. However, if you're developing with a starter kit, the test shared secret is specified in the example
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

None
No events invoked.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Sets the shared secret using the test key
api.SetSharedSecret("0102030405060708091011121314151617181920212223242526272829303132");

Set parameter

method Available since 1.1.7

SetParameter

Changes values of certain parameters on the card reader.

Parameters

Parameter Notes
param *
DeviceParameter
The name of the parameter to change
value *
String
New value of the parameter
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

None
No events are invoked.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Changes the bluetooth name of card reader
api.SetParameter(DeviceParameter.BluetoothName, "OrangeCardReader");

Set logging level

method Available since 1.1.7

SetLogLevel

Sets the log level (info, debug...) for both the card reader and the API. Note : At the end of a transaction, the card reader logs are always automatically fetched to the API.

Parameters

Parameter Notes
level *
LogLevel
The desired log level. Can be LogLevel.None, LogLevel.Info, LogLevel.Full, LogLevel.Debug
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

None
No events are invoked.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Sets the log level to info
api.SetLogLevel(LogLevel.info);

Request device logs

method Available since 1.1.7

GetDeviceLogs

Fetches the logs from the device and reports them to the DeviceLogsReady event.

Parameters

Parameter Notes
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

DeviceLogsReady
Invoked when hapi has finished downloading logs from the card reader.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Downloads logs from device
api.GetDeviceLogs();

Request pending transaction results

method Available since 1.1.8

GetPendingTransaction

Please note this method is only supported on Card Readers with EFT Software versions 1.7.x and 2.2.x and up
In the case of a communication failure between the device and the API a TransactionResult might have not been delivered to the API. This function fetches a pending TransactionResult (which contains receipts) from the device, if any. If no TransactionResult was pending a result will be delivered containing default fields. In order to receive only valid TransactionResults this function should only be called when PendingTransactionResult event is invoked or when HapiManager.IsTransactionResultPending() is true. To receive events when a TransactionResult is pending on the device please add a Events.PendingResults listener.

Parameters

Parameter Notes
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

TransactionResultReady
Invoked when hapi has finished fetching a TransactionResult from the device.

Returns

Boolean
true if the operation was successfully sent to the device

Code example

//Fetches a pending TransactionResult from a device
api.GetPendingTransaction();

Update device

method Available since 1.1.7

Update

The update operation checks for update to the card reader and initiates an update if needed. The update can either be a software update or a configuration update.

Parameters

Parameter Notes
device
Device
This parameter specifies to the system which device you want to use for the operations. If none is supplied the system will attempt to use a default device, if any.


Events invoked

None
Information about this process should be available at the device's screen.

Returns

Boolean
true if the operation was successfully sent to device

Code example

//Check for card reader update
api.Update();

List Devices (search)

method Available since 3.0.0

ListDevices

Starts the search for devices to connect with the specified ConnectionMethod

Parameters

Parameter Notes
method *
ConnectionMethod
The means of connection you intend to use to talk to the device. (Bluetooth, Cloud, Serial, USB, etc...)


Events invoked

deviceDiscoveryFinished
Invoked after the search is finished returning a list of the devices finished.

Code example

//Search for Bluetooth devices
api.ListDevices(ConnectionMethod.BLUETOOTH);

//Search for Cloud devices
api.ListDevices(ConnectionMethod.CLOUD);

Start monitoring connections

method Available since 1.1.8

StartMonitoringConnections

Starts a connection monitoring service. The service listens to events sent by the operating system about the connected hardware. If the service notices that a previously connected device suddenly disconnects on the hardware layer it attempts to reconnect to that particular device. Since this is a service it is necessary that the service is turned off before the application ends its life-time. This means that, if the service was running, stopMonitoringConnections() has to be called before the application is exited completely. Note that the service currently only works with USB. In the case of USB the service will only disconnect from the device and when it notices that it has been plugged in again it will connect to it.

Events invoked

ConnectionStatusChanged
Causes the connection manager to invoke this event with the appropriate information.

Returns

None
No information is returned.

Code example

//Starts the connection monitoring service
//app starts it's life-time
api.StartMonitoringConnections();
...
//app ends its life-time
api.StopMonitoringConnections

Stop monitoring connections

method Available since 1.1.8

StopMonitoringConnections

Stops a connection monitoring service. The service listens to events sent by the operating system about the connected hardware. If the service notices that a previously connected device suddenly disconnects on the hardware layer it attempts to reconnect to that particular device. Since this is a service it is necessary that the service is turned off before the application ends its life-time. This means that, if the service was running, stopMonitoringConnections() has to be called before the application is exited completely. Note that the service currently only works with USB. In the case of USB the service will only disconnect from the device and when it notices that it has been plugged in again it will connect to it.

Events invoked

ConnectionStatusChanged
Causes the connection manager to invoke this event with the appropriate information.

Returns

None
No information is returned.

Code example

//Starts the connection monitoring service
//app starts it's life-time
api.StartMonitoringConnections();
...
//app ends its life-time
api.StopMonitoringConnections

Events subscribers

Register events delegate

method Available since 3.0.0

RegisterEventsDelegate

Registers a delegate for the SDK events. Method getAsyncInterface in HapiFactory executes internally this subscription.

Parameters

Parameter Notes
listener *
Object
Any Object implementing one or more of the available delegate interfaces.


Returns

Boolean
True if the new delegate was added successfully

Code example

public class ObjectHelper : Events.Required, Events.Status, Events.Log {
	...
	private void RegisterEventHandler() {
		// Register this class as listener for events 
		this.api.RegisterEventsDelegate(this);
		...
	}

}

Unregister events delegate

method Available since 3.0.0

UnregisterEventsDelegate

Unregisters an object from SDK events.

Parameters

Parameter Notes
listener *
Object
Any Object implementing one or more of the available delegate interfaces.


Returns

Boolean
True if the new delegate was removed successfully

Code example

public class ObjectHelper : Events.Required, Events.Status, Events.Log {
	...
	private void Unsubscribe() {
	// Stop receiving events
	this.api.UnregisterEventsDelegate(this);
	...
}

Events

Transaction Result Recovery over CLOUD connection

Available since 3.0.0

CloudTransactionResultRecovery

The terminal has a transaction recovery loop to automatically send back the pending Transaction Result to the Point of sale in case it becomes unreachable (network issue or other).
For the first 100 seconds after a transaction is completed, a background thread will attempt to deliver the result every 5 seconds. If the point of sale is still unreachable after the first 100 seconds, the retry loop turns into an exponential increment to the power of 2 (8s-16s-32s etc…).
The recovery loop is reinitialized every time the Handpoint application is restarted.The Transaction Result received through the transaction recovery loop will have the recoveredTransaction field set to true.
Important information: The point of sale must be successfully connected to a terminal in order to receive the pending transactions.

Returns

Transaction Result Ready Event
Event containing the pending Transaction Result

Device discovery finished

method Available since 1.0.0

DeviceDiscoveryFinished

deviceDiscoveryFinished event gets called when a device discovery has finished and returns a list of devices.

Parameters

Parameter Notes
device *
Device
The device that is invoking the event


Subscribers Needed

AddRequiredEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve the devices information.

Code example

//Receiving a list of connectable devices
List<Device> myListOfDevices = new List<Device>();
public void DeviceDiscoveryFinished(List<Device> devices)
{
    foreach(Device device in devices)
    {
        myListOfDevices.Add(device);
    }
}

Signature required

method Available since 3.0.0

SignatureRequired

SignatureRequired event gets called when a card requires a signature instead of PIN entry and has two parameters, request and device. Integrations with PAX or Telpo devices DO NOT need the implementation of this event.

Parameters

Parameter Notes
request *
SignatureRequest
Holds the signature request
device *
Device
The device that is invoking the event


Subscribers Needed

AddRequiredEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve signature information.

Code example

//Receiving a SignatureRequest from the SDK.
public void SignatureRequired(SignatureRequest signatureRequest, Device device)
{
    //You might want to print out the receipt or ask the customer to sign the receipt on your device
    DisplayReceiptInUI(signatureRequest.MerchantReceipt)
    //If you accept the signature
    api.SignatureResult(true);
}

End of transaction

method Available since 1.0.0

EndOfTransaction

EndOfTransaction event gets called at the end of each transaction and has two parameters, result and device.

Parameters

Parameter Notes
result *
TransactionResult
Holds the results for the transaction
device *
Device
The device that is invoking the event


Subscribers Needed

AddRequiredEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve transaction information.

Code example

//Receiving a TransactionResult from the SDK.
public void EndOfTransaction(TransactionResult transactionResult, Device device)
{
    //You might want to display this information in the UI
    postTransactionResultToUI(transactionResult);
}

Connection status changed

method Available since 1.0.0

ConnectionStatusChanged

ConnectionStatusChanged event gets called when the state of a card reader connection changes.

Parameters

Parameter Notes
status *
ConnectionStatus
An enum containing the status code for the connection
device *
Device
The device that is invoking the event


Subscribers Needed

AddStatusNotificationEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve the different connection statuses (e.g : CONNECTED, DISCONNECTED...).

Code example

//Receiving a new ConnectionStatus from the SDK
public void ConnectionStatusChanged(ConnectionStatus connectionStatus, Device device)
{
    //You might want to display this information in the UI
    postNewStatusToUI(connectionStatus);
}

Current transaction status

method Available since 1.0.0

CurrentTransactionStatus

currentTransactionStatus event gets called when the state of an ongoing transaction changes.

Parameters

Parameter Notes
statusInfo *
StatusInfo
An object containing information about the current transaction
device *
Device
The device that is invoking the event


Subscribers Needed

AddStatusNotificationEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve the different states from the card reader (e.g : Waiting for card, Waiting for PIN entry...).

Code example

//Receiving a transaction status from the SDK.
public void currentTransactionStatus(StatusInfo statusInfo, Device device)
{
    //You might want to display some of this information in the UI
    DisplayTransactionStatusInUI(statusInfo)
}

Message logged

method Available since 1.0.0

OnMessageLogged

OnMessageLogged event gets called for all log messages that are being logged. This is only intended for debugging.

Parameters

Parameter Notes
logLevel *
LogLevel
An enum containing the log level
message *
String
A String containing the current log message


Subscribers Needed

AddLogEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve the different log messages.

Code example

//Receiving a log from the SDK
public void OnMessageLogged(LogLevel logLevel, String message)
{
    //You do not want to display this information in the UI
    Debug.WriteLine(message);
}

Logs ready

method Available since 1.0.0

DeviceLogsReady

DeviceLogsReady event gets called when the card reader logs requested by a call to getDeviceLogs() are ready. This Event is really useful if there has been a communication error between the card reader and the API (e.g : Bluetooth communication lost). After reconnecting, you can then fetch the card reader logs to the API.

Parameters

Parameter Notes
logs *
String
String containing the current log
device *
Device
The device that is invoking the event


Subscribers Needed

AddLogEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve the card reader logs.

Code example

//Receiving a log from the device
public void DeviceLogsReady(string logs, Device device)
{
    //You might want to save this information
    WriteLogsToDisk(logs);
}

Pending transaction result

method Available since 1.1.8

PendingTransactionResult

In the case of a communication failure between the device and the API a TransactionResult might have not been delivered to the API. This event is invoked when the device has a pending TransactionResult. This event might be invoked when reconnecting to a device after a communication failure during a transaction. This event will not be called if HapiManager.Settings.AutoRecoverTransactionResult is set to true.

Parameters

Parameter Notes
device *
Device
The device that is invoking the event


Subscribers Needed

AddPendingResultsEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve information about pending results.

Code example

@Override
public void PendingTransactionResult(Device device){
	//Here you might want to call api.GetPendingTransaction(); to receive the TransactionResult
}

Transaction result ready

method Available since 1.1.8

TransactionResultReady

In the case of a communication failure between the device and the API a TransactionResult might have not been delivered to the API. This event will be invoked after using hapi.GetPendingTransaction();. When there is no pending transaction the TransactionResult will contain default/error fields and no receipts. This event is called if HapiManager.Settings.AutoRecoverTransactionResult is set to true.

Parameters

Parameter Notes
result *
TransactionResult
Holds the results for the transaction
device *
Device
The device that is invoking the event


Subscribers Needed

AddPendingResultsEventHandler
This listener has to be implemented (preferably during initialisation) in order to retrieve information about pending results.

Code example

@Override
public void TransactionResultReady(TransactionResult transactionResult, Device device){
	//Here you might want to do stuff to the transactionResult
}

Objects

Transaction Result Object

object Available since 3.0.0

TransactionResult

An object holding information about the result of a transaction.

Properties

Property Description
aid
String
Application Identifier of the card (EMV tag 9F06)
arc
String
EMV Authorisation Response Code (EMV tag 8A)
authorisationCode
String
Acquirer response code
balance
BigInteger
Balance available on the card
budgetNumber
String
Used to split payments over a period of months
cardEntryType
CardEntryType
Method used by the terminal to read the card
cardLanguagePreference
String
Preferred language of the card (EMV tag 5F2D)
cardSchemeName
CardSchemeName
The brand of the card
cardToken
String
Token representing the PAN of the card
chipTransactionReport
String
Full report of the card EMV parameters
currency
Currency
The currency used for the transaction
customerReceipt
String
A URL containing the customer receipt in HTML format
customerReference
String
If a customerReference was provided as an optional parameter in the transaction request it is echoed unaltered in this field
deviceStatus
DeviceStatus
Status of the device
dueAmount
String
In case of a partial approval for the transaction, this field contains the amount which remains to be paid
efttimestamp
Date
Time of the transaction
efttransactionID
String
Handpoint unique identifier for a transaction, this id is the one to be used for a transaction to be reversed.
errorMessage
String
Detailed reason for the transaction error
expiryDateMMYY
String
Expiry date of the card used for the operation
finStatus
FinancialStatus
The financial status contains the outcome of the transaction. For example "AUTHORISED" or "DECLINED"
iad
String
Issuer Application Data (EMV tag 9F10)
issuerResponseCode
String
Response code from the card issuer
maskedCardNumber
String
Masked card number of the card used for the operation
merchantAddress
String
Merchant Address
merchantName
String
Merchant Name
merchantReceipt
String
A URL containing the customer receipt in HTML format
mid
String
Merchant Identifier
originalEFTTransactionID
String
In case the transaction type is a reversal, this field will contain the identifier of the original transaction being reversed
paymentScenario
PaymentScenario
Indicates the card entry mode
recoveredTransaction
boolean
This flag is set to true if the transaction result is sent through the transaction recovery logic explained in the Recovey Section, false otherwise
requestedAmount
BigInteger
The requested amount is the transaction amount sent to the terminal
rrn
String
Retrieval Reference Number, unique number assigned by the acquirer
signatureUrl
String
If a digital signature is required, this is the URL containing the image of the captured signature
statusMessage
String
The status of the transaction, for example "Waiting for pin"
tenderType
TenderType
Transaction tender type (credit / debit)
tid
String
Terminal Identifier
tipAmount
BigInteger
Tip amount, if any, in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
tipPercentage
double
If tipping is enabled, this field will return the tip percentage added on top of the base amount
totalAmount
BigInteger
The total amount is the amount the card was charged for. It is possible that the total amount is not the same as the requested amount since an additional fee can be added, with the customer's approval, via the tipping functionality
transactionID
String
The transaction id is a terminal internal counter incremented for each transaction
tsi
String
Transaction Status Information (EMV tag 9B)
tvr
String
Transaction Verification Results (EMV tag 95)
type
TransactionType
The type of transaction initiated, for example "SALE"
unMaskedPan
String
Unmasked PAN, only received if the card is a non-payment card (loyalty)
verificationMethod
VerificationMethod
cardholder verification method, for example "PIN"

Code example

{
  "aid": "A0000000041010",
  "arc": "0000",
  "authorisationCode": "123456",
  "balance": null,
  "budgetNumber": "",
  "cardEntryType": "UNDEFINED",
  "cardLanguagePreference": "",
  "cardSchemeName": "MasterCard",
  "cardToken": "",
  "chipTransactionReport": "",
  "currency": "USD",
  "customerReceipt": "https://s3.[...]/customerReceipt.html",
  "customerReference": "",
  "deviceStatus": {
      "applicationName": "ClientApp",
      "applicationVersion": "20.1.0",
      "batteryCharging": "Not Charging",
      "batteryStatus": "100",
      "batterymV": "4126",
      "bluetoothName": "PAXA920",
      "externalPower": "USB",
      "serialNumber": "0821032398",
      "statusMessage": "Approved or completed successfully"
  },
  "dueAmount": 0,
  "errorMessage": "",
  "expiryDateMMYY": "0422",
  "finStatus": "AUTHORISED",
  "iad": "0210A000002A0000000000000000000000FF",
  "issuerResponseCode": "00",
  "maskedCardNumber": "************1456",
  "merchantAddress": "Plaza Soledad Torres Acosta 1 28013 Madrid",
  "merchantName": "Hago la cama",
  "merchantReceipt": "https://s3.[...]/merchantReceipt.html",
  "mid": "",
  "originalEFTTransactionID": "",
  "paymentScenario": "CHIPCONTACTLESS",
  "rrn": "",
  "signatureUrl": "",
  "statusMessage": "Approved or completed successfully",
  "tenderType": "CREDIT",
  "tid": "ACQUIRER_TID",
  "tipAmount": 0,
  "totalAmount": 100,
  "transactionID": "01236fc0-8192-11eb-9aca-ad4b0e95f241",
  "tsi": "0000",
  "tvr": "0400008001",
  "type": "SALE",
  "unMaskedPan": "",
  "verificationMethod": "UNDEFINED",
  "efttimestamp": 1615374961000,
  "efttransactionID": "01236fc0-8192-11eb-9aca-ad4b0e95f241",
  "requestedAmount": 100,
  "tipPercentage": 0,
  "recoveredTransaction": false
}

Handpoint Credentials

object Available since 3.0.0

HandpointCredentials

A class containing information related to the Actor credentials: Shared secret (always required) and Cloud API Key (ony required when using CLOUD connection method).

Properties

Property Description
SharedSecret
String
String the value of the Shared secret.
CloudApiKey
String
String the value of the merchant Cloud Api Key, just required when using CLOUD connection method

Code example

{
	string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
	new HandpointCredentials(sharedSecret);
	//We've even set a default shared secret!
}
	
{
	string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
	string apikey = "This-Is-The-Merchant-Api-Key";
	new HandpointCredentials(sharedSecret, apikey);
	//We've even set a default shared secret and the merchant Api Key!
}

Handpoint API (Hapi) factory

object Available since 3.0.0

HapiFactory

A factory to provide a unified entrypoint and to simplify the way to instantiate the Hapi object.

Methods

Static factory

getAsyncInterface( Events.Required requiredListener , HandpointCredentials handpointCredentials );

Parameter Notes
requiredListener *
Events.Required
A listener object to report the required events.
handpointCredentials *
HandpointCredentials
Object containing the actor's Ssk or Ssk and Api Key for CLOUD connections.

Code example

//InitApi for Datecs devices
public void InitApi()
{
	string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
	api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret));
	//The api is now initialized. Yay! we've even set a default shared secret
}

//InitApi for Cloud devices
public void InitApi()
{
	string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
	string apikey = "This-Is-The-Merchant-Api-Key";
	api = HapiFactory.GetAsyncInterface(this, new HandpointCredentials(sharedSecret, apikey));
	//The api is now initialized. Yay! we've even set a default shared secret and the merchant Api Key!
}

Transaction Type

enum Available since 3.1.1

TransactionType

An enum representing different types of transactions.

Possible values

UNDEFINED SALE VOID_SALE REFUND VOID_REFUND CANCEL_SALE CANCEL_REFUND TOKENIZE_CARD SALE_AND_TOKENIZE_CARD REVERSAL UPDATE HOST_INIT PRINT_RECEIPT CARD_PAN

Connection Method

enum Available since 3.0.0

ConnectionMethod

An enum representing different types of connection methods.

BLUETOOTH, CLOUD and SIMULATOR are supported for Windows.

Possible values

USB SERIAL BLUETOOTH CLOUD HTTPS WIFI ETHERNET SIMULATOR

Code example

//Currently CLOUD, BLUETOOTH, and SIMULATOR are the only ConnectionMethod available.
public enum ConnectionMethod 
{
	USB,
	SERIAL,
	HTTPS,
	WIFI,
	ETHERNET,
	BLUETOOTH,
	CLOUD,
	SIMULATOR
}

Device

object Available since 3.0.0

Device

An object to store the information about the device we're working with.

Methods

Constructor

Device( String name , String address , String port , ConnectionMethod connectionMethod , String sharedSecret , int timeout );

Parameter Notes
name *
String
A name to identify the device
address *
String
The address of the device you wish to connect to. E.g.: "08:00:69:02:01:FC" for bluetooth or "9822032398-PAXA920" for CLOUD (composition of serial number and model of the target device) .
port *
String
The port to connect to.
connectionMethod *
ConnectionMethod
Enumerated type to specify the type of connection with the device. E.g: Bluetooth, Cloud, Serial, etc...
sharedSecret
String
This is used if you want this specific device to use the specified sharedSecret instead of the default one proviced in the initialization.
timeout
int
The amount of miliseconds to consider the connection has timed out. If not set, the default timeout is 15 seconds.

Properties

Property Description
Id
String
An unique identifier of the device.

Code example

//Create and init a new Datecs Device
Device dev = new Device("CardReader7", "08:00:69:02:01:FC", "1", ConnectionMethod.BLUETOOTH);

//Create and init a new PAX/Telpo Device
Device dev = new Device("CloudDevice", "9822032398-PAXA920", "", ConnectionMethod.CLOUD);
// The address is the composition of the serial number and model ot the target device.
//Example for a PAX A920 device: serial_number - model  -> 9822032398-PAXA920

Connection Status

enum Available since 1.1.2

ConnectionStatus

A list of statuses given to a connection

Possible values

Connected Connecting Disconnected Disconnecting Initializing NotConfigured

Currency

enum Available since 1.0.0

Currency

An enum of most currencies in the world.

Contains the ISO name, ISO number and the name of the currency. Additionally contains information about how many decimals the currency uses.

Possible values

AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYR BZD CAD CDF CHF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EEK EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LTL LVL LYD MAD MDL MKD MMK MNT MOP MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLL SOS SRD STD SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD UZS VEF VND VUV WST XAF XCD XOF XPF YER ZAR ZMK ZWL

Signature Request

object Available since 1.1.2

SignatureRequest

A class containing information about a signature request/signature verification.

Properties

Property Description
Timeout
int
int the value of the timeout in seconds.
MerchantReceipt
String
String the merchant receipt as html.

Card Scheme Name

String Available since 3.1.0

CardSchemeName

A string representing different card brands.

Possible values

MasterCard Visa Maestro American Express Discover JCB Diners UnionPay

Device Parameter

enum Available since 3.1.1

DeviceParameter

An enum describing all the available commands to send to a device.

When used a legal value is expected with the command

Possible values

BluetoothName BluetoothPass SystemTimeout ScreenTimeout SignatureTimeout Language

Device Status

object Available since 1.1.2

DeviceStatus

A class that holds the device status.

Properties

Property Description
SerialNumber
String
Gets the serial number of the device
BatteryStatus
String
Gets the battery status in percentages of a device
BatterymV
String
Gets the battery milli volts of a device
BatteryCharging
String
Gets the battery charging status of a device
ExternalPower
String
Gets the status of an external power of a device
ApplicationName
String
Gets the application name used on a device
ApplicationVersion
String
Gets the application version number used on a device

Terminal Type

enum Available since 3.1.1

TerminalType

An enum describing all the supported terminal types.

Possible values

BluetoothName BluetoothPass SystemTimeout ScreenTimeout SignatureTimeout Language

Financial Status

enum Available since 1.0.0

FinancialStatus

An enum representing different statuses of a finalized transaction

Possible values

UNDEFINED AUTHORISED DECLINED PROCESSED FAILED CANCELLED

Optional Transaction Parameters

object Available since 1.0.0

OptionalParameters

A class containing optional transaction parameters now supported by the device.

Properties

Property Description
Budget
String
Budget is only available for sale transactions.
A String representing the key for a budget number.

A budget number can be used to split up an amout over a period of months. The value has to be a String of 2 digits representing the number of months to split the transaction to. Example: "03" or "24"

CustomerReference
String
CustomerReference is available for all transactions.
A String representing the key for a customer reference.

A customer reference can be used for an internal marking system. The value is sent as a String of a maximum 25 characters and received back when the transaction has been processed. Example: "C.nr. 212311"

Log Level

enum Available since 1.0.0

LogLevel

An enum describing the different levels of logging used in the hapi and used in the device.

Possible values

None Info Full Debug

Status Info

object Available since 1.0.0

statusInfo

A class containing information about the status of the transaction.

Properties

Property Description
CancelAllowed
bool
A bool representing if the card reader will accept a cancel request.
status
Status
A Status enum representing the status of the transaction.
message
string
A String containing the status message of the transaction.
DeviceStatus
DeviceStatus
A DeviceStatus object containing information about the device.

Verification Method

enum Available since 3.1.1

VerificationMethod

An enum representing different verification methods used in the transaction.

Possible values

UNDEFINED SIGNATURE PIN PIN_SIGNATURE FAILED NOT_REQUIRED MOBILE_PASS_CODE

Payment Scenario

String Available since 3.0.0

PaymentScenario

An enum representing different types of scenario.

Possible values

UNKNOWN MAGSTRIPE MAGSTRIPECONTACTLESS CHIP CHIPCONTACTLESS CHIPFAILMAGSTRIPE

Status

enum Available since 2.0.4

status

An enum containing information about the status of the transaction.

Possible values

Undefined Success InvalidData ProcessingError CommandNotAllowed NotInitialised ConnectTimeout ConnectError SendingError ReceivingError NoDataAvailable TransactionNotAllowed UnsupportedCurrency NoHostAvailable CardReaderError CardReadingFailed InvalidCard InputTimeout UserCancelled InvalidSignature WaitingForCard CardInserted ApplicationSelection ApplicationConfirmation AmountValidation PinInput ManualCardInput WaitingForCardRemoval TipInput SharedSecretInvalid SharedSecretAuth WaitingSignature WaitingHostConnect WaitingHostSend WaitingHostReceive WaitingHostDisconnect PinInputCompleted PosCancelled RequestInvalid CardCancelled CardBlocked RequestAuthTimeout RequestPaymentTimeout ResponseAuthTimeout ResponsePaymentTimeout IccCardSwiped RemoveCard ScannerIsNotSupported ScannerEvent BatteryTooLow AccountTypeSelection BtIsNotSupported PaymentCodeSelection PartialApproval AmountDueValidation InvalidUrl WaitingCustomerReceipt PrintingMerchantReceipt PrintingCustomerReceipt

Tender Type

String Available since 3.0.0

TenderType

An enum representing different tender types.

Possible values

NOT_SET CREDIT DEBIT

Card Entry Type

enum Available since 1.0.0

CardEntryType

An enum representing different card entry types.

Possible values

UNDEFINED MSR ICC CNP

Hapi Manager

object Available since 1.1.7

HapiManager

A static class containing information about the current status of the SDK

Properties

Property Description
DefaultSharedSecret
String
Gets the default shared secret is use in the SDK.
LogLevel
LogLevel
Gets the current log level of the SDK and card reader.
inTransaction
bool
Checks whether the SDK is in transaction or not. True if the SDK is in transaction, false otherwise. This might return a true if there is a communication error between the SDK and card reader but the transaction has been completed on the card reader.
SdkVersion
string
Gets the current Sdk version.
IsTransactionResultPending
boolean
In the case of a communication failure between the device and the API a TransactionResult might have not been delivered to the API. This function checks if there is a pending TransactionResult. This field is only updated when connecting to a device. If this function returns true the TransactionResult (which includes the receipt) can be fetched with hapi.GetPendingTransactionResult();. This function serves the same functionality as the event PendingTransactionResult(Device device), so every time that event is invoked, HapiManager.IsTransactionResultPending() is true until the result is fetched.
Settings.AutoRecoverTransactionResult
boolean
In the case of a communication failure between the device and the API a TransactionResult might have not been delivered to the API. This property can be set to true or false. If set to true, the SDK will automatically fetch the pending TransactionResult when detected and return it via TransactionResultReady. The function PendingTransactionResult is never invoked if this property is set to true. If set to false PendingTransactionResult will be called when a TransactionResult is pending.

Code example

//Check if the SDK is in transaction
bool inTransaction = HapiManager.InTransaction(SomeConnectedDevice);
//Check the current logLevel
LogLevel level = HapiManager.GetLogLevel();