IDTech iOS Framework Guide  1.1.088
API reference for UniPay
Sample Project Tutorial

We will add EMV capabilities to the previous sample project tutorial for UniPay:

  • start EMV transaction
  • complete EMV transaction

Protocol Delegates:

  • Protocol to report EMV card swipes
  • Protocol to report EMV data

Step 1: Create iOS Sample Project

Create the sample project for UniPay

Sample Project Tutorial

Step 2: Import Frameworks

Import the necessary framework/libraries

Step 3: Append Interface

Add to User Interface by editing the storyboard file
Open your main storyboard file, and add three more buttons:

  • Add a button to start EMV transaction.
  • Add a button to complete EMV transaction.
  • Add a button to cancel emv transaction:
emvstory.png

Step 4: Configure Header File

In the header file, perform the following:

#import <UIKit/UIKit.h>
#import <IDTech/IDTech.h>
#import <IDTechEMV/IDTechEMV.h>
@interface ViewController : UIViewController <IDT_UniPay_Delegate,IDTechEMV_Delegate>{
IBOutlet UITextView *tv;
IBOutlet UILabel *connectedLabel;
}
-(IBAction) msrON:(id)sender;
-(IBAction) msrOff:(id)sender;
-(IBAction) getFirmware:(id)sender;
-(IBAction) startEMV:(id)sender;
-(IBAction) completeEMV:(id)sender;
-(IBAction) cancelEMV:(id)sender;
@end

