Skip to main content
Version: iOS SDK 4.0.0

SDK integration example

HandpointModule header

HandpointModule.h

#import "HandpointAll.h"

@interface HandpointModule : NSObject <HeftDiscoveryDelegate, HeftStatusReportDelegate>

- (instancetype)initWithSharedSecret:(NSString *)sharedSecret;

- (void)saleWithAmount:(NSInteger)amount
currency:(NSString *)currency;

- (void)refundWithAmount:(NSInteger)amount
currency:(NSString *)currency;

- (void)saleReversalWithAmount:(NSInteger)amount
currency:(NSString *)currency
originalTransactionID:(NSString *)originalTransactionID;

- (void)refundReversalWithAmount:(NSInteger)amount
currency:(NSString *)currency
originalTransactionID:(NSString *)originalTransactionID;

- (void)connectToAddress:(NSString *)address;

- (void)setLogLevel:(eLogLevel)logLevel;

- (void)getDeviceLogs;

- (void)getPendingTransaction;

- (void)update;

- (void)listDevices;

@end

HandpointModule

HandpointModule.m

#import "<Foundation/Foundation.h>"
#import "HandpointModule.h"
#import "HeftRemoteDevice+SendableDevice.h"
#import "SDKEvent.h"
#import "ConnectionStatus.h"
#import "Currency.h"
#import "CDVInvokedUrlCommand+Arguments.h"
#import "StatusInfo.h"
#import "TransactionResult.h"

typedef NS_ENUM(NSInteger, ConnectionStatus)
{
ConnectionStatusNotConfigured,
ConnectionStatusConnected,
ConnectionStatusConnecting,
ConnectionStatusDisconnected,
ConnectionStatusDisconnecting,
ConnectionStatusInitializing
};

@interface HandpointModule ()

@property (nonatomic) HeftManager* manager;
@property (nonatomic, strong) id<HeftClient> api;
@property (nonatomic) NSString *ssk;
@property (nonatomic) HeftRemoteDevice* preferredDevice;
@property (nonatomic) NSString *eventHandlerCallbackId;
@property (nonatomic) NSMutableDictionary *devices;

@end

@implementation HandpointModule

- (instancetype)initWithSharedSecret:(NSString *)sharedSecret
{
NSLog(@"\n\tpluginInitialize");
self.manager = [HeftManager sharedManager];
self.manager.delegate = self;
self.devices = [@{} mutableCopy];

[self fillDevicesFromConnectedCardReaders];

self.ssk = sharedSecret;
}

- (void)saleWithAmount:(NSInteger)amount
currency:(NSString *)currency
{
BOOL result = [self.api saleWithAmount:amount
currency:currency
cardholder:YES];

if (result == false)
{
//Do something
}
}

- (void)refundWithAmount:(NSInteger)amount
currency:(NSString *)currency
{
BOOL result = [self.api refundWithAmount:amount
currency:currency
cardholder:YES]

if (result == false)
{
//Do something
}
}

- (void)saleReversalWithAmount:(NSInteger)amount
currency:(NSString *)currency
originalTransactionID:(NSString *)originalTransactionID
{
BOOL result = [self.api saleVoidWithAmount:amount
currency:currency
cardholder:YES
transaction:originalTransactionID];

if (result == false)
{
//Do something
}
}

- (void)refundReversalWithAmount:(NSInteger)amount
currency:(NSString *)currency
originalTransactionID:(NSString *)originalTransactionID
{
BOOL result = [self.api refundVoidWithAmount:amount
currency:currency
cardholder:YES
transaction:originalTransactionID];

if (result == false)
{
//Do something
}
}

#pragma mark - Device Management

- (void)connectToAddress:(NSString *)address
{
HeftRemoteDevice *remoteDevice = self.devices[address];

if (remoteDevice)
{
BOOL isRemoteDeviceSameAsPreferred = self.preferredDevice &&
[self.preferredDevice.address isEqualToString:remoteDevice.address];

// If we are already connected to this device, update shared secret
if (self.api && isRemoteDeviceSameAsPreferred)
{
// Already connected to device
}
else
{
self.preferredDevice = remoteDevice;

[self.manager clientForDevice:remoteDevice
sharedSecret:self.ssk
delegate:self];
}

[self connectionStatusChanged:ConnectionStatusConnecting];
}
else
{
NSLog(@"Can't connect. No device available. Have you searched?");
}
}

