Methodology
Mobile API

Overview

There are two parts to the Mobile APIs, the end-to-end encryption method and the swipe device library.

End-to-End Encryption

The end-to-end encryption library allows credit card data to be encrypted on a mobile device before sending it to the Merchant's back-end server. During the sale process, the Merchant's server can send the encrypted card data to the Payment Gateway, where it is decrypted and treated like a normal credit card. This gives the merchant more control of mobile transactions without having to increase compliancy costs.

The merchant's encryption key is an RSA public key that is unique to them. This means that the encrypted credit card data will only be able to be used to make a transaction in that merchant's payment gateway account. Only the Payment Gateway has access to the private key that corresponds to this public key.

Card data is encrypted using AES encryption with a new randomly generated key for every card. This key is then encrypted with the public key along with the card data. This packet(the encrypted card and AES key) is unreadable to anybody without the private key which is only known to the Payment Gateway.

Note: The public key can NOT be used to decrpt an encrypted card. Once encrypted, the card is unusable except by the Gateway when it processes the payment for the merchant. For this reason, there is no need to keep the public key a secret.

Swipe Device Library

This library supports the encrypted card readers supported by the payment gateway. This includes parsing the data and notifying you when a card reader is connected, disconnected, ready to receive a swipe, etc.

Using the Library
Mobile API: iOS

Creating a Project

The fastest way to get started is to check out the PaymentGatewayEncryptionExample and PaymentGatewaySwipeExample projects that can be downloaded from the Payment Gateway's Integration section. If you prefer to create your own project instead, use these steps (current as of Xcode 4.5):

  1. Download the PaymentGatewayMobileSDK.zip file from the Integration section on the Payment Gateway.
  2. Create a new Xcode Project.
  3. Copy the files in the .zip file (PGMobileSDK.a and the folder PGMobileSDK containing the headers) into your project folder, and add them to your Xcode project.
  4. Add the following frameworks to your project:
    • AudioToolbox.framework
    • AVFoundation.framework
    • ExternalAccessory.framework
    • MediaPlayer.framework
    • Security.framework
  5. (Optional - see note below) - In your Info.plist, add a row for "Supported external accessory protocols", and add "com.gatewayprocessingservices.iprocess" as Item 0. This enables connection to the iDynamo swipe reader.

Note: You may wish to skip step 5 if you do not need to support the iDynamo. Apple requires manufacturers of accessories that use the dock connector to add your app to their product plan before approving your app for the app store. You will need to contact MagTek in order to have your app added to their product plan. See the MagTek iDynamo Software Submission Request Form here: http://www.magtek.com/documentation/public/99800121-1.01.pdf

Viewing documentation in Xcode

Adding the doc set to Xcode allows the most up-to-date, relevant documentation to appear in the IDE as you type. To enable access to the SDK documentation from inside Xcode:

  1. Under the Xcode menu, click Preferences
  2. Navigate to the Downloads page
  3. On the Documentation tab, click Add.
  4. On the "Enter a doc set feed URL" window that pops up, enter: https://secure.safewebservices.com/merchants/resources/integration/docset/iOSSDK.atom
  5. Click Add
  6. Click the newly-added install button

Important Info About the App Store

The Apple App Store's current policy is to require mobile apps to purchase digital goods (e.g. downloadable content, etc.) through the App Store. For that reason, this SDK is intended only for use in apps selling real-world goods and services. Please direct questions about Apple's App Store policies to Apple. Their policies are subject to change at their discretion.

End-to-End Encryption
Mobile API: iOS

Acquiring a Public Key

  1. After logging into the Payment Gateway, navigate to Settings->Security Keys->View Mobile SDK Key. You can click on the Objective-C example link to get a version that can easily be copied and pasted into your project.

  2. Use the Query API. In order to get the public key, you will need to use 'report_type=sdk_key'. The key will be returned in the <sdk_key> tag.

Encrypting a Card

#import "PGEncrypt.h"
#import "PGCards.h"

PGEncrypt encryption = [[PGEncrypt alloc] init];
[encryption setKey:
    @"***999|MIIEEjCCA3ugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBvTELMAkGA1UEBh"
    "MCVVMxETAPBgNVBAgTCElsbGlub2lzMRMwEQYDVQQHEwpTY2hhdW1idXJnMRgwFg"
                    [Several lines omitted]
    "cNAQEEBQADgYEAKY8xYc91ESNeXZYTVxEsFA9twZDpRjSKShDCcbutgPlC0XcHUt"
    "a2MfFPsdgQoq0I8y1nEn1qJiOuEG1t9Uwux4GAvAPzsWSsKyKQkZhqxrxkJUB39K"
    "Pg57pPytfJnlQTgYiSrycCEVHdDvhk92X7K2cab3aVV1+j0rKlR/Sy6b4=***"];


