AgentCASH SDK for iOS

The AgentCASH SDK makes it possible to accept card payments with an AgentCASH card reader from any iOS app.

Main features

  • Take card payments with an AgentCASH card reader.
  • Refund card payments.
  • Retrieve information about a payment.

Installation

CocoaPods Installation

CocoaPods is an easy way to install AgentCASH SDK.

1. Podfile

source 'https://github.com/CocoaPods/Specs.git'
source 'https://bitbucket.org/agentcash/agentcash-pods.git'

target :"<your target>" do
    platform :ios, '8.0'
    pod 'AgentCASHSDK'
end

2. Continue from step 5 in manual installation process.

Manual Installation

1. Requirements

  • iOS 8.0 or later
  • Xcode 6 (iOS 8 SDK)
  • An AgentCASH API Key. Please contact us at support@agentcash.com in order to obtain one)

2. Include the following framework and bundles in your project

AgentCASHSDK.framework

4. Modify your targets “Other Linker Flags” and add

-ObjC

5. Setup external accessory protocols in info.plist

Add/modify the property “Supported external accessory protocols” and add com.miura.shuttle.agentcash

This is what it should look like in the “source code” view of your info.plist:

<key>UISupportedExternalAccessoryProtocols</key>
<array>
<string>com.miura.shuttle.agentcash</string>
</array>

Important

The AgentCASH bluetooth card reader is part of the Apple MFi program. In order to release apps supporting accessories that are part of the MFi Program, you have to apply at Apple. Please contact us at support@agentcash.com and we will help you with this process.

6. Include the framework headers and use the SDK

Make sure to include the AgentCASH SDK header:

#import <AgentCASHSDK/AgentCASHSDK.h>

Integration

Before you execute any operations with AgentCASH SDK, you’ll have to initialise the payment provider. This is typically done only once, in your AppDelegate method application:didFinishLaunchingWithOptions: or in your main view controller.

ACPaymentProvider *paymentProvider;
paymentProvider = [ACPaymentProvider paymentProviderWithType:acPaymentProviderType_Mock
                                                    username:@"PUT_YOUR_AGENTCASH_USERNAME_HERE"
                                                    password:@"PUT_YOUR_AGENTCASH_PASSWORD_HERE"];

The first parameter defines how SDK behaves. There are three possible modes of operation:

  • acPaymentProviderType_Mock - All operations are simulated on the client.
  • acPaymentProviderType_Test - SDK connects to the test reader and to the test payment gateway. However, no real charge is done.
  • acPaymentProviderType_Production - SDK connects to the production payment gateway. Used when going live.

Mock mode

You can test the integration by using the Mock mode. In the Mock mode, AgentCASH SDK does not connect to the card reader or the payment gateway. It just simulates a transaction workflow. To use Mock mode, pass acPaymentProviderType_Mock parameter when initializing the payment provider. You can test various payment scenarios depending on the amount:

  • xxx.01 - if you charge the amount which ends with .01, SDK will emulate signature-authorised transaction,
  • xxx.99 - if you charge the amount which ends with .99, SDK will emulate declined transaction,
  • everything else - if you charge any other amount (not ending with .01 or 0.99), SDK will emulate PIN-authorised, approved transaction.

Test mode

Test mode is similar to production mode, but no real charge is done. Application will communicate with the reader and with the test payment gateway. You’ll be able to see successful and failed transactions on your AgentCASH web dashboard (dev.agentcash.net)

Production mode

Before going into production, AgentCASH will have to check your mobile application, the payment flow and receipts to ensure that everything complies with the rules and regulations set by the acquirer and the card schemes. Please contact us at support@agentcash.com when you are ready to go live with your solution.

Charge

As the first step, you’ll have to create an instance of the ACAuthRequestParams class and fill it with authorisation parameters, like amount or currency.

ACAuthRequestParams *p = [[ACAuthRequestParams alloc] init];
p.amount = [NSDecimalNumber decimalNumberWithString:@"15.99"];
p.currency = @"GBP";
p.capture = YES;
p.installmentCount = 1;
p.externalId = @"1234567890";
p.webhookURL = @"http://www.myserver.com/mycallback";
  • amount - A positive decimal number (with up to two decimals) representing how much to charge.
  • currency - 3-letter ISO 4217 currency code (e.g. GBP or EUR).
  • capture - Whether or not to immediately capture the charge. When NO, the charge issues an authorisation (or pre-authorisation), and will need to be captured later.
  • installmentCount - Number of installments for the charge. Should be 1.
  • externalId - A string that you can attach to a charge object. It can be useful for storing additional information about the charge (for example the invoice ID or your internal reference number).
  • webhookURL - A URL that we will notify anytime an event happens in your account. When the event occurs—for example, when a successful charge is made, AgentCASH creates an Event object. This object contains all the relevant information about what just happened, including the type of event and the data associated with that event. Creating a webhoook endpoint on your server is no different from creating any page on your website. Webhook data is sent as JSON in the POST request body. The full event details are included and can be used directly, after parsing the JSON into an Event object.

Initialising the card reader

As the second step, you’ll have to specify the card reader you want to use for the transaction.

Bluetooth card readers are initialised by specifying the name of the Bluetooth device:

ACCardReader *reader = [ACCardReader bluetoothCardReaderWithVendor:ACCardReaderVendorMiura name:@"AgentCASH xxx"];

where xxx are the last three digits of the reader’s serial number.

WiFi card readers are initialised by specifying the IP address and the port of the device:

[ACCardReader networkCardReaderWithVendor:ACCardReaderVendorMiura address:@"192.168.0.90 port:6543];
Wi-Fi Configuration

Terminals equipped with a Wi-Fi interface require a "wifi.cfg" file to be dowloaded before the Wi-Fi interface will operate. There is no default "wifi.cfg" file. The format of the file is show below:

[general]
dhcp = false
## If dhcp is true the following parameters are ignored.
## If dhcp is false they are all mandatory except for dns.
address = 192.168.0.90
netmask = 255.255.255.0
gateway = 192.168.0.1
dns = 0.0.0.0
#server_address = 192.168.0.100
#server_port = 3456
listen_port = 6543

[ap_00]
ssid = "<your-SSID>"
psk = "<your-psk>"

[ap_01]
ssid = "<your-other-SSID>"
psk = "<your-other-psk>"

In the [general] section, set dhcp = false when a static IP configuration is required, and change the address, netmask, gateway, and optionally dns values to suit your access point(s). listen_port is mandatory. MPI will listen on listen_port port for a connection from an application on the IP address it has been assigned. The subsequent sections are used to specify access points, and have section names [ap_00] through to [ap_09]. Only [ap_00] is required. Any further access point sections can be specified if the terminal is expected to roam between multiple access points.

Starting a transaction

You start the transaction by calling authorize method of the ACPaymentProvider, passing the ACAuthRequestParams object from the first step as the first parameter and passing the ACCardReader object from the second step as the second parameter.

currentRequest = [paymentProvider authorize:p
                                     cardReader:reader
                                progressChanged:^(ACRequest *request,
                                                  ACPaymentProcessState state)
    {
        // This block will be invoked at each status change of the payment process. 
        // You can use it for logging or for updating the progress message on your screen.
    }
                             userActionRequired:^(ACRequest *request,
                                                  ACPaymentUserAction userAction)
    {
        // This block will be invoked when some user action is required, for example 
        // when a card reader decides that transaction should be authorised with a signature.
    }
                                      completed:^(ACRequest *request,
                                                  NSError *error)
    {
	    // This block will be invoked when the transaction finishes. If transaction could 
	    // not be processed, error parameter will be != nil and will contain detailed error information. 
        // If transaction completes successfully (i.e. error == nil), request.paymentInfo 
        // will contain information about the payment. You will need this information for 
        // creating a custom payment receipt.
    }];

Signature

In the case when the card requires signature authorisation, payment provider will invoke userActionRequired block with userAction parameter set to ACPaymentUserActionCollectSignature.

If this happens, your task will be to display the signature capture dialog, where customer will paint the signature with his finger. It should look similar to this one: Signature collection screen

In the case when customer declines to authorise the transaction and presses “Cancel”, you will have to cancel the current request by invoking [request continueWithSignature:nil signatureCollectionResult:ACSignatureCollectionCancelled];

In the more common case, when customer successfully signs on the screen and presses Authorise, application should ask the merchant to match the signature on the back of the card to the signature on the screen. It should be done by displaying an appropriate confirmation dialog similar to this one:

Signature verification screen

In the case when signatures don’t match, application should cancel the transaction by invoking [request continueWithSignature:signatureImage signatureCollectionResult:ACSignatureCollectionSignaturesDontMatch] and advise the operator to adhere to the merchant store procedures and respond accordingly.

In the case when signatures match, application should finish the transaction by calling [request continueWithSignature:signatureImage signatureCollectionResult:ACSignatureCollectionSuccessful], where signatureImage is image collected in the previous step.

Signature will be stored on AgentCASH servers and will be shown on digital and printed receipts and used in case of chargeback - i.e. as a proof of authorisation if customer later decides to dispute the transaction through his issuing bank. URL to the stored signature image can be later accessed as one of the fields of ACPaymentInfo object.

Auth & Capture

AgentCASH does support two-step payments, also known as “auth and capture”. This process allows you to authorise a charge and wait to settle it later.

Authorisation

When creating the charge, you’ll want to pass in the capture parameter as NO.

Capture

When you’re ready to actually accept the payment, you’ll just need to make a second API call to capture the charge. By default, we’ll capture the total amount that was authorised. If you want to charge less than the initial amount, you can pass in the amount parameter and we’ll refund the rest back to the customer. Note that a charge must be captured within several days (depending on the acquirer) or it will be cancelled. You can also manually cancel an uncaptured payment by refunding it via the API or in your dashboard.