Link

iOS Swiped Payments Guide v2

Looking for the v1.x docs? →


Mobile Reader Payments

Supercharge your mobile app by quickly adding mobile reader payments using the Omni Mobile SDK. These payments will create invoices, customers, and transaction objects in the Stax platform. You can also choose to have the payment method stored within Stax so you can use it from the Stax API.

How it works

  1. You’ll first need to create an ephemeral key to initialize the Omni object.
  2. Then you’ll create a TransactionRequest that holds all necessary data to take a payment.
  3. Finally, you’ll ask Omni to take the payment by calling the takeMobileReaderPayment() method, passing in the TransactionRequest and a block to run once the payment is complete.

Requirements

  • Xcode 8+
  • iOS 9+
  • Ephemeral Stax API key

Installation

Use CocoaPods to install the Fattmerchant iOS SDK.

  1. Install CocoaPods
  2. Add pod 'Fattmerchant' to your Podfile
  3. Run pod install

Getting Started

Setup Info.plist

In order to build and run with the Cardpresent functionality, you must include the following in your project’s Info.plist

  • NSBluetoothAlwaysUsageDescription: Provide a value here to let your users know why Bluetooth access is required

Initialize

Create an instance of InitParams

var initParams = Omni.InitParams(appId: "fmiossample", apiKey: apiKey, environment: Environment.LIVE)

Pass the initParams to Omni.initialize(...), along with a completion block and an error block

omni = Omni()

log("Attempting initalization...")

// Initialize Omni
omni?.initialize(params: initParams, completion: {
	// Initialized!
}) { (error) in

}

Connect a Mobile Reader

In order to connect a mobile reader, you must first search for a list of available readers

omni.getAvailableReaders { readers in

}

Once you have the list of available ones, you can choose which one you’d like to connect

omni?.getAvailableReaders(completion: { readers in
	guard !readers.isEmpty else {
		self.log("No readers found")
		return
	}

	var chosenReader = ... // Choose a reader

	omni.connect(reader: chosenReader, completion: { connectedReader in
		self.log("Connected reader: \(connectedReader)")
	}) { (error) in
		// Something went wrong
	}
}) {
	self.log("Couldn't connect to the mobile reader")
}

Listen to connection events via MobileReaderConnectionStatusDelegate

Connecting to your mobile reader is a multi-step process. For example, your mobile reader may require a firmware update, or it may be fetching useful configurations from your merchant account. You can know be notified of these updates by assigning a MobileReaderConnectionStatusDelegate. Conformance of this protocol requires that you define a func mobileReaderConnectionStatusUpdate(status: MobileReaderConnectionStatus) via which you’ll be notified of the status of the mobile reader as it’s connecting.

class YourClass: MobileReaderConnectionStatusDelegate {
	func mobileReaderConnectionStatusUpdate(status: MobileReaderConnectionStatus) {
		print("Mobile reader is: \(status)")
	}


	omni?.mobileReaderConnectionUpdateDelegate = self
	omni?.connect(...)
}

Take a Payment

TransactionRequest

TransactionRequest is an object that represents an intent to make a transaction. This object contains necessary data about transaction parameters, such as how much money should be collected and whether or not the payment method should be tokenized. You can pass the following items to a TransactionRequest:

  /// The `Amount` to be collected during the transaction
  var amount: Amount

  /// The `CreditCard` to charged, if you are not paying with a mobile reader
  var card: CreditCard?

  /// The LineItems being passed to the transaction
  var lineItems: [CatalogItem]?

  /// The subtotal of the transaction
  var subtotal: Double?

  /// The tax applied to the transaction
  var tax: Double?

  /// The tip amount applied to the transaction
  var tip: Double?

  /// A memo for the transaction
  var memo: String?

  /// A reference for the transaction
  var reference: String?

  /// The option to tokenize the payment method for later usage
  ///
  /// - Note: Defaults to true
  ///
  /// Set this to false if you do not want the payment method stored
  var tokenize: Bool = true

  /// The id of the invoice that this payment should be applied to
  ///
  /// If nil, then a new invoice will be created
  var invoiceId: String?

  /// The option to perform a preauthorization
  ///
  /// - Note: Defaults to false
  ///
  /// Set this to true if you would like to *only* authorize an amount. This means that the transaction will
  /// only hold funds and you will need to capture it at a later date via the Stax API or the SDK
  public var preauth: Bool = false