PGCard *cardData = [[PGKeyedCard alloc] initWithCardNumber:cardNumberField.text
                                            expirationDate:expirationField.text
                                                       cvv:cvvField.text];

NSString *encryptedCardData = [encryption encrypt:cardData includeCVV:NO];

encryptedCardData will contain a string that can be passed to the Payment Gateway in place of credit card information. The parameter name to use when passing this value through DirectPost is "encrypted_payment". For example, a simple DirectPost API string would look something like this:

(This example assumes your Merchant server is running a PHP script that has received the encrypted card data through a POST parameter called 'cardData'.)


//Business logic, validation, etc.  When ready to process the payment...

$cardData = $_POST['cardData'];
$postString = "username=demo&password=1234&type=sale&amount=1.00&encrypted_payment=$cardData";

//Post to Gateway
            

For more information on how to communicate with the Payment Gateway, see the API documentation.

Swipe Devices
Mobile API: iOS

Creating the Controller

In the class that intends to handle swipe events, create a PGSwipeController object in your init method. Initialize the object with this line to support Shuttle readers:

swipeController = [[PGSwipeController alloc] initWithDelegate:self audioReader:AudioJackReaderUnimag];

or for the IPS Encrypted Card Reader:

swipeController = [[PGSwipeController alloc] initWithDelegate:self audioReader:AudioJackReaderIps];

Only a single model of audio jack-connected reader can be enabled at a time. The audioReader parameter allows you to choose which type, UniMag (Shuttle) or IPS Encrypted Card Reader, you want to allow. See the PGSwipeController's initWithDelegate:audioReader: documentation for more details.

Your class will have to implement the PGSwipeDelegate protocol. If you are only interested in knowing when a card is swiped, you can safely leave every other event handler empty, as shown here (or add your own code to, for example, display an image indicating that the swipe reader is ready for a swipe). In this example, when the swipe is received, the card data is saved in a property (swipedCard) for eventual transmission to the Gateway (not shown), and two UITextField properties (cardNumberField and expirationField) are set to show the masked card number and expiration date.

If a bad swipe occurs, didSwipeCard:device: may still be called, but "card" will be nil. An error message is displayed in this example. Note: Not all card reader models give feedback when a bad swipe is received.

-(void)deviceConnected:(PGSwipeDevice *)sender
{
}

-(void)deviceDisconnected:(PGSwipeDevice *)sender
{
}

-(void)deviceActivationFinished:(PGSwipeDevice *)sender result:(SwipeActivationResult)result
{
}

-(void)deviceDeactivated:(PGSwipeDevice *)sender
{
}

-(void)deviceBecameReadyForSwipe:(PGSwipeDevice *)sender
{
}

-(void)deviceBecameUnreadyForSwipe:(PGSwipeDevice *)sender reason:(SwipeReasonUnreadyForSwipe)reason;
{
}

-(void)didSwipeCard:(PGSwipedCard *)card device:(PGSwipeDevice *)sender
{
    if (card != nil) {

        swipedCard = [card retain];

        cardNumberField.text = card.maskedCardNumber;
        expirationField.text = card.expirationDate;

    } else {

        //A nil card means that there was a swipe but it was unsuccessful.

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Swipe Error"
                                                        message:@"The reader was not able to read the card. Please Try Again."
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];

        [alert show];
        [alert release];
    }

}

Supported Devices


IPS Encrypted Card Reader

The IPS is an audio jack-connected card reader. Unlike the IDTECH Shuttle, the IPS is powered by an internal battery. The IPS has a fast startup time and does not produce a constant tone through the audio jack.

Because the IPS connects through the audio port and there is no way to immediately detect the device type, you will receive a deviceConnected: event even if the user has only plugged in headphones. Since there is no activation with the IPS, a deviceActivated: and deviceBecameReadyForSwipe: will also be sent immediately. In order to be sure that the device is an IPS reader, the PGSwipeIps provides a beginTestCommunication: method you can use to attempt to communicate with the device. If it returns success, the device is an IPS reader. This is not done by default to eliminate a delay before the device becomes active.

IDTECH Shuttle

The Shuttle (referred to in code as a UniMag device) is an audio jack-connected card reader. It is powered by a tone from the iPod / iPad / mobile phone. Before the Shuttle can receive swipes, it must be powered up.

Because the Shuttle connects through the audio port and there is no way to detect the device type until the device is activated, you will receive deviceConnected events whenever any device is attached to that port. For example, if the user attaches headphones, you will receive a connection event from the Mobile SDK.

