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¶
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
3. Make sure you link with the following frameworks and libraries¶
libz.dylib
libc++.dylib
SystemConfiguration.framework
ExternalAccessory.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:
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:
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.