Using a TransactionRequest to take a payment

To take a payment, create a TransactionRequest and pass it along to omni.takeMobileReaderTransaction(...)

// Create an Amount
let amount = Amount(cents: 50)

// Create the TransactionRequest
let request = TransactionRequest(amount: amount)

// Take the payment
omni.takeMobileReaderTransaction(request, { completedTransaction in
    // Payment successful!
}) {
    // Error
}

By default, the PaymentMethod used in the Transaction is tokenized for reuse. This allows the PaymentMethod to be used from the Stax Virtual Terminal and via the Stax API. To opt-out of tokenization, you can set the tokenize field of TransactionRequest to false

// Create a TransactionRequest with no tokenization
let request = TransactionRequest(amount: amount, tokenize: false)

Listen to transaction events via UserNotificationDelegate

During a transaction, there are some messages that need to be shown to the user. These messages usually occur because of some kind of error that the user and have a proposed suggestion. For example, if the user attempts to pay with a chip EMV card by swiping it, the BBPOS mobile reader will reject this (since the card is meant to be inserted into the chip EMV slot). In this case, the Omni SDK will notify the user that the card must be inserted. This happens via the UserNotificationDelegate. Conformance of this protocol requires that you declare a func onUserNotification(userNotification: UserNotification), via which you will receive the UserNotification objects. Then you can assign that delegate to Omni.userNotificationDelegate

class YourClass: UserNotificationDelegate {
	func onUserNotification(userNotification: UserNotification) {
		print(userNotification.userFriendlyMessage)
	}

	omni?.userNotificationDelegate = self
	omni?.takeMobileReaderTransaction(...)
}

Refund a Payment

You can use the Stax API to do so. Once you get the transaction, you can use the refundMobileReaderTransaction method to attempt the refund.

At this time, you may only refund transactions that were performed on the same device that performed the original transaction

// Attain a transaction
var transaction = Transaction()

// Perform refund
omni.refundMobileReaderTransaction(transaction: transaction, completion: { (refundedTransaction) in
	// Refund successful!
}, error: { error in
	// Error
})

Pre Authorizations

If you’d like to authorize a transaction and capture those at a later date, you can do that by setting the preauth field in a TransactionRequest. You would still use the omni.takeMobileReaderTransaction(...) method, but by setting preauth to true, the transaction will only the requested amount. This leaves the transaction in a state of of “pending capture”. At this point, you are able to capture those funds via our SDK or the Stax API.

// Create an Amount
let amount = Amount(cents: 50)

// Create the TransactionRequest
var request = TransactionRequest(amount: amount)

// Set preauth
request.preauth = true

// Authorize the payment
omni.takeMobileReaderTransaction(request, { completedTransaction in
    // Auth successful!
}) {
    // Error
}

Capture a Pre-Auth Transaction

There are several ways for you to capture a pre_auth transaction. You can perform the capture via our Stax API, or by calling the Omni.capturePreauthTransaction(...) method in our iOS or Android SDK. You’ll need to know:

  1. The id of the transaction
  2. (optional) the amount that you’d like to capture. By default, this is the authorized amount
/// Captures a previously-authorized transaction
///
/// - Parameters:
///   - transactionId: The id of the transaction you want to capture
///   - amount: the amount that you want to capture. If nil, then the original transaction amount will be captured
///   - completion: Called when the operation is complete successfully. Receives a Transaction
///   - error: Receives any errors that happened while attempting the operation
public func capturePreauthTransaction(transactionId: String,
                                      amount: Amount?,
                                      completion: @escaping (Transaction) -> Void,
                                      error: @escaping (OmniException) -> Void)

Be mindful of the amount you’d like to capture. If you attempt to capture an amount greater than the amount that was authorized, you may get a CapturePreauthTransactionException.

Void a Pre-Auth Transaction

There are several ways for you to void a pre_auth transaction. You can perform the void via our Stax API, or by calling the Omni.voidTransaction(...) method in our iOS or Android SDK. You’ll need to know:

  1. The id of the transaction
/// Voids a transaction
///
/// - Parameters:
///   - transactionId: The id of the transaction you want to void
///   - completion: Called when the operation is complete successfully. Receives a Transaction
///   - error: Receives any errors that happened while attempting the operation
public func voidTransaction(transactionId: String,
                            completion: @escaping (Transaction) -> Void,
                            error: @escaping (OmniException) -> Void)