README
Cordova Handpoint SDK Plugin
Cross-platform Handpoint SDK for Cordova. This plugin is intended to enable the access to Handpoint Card Readers from any cross-platform application built over Cordova.
You might want to take a look at the Ionic 2 starter application to see a fully functional app using the plugin.
Installation
You can install handpoint plugin with Cordova CLI, from npm:
cordova plugin add cordova-plugin-handpoint
Overview
The plugin creates the object cordova.plugins.Handpoint with the following public methods and properties:
Properties
Property | Description |
---|---|
ConnectionMethod | Enum. containing supported connection methods |
Currency | Enum. containing ISO4217 currency codes |
LogLevel | Enum. containing supported logging levels |
Methods
Method | Description |
---|---|
setup | Initializes the SDK |
setSharedSecret | Set shared secret for current card reader |
eventHandler | Adds the event listener. |
tokenizeCard | Returns the tokenized version of the card used if successful |
sale | A sale initiates a payment operation to the card reader |
saleAndTokenizeCard | A saleAndTokenizeCard initiates a payment operation and card tokenization request to the card reader |
refund | A refund initiates a refund operation to the card reader |
saleReversal | A sale Reversal, also called sale VOID allows the user to reverse a previous sale operation |
refundReversal | A Refund Reversal, also called refund VOID allows the merchant to reverse a previous refund operation |
enableScanner | Enable Scanner allows the merchant to use the QR / Barcode scanner (where available) |
signatureResult | When signature is required, we use this method to tell the card reader the result of the signature (usually accepted) |
listDevices | Starts the search for devices to connect to with the specified ConnectionMethod |
connect | Connect to a device |
disconnect | Disconnect will stop the active connection with the device |
getPendingTransaction | only supported on Card Readers with EFT Software versions 1.7.x and 2.2.x |
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. |
setLogLevel | Sets the log level for both the card reader and the SDK |
getDeviceLogs | Fetches the logs from the device and reports them to the deviceLogsReady event. |
getSDKVersion | Returns the underlying SDK version |
Quick start
- 1. Setup the Handpoint SDK Singleton with your shared secret. 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:
// Init Handpoint SDK
cordova.plugins.Handpoint.setup({}, () => {
// SDK initialization succeed
// set shared secret
cordova.plugins.Handpoint.setSharedSecret({
sharedSecret: '0102030405060708091011121314151617181920212223242526272829303132'
}, () => {
// Initialization completed
}, (error) => {
// Set shared secret failed
});
}, (error) => {
// SDK initialization failed
});
- 2. Configure event handler to receive async notifications from the Card Reader. Most of the methods of the SDK are asynchronous. Once you send the operation to the Card reader, you will be notified of the status through the event handler function. See Event Handling section.
// Configure event handler
cordova.plugins.Handpoint.eventHandler(function (event) {
// Event handling goes here
// event.event contains the type of event
// event.data contains the event payload
console.log(event);
}, function (error) {
// Error in event handler setup
console.log(error);
});
- 3. Scan devices: This is a very expensive operation and you should consider to cache the result in local storage and call it again only if user has paired a new device. IMPORTANT NOTE: You need to ask the user to pair the device before it appears in the results:
cordova.plugins.Handpoint.listDevices({
connectionMethod: cordova.plugins.Handpoint.ConnectionMethod.BLUETOOTH
}, function() {
// Call succeed. You will receive the list of devices in the event handler declared above. Event 'deviceDiscoveryFinished'
}, function() {
// Call failed
});
- 4. Connect to one the devices scanned above:
cordova.plugins.Handpoint.connect({
device: {
name: device.name,
address: device.address,
port: "1",
connectionMethod: cordova.plugins.Handpoint.ConnectionMethod.BLUETOOTH
}
}, (result) => {
// Nothing to do. Wait for Connected event or timeout
}, (error) => {
// Error connecting to device
});
- 5. Start transaction:
cordova.plugins.Handpoint.sale({
amount: 120,
currency: cordova.plugins.Handpoint.Currency.ISK,
}, function() {
// Success. Wait for currentTransactionStatus events
}, function() {
// Error
});
- 6. Wait for currentTransactionStatus events. F. ex. you might want to listen to currentTransactionStatus event to notify user of different Card Reader statuses, and of course endOfTransaction event to know the final result of the transaction. See Event Handling section.
// Handler declared in second step
cordova.plugins.Handpoint.eventHandler(function (event) {
if (event.event == 'currentTransactionStatus') {
// Show status to the user
switch (event.data.info.status) {
case "WaitingForCard":
case "WaitingForCardRemoval":
case "TipInput":
case "WaitingCustomerReceipt":
case "PrintingMerchantReceipt":
case "PrintingCustomerReceipt":
case "WaitingSignature":
case "ApplicationSelection":
case "AmountValidation":
case "AccountTypeSelection":
case "PaymentCodeSelection":
case "WaitingHostConnect":
case "WaitingHostSend":
case "WaitingHostReceive":
case "WaitingHostDisconnect":
case "WaitingHostMessageRequest":
case "WaitingHostMessageResponse":
case "PinInputComplete":
case "PinInput":
}
}
// Wait for transaction end
else if (event.event == 'endOfTransaction') {
switch (event.data.transactionResult.finStatus) {
case "AUTHORISED": // Succeed. Inspect event.data.transactionResult for details
break;
case "DECLINED": // Failed
case "CANCELLED":
case "FAILED":
break;
}
}
});
API Documentation
Properties
ConnectionMethod
Enum. containing supported connection methods. You have to pass the ConnectionMethod when searching for devices or connect to one of them:
Value | Notes |
---|---|
cordova.plugins.Handpoint.ConnectionMethod.BLUETOOTH | This is the |
cordova.plugins.Handpoint.ConnectionMethod.HTTPS | Define for future use |
cordova.plugins.Handpoint.ConnectionMethod.SIMULATOR | Supported only in Android |
Currency
Enum. containing ISO 4217 codes. f.ex. cordova.plugins.Handpoint.Currency.ISK evaluates as 352. You need to speficy the currency in financial transactions sale, refund, saleReversal and refundReversal:
LogLevel
Enum. containing supported logging levels:
Value | Notes |
---|---|
cordova.plugins.Handpoint.LogLevel.None | No logging |
cordova.plugins.Handpoint.LogLevel.Info | Info logging level |
cordova.plugins.Handpoint.LogLevel.Full | Full logging level |
cordova.plugins.Handpoint.LogLevel.Debug | Provides highest logging level |
Methods
All the methods of the plugin are asynchronous and return the result of the execution either to a success or an error callback:
cordova.plugins.Handpoint.methodName([config], successCallback, errorCallback)
setup
Initializes the Handpoint SDK. Don't forget to execute it before trying to use the SDK:
cordova.plugins.Handpoint.setup({}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.automaticReconnection | If set to true, the SDK will automatically reconnect to the last known device when the connection is lost. The default value is false |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
setSharedSecret
Validates the app for this session, thus enabling financial transactions. Don't forget to set shared secret before connect to a device:
cordova.plugins.Handpoint.setSharedSecret({ sharedSecret: '0102030405060708091011121314151617181920212223242526272829303132' }, successCallback, errorCallback)
Parameter | Description |
---|---|
config.sharedSecret | Your shared secret |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
eventHandler
Sets up the SDK event handler. See Event Handling section.
cordova.plugins.Handpoint.eventHandler(function(data) {
// data.event contains the event name
// data.data contains the event payload
}, errorCallback)
Parameter | Description |
---|---|
successCallback | This function will received all the events from the SDK |
errorCallback | Executed if event handler was not configured |
tokenizeCard
A 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)
cordova.plugins.Handpoint.tokenizeCard({}, successCallback, errorCallback)
sale
A sale initiates a payment operation to the card reader.
cordova.plugins.Handpoint.sale({
amount: 1000, // Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency: cordova.plugins.Handpoint.Currency.GBP
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.amount | Amount to pay in the minor unit of currency (f.ex. 1000 is 10.00 GBP) |
config.currency | Currency for this transaction. F. ex cordova.plugins.Handpoint.Currency.ISK |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
saleAndTokenizeCard
A saleAndTokenizeCard initiates a payment operation and card tokenization request to the card reader
cordova.plugins.Handpoint.saleAndTokenizeCard({
amount: 1000, // Amount of funds to charge - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency: cordova.plugins.Handpoint.Currency.GBP
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.amount | Amount to pay in the minor unit of currency (f.ex. 1000 is 10.00 GBP) |
config.currency | Currency for this transaction. F. ex cordova.plugins.Handpoint.Currency.ISK |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
refund
A refund initiates a refund operation to the card reader.
cordova.plugins.Handpoint.refund({
amount: 1000, // Amount of funds to refund - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency: cordova.plugins.Handpoint.Currency.GBP
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.amount | Amount to refund in the minor unit of currency (f.ex. 1000 is 10.00 GBP) |
config.currency | Currency for this transaction. F. ex cordova.plugins.Handpoint.Currency.ISK |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
saleReversal
A sale Reversal, also called sale VOID allows the user to reverse a previous sale operation.
cordova.plugins.Handpoint.saleReversal({
amount: 1000, // Amount of funds to reverse - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency: cordova.plugins.Handpoint.Currency.GBP,
originalTransactionID: result.transactionResult.eFTTransactionID // where result is the endOfTransaction event payload
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.amount | Amount to reverse in the minor unit of currency (f.ex. 1000 is 10.00 GBP) |
config.currency | Currency for this transaction. F. ex cordova.plugins.Handpoint.Currency.ISK |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
refundReversal
A Refund Reversal, also called Refund VOID allows the merchant to reverse a previous refund operation.
cordova.plugins.Handpoint.refundReversal({
amount: 1000, // Amount of funds to reverse - in the minor unit of currency (f.ex. 1000 is 10.00 GBP)
currency: cordova.plugins.Handpoint.Currency.GBP,
originalTransactionID: result.transactionResult.eFTTransactionID // where result is the endOfTransaction event payload
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.amount | Amount to reverse in the minor unit of currency (f.ex. 1000 is 10.00 GBP) |
config.currency | Currency for this transaction. F. ex cordova.plugins.Handpoint.Currency.ISK |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
enableScanner
Enable Scanner allows the merchant to use the QR / Barcode scanner (where available)
cordova.plugins.Handpoint.enableScanner({
multiScan: false,
autoScan: false,
resultsGrouped: true,
timeout: 0
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.multiScan | true if you want to scan multiple items before returning to your app. |
config.autoScan | true if you want the scanner always on without the pushing of a button |
config.resultsGrouped | true if you want scans from a multi scan to come all together when true if you want scans from a multi scan to come all together when you're finished. you're finished. |
config.timeout | the amount of seconds until the scanner shuts itself off. 0 means no timeout. |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
signatureResult
When a signatureRequired event is fired, the merchant is required to ask the cardholder for signature and approve or decline it. After that you can execute this method to inform on the result
cordova.plugins.Handpoint.signatureResult({
accepted: true
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.accepted | true if customer signature was accepter, false otherwise |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
listDevices
Starts the search for devices to connect to with the specified ConnectionMethod.
cordova.plugins.Handpoint.listDevices({
connectionMethod: cordova.plugins.Handpoint.ConnectionMethod.SIMULATOR
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.connectionMethod | One of the accepted connection methods |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
connect
Configures the device as the preferred device and tries to connect to it.
cordova.plugins.Handpoint.connect({
device: device // One of the devices returned from listDevices operation
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.device | Device to connect to. One of device object returned by listDevices method |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
disconnect
Disconnect will stop the active connection
cordova.plugins.Handpoint.disconnect({
device: device // One of the devices returned from listDevices operation
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.device | Device to disconnect from. One of device object returned by listDevices method |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
getPendingTransaction
In the case of a communication failure between the device and the SDK a TransactionResult might have not been delivered to the SDK. This function fetches a pending TransactionResult (which contains receipts) from the device, if any.
cordova.plugins.Handpoint.getPendingTransaction({}, successCallback, errorCallback)
Parameter | Description |
---|---|
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
update
The update operation checks for update to the current card reader and initiates an update if needed. The update can either be a software update or a configuration update.
cordova.plugins.Handpoint.update({}, successCallback, errorCallback)
Parameter | Description |
---|---|
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
setLogLevel
Sets the log level for both the card reader and the SDK.
cordova.plugins.Handpoint.setLogLevel({
level: cordova.plugins.Handpoint.LogLevel.Debug
}, successCallback, errorCallback)
Parameter | Description |
---|---|
config.level | Log level. See the list of supported log levels |
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
getDeviceLogs
Fetches the logs from the device and reports them to the deviceLogsReady event.
cordova.plugins.Handpoint.getDeviceLogs({}, successCallback, errorCallback)
Parameter | Description |
---|---|
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
getSDKVersion
Returns the underlying SDK version in the success callback.
cordova.plugins.Handpoint.getSDKVersion({}, (version) => {
console.log(version);
}, errorCallback)
Parameter | Description |
---|---|
successCallback | Executed if the method execution succeed |
errorCallback | Executed if the method execution failed |
Event Handling
As explained before, all the methods of the plugin are asynchronous and return the result of the execution either to a success or an error callback.
If you don't want to deal with callbacks and you prefer to turn Callbacks into Promises you might want to publish the events received in the callback function passed to cordova.plugins.Handpoint.eventHandler
method to a publish-subscribe style event system and then encapsulate the event handling logic in an SDK wrapper module.
Let's suppose that you want to implement a sale which returns a Promise that resolves when the transaction is completed, or rejects when it is failed.
First we need to publish sale related events to our event system:
cordova.plugins.Handpoint.eventHandler(function (event) {
…
// Publish event
if (event.event == 'endOfTransaction') {
events.publish("handpoint:" + event.event + ":" + event.data.transactionResult.finStatus, event.data);
}
…
}, function (error) {
…
});
Now we are publishing Handpoint events as handpoint:endOfTransaction:AUTHORISED, handpoint:endOfTransaction:DECLINED, etc.
And finally encapsulate the Handpoint SDK sale method in a function that returns a Promise which deals with event subscriptions:
function salePromise(): Promise<any> {
return new Promise((resolve, reject) => {
cordova.plugins.Handpoint.sale(params, ()=> {
// Subscribe to success events and resolve the promise: handpoint:endOfTransaction:AUTHORISED
…
successEvents.subscribe((result) => {
resolve(result);
});
// Subscribe to error events and reject the promise: handpoint:endOfTransaction:DECLINE handpoint:endOfTransaction:FAILED handpoint:endOfTransaction:CANCELLED
…
errorEvents.subscribe((result) => {
reject(result);
});
// Clean up and unsubscribe
…
}, (error) => {
reject(error);
});
})
}
NOTE: the example above is pseudocode, you have a fully implemented wrapper here.