Android Intent SDK
The Stitch Payment App offers merchants the ability to integrate their POS system directly with the Stitch Payment App via an Android Intent SDK.
Stitch Android Intent SDK
Add the Maven Repository and include the dependency:
dependencyResolutionManagement {
repositories {
...
maven("https://gitlab.com/api/v4/projects/69499542/packages/maven")
}
}
See required lib versions.
Initiating a Transaction
override fun onCreate(savedInstanceState: Bundle?) {
...
val sale = Sale.Builder(
this,
object : SaleTransactionListener {
override fun onSaleResult(result: SaleResult) {
// handle response, setting a viewModel attribute
}
override fun alertError(error: IntentError) {
// handle error, setting a viewModel attribute
}
},
).build()
...
}
fun onButtonClick() {
val externalPosData = mapOf(
"posEg1" to UUID.randomUUID().toString(),
"posEg2" to Random().nextInt().toString(),
"posEg3" to true.toString(),
)
// the amount is represented in cents, so an amount of 1059 is R10.59
if (cashback) {
sale.startTransactionWithCashback(amount, cashAmount, externalPosData)
} else {
sale.startTransaction(amount, externalPosData)
}
...
}
The actions have a Builder that require at least the following parameters: context & listener. The context is what Android needs to start the Intent and can be the current Activity, the listener is a callback interface where the library will provide the result or error. The builder should be be created in the onCreate() before, content is rendered, and on a button tap the transaction can be initiated.
externalPosData
a map representing key value pairs that'll be echoed in the result and be sent on the webhooks (payment app may add additional keys). Can be used for adding identifiers aiding in matching, like a DB row id or an order number, etc.disableReceiptingOnOutcome
disables receipt printing and QR code on the outcome screen.
Voiding a Transaction
override fun onCreate(savedInstanceState: Bundle?) {
...
val voider = VoidTransaction.Builder(
this,
object : VoidTransactionListener {
override fun onVoidResult(result: VoidResult) {
// handle response, setting a viewModel attribute
}
override fun alertError(error: IntentError) {
// handle error, setting a viewModel attribute
}
},
).build()
...
if (TransactionUtil.isVoidable(response)) {
// enable void button
}
...
}
fun onButtonClick() {
voider.voidTransaction(transactionId)
...
}
It is the responsibility of the calling app to verify that the user is authorised to perform void actions.
Refunding a Transaction
Refunds initiated via the Android Intent SDK are processed as a card-present refund. This means the customer must present their physical card at the terminal in-store to complete the refund.
override fun onCreate(savedInstanceState: Bundle?) {
...
val refund = Refund.Builder(
this,
object : RefundTransactionListener {
override fun onRefundResult(result: RefundResult) {
// handle response, setting a viewModel attribute
}
override fun alertError(error: IntentError) {
// handle error, setting a viewModel attribute
}
},
).build()
...
if (TransactionUtil.isRefundable(response)) {
// enable void button
}
...
}
fun onButtonClick() {
// the amount is represented in cents, so an amount of 1059 is R10.59
refund.startRefund(amount, transactionId)
...
}
It is the responsibility of the calling app to verify that the user is authorised to perform refund actions.
Bypass PIN entry on the Stitch Payment App
The Stitch Payment App normally requires a PIN to authenticate the user and terminal before a transaction can be initiated. This PIN is also required for void and refund transactions.
However, the Merchant POS App can bypass the manual PIN entry by logging the user in automatically in the background. This approach is recommended when the Merchant POS App has already implemented the necessary permission checks, ensuring security without requiring additional user input on the Stitch Payment App.
override fun onCreate(savedInstanceState: Bundle?) {
...
val login = Login.Builder(
this,
object : LoginListener {
override fun onLoginResult(result: Boolean) {
// handle login success, setting a viewModel attribute
}
override fun alertError(error: IntentError) {
// handle error, setting a viewModel attribute
}
},
).build()
...
}
fun onButtonClick() {
login.login(merchantPin)
...
}
merchantPin
merchantPin
auto login without prompting for the PIN.
Lib Version Mapping
Pay Version | Core Version | dto Version | intent-lib Version |
---|---|---|---|
v1.0.0 | v1.0.0 | 1.0.3 | 3.0.2 |
v1.0.1 | v1.0.1 | 1.0.5 | 3.0.2 |
v1.0.2 | v1.0.2 | 1.0.8 | 3.0.3 |
Gradle base config (same for all versions):
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
implementation("com.exipay.terminal.modules:dto:<version>")
implementation("com.exipay.terminal.modules:intent-lib:<version>")
}