IDTech iOS/OSX SDK Guide  1.1.052
API reference for BTPay 200
 All Data Structures Functions Variables Properties Pages
Sample Project Tutorial

Using Xcode 5.0+, we will create a sample project that will interface with the BTPay200 and will perform the following activities:

  • Execute a beep
  • Display unsecured message
  • Turn on/off MSR reader and perform a card capture
  • Request a PIN and capture KSN

Protocol Delegates:

  • Protocol to report unsolicited card swipes
  • Protocol to report captured PIN
  • Protocol to report device connected
  • Protocol to report device disconnected

Step 1: Create New Project

Create a new Single View Application in Xcode

new_project1.png
new_project2.png

Step 2: Import Frameworks

Import the necessary framework/libraries

Step 3: Add Protocol Strings to .pList

We would like the application to work with apple External Accessory protocol, so we will add the BTPay200 protocol string to the .pList:
Add Protocol Strings to .pList

Step 4: Design Interface

Design the User Interface by editing the iPhone storyboard file
Open your storyboard and add items to so it contains the following buttons/fields:

  • Add a label to the top that will signify connection/disconnection status.
  • Add a text view to communicate data from the BTPay200. Remove the Editable behavior if you don't want the keyboard to pop up if you accidentally select it.
  • Add buttons to execute the following functions:
    • Request PIN
    • Turn ON MSR
    • Turn OFF MSR
    • Send Message
    • Send Beep
xib.png

Step 5: Configure Header File

In the header file, perform the following:

  • Add Import statements to utilize frameworks
  • Amend the view controller interface
  • Create an IBOutlet for the UITextView and link it as a Referencing Outlet to the UITextView on the storyboard
  • Create an IBOutlet for the UILabel and link it as a Referencing Outlet to the UILabel on the storyboard
  • Create the 5 IBAction for the buttons, and link them to the "Touch Up Inside" event on the storyboard buttons
#import <UIKit/UIKit.h>
#import <IDTech/IDTech.h>
#import <ExternalAccessory/ExternalAccessory.h>
@interface ViewController : UIViewController <IDT_BTPay_Delegate>{
IBOutlet UITextView *tv;
IBOutlet UILabel *connectedLabel;
}
-(IBAction) msrON:(id)sender;
-(IBAction) msrOff:(id)sender;
-(IBAction) sendUnsecureMessage:(id)sender;
-(IBAction) device_sendBeep:(id)sender;
-(IBAction) requestPIN:(id)sender;
@end

Storyboard Source Code

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="13C1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="DEVICE DISCONNECTED" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E0F-BN-oKL">
<rect key="frame" x="0.0" y="20" width="320" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="13"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" editable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B4R-yf-dxd">
<rect key="frame" x="14" y="269" width="293" height="279"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uBt-t4-tkZ">
<rect key="frame" x="14" y="182" width="286" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Send Unsecured Message">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="sendUnsecureMessage:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="TOF-Lp-y60"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZqT-dn-dUn">
<rect key="frame" x="14" y="220" width="286" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Send Beep">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="device_sendBeep:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="Of8-WU-aQJ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Xz-6S-T1y">
<rect key="frame" x="14" y="68" width="286" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Request PIN">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="requestPIN:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="eQC-p1-qjT"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="841-S2-Myl">
<rect key="frame" x="17" y="106" width="286" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Turn ON MSR">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="msrON:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="jX1-O0-N84"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VKl-53-hV1">
<rect key="frame" x="17" y="144" width="286" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Turn OFF MSR">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="msrOff:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="hkB-ik-jO9"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
</view>
<connections>
<outlet property="connectedLabel" destination="E0F-BN-oKL" id="0Sj-NW-OEl"/>
<outlet property="tv" destination="B4R-yf-dxd" id="Dxt-QI-I57"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

Step 6: Configure Method File

In the header file, perform the following:

  • set delegate and initialize IDT_BTPay singleton object in the viewDidLoad method. Reference: Call the Singleton instance of the IDT_BTPay framework object
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [[IDT_BTPay sharedController] setDelegate:self];
    }
  • Implement protocol delegate IDT_BTPayDelegate::deviceDisconnected() and IDT_BTPayDelegate::deviceConnected() to monitor connect/disconnect events and modify our connection label upon change. Reference: Implement optional delegate protocols
    -(void) deviceConnected{
    [connectedLabel setText:@"DEVICE CONNECTED"];
    }
    -(void) deviceDisconnected{
    [connectedLabel setText:@"DEVICE DISCONNECTED"];
    }
  • Implement protocol delegate IDT_BTPayDelegate::pinpadData:keySN:event:() to receive pinpad data. Reference: Implement optional delegate protocols
    - (void) pinpadData:(NSData*)value keySN:(NSData*)KSN event:(EVENT_PINPAD_Types)event{
    if (event == EVENT_PINPAD_ENCRYPTED_PIN) {
    tv.text = [NSString stringWithFormat:@"%@\nPINBLOCK: %@",tv.text,value.description];
    tv.text = [NSString stringWithFormat:@"%@\nKSN: %@",tv.text,KSN.description];
    }
    }
  • Implement protocol delegate swipeMSRData:() to receive unsolicited card swipe data. Reference: Implement optional delegate protocols
    - (void) swipeMSRData:(IDTMSRData*)cardData{
    switch (cardData.event) {
    case EVENT_MSR_CARD_DATA:
    {
    switch (cardData.encryptionType) {
    case CaptureEncodeType_ISOABA:
    tv.text = [NSString stringWithFormat:@"%@\nEncryption Type: %@",tv.text, @"ISO/ABA"];
    break;
    case CaptureEncodeType_AAMVA:
    tv.text = [NSString stringWithFormat:@"%@\nEncryption Type: %@",tv.text, @"AA/MVA"];
    break;
    case CaptureEncodeType_Other:
    tv.text = [NSString stringWithFormat:@"%@\nEncryption Type: %@",tv.text, @"Other"];
    break;
    case CaptureEncodeType_Undecoded:
    tv.text = [NSString stringWithFormat:@"%@\nEncryption Type: %@",tv.text, @"Undecoded"];
    break;
    default:
    tv.text = [NSString stringWithFormat:@"%@\nEncryption Type: %@",tv.text, @"UNKNOWN"];
    break;
    }
    tv.text = [NSString stringWithFormat:@"%@\nTrack 1: %@",tv.text, cardData.track1];
    tv.text = [NSString stringWithFormat:@"%@\nTrack 2: %@",tv.text, cardData.track2];
    tv.text = [NSString stringWithFormat:@"%@\nTrack 3: %@",tv.text, cardData.track3];
    tv.text = [NSString stringWithFormat:@"%@\nEncoded Track 1: %@",tv.text, cardData.encTrack1.description];
    tv.text = [NSString stringWithFormat:@"%@\nEncoded Track 2: %@",tv.text, cardData.encTrack2.description];
    tv.text = [NSString stringWithFormat:@"%@\nEncoded Track 3: %@",tv.text, cardData.encTrack3.description];
    tv.text = [NSString stringWithFormat:@"%@\nHash Track 1: %@",tv.text, cardData.hashTrack1.description];
    tv.text = [NSString stringWithFormat:@"%@\nHash Track 2: %@",tv.text, cardData.hashTrack2.description];
    tv.text = [NSString stringWithFormat:@"%@\nHash Track 3: %@",tv.text, cardData.hashTrack3.description];
    tv.text = [NSString stringWithFormat:@"%@\nKSN: %@",tv.text, cardData.KSN.description];
    return;
    }
    break;
    case EVENT_MSR_CANCEL_KEY:
    {
    tv.text = [NSString stringWithFormat:@"%@\n(Event) MSR Cancel Key received: %@",tv.text, cardData.encTrack1];
    return;
    }
    break;
    case EVENT_MSR_BACKSPACE_KEY:
    {
    tv.text = [NSString stringWithFormat:@"%@\n(Event) MSR Backspace Key received: %@",tv.text, cardData.encTrack1];
    return;
    }
    break;
    case EVENT_MSR_ENTER_KEY:
    {
    tv.text = [NSString stringWithFormat:@"%@\n(Event) MSR Enter Key received: %@",tv.text, cardData.encTrack1];
    return;
    }
    break;
    case EVENT_MSR_UNKNOWN:
    {
    tv.text = [NSString stringWithFormat:@"%@\n(Event) MSR unknown event, data: %@",tv.text, cardData.encTrack1];
    return;
    }
    break;
    default:
    break;
    }
    }
  • Implement the button press methods
    -(IBAction) msrON:(id)sender{
    IDT_STATUS rt = [[IDT_BTPay sharedController] msr_startMSRSwipeWithDisplay:@"Please" line2:@"swipe card" line3:nil];
    tv.text = [NSString stringWithFormat:@"%@\nEnable MSR Return Status Code %i ",tv.text, rt];
    }
    -(IBAction) msrOff:(id)sender{
    IDT_STATUS rt = [[IDT_BTPay sharedController] msr_cancelMSRSwipe];
    tv.text = [NSString stringWithFormat:@"%@\nDisable MSR Return Status Code %i ",tv.text, rt];
    }
    -(IBAction) sendUnsecureMessage:(id)sender{
    IDT_STATUS rt = [[IDT_BTPay sharedController] lcd_displayMessage:@"This is" line2:@"an unsecured" line3:@"message." line4:@"Thank you!"];
    tv.text = [NSString stringWithFormat:@"%@\nDisplay Message Return Status Code %i ",tv.text, rt];
    }
    -(IBAction) device_sendBeep:(id)sender{
    unsigned short beep[] = {0xb00,0x400,0x800,0x300};
    IDT_STATUS rt = [[IDT_BTPay sharedController] device_sendBeep:beep numberOfTones:2];
    tv.text = [NSString stringWithFormat:@"%@\nControl Beep Return Status Code %i ",tv.text, rt];
    }
    -(IBAction) requestPIN:(id)sender{
    IDT_STATUS rt = [[IDT_BTPay sharedController] pin_getEncryptedPIN:@"1234567890123456" keyType:PIN_KEY_TDES_DUKPT_extp line1:@"Please" line2:@"input PIN" line3:nil];
    tv.text = [NSString stringWithFormat:@"%@\nRequest PIN Return Status Code %i ",tv.text, rt];
    }