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
      )

  1. 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  
    }  
)