Accept a Payment using an Android Device
Connecting to Mobile Reader
Connecting to a mobile reader is a two-step process. First, you search for all readers that you can connect to, and then you connect to one of the available readers. Below is an example of searching for and connecting to a mobile reader.
Omni.shared()?.getAvailableReaders { found ->
val readers = found.map { it.getName() }.toTypedArray()
// Create an AlertDialog to select a reader
val dialog = AlertDialog.Builder(context).setItems(readers) { _, which ->
// Connect to the the selected item
val selected = found[which]
Omni.shared()?.connectReader(
mobileReader = selected,
onConnected = { connected ->
// Callback called when successfully connected
},
onFail = { errorMsg ->
// Callback called when failing to connect
}
)
}.create()
dialog.show()
}
See the Stax Android SDK sample project for an example of connecting to a reader with the SDK.
USB VP3350 Support
Starting with Android SDK 2.7, the VP3350 reader style is supported. To use the USB variant, you will need to add the following lines to your AndroidManifest.xml file:
<uses-feature android:name=“android.hardware.usb.host“ android:required=“false“ />
<uses-feature android:name=“android.hardware.usb.accessory“ android:required=“false“ />
Listen to Connection Events
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 now be notified of these updates by creating a MobileReaderConnectionStatusDelegate.
class MyStatusDelegate : MobileReaderConnectionStatusDelegate {
fun mobileReaderConnectionStatusUpdate(status: MobileReaderConnectionStatus) {
// Called when the connection status has changed
}
}
After creating the connection status delegate, you can assign it to the Omni.shared() singleton.
Omni.shared().mobileReaderConnectionUpdateListener = MyStatusDelegate()
Taking a Payment
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.
val request = TransactionRequest(
amount = Amount(1) // Amount to charge in cents
tokenize = true // Optional: Tokenize the card for re-use. Defaults to true
invoiceId = null, // Optional: The existing Stax Invoice ID
customerId = null, // Optional: The existing Stax Customer ID
lineItems: List<CatalogItem>? = listOf(), // Optional: The Stax Items to assign in the Invoice
subtotal = null // Optional: Custom amount to show for subtotal
tax = null, // Optional: Custom amount to show for tax
tip = null, // Optional: Custom amount to show for tip
shippingAmount? = null, // Optional: Custom amount for shipping cost
poNumber = null, // Optional: A string value for tracking purchase orders
memo = null, // Optional: A string value for a custom memo
reference = null, // Optional: A string value for making a freeform reference
preauth = false, // Optional: If true, authorizes the amount, but does not capture. Defaults to true.
meta = null, // Optional: A map of any other data you'd like to track on the transaction
)
- To take a payment, create a TransactionRequest and pass it along to Omni.shared()?.takeMobileReaderTransaction().
val amount = Amount(1) // 1¢
Omni.shared()?.takeMobileReaderTransaction(
request = TransactionRequest(amount)
completion = {
// Payment successful!
},
error = {
// Error
}
)
See the Stax Android SDK sample project for an example of paying with a reader with the SDK.
Listen to transaction events via UserNotificationListener
During a transaction, some messages need to be shown to the user. 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 UserNotificationListener. Conformance of this protocol requires that you declare a fun onUserNotification(userNotification: UserNotification), via which you will receive the UserNotification objects. Then you can assign that delegate to Omni.userNotificationDelegate.
class MyNotificationListener : UserNotificationListener {
fun onUserNotification(userNotification: UserNotification) {
// called when transaction events are called
}
}
After creating the user notficiation listener, you can assign it to the Omni.shared() singleton.
Omni.shared().userNotificationListener = MyNotificationListener()
Tokenize a Payment
Once you have a CreditCard object, call the tokenize(:) method on the Omni object and pass a listener to be notified once tokenization is complete.
omni.tokenize(card, completion: { (paymentMethod) in
}) { error in
}
Testing
If you’d like to try tokenization without real payment information, you can use the CreditCard.testCreditCard() method to get a test credit card.
val creditCard = CreditCard.testCreditCard()
If you want to test failures, you can use the following method
val failingCreditCard = CreditCard.failingTestCreditCard()
Refund a Payment
To refund a payment, you must first get the Transaction you want to refund. You can use the Stax API to do so. Once you get the transaction, you can use the refundMobileReaderTransaction method to attempt the refund.
// Attain a transaction
val transaction = MyCoolApi.getTransactionToRefund()
Omni.shared()?.refundMobileReaderTransaction(
transaction = transaction,
completion = {
// Called when refund is successful
},
error = { exception ->
// Called when the SDK fails to refund
}
)
Voiding a Payment
To void a payment, you must first get the transaction ID you want to void. You can use the Stax API to do so. Once you get the transaction, you can use the voidTransaction function to attempt the refund. The voidTransaction function handles both voiding and refunding, so you should default to using this function over the refundMobileReaderTransaction function.
val id = // TransactionIdToVoid
Omni.shared()?.voidTransaction(
transactionId = id,
completion = { transaction ->
if (transaction.success == true) {
// Successfully voided or refunded
} else {
// Transaction failed to void or refund
}
},
error = {
// There was an error and a void or refund was never processed
}
)
Updated 7 months ago