Transaction
Create transaction intent
To start a transaction it is needed to create a TransactionIntent, specifying the type transaction (sale, cancel or refund).
To create a SDKTransactionIntent
, use the SDKTransactionIntentFactor.createTransactionIntent
, this method receives
transaction type (sale, refund, cancel) and the implementation of SDKTransactionListener
interface
In case there is an ongoing transaction, it is attempted to be aborted beforehand to prevent having more than one active transaction simultaneously.
var txData : SDKTransactionData = SDKTransactionData(SDKTransactionType.Sale)
SDKTransactionIntentFactory.createTransactionIntent(txData, object : SDKTransactionListener {
override fun onTransactionCreated(result: SDKTransactionIntentResult) {
when(result) {
is SDKTransactionIntentResult.Success -> {
currentTx = result.transactionIntent
}
is SDKTransactionIntentResult.Error -> {
appendInfo("Error creating a new transaction: ${result.message}")
}
}
}
override fun onTransactionStateChanged(state: SDKTransactionState) {
handleTxState(state)
}
override fun onReaderStateChanged(state: SDKReaderState) {
handleReaderState()
}
})
SDKTransactionIntentResult.Error is thrown when a previous transaction exists and for some reason it cannot be aborted. The transaction cannot be aborted during the reader connection or after the confirmation.
Provide a device
Provide a device which was previously scanned.
Call the method provideDevice
in SDKTransactionState.DeviceRequired
state
fun handleTxState(state: SDKTransactionState) {
when (state) {
is SDKTransactionState.DeviceRequired -> {
state.provideDevice(selectedDevice!!) // device previously found by the scanner
}
...
}
}
Provide reader configuration
Create a SDKReadConfig
object and call the method provideDevice
in ReadConfigRequired
state.
fun handleTxState(state: SDKTransactionState) {
val readConfig = SDKReadConfig(
60000,
setOf(SDKCardReadMode.Chip, SDKCardReadMode.Swipe, SDKCardReadMode.Nfc),
SDKCardInsertionStatus.NotInserted,
getSDKTransactionTotals()
)
when (state) {
is ReadConfigRequired -> {
state.provideReadConfig(readConfig)
}
...
}
}
Providing a transaction totals
The SDKTransactionTotals
object allows you to specify the net transaction amount, taxes, and tip.
It is configured within the SDKReadConfig
object to ensure that all necessary transaction details are provided for accurate reporting.
private fun getSDKTransactionTotalsWithList(tax1 : BigDecimal, tax2 : BigDecimal, tip : BigDecimal): SDKTransactionTotals {
return SDKTransactionTotals(
net = SDKMoney(TRANSACTION_TOTAL, SDKCurrency.ars()),
taxes = SDKTaxes.BreakDown(
listOf(
SDKTax(SDKMoney(tax1, SDKCurrency.ars()), "tax1"),
SDKTax(SDKMoney(tax2, SDKCurrency.ars()), "tax2")
)
),
tip = SDKMoney(tip, SDKCurrency.ars())
)
}
- net: Represents the total amount of the transaction, specified in the
SDKMoney
object. This includes both the amount and the currency. - taxes: Represents the tax amounts, included within the net amount for reference purposes.
SDKTaxes.Total(...)
— Use this to specify a single tax amount if applicable.SDKTaxes.BreakDown(listOf(... , ...))
— Use this option to specify multiple taxes as a list ofSDKTax
objects, each with a labeled description (e.g., "iva" and "iva2" in the example).
- tip: Specifies the tip amount, also provided in an
SDKMoney
object. This field is optional and can be omitted if a tip is not applicable.
Each component (net, taxes, and tip) uses SDKMoney
to ensure accurate and consistent handling of currency and decimal values across all transaction amounts.
Select EMV app
There are cards that have more than one EMV application internally in the chip. This is a way that allows the standard to have several logic cards in the same plastic (for example, a credit card and a debit card), In this state the Readers SDK provides the list of available applications and you must choose which one you want to use (if the card only has one emv application, this state is not called).
Call the method selectEmvApp
in SDKTransactionState.SelectEmvApp
state.
fun handleTxState(state: SDKTransactionState) {
when (state) {
is SelectEmvApp -> {
val availableEmvApps = state.availableEmvApps
customMethodForSelectEmvApp(availableEmvApps) { emvApp ->
state.selectEmvApp(emvApp)
}
}
}
}
Confirm transaction
When the card is read, this data is provided to the Readers SDK user who decides to confirm or reject the transaction, then online processing is performed. Finally, an approved or declined, or error response is obtained,the data necessary to confirm the transaction will be explained in using JSON for confirmation section.
There is a deprecated version of the confirm() function that accepts typed parameters through the SDKConfirmation class.
Confirm a sale.
fun handleTxState(state: SDKTransactionState) {
when (state) {
val confirmation: SDKConfirmationJson = getNewSaleConfirmationJson()
is SDKTransactionState.ConfirmTransaction.Sale -> {
state.confirm(confirmation)
}
...
}
}
Confirm a refund.
fun handleTxState(state: SDKTransactionState) {
when (state) {
val confirmation: SDKConfirmationJson = getNewRefundConfirmationJson()
is SDKTransactionState.ConfirmTransaction.Refund -> {
state.confirm(confirmation)
}
...
}
}
Confirm a cancel.
fun handleTxState(state: SDKTransactionState) {
when (state) {
val confirmation: SDKConfirmationJson = getNewCancelConfirmationJson()
is SDKTransactionState.ConfirmTransaction.Cancel -> {
state.confirm(confirmation)
}
...
}
}
Transaction approved
If the transactions is approved, the response is obtained in the following methods.
Check for SDKTransactionState.TransactionApproved
state.
fun handleTxState(state: SDKTransactionState) {
when (state) {
is SDKTransactionState.TransactionApproved -> {
if(state is SDKTransactionState.TransactionApproved.Sale) {
// Approved sale
} else {
// Approved refund or cancel
}
...
}
}
Transaction error
During a transaction, two kind of errors can occur: recoverable and not recoverable. In the recoverable, it’s possible to retry the transaction calling the associate callback, in the not recoverable errors, the transaction finished and ç it's necessary to create another one.
Check whether state is SDKTransactionState.RecoverableError
or SDKTransactionState.NonRecoverableError
.
fun handleTxState(state: SDKTransactionState) {
when (state) {
is SDKTransactionState.RecoverableError -> {
...
state.recover() //if you want try recover an error
}
is SDKTransactionState.NonRecoverableError -> {
//transaction is finished by an error
}
...
}
}