XIB Source Code

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</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="600" height="600"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="UNIPAY DISCONNECTED" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i1O-SW-UeA">
<rect key="frame" x="0.0" y="-21" width="42" height="21"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="g4D-Lo-gdS">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="L4N-Q3-gDw"/>
</constraints>
<state key="normal" title="Get Firmware">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="L4N-Q3-gDw"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="L4N-Q3-gDw"/>
</mask>
</variation>
<connections>
<action selector="getFirmware:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="LRv-H3-uBz"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qJM-Uo-OAl">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="mjm-6i-7SI"/>
</constraints>
<state key="normal" title="Start Swipe">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="mjm-6i-7SI"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="mjm-6i-7SI"/>
</mask>
</variation>
<connections>
<action selector="msrON:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="6sg-MT-Toy"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="e9C-sp-2x2">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="GEC-7y-53r"/>
</constraints>
<state key="normal" title="Cancel Swipe">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="GEC-7y-53r"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="GEC-7y-53r"/>
</mask>
</variation>
<connections>
<action selector="msrOff:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="kCd-Zc-dgc"/>
</connections>
</button>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cOU-wT-aWM">
<rect key="frame" x="0.0" y="0.0" width="240" height="128"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lno-54-uPL">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="jxp-gq-pgx"/>
</constraints>
<state key="normal" title="Start EMV Transaction">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="jxp-gq-pgx"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="jxp-gq-pgx"/>
</mask>
</variation>
<connections>
<action selector="startEMV:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="13Z-YV-Jna"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8oa-Fa-Cr0">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="g23-Uy-8zX"/>
</constraints>
<state key="normal" title="Complete EMV Transaction">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="g23-Uy-8zX"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="g23-Uy-8zX"/>
</mask>
</variation>
<connections>
<action selector="completeEMV:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="sFK-R4-fu6"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dZy-ey-pqm">
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="umd-iR-zI9"/>
</constraints>
<state key="normal" title="Cancel EMV Transaction">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="default">
<mask key="constraints">
<exclude reference="umd-iR-zI9"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="constraints">
<include reference="umd-iR-zI9"/>
</mask>
</variation>
<connections>
<action selector="cancelEMV:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="R4F-u7-jv3"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.7662318441" green="0.94110946179999999" blue="0.96664826770000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="dZy-ey-pqm" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="2L0-nG-LIK"/>
<constraint firstItem="g4D-Lo-gdS" firstAttribute="top" secondItem="i1O-SW-UeA" secondAttribute="bottom" constant="8" id="4JI-80-Dtl"/>
<constraint firstItem="e9C-sp-2x2" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="4ql-n9-Mob"/>
<constraint firstItem="Lno-54-uPL" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="7Iq-0b-6tA"/>
<constraint firstItem="cOU-wT-aWM" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="DkE-hg-tZJ"/>
<constraint firstItem="8oa-Fa-Cr0" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="Fcg-Ny-8dU"/>
<constraint firstItem="qJM-Uo-OAl" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="Gei-Yo-Nnl"/>
<constraint firstItem="8oa-Fa-Cr0" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="JLi-BG-iUm"/>
<constraint firstItem="qJM-Uo-OAl" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="MiH-76-1tD"/>
<constraint firstItem="Lno-54-uPL" firstAttribute="top" secondItem="e9C-sp-2x2" secondAttribute="bottom" constant="8" id="Nca-eQ-6sS"/>
<constraint firstItem="dZy-ey-pqm" firstAttribute="top" secondItem="8oa-Fa-Cr0" secondAttribute="bottom" constant="8" id="V2B-L0-Dzc"/>
<constraint firstItem="g4D-Lo-gdS" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="atl-BT-IkW"/>
<constraint firstItem="cOU-wT-aWM" firstAttribute="top" secondItem="e9C-sp-2x2" secondAttribute="bottom" constant="122" id="bUd-oq-RSO"/>
<constraint firstItem="dZy-ey-pqm" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="ctt-g9-K00"/>
<constraint firstItem="e9C-sp-2x2" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="dsT-QT-3pX"/>
<constraint firstItem="i1O-SW-UeA" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="fvJ-Jb-F4D"/>
<constraint firstItem="g4D-Lo-gdS" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" id="i8i-vS-GHG"/>
<constraint firstItem="cOU-wT-aWM" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="kTP-Pr-rCR"/>
<constraint firstItem="e9C-sp-2x2" firstAttribute="top" secondItem="qJM-Uo-OAl" secondAttribute="bottom" constant="8" id="lOc-pC-2TS"/>
<constraint firstItem="Lno-54-uPL" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="nYS-LI-2HM"/>
<constraint firstItem="qJM-Uo-OAl" firstAttribute="top" secondItem="g4D-Lo-gdS" secondAttribute="bottom" constant="8" id="o1P-I3-vHp"/>
<constraint firstItem="8oa-Fa-Cr0" firstAttribute="top" secondItem="Lno-54-uPL" secondAttribute="bottom" constant="8" id="pCl-es-4vT"/>
<constraint firstItem="i1O-SW-UeA" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" id="tmv-so-RdM"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="cOU-wT-aWM" secondAttribute="bottom" constant="20" id="wPc-2Y-bol"/>
<constraint firstItem="i1O-SW-UeA" firstAttribute="trailing" secondItem="kh9-bI-dsS" secondAttribute="trailingMargin" id="zKQ-gV-BB6"/>
</constraints>
<variation key="default">
<mask key="subviews">
<exclude reference="i1O-SW-UeA"/>
<exclude reference="g4D-Lo-gdS"/>
<exclude reference="qJM-Uo-OAl"/>
<exclude reference="e9C-sp-2x2"/>
<exclude reference="cOU-wT-aWM"/>
<exclude reference="Lno-54-uPL"/>
<exclude reference="8oa-Fa-Cr0"/>
<exclude reference="dZy-ey-pqm"/>
</mask>
<mask key="constraints">
<exclude reference="fvJ-Jb-F4D"/>
<exclude reference="tmv-so-RdM"/>
<exclude reference="zKQ-gV-BB6"/>
<exclude reference="4JI-80-Dtl"/>
<exclude reference="atl-BT-IkW"/>
<exclude reference="i8i-vS-GHG"/>
<exclude reference="Gei-Yo-Nnl"/>
<exclude reference="MiH-76-1tD"/>
<exclude reference="o1P-I3-vHp"/>
<exclude reference="4ql-n9-Mob"/>
<exclude reference="dsT-QT-3pX"/>
<exclude reference="lOc-pC-2TS"/>
<exclude reference="7Iq-0b-6tA"/>
<exclude reference="Nca-eQ-6sS"/>
<exclude reference="nYS-LI-2HM"/>
<exclude reference="Fcg-Ny-8dU"/>
<exclude reference="JLi-BG-iUm"/>
<exclude reference="pCl-es-4vT"/>
<exclude reference="2L0-nG-LIK"/>
<exclude reference="V2B-L0-Dzc"/>
<exclude reference="ctt-g9-K00"/>
<exclude reference="DkE-hg-tZJ"/>
<exclude reference="bUd-oq-RSO"/>
<exclude reference="kTP-Pr-rCR"/>
<exclude reference="wPc-2Y-bol"/>
</mask>
</variation>
<variation key="widthClass=compact">
<mask key="subviews">
<include reference="i1O-SW-UeA"/>
<include reference="g4D-Lo-gdS"/>
<include reference="qJM-Uo-OAl"/>
<include reference="e9C-sp-2x2"/>
<include reference="cOU-wT-aWM"/>
<include reference="Lno-54-uPL"/>
<include reference="8oa-Fa-Cr0"/>
<include reference="dZy-ey-pqm"/>
</mask>
<mask key="constraints">
<include reference="fvJ-Jb-F4D"/>
<include reference="tmv-so-RdM"/>
<include reference="zKQ-gV-BB6"/>
<include reference="4JI-80-Dtl"/>
<include reference="atl-BT-IkW"/>
<include reference="i8i-vS-GHG"/>
<include reference="Gei-Yo-Nnl"/>
<include reference="MiH-76-1tD"/>
<include reference="o1P-I3-vHp"/>
<include reference="4ql-n9-Mob"/>
<include reference="dsT-QT-3pX"/>
<include reference="lOc-pC-2TS"/>
<include reference="7Iq-0b-6tA"/>
<include reference="Nca-eQ-6sS"/>
<include reference="nYS-LI-2HM"/>
<include reference="Fcg-Ny-8dU"/>
<include reference="JLi-BG-iUm"/>
<include reference="pCl-es-4vT"/>
<include reference="2L0-nG-LIK"/>
<include reference="V2B-L0-Dzc"/>
<include reference="ctt-g9-K00"/>
<include reference="DkE-hg-tZJ"/>
<include reference="bUd-oq-RSO"/>
<include reference="kTP-Pr-rCR"/>
<include reference="wPc-2Y-bol"/>
</mask>
</variation>
</view>
<connections>
<outlet property="connectedLabel" destination="i1O-SW-UeA" id="aq7-Us-Fcj"/>
<outlet property="tv" destination="cOU-wT-aWM" id="5kv-jl-7Yp"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="205.5" y="385"/>
</scene>
</scenes>
</document>
  • Implement the button press methods