The Mobile SDK can be configured to automatically attempt to power on the swipe reader immediately (this is the default), or you can disable the automatic activation and only activate the device when desired (e.g. on a payment screen, or when the user clicks a button).

Important: When powering on the device, the audio volume must be at maximum (done automatically by default). The tone generated through the audio port to activate the device can be very painful to a listener if they have connected speakers or headphones. For this reason, swipeController.uniMagReader.messageOptions.activateReaderWithoutPromptingUser is set to NO by default, causing the SDK to prompt the user for confirmation before activating the reader.

The Shuttle saves battery by only allowing swipes when a swipe has been requested, and a timeout occurs if a swipe is not received quickly enough (20 seconds by default). For simplicity, the SDK defaults to automatically requesting a swipe on activation and continuously renewing the swipe request. If you have issues with battery life, you can set swipeController.uniMagReader.alwaysAcceptSwipe to NO and manually call [swipeController.uniMagReader requestSwipe] when ready for a swipe.

iDynamo

The iDynamo connects to the mobile device via Apple's dock connector and is only compatible with iOS devices that use the older 30-pin (non-Lightning) dock connector.

When physically attached, the iDynamo is almost immediately ready to receive swipe events. When connected, the Swipe Delegate should expect a deviceConnected: message, immediately followed by a deviceActivationFinished: message, then a deviceBecameReadyForSwipe: message.

When the device is physically detached, the delegate receives the events in reverse order, i.e. deviceBecameUnreadyForSwipe:, deviceDeactivated:, deviceDisconnected:.

App Store: To support the iDynamo on an app distributed through the App Store, Apple may require you to contact Magtech for information before they will process your submission. To disable iDynamo support, do not add it to "Supported external accessory protocols" in your info.plist. You will still receive connect and disconnect events, but activation will fail, so be sure to check if the sending device is the iDynamo object and ignore it if so.

Known Issue with the iDynamo: There is an issue with device disconnection with the iDynamo and iOS's ExternalAccessory framework. Upon disconnection, the stream communicating with the device is closed, during which you may receive the warning: [NSCondition dealloc]: condition (<NSCondition: 0x1d54ce90> '(null)') deallocated while still in use. After reconnecting, a later disconnect may randomly cause the app to crash with an attempt to send a message to the deallocated instance. This does not occur frequently, and is more likely to occur when rapidly opening and closing the application (which sends a disconnect followed by a reconnect when the app re-opens). This issue is with Apple's accessory-handling framework. Apple is aware of the issue and may fix it in a future iOS release.

Classes Overview
Mobile API: iOS

PGSwipeController

The PGSwipeController contains a set of swipe reader classes that control individual swipe readers. This is the main Mobile Swipe SDK class required for using swipe devices, intended to be instantiated near the app's startup. The delegate you set on the PGSwipeController is the object that will receive all of the SDK's swipe events.

Through this class, you can access the controller classes for individual swipe device types (PGSwipeIps *ipsReader, PGSwipeIDynamo *iDynamoReader, and PGSwipeUniMag *uniMagReader).

You should be sure to call initWithDelegate rather than the parameterless init because during initialization a check is made to see if any devices are already connected and sends a deviceConnected event if they are. If the parameterless init is used, the initial connection message will be missed.

PGSwipeDevice

The PGSwipeDevice class represents the functionality that is common to the swipe reader devices. PGSwipeIDynamo and PGSwipeUniMag both use PGSwipeDevice as a base class.

A PGSwipeDevice object is passed along with every event generated by the swipe devices to allow you to identify the device type and access device-specific features by casting to the specific swipe type.

PGSwipeDelegate

The PGSwipeDelegate protocol must be implemented by the class that intends to receive swipe reader events. The following event handlers will need to be implemented.

PGSwipeIDynamo

This class is the interface to the iDynamo reader. It is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create a PGSwipeIDynamo instance to interact with the iDynamo device.

The iDynamo has no configurable options. When the device is attached, it is active and ready for swipe. The only property for the PGSwipeIDynamo class is a delegate to receive events, which should not be set directly. When the delegate is set for the PGSwipeController, the same delegate is passed to the PGSwipeIDynamo instance it contains.

PGSwipeUniMag

This class is the interface to the IDTECH Shuttle reader. It is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create a PGSwipeUniMag instance to interact with the Shuttle device.

There are several flags and methods available for the Shuttle. For an app that does not need much specific control of the swipe device and is mostly interested in the swipe event, the defaults can be kept and the device will power up and become ready for swipe when attached.

PGSwipeUniMagMessageOptions

This class contains a set of user-interaction options for the Shuttle device.

PGSwipeIps

This class is the interface to the IPS Encrypted Card Reader. It is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create a PGSwipeIps instance to interact with the IPS device.