- (void)setLogLevel:(eLogLevel)logLevel
{
[self.api logSetLevel:logLevel];
}

- (void)getDeviceLogs
{
[self.api logGetInfo];
}

- (void)getPendingTransaction
{
BOOL success = NO;

if ([self.api isTransactionResultPending])
{
success = [self.api retrievePendingTransaction];
}

if (success)
{
//...
}
else
{
//...
}
}

- (void)update
{
[self.api financeInit];
}

- (void)listDevices
{
NSArray* devices = [self.manager connectedCardReaders];

/**
* A device can have four levels of connection: unpaired, paired,
* connected and connected in the SDK.
*
* Due to the nature of the iOS ExternalAccessory framework,
* devices that are already connected at an iOS level will not appear in a normal search,
* as they already appear through the "connectedCardReaders" array in the manager
* (Yeah, I know)
*
* So the "if" takes care of differentiating those two cases
*
* If we have device(s) connected we just go for those, otherwise, search.
*/

if(devices.count)
{
//We have device(s) already connected, we skip the search.
for (HeftRemoteDevice *device in devices)
{
[self addDevice:device];
}

[self didDiscoverFinished];
}
else
{
//We search and wait...
[self.manager startDiscovery];
}
}

# pragma mark - Callbacks

- (void)didFindAccessoryDevice:(HeftRemoteDevice*)newDevice
{
[self addDevice:newDevice];
}

- (void)didLostAccessoryDevice:(HeftRemoteDevice *)oldDevice
{
[self removeDevice:oldDevice];

if(self.preferredDevice && self.preferredDevice.address == oldDevice.address)
{
[self connectionStatusChanged:ConnectionStatusDisconnected];

self.preferredDevice = nil;
}
}

- (void)didDiscoverFinished
{
[self fillDevicesFromConnectedCardReaders];

for (NSString *key in [self.devices allKeys])
{
HeftRemoteDevice *device = self.devices[key];

if ([device.address isEqualToString:<my_saved_mac_address>])
{
//Do something with the device if it's the same one you expect.
break;
}
}
}

- (void)didConnect:(id <HeftClient>)client
{
if(client)
{
self.api = client;

[self connectionStatusChanged:ConnectionStatusConnected];
}
}

- (void)connectionStatusChanged:(ConnectionStatus)status
{
//Here you get notified of connection status changes
}

- (NSString *)stringFromConnectionStatus:(ConnectionStatus)status
{
switch(status)
{
case ConnectionStatusNotConfigured:
return @"NotConfigured";
case ConnectionStatusConnected:
return @"Connected";
case ConnectionStatusConnecting:
return @"Connecting";
case ConnectionStatusDisconnected:
return @"Disconnected";
case ConnectionStatusDisconnecting:
return @"Diconnecting";
case ConnectionStatusInitializing:
return @"Initializing";
}
}

- (void)responseStatus:(id <ResponseInfo>)info
{
//Here you'll get status updates during the transaction
}

- (void)responseError:(id <ResponseInfo>)info
{
//Here if something went wrong
}

- (void)responseFinanceStatus:(id <FinanceResponseInfo>)info
{
//Here's the result of your transaction
}

- (void)responseLogInfo:(id <LogInfo>)info
{
NSLog(@"\n\tresponseLogInfo: %@", info.status);
}

- (void)requestSignature:(NSString *)receipt
{
[self.api acceptSignature:YES];
}

- (void)addDevice:(HeftRemoteDevice *)device
{
self.devices[device.address] = device;
}

- (void)removeDevice:(HeftRemoteDevice *)device
{
if (self.devices[device.address])
{
[self.devices removeObjectForKey:device.address];
}
}

- (void)fillDevicesFromConnectedCardReaders
{
for (HeftRemoteDevice *device in [self.manager connectedCardReaders])
{
[self addDevice:device];
}
}

@end