-(IBAction)startEMV:(id)sender{
[[IDTechEMV sharedController] startEMVTransaction:2.95 timeout:30 transactionType:0 additionalTags:nil];
}
-(IBAction)completeEMV:(id)sender{
[[IDTechEMV sharedController] completeOnlineEMVTransaction:EMV_COMPLETION_RESULT_ACCEPTED resultCode:@"00" issuerAuthenticationData:nil issuerScripts:nil];
}
-(IBAction) cancelEMV:(id)sender{
[[IDTechEMV sharedController] cancelTransaction];
}
  • Implement the EMV delegates
- (void) emvTransactionMessage:(MESSAGE_Types)message{
switch (message) {
case MESSAGE_INSERT_CARD:
[self appendMessageToResults:@"PLEASE INSERT OR SWIPE CARD"];
break;
case MESSAGE_REMOVE_CARD:
[self appendMessageToResults:@"PLEASE REMOVE CARD"];
break;
case MESSAGE_BAD_ICC:
[self appendMessageToResults:@"CHIP READ ERROR-USE MSR"];
break;
case MESSAGE_TRANSACTION_CANCELLED:
[self appendMessageToResults:@"TRANSACTION CANCELLED"];
break;
case MESSAGE_FALLBACK_FAILED:
[self appendMessageToResults:@"FALLBACK FAILED"];
break;
case MESSAGE_USE_CHIP_READER:
[self appendMessageToResults:@"MUST USE ICC READER"];
break;
case MESSAGE_PROCESSING:
[self appendMessageToResults:@"PROCESSING"];
break;
case MESSAGE_READY:
[self appendMessageToResults:@"UniPay Ready"];
break;
case MESSAGE_USE_MSR:
[self appendMessageToResults:@"Please Swipe Card"];
break;
case MESSAGE_NOT_ACCEPTED:
[self appendMessageToResults:@"Not Accepted"];
break;
default:
break;
}
}
- (void) swipeMSRDataEMV:(IDTMSRData*)cardData emv:(NSDictionary*)emvData{
switch (cardData.event) {
case EVENT_MSR_CARD_DATA:
{
switch (cardData.captureEncodeType) {
case CAPTURE_ENCODE_TYPE_ISOABA:
[self appendMessageToResults:[NSString stringWithFormat:@"Encryption Type: %@", @"ISO/ABA"]];
break;
case CAPTURE_ENCODE_TYPE_AAMVA:
[self appendMessageToResults:[NSString stringWithFormat:@"Encryption Type: %@", @"AA/MVA"]];
break;
case CAPTURE_ENCODE_TYPE_Other:
[self appendMessageToResults:[NSString stringWithFormat:@"Encryption Type: %@", @"Other"]];
break;
case CAPTURE_ENCODE_TYPE_Raw:
[self appendMessageToResults:[NSString stringWithFormat:@"Encryption Type: %@", @"Raw"]];
break;
default:
[self appendMessageToResults:[NSString stringWithFormat:@"Encryption Type: %@", @"UNKNOWN"]];
break;
}
if (cardData.cardData.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Full card data: %@", cardData.cardData]];
if (cardData.track1 > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Track 1: %@", cardData.track1]];
if (cardData.track2 > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Track 2: %@", cardData.track2]];
if (cardData.track3 > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Track 3: %@", cardData.track3]];
if (cardData.encTrack1.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Encoded Track 1: %@", cardData.encTrack1.description]];
if (cardData.encTrack2.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Encoded Track 2: %@", cardData.encTrack2.description]];
if (cardData.encTrack3.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Encoded Track 3: %@", cardData.encTrack3.description]];
if (cardData.hashTrack1.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Hash Track 1: %@", cardData.hashTrack1.description]];
if (cardData.hashTrack2.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Hash Track 2: %@", cardData.hashTrack2.description]];
if (cardData.hashTrack3.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"Hash Track 3: %@", cardData.hashTrack3.description]];
if (cardData.KSN.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"KSN: %@", cardData.KSN.description]];
if (cardData.sessionID.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"\nSessionID: %@", cardData.sessionID.description]];
if (cardData.RSN.length > 0) [self appendMessageToResults:[NSString stringWithFormat:@"\nReader Serial Number: %@", cardData.RSN]];
[self appendMessageToResults:[NSString stringWithFormat:@"\nRead Status: %2X", cardData.readStatus]];
if (emvData != nil) {
[self appendMessageToResults:emvData.description];
}
return;
}
break;
default:
break;
}
[self appendMessageToResults:[NSString stringWithFormat:@"Tags: %@",emvData.description]];
}
- (void) emvTransactionData:(IDTEMVData*)emvData errorCode:(int)error performReversal:(BOOL)reversal{
[self appendMessageToResults:[NSString stringWithFormat:@"Result code = %2X, Error Code %4X",emvData.resultCode,error]];
Byte *b = malloc(1);
NSData*CID = [emvData.unencryptedTags objectForKey:@"9F27"];
[CID getBytes:b];
if (b[0] == 0x01) {
[self appendMessageToResults:@"ERROR: SERVICE NOT ALLOWED"];
free(b);
return;
}
if (reversal) {
[self appendMessageToResults:@"WARNING: TRANSACTIONS WAS APPROVED ONLINE, BUT TERMINAL DECLINED. PLEASE REVERSE/VOID ONLINE APPROVAL FOR THIS TRANSACTION"];
}
bool isError = (error != 0x100);
if (!isError || emvData.resultCode == 2) {
[self appendMessageToResults:@"GENERATE AC RESULTS:"];
}
else {
[self appendMessageToResults:@"ERROR: TRANSACTION TERMINATED"];
}
if (emvData.unencryptedTags != nil) {
[self appendMessageToResults:[NSString stringWithFormat:@"Tags:\n%@",emvData.unencryptedTags.description]];
}
if ((emvData.resultCode == 2) || (b[0] == 0x88) || (b[0] == 0x8B) || (b[0] == 0x8A)) {
[self appendMessageToResults:@"GO ONLINE"];
return;
}
else{
NSString* cvmString = [(NSData*)[emvData.unencryptedTags objectForKey:@"9F34"] description];
NSString* results = @"SUCCESS - TC";
if ([CID.description hasPrefix:@"<0"]) {
results = @"DECLINE - AAC";
}
[self appendMessageToResults:[NSString stringWithFormat:@"RESULT: %@\nTVR: %@\nTSI: %@\nCVM: %@",results,[(NSData*)[emvData.unencryptedTags objectForKey:@"95"] description],[(NSData*)[emvData.unencryptedTags objectForKey:@"9B"] description],cvmString]];
}
free(b);
}