On iOS
Refers to iOS SDK v4.0
The Clover Connector iOS SDK provides an interface that enables your point-of-sale (POS) software to interact with Clover’s customer-facing payment devices.
This tutorial will guide you through the process of connecting to your Clover device, initiating a Sale request, and handling the response to your Sale request. It covers the current version of the SDK (v4.0).
Platform-specific prerequisites
In addition to the prerequisites in Use Clover Connector, this tutorial assumes you have already:
- Installed the Secure Network Pay Display app (currently available for Clover Flex, Clover Mini, and Clover Mobile)
- Installed the appropriate IDE on your computer. The iOS SDK requires:
Your Podfile entry should look like this:
pod 'Starscream', :git => 'https://github.com/clover/Starscream.git', :branch => 'queuePriority'
pod 'CloverConnector', :git => 'https://github.com/clover/remote-pay-ios.git', :tag => '3.0.2'
post_install do |installer|
['CloverConnector'].each do |targetName|
targets = installer.pods_project.targets.select { |target| target.name == targetName }
target = targets[0]
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.0'
end
end
end
Connectivity
The iOS SDK currently supports network tethering via WebSockets only.
Configure a connection
To connect your iOS device to the Clover device, complete the following steps to pair the two devices.
- Connect your POS to the Clover device. The Clover device sends a pairing code to the POS.
- Enter the code your POS received on the Clover device.
The Clover device will send a pairingAuthToken
to the POS. The POS uses the pairingAuthToken
for the next connection, streamlining the pairing process.
The pairingAuthToken
is single-use. Clover will expire the original pairingAuthToken
and send a new one to the POS for each connection.
NOTE
To create a secure connection:
- Install the Clover Device Server Root CA certificate on the iOS device. The certificate is hosted at
https://sandbox.dev.clover.com/v2/device_ca_certificate.der
. Once you install the certificate, you can find it at Settings > General > Profile > Clover Device Server Root CA. Confirm that the certificate is verified.- Manually trust the installed certificate at Settings > General > About > Certificate Trust Settings. Under ENABLE FULL TRUST FOR ROOT CERTIFICATES, enable trust for the installed certificate.
/// To connect over a network, you will need a PairingDeviceConfiguration
/// class to handle pairing callbacks from the Clover device
class ExamplePairingDeviceConfig : PairingDeviceConfiguration {
@objc private func onPairingCode(pairingCode: String) {
// present pairingCode to the user to be
// entered on the Clover Device
...
}
@objc private func onPairingSuccess(authToken: String) {
// The authToken can be used for the next connection
// WebSocketDeviceConfiguration (see pairingAuthToken below)
...
}
}
let pdc = ExamplePairingDeviceConfig()
// ws vs wss must match Network Pay Display setting
// wss requires Clover root CA
let endpoint = "ws://192.168.0.15:12345/remote_pay"
// Network Pay Display must be installed and configured to allow
// insecure connections for the above configuration
// Create a WebSocketDeviceConfiguration with the appropriate
// remoteApplicationID (see above), POS name, and POS serial number
let configuration = WebSocketDeviceConfiguration(endpoint: endpoint,
// remoteApplicationID, posName and
// posSerial are associated with
// pairingAuthToken
remoteApplicationID: "SWDEFOTWBD7XT.9MGLGMDLSYWTV",
posName: "Aisle 2",
posSerial: "ABC123",
pairingAuthToken: nil,
// use token from onPairingSuccess callback
pairingDeviceConfiguration: pdc)
Create a Clover Connector
Create a Clover Connector and pass in the configuration from the previous step.
/// Use instance of WebSocketDeviceConfiguration
cloverConnector = CloverConnector(config: configuration)
Add a listener to the Clover Connector
- Define an
ICloverConnectorListener
that will listen for callbacks when transactions finish and other events occur. Include the connection status methods that will be called.
OnDeviceDisconnected()
– The Clover device is not available.OnDeviceConnected()
– The Clover device is connected, but not available to process requests.OnDeviceReady()
– The device is connected and available to process requests. It will automatically pass in aMerchantInfo
object with information about the device, merchant, and some potential merchant payment configuration data, such assupportsAuths
orsupportsVaultCards
.
// Create an implementation of ICloverConnectorListener
class ExampleCloverConnectorListener : DefaultCloverConnectorListener {
override func onDeviceDisconnected() {
// Disconnected
...
}
override func onDeviceConnected() {
// Connected, but not available to process requests
...
}
override func onDeviceReady(merchantInfo: MerchantInfo) {
// Connected and available to process requests
...
}
}
- Add the listener to the Clover Connector.
// Add an instance of an ICloverConnectorListener
let ccl = ExampleCloverConnectorListener(cloverConnector: cloverConnector)
cloverConnector.addCloverConnectorListener(ccl)
Initialize the connection
Initialize the connection to start communication with the Clover device. Note that you must do this before calling any other methods (other than those that add or remove listeners).
cloverConnector.initializeConnection()
Display a message on the Clover device
Send a test message to the Clover device.
cloverConnector.showMessage("Welcome to Clover Connector!")
Now that you’ve connected to the Clover device and sent a successful test message, you’re ready to start making requests.
Initiate a sale from your POS software
To make a Sale()
request:
- Define how to handle the
SaleResponse
in yourICloverConnectorListener
first. The truncated code below provides a generalized overview of the methods you’ll need to use to get a response to your request for aSale
. A detailed interpretation of the SaleResponse appears in the Handle the result of a Sale transaction section section.
public class ExampleCloverConnectorListener:DefaultCloverConnectorListener {
…
public override func onSaleResponse(_ response:SaleResponse){
// check response for success and process accordingly
// see the ‘Handling the Result of a Sale Transaction’ section below for more detail
…
}
public override func onConfirmPaymentRequest(){
// must accept or reject the payment using the ICloverConnector
// see the ‘Handling the Result of a Sale Transaction’ section below for more detail
…
}
public override func onVerifySignatureRequest(_ request:VerifySignatureRequest) {
// must accept or reject the signature using the ICloverConnector
// see the ‘Handling the Result of a Sale Transaction’ section below for more detail
…
}
…
}
- Create a
SaleRequest
and call theSale()
method.
/// hold the pendingPaymentId to track the payment within Clover
let uuid = NSUUID().uuidString as NSString
let pendingPaymentId = uuid.replacingOccurrences(of: "-", with: "")
let saleRequest = SaleRequest(amount: 2250, externalId: pendingPaymentId)
cloverConnector!.sale(saleRequest)
NOTE
The code snippets in this tutorial are not feature-rich. For the best way to implement the SDK in production, see the Example iOS POS.
Once you call the Sale()
method, Clover will contact the payment gateway and return information about the result of the transaction to your POS.
Handle the result of a sale transaction
After Clover has finished processing the Sale
transaction request, OnSaleResponse()
will be called. Transaction responses have a boolean Success
property, as well as an enum Result
property that provides information on the success flag.
If the transaction is successful, the response will also have the Payment
object, which may contain the full or partial amount of the Sale request.
NOTE
A
Sale
transaction may come back as a tip-adjustableAuth
, depending on the payment gateway. TheSaleResponse
includes a booleanisSale
variable that indicates whether theSale
is final, or will be finalized during closeout.
class ExampleCloverConnectorListener:DefaultCloverConnectorListener {
override func onSaleResponse(response: SaleResponse) {
if response.success {
if let payment = response.payment {
if pendingPaymentId == payment.externalPaymentId {
// it is the expected payment
debugPrint("Got the payment for \(payment.amount ?? -1)")
} else {
debugPrint("Got a response, but not for the expected payment")
}
} else {
debugPrint("Something went wrong...No payment found!")
}
} else {
debugPrint("Payment failed: \(response.reason):\(response.message)")
}
cloverConnector?.dispose() /// if done using the connector, dispose of it
}
// a sale may require payment confirmation requests from the Clover device
override func onConfirmPaymentRequest(request: ConfirmPaymentRequest) {
// by default, Clover will just accept the payment
if let payment = request.payment {
cloverConnector?.acceptPayment(payment)
} else {
debugPrint("Payment is nil in ConfirmPaymentRequest")
}
}
// a sale may require signature verification requests from the Clover device
override func onVerifySignatureRequest(signatureVerifyRequest: VerifySignatureRequest)
{
// by default, Clover will just accept the signature
cloverConnector?.acceptSignature(signatureVerifyRequest)
}
}
Sale transaction errors
OnSaleResponse()
also returns one of the following codes:
Code | Description |
---|---|
SUCCESS | Call succeeded and was successfully queued or processed. |
FAIL | Call failed due to an incorrect value that was passed in, an invalid card, insufficient funds, or another reason. |
UNSUPPORTED | Current merchant configuration doesn’t support the capability. |
CANCEL | Merchant or customer has pressed the Cancel or Back button on the Clover device. |
ERROR | Unexpected error or error that wasn't handled appropriately. Returned when the SDK encounters one of the following problems: - Device Connection Error : Clover device is not connected.- Request Validation Error : Request that was passed in for processing is empty.- Request Validation Error : Request ExternalId cannot be null or blank.- Request Validation Error : Request amount cannot be zero.- Request Validation Error : Request tip amount cannot be less than zero.- Merchant Configuration Validation Error : Not offered by the merchant-configured gateway. |
Test your app
Test your app using the Test card numbers for declines and partial transactions. For information, see Test region-based payment flows page.
Additional resources
Updated about 2 months ago