The new generation of Handpoint APIs and SDKs are engineered to make your life simpler, happier.
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.
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.
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 |
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. We undergo an audit on a yearly basis to be able to maintain the license to handle, process, store and transmit card data.
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))
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]
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
{
}
}
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).DefaultSharedSecret(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.
}
}
}
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).DefaultSharedSecret(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...
}
}
}
public void Connect()
{
Device device = new Device("Name", "Address", "Port", ConnectionMethod.SIMULATOR);
api.UseDevice(device);
}
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
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).DefaultSharedSecret(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...
}
}
}
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.
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;
}
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();
}
}
}
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);
}
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;
}
}
Here is how MyClass.cs and Form1.cs must eventually look like :
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).DefaultSharedSecret(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);
}
}
}
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;
}
}
}
}
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!
This tutorial is guiding you through all the steps to create a basic payment application for Android devices using a development card reader.
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. We undergo an audit on a yearly basis to be able to maintain the license to handle, process, store and transmit card data.
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 WindowsGettingStartedApp
{
class MyClass
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.handpoint.api;
namespace WindowsGettingStartedApp
{
class MyClass
{
Hapi api;
public MyClass()
{
InitApi();
}
public void InitApi()
{
string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
api = HapiFactory.GetAsyncInterface(this).DefaultSharedSecret(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.
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.handpoint.api;
namespace WindowsGettingStartedApp
{
class MyClass : Events.Required
{
Hapi api;
Device device;
public MyClass()
{
InitApi();
}
public void InitApi()
{
string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
api = HapiFactory.GetAsyncInterface(this).DefaultSharedSecret(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.
}
public void DeviceDiscoveryFinished(List<Device> devices)
{
// here you get a list of Bluetooth payment terminals paired with your computer
// 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...
}
}
}
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.UseDevice(this.device);
//Connection to the device is handled automatically in the API
}
}
}
}
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.UseDevice(device);
}
public bool Pay()
{
return api.Sale(new BigInteger("1000"), Currency.GBP);
// Let´s start our first payment of 10 pounds
}
public void Disconnect()
{
api.Disconnect();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.handpoint.api;
namespace WindowsGettingStartedApp
{
class MyClass : Events.Required
{
Hapi api;
Device device;
public MyClass()
{
InitApi();
}
public void InitApi()
{
string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
api = HapiFactory.GetAsyncInterface(this).DefaultSharedSecret(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.
}
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.UseDevice(this.device);
//Connection to the device is handled automatically in the API
}
}
}
}
// You can also connect directly to a specific device without having to discover the other devices around :
public void DirectConnect()
{
Device device = new Device("PP0513901435", "68:AA:D2:00:D5:27", "", ConnectionMethod.BLUETOOTH);
//The MAC Adress always has to be written in UPPER CASE
//new Device("name", "address", "port", ConnectionMethod);
api.UseDevice(device);
}
public bool Pay()
{
return api.Sale(new BigInteger("1000"), Currency.GBP);
// Let´s start our first payment of 10 pounds
}
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...
}
public void Disconnect()
{
api.Disconnect();
}
}
}
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.
In MyClass.cs, create an instance of Form1 called UIClass and initialize it. Instantiate MyClass and add form1 as a parameter for the Class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.handpoint.api;
namespace WindowsGettingStartedApp
{
class MyClass : Events.Required
{
Hapi api;
Device device;
private Form1 UIClass;
public MyClass(Form1 form1)
{
InitApi();
UIClass = form1;
}
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.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsGettingStartedApp
{
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.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsGettingStartedApp
{
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();
}
}
}
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);
}
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;
}
}
Here is how MyClass.cs and Form1.cs must eventually look like :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.handpoint.api;
namespace WindowsGettingStartedApp
{
class MyClass : Events.Required
{
Hapi api;
Device device;
private Form1 UIClass;
public MyClass(Form1 form1)
{
InitApi();
UIClass = form1;
}
public void InitApi()
{
string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
api = HapiFactory.GetAsyncInterface(this).DefaultSharedSecret(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.
}
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.UseDevice(this.device);
//Connection to the device is handled automatically in the API
}
}
}
}
// You can also connect directly to a specific device without having to discover the other devices around :
public void DirectConnect()
{
Device device = new Device("PP0513901435", "68:AA:D2:00:D5:27", "", ConnectionMethod.BLUETOOTH);
//The MAC Adress always has to be written in UPPER CASE
//new Device("name", "address", "port", ConnectionMethod);
api.UseDevice(device);
}
public bool Pay()
{
return api.Sale(new BigInteger("1000"), Currency.GBP);
// Let´s start our first payment of 10 pounds
}
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);
}
public void Disconnect()
{
api.Disconnect();
}
}
}
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 WindowsGettingStartedApp
{
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();
}
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;
}
}
}
}
Run the program by clicking the "play" button :
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.
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. |
//Initiate a sale for 10.00 Pounds
api.Sale(new BigInteger(1000),Currency.GBP);
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)
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. |
//Initiate a sale for 10.00 in Great British Pounds
api.SaleAndTokenizeCard(new BigInteger("1000"),Currency.GBP);
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.
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. |
//Initiate a reversal for 10.00 Pounds
api.SaleReversal(new BigInteger(1000),Currency.GBP,"00000000-0000-0000-0000-000000000000");
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.
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. |
//Initiate a refund for 10.00 in Great British Pounds
api.Refund(new BigInteger(1000),Currency.GBP);
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.
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. |
//Initiate a refund reversal for 10.00 in Great British Pounds
api.RefundReversal(new BigInteger(1000),Currency.GBP,"00000000-0000-0000-0000-000000000000");
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.
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) |
//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
}
}
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.
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. |
//Receiving a SignatureRequest from the SDK.
public void SignatureRequired(SignatureRequest signatureRequest, Device device)
{
//If you accept the signature
api.SignatureResult(true);
}
CancelRequest
This method attempts to cancel the current transaction on the card reader. Note that operations cannot be cancelled at certain points during the transaction process
//Attempts to cancel an operation
api.CancelRequest();
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).
Parameter | Notes |
---|---|
map
Map |
A map including extra optional transaction parameters. |
//Initiates a card tokenization operation.
api.TokenizeCard();
UseDevice
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.
Parameter | Notes |
---|---|
device *
Device |
This parameter specifies to the system which device you want to use for the operations. |
//Connect to a device
Device device = new Device("CardReader7", "08:00:69:02:01:FC", "1", ConnectionMethod.BLUETOOTH);
api.UseDevice(device);
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
.
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. |
//Disconnect from current device
api.Disconnect();
SetSharedSecret
Validates the app for this session, thus enabling financial transactions
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. |
//Sets the shared secret using the test key
api.SetSharedSecret("0102030405060708091011121314151617181920212223242526272829303132");
SetParameter
Changes values of certain parameters on the card reader.
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. |
//Changes the bluetooth name of card reader
api.SetParameter(DeviceParameter.BluetoothName, "OrangeCardReader");
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.
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. |
//Sets the log level to info
api.SetLogLevel(LogLevel.info);
GetDeviceLogs
Fetches the logs from the device and reports them to the DeviceLogsReady event.
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. |
//Downloads logs from device
api.GetDeviceLogs();
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.
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. |
//Fetches a pending TransactionResult from a device
api.GetPendingTransaction();
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.
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. |
//Check for card reader update
api.Update();
ListDevices
Starts the search for devices to connect with the specified ConnectionMethod
Parameter | Notes |
---|---|
method *
ConnectionMethod |
The means of connection you intend to use to talk to the device. (Bluetooth, Serial, USB, etc...) |
//Search for Bluetooth devices
api.ListDevices(ConnectionMethod.BLUETOOTH);
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.
//Starts the connection monitoring service
//app starts it's life-time
api.StartMonitoringConnections();
...
//app ends its life-time
api.StopMonitoringConnections
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.
//Starts the connection monitoring service
//app starts it's life-time
api.StartMonitoringConnections();
...
//app ends its life-time
api.StopMonitoringConnections
AddRequiredEventHandler
Adds a listener so necessary information can be retrieved. Such as signature verification, receipts and list of devices. This listener fetches information from the following events : DeviceDiscoveryFinished, SignatureRequired and EndOfTransaction. The corresponding removal method, RemoveRequiredEventHandler, must be called before the end of your applications life-time to prevent memory leakage.
Parameter | Notes |
---|---|
listener *
Required |
An implementation of the Events.Required interface |
//Register a listener for required events
this.api.AddRequiredEventHandler(this);
//In this context the keyword "this" is an implementation of:
interface Events.Required {
void SignatureRequired(SignatureRequest request, Device device);
void EndOfTransaction(TransactionResult result, Device device);
void DeviceDiscoveryFinished(List devices);
}
AddStatusNotificationEventHandler
Adds a listener so transaction information can be retrieved. This listener fetches information from the following events : ConnectionStatusChanged, CurrentTransactionStatus. The corresponding removal method, RemoveStatusNotificationEventHandler, must be called before the end of your applications life-time to prevent memory leakage.
Parameter | Notes |
---|---|
listener *
Status |
An implementation of the Events.Status interface |
//Register a listener for transaction information events
this.api.AddStatusNotificationEventHandler(this);
//In this context the keyword "this" is an implementation of:
interface Events.Status {
void ConnectionStatusChanged(ConnectionStatus status, Device device);
void CurrentTransactionStatus(StatusInfo info, Device device);
}
AddLogEventHandler
Adds a listener so log information can be retrieved. This listener fetches information from the following events : OnMessageLogged, DeviceLogsReady. The corresponding removal method, RemoveLogEventHandler, must be called before the end of your applications life-time to prevent memory leakage.
Parameter | Notes |
---|---|
listener *
Log |
An implementation of the Events.Log interface |
//Register a listener for log information events
this.api.AddLogEventHandler(this);
//In this context the keyword "this" is an implementation of:
interface Events.Log {
void DeviceLogsReady(String logs, Device device);
void OnMessageLogged(LogLevel level, String message);
}
AddPendingResultsEventHandler
Adds a listener so information can be retrieved when there is a pending TransactionResult. This listener fetches information from the following events : PendingTransactionResult, TransactionResultReady. The corresponding removal method, RemovePendingResultsEventHandler, must be called before the end of your applications life-time to prevent memory leakage.
Parameter | Notes |
---|---|
listener *
PendingResults |
An implementation of the Events.PendingResult interface |
//Register a listener for log information events
this.api.AddPendingResultsEventHandler(this);
//In this context the keyword "this" is an implementation of:
interface Events.PendingResults {
void PendingTransactionResult(Device device);
void TransactionResultReady(TransactionResult transactionResult, Device device);
}
RemoveRequiredEventHandler
Removes a listener so information is not passed on to that listener any more.
Parameter | Notes |
---|---|
listener *
Required |
The listener to be removed |
//Remove a listener for required events
this.api.RemoveRequiredEventHandler(this);
RemoveStatusNotificationEventHandler
Removes a listener so information is not passed on to that listener any more.
Parameter | Notes |
---|---|
listener *
Status |
The listener to be removed |
//Remove a listener for status notification events
this.api.RemoveStatusNotificationEventHandler(this);
RemoveLogEventHandler
Removes a listener so information is not passed on to that listener any more.
Parameter | Notes |
---|---|
listener *
Log |
The listener to be removed |
//Remove a listener for log events
this.api.RemoveLogEventHandler(this);
RemovePendingResultsEventHandler
Removes a listener so information is not passed on to that listener any more.
Parameter | Notes |
---|---|
listener *
PendingResults |
The listener to be removed |
//Remove a listener for pending results events
this.api.RemovePendingResultsEventHandler(this);
DeviceDiscoveryFinished
deviceDiscoveryFinished event gets called when a device discovery has finished and returns a list of devices.
Parameter | Notes |
---|---|
device *
Device |
The device that is invoking the event |
//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);
}
}
SignatureRequired
signatureRequired event gets called when a card requires a signature instead of PIN entry and has two parameters, request and device.
Parameter | Notes |
---|---|
request *
SignatureRequest |
Holds the signature request |
device *
Device |
The device that is invoking the event |
//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);
}
EndOfTransaction
EndOfTransaction event gets called at the end of each transaction and has two parameters, result and device.
Parameter | Notes |
---|---|
result *
TransactionResult |
Holds the results for the transaction |
device *
Device |
The device that is invoking the event |
//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);
}
ConnectionStatusChanged
ConnectionStatusChanged event gets called when the state of a card reader connection changes.
Parameter | Notes |
---|---|
status *
ConnectionStatus |
An enum containing the status code for the connection |
device *
Device |
The device that is invoking the event |
//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);
}
CurrentTransactionStatus
currentTransactionStatus event gets called when the state of an ongoing transaction changes.
Parameter | Notes |
---|---|
statusInfo *
StatusInfo |
An object containing information about the current transaction |
device *
Device |
The device that is invoking the event |
//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)
}
OnMessageLogged
OnMessageLogged event gets called for all log messages that are being logged. This is only intended for debugging.
Parameter | Notes |
---|---|
logLevel *
LogLevel |
An enum containing the log level |
message *
String |
A String containing the current log message |
//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);
}
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.
Parameter | Notes |
---|---|
logs *
String |
String containing the current log |
device *
Device |
The device that is invoking the event |
//Receiving a log from the device
public void DeviceLogsReady(string logs, Device device)
{
//You might want to save this information
WriteLogsToDisk(logs);
}
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.
Parameter | Notes |
---|---|
device *
Device |
The device that is invoking the event |
@Override
public void PendingTransactionResult(Device device){
//Here you might want to call api.GetPendingTransaction(); to receive the TransactionResult
}
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.
Parameter | Notes |
---|---|
result *
TransactionResult |
Holds the results for the transaction |
device *
Device |
The device that is invoking the event |
@Override
public void TransactionResultReady(TransactionResult transactionResult, Device device){
//Here you might want to do stuff to the transactionResult
}
TransactionType
An enum representing different types of transactions.
UNDEFINED
SALE
VOID_SALE
REFUND
VOID_REFUND
CANCEL_SALE
CANCEL_REFUND
TOKENIZE_CARD
TransactionResult
A class holding information about a transaction result.
Property | Description |
---|---|
StatusMessage String |
Gets the status message from the TransactionResult . The status message is a human readable string from our servers which contains a value representing the result from the server side. "AUTH CODE 12345" for example. |
Type TransactionType |
Gets the transaction type from the TransactionResult . The transaction type represents which type of transaction was done. "SALE" for example. |
FinStatus FinancialStatus |
Gets the financial status from the TransactionResult . The financial status describes the conclusion of the transaction as received from the card reader. "AUTHORISED" for example. |
RequestedAmount BigInteger |
Gets the requested amount from the TransactionResult . The requested amount is the payment amount sent in the original request to the card reader, i.e. the amount which was to charge the card with. |
GratuityAmount BigInteger |
Gets the gratuity amount from the TransactionResult . The gratuity amount is an additional amount added to the requested payment amount which represents additional fee added to the requested amount. This is used when the card reader is supporting the tipping functionality. An example: A sale is started with the amount 1000 and the card reader is set to support tipping. The card reader asks if a tip should be applied by the customer. The customer inputs an additional amount as a tip, lets say 100. The card is then charged for the requested amount, 1000, as well as the additional gratuity amount, 100. The result will be that the card will be charged for 1100. A calculated gratuity percentage will also be returned. |
GratuityPercentage double |
Gets the gratuity percentage from the TransactionResult The gratuity percentage is used to calculate an additional amount to the requested amount. The card reader calculates that amount, rounded up to the closest whole number. This is used when the card reader is supporting the tipping functionality. An example: A sale is started with the amount 1000 and the card reader is set to support tipping. The card reader asks if a tip should be applied by the customer. Instead of the customer adding a value he selects the percentage of the requested amount to be applied as a tip, lets say 10%. The card is then charged for the requested amount, 1000, as well as the additional gratuity percentage, 10%. The result will be that the card will be charged for 1100. A calculated gratuity amount will also be returned. |
TotalAmount BigInteger |
Gets the total amount from the TransactionResult . 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. |
Currency Currency |
Gets the currency from the TransactionResult . The currency used in this transaction. |
TransactionID String |
Gets the device transaction id from the TransactionResult . The transaction id is an internal increasing counter in the card reader which is incremented in each transaction. |
eFTTransactionID String |
Gets the device transaction id from the TransactionResult . The EFT (electronic funds transfer) transaction id is a unique GUID from the servers which is linked to this transaction in order to search for a particual transaction. This id is used if a transaction is to be reversed. |
OriginalEFTTransactionID String |
Gets the original EFT transaction id from the TransactionResult . The original EFT (electronic funds transfer) transaction id is a unique GUID previously received from the servers in order to reverse a transaction. This id is sent with the new eFTTransactionID in order to reference the original transaction. An example: A transaction is made. An eFTTransactionID is received. That transaction has to be reversed. A new transaction is started, now a reverse transaction, with the previously received eFTTransactionID as a parameter in the transaction. In the end result there will be a new eFTTransactionID, for the reverse transaction, and an originalEFTTransactionID referencing the original transaction. |
eFTTimestamp Date |
Gets the time stamp from the TransactionResult . The eFTTimestamp represents the time when the transaction was done. This time is set by the device communicating to the card reader when the connection is established to the card reader. |
AuthorisationCode String |
Gets the authorisation code from the TransactionResult . If the transaction was authorised the value represented can be used to search for a transaction in our system. |
VerificationMethod VerificationMethod |
Gets the verification method from the TransactionResult . The verification method represents the card holder verification method used to allow the payment. "PIN" for example. |
CardEntryType CardEntryType |
Gets the card entry type from the TransactionResult . The card entry type is the method the card information was input to card reader. "ICC" for example represents "Integrated Circuit Card" i.e. the information was read from the chip of the card. |
CardSchemeName String |
Gets the card scheme name from the TransactionResult . The scheme which was used when the transaction was made. |
ErrorMessage String |
Gets the error message from the TransactionResult . If there was an error during the transaction it is represented here in a human readable text. |
CustomerReference String |
Gets the customer reference from the TransactionResult . If a customer reference was added, as an optional parameter, when the transaction was started. It is received here, unaltered. The customer reference can be used to reference in internal systems. |
BudgetNumber String |
Gets the budget number from the TransactionResult . If a budget number was added, as an optional parameter, when the transaction was started. It is received here, unaltered. The budget number can be used to split payments over a period of months. |
RecoveredTransaction boolean |
Gets the flag recovered transaction from the TransactionResult . This flag is true if the transaction result is from a previous transaction which failed to get sent from the card reader, false otherwise. In the case that the communication between the device and the card reader breaks down, the card reader will attempt to send the result of the previous transaction as an immediate reply when the next transaction is started. If this happens the transaction is flagged as a "RecoveredTransaction". This should be displayed very well in the UI since this is *NOT* the result from the transaction just started. |
CardTypeId String |
Gets the card type id from the transaction. The card type id is an identifier inside the Handpoint gateway which represents what kind of card was used. "U015" for example represents SAS Airline-Systems in our systems. |
MerchantReceipt String |
Gets the merchant receipt from the TransactionResult . An HTML containing the merchant receipt. |
CustomerReceipt String |
Gets the customer receipt from the TransactionResult . An HTML containing the customer receipt. |
DeviceStatus DeviceStatus |
Gets the device status from the TransactionResult . |
CardToken String |
Gets the card token if it's available, null otherwise. |
HapiFactory
A factory to provide a unified entrypoint and to simplify the way to instantiate the Hapi object.
getAsyncInterface( Events.Required requiredListener );
Parameter | Notes |
---|---|
requiredListener *
Events.Required |
A listener object to report the required events. |
public void InitApi()
{
string sharedSecret = "0102030405060708091011121314151617181920212223242526272829303132";
api = HapiFactory.GetAsyncInterface(this).DefaultSharedSecret(sharedSecret);
//The api is now initialized. Yay! we've even set a default shared secret!
}
ConnectionMethod
An enum representing different types of connection methods.
BLUETOOTH
and SIMULATOR
are supported for Windows.
USB
SERIAL
BLUETOOTH
HTTPS
WIFI
ETHERNET
SIMULATOR
//Currently BLUETOOTH, and SIMULATOR are the only ConnectionMethod available.
public enum ConnectionMethod
{
USB,
SERIAL,
HTTPS,
WIFI,
ETHERNET,
BLUETOOTH,
SIMULATOR
}
Device
An object to store the information about the device we're working with.
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 "192.168.1.105" for ethernet. |
port *
String |
The port to connect to. |
connectionMethod *
ConnectionMethod |
Enumerated type to specify the type of connection with the device. E.g: Bluetooth, 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. |
Property | Description |
---|---|
Id String |
An unique identifier of the device. |
//Create and init a new Device
Device dev = new Device("CardReader7", "08:00:69:02:01:FC", "1", ConnectionMethod.BLUETOOTH);
ConnectionStatus
A list of statuses given to a connection
Connected
Connecting
Disconnected
Disconnecting
Initializing
NotConfigured
SignatureRequest
A class containing information about a signature request/signature verification.
Property | Description |
---|---|
Timeout int |
int the value of the timeout in seconds. |
MerchantReceipt String |
String the merchant receipt as html. |
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.
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
DeviceParameter
An enum describing all the available commands to send to a device.
When used a legal value is expected with the command
BluetoothName
BluetoothPass
SystemTimeout
ScreenTimeout
SignatureTimeout
DeviceStatus
A class that holds the device status.
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 |
FinancialStatus
An enum representing different statuses of a finalized transaction
UNDEFINED
AUTHORISED
DECLINED
PROCESSED
FAILED
CANCELLED
statusInfo
A class containing information about the status of the transaction.
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. |
LogLevel
An enum describing the different levels of logging used in the hapi and used in the device.
None
Info
Full
Debug
OptionalParameters
A class containing optional transaction parameters now supported by the device.
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 |
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 |
VerificationMethod
An enum representing different verification methods used in the transaction.
UNDEFINED
SIGNATURE
PIN
PIN_SIGNATURE
FAILED
NOT_REQUIRED
status
An enum containing information about the status of the transaction.
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
CardEntryType
An enum representing different card entry types.
UNDEFINED
MSR
ICC
CNP
HapiManager
A static class containing information about the current status of the SDK
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. |
//Check if the SDK is in transaction
bool inTransaction = HapiManager.InTransaction(SomeConnectedDevice);
//Check the current logLevel
LogLevel level = HapiManager.GetLogLevel();