diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 594a34b..ae6aec3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -47,7 +47,7 @@ android { } dependencies { - implementation(files("libs/AditumSdkIntegration-2.3.6.67824-release.aar")) + implementation(files("libs/AditumSdkIntegration-2.3.4.860743-release.aar")) implementation("com.google.code.gson:gson:2.13.1") implementation("androidx.datastore:datastore-preferences:1.1.7") implementation(libs.androidx.core.ktx) diff --git a/app/libs/AditumSdkIntegration-2.3.4.860743-release.aar b/app/libs/AditumSdkIntegration-2.3.4.860743-release.aar new file mode 100644 index 0000000..db75a11 Binary files /dev/null and b/app/libs/AditumSdkIntegration-2.3.4.860743-release.aar differ diff --git a/app/src/main/java/com/example/mypos/MainActivity.kt b/app/src/main/java/com/example/mypos/MainActivity.kt index e018939..b516753 100644 --- a/app/src/main/java/com/example/mypos/MainActivity.kt +++ b/app/src/main/java/com/example/mypos/MainActivity.kt @@ -4,16 +4,11 @@ import android.content.Context import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview -import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.viewmodel.viewModelFactory import com.example.mypos.models.PaymentViewModel import com.example.mypos.screen.PaymentScreen -import com.example.mypos.services.AditumSdkService import com.example.mypos.services.PaymentApplication import com.example.mypos.ui.theme.POSTheme @@ -22,14 +17,13 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) val context = this var paymentApplication = application as PaymentApplication - var aditumSdkService = AditumSdkService(paymentApplication) var paymentViewModel = ViewModelProvider( this, - PaymentViewModel.provideFactory(paymentApplication, context, aditumSdkService) + PaymentViewModel.provideFactory(paymentApplication, context) )[PaymentViewModel::class.java] setContent { POSTheme { - PaymentScreen(paymentViewModel, aditumSdkService) + PaymentScreen(paymentViewModel) } } } diff --git a/app/src/main/java/com/example/mypos/models/PaymentViewModel.kt b/app/src/main/java/com/example/mypos/models/PaymentViewModel.kt index a24cfcd..688790a 100644 --- a/app/src/main/java/com/example/mypos/models/PaymentViewModel.kt +++ b/app/src/main/java/com/example/mypos/models/PaymentViewModel.kt @@ -6,11 +6,36 @@ import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope +import br.com.aditum.data.v2.IPaymentCallback import br.com.aditum.data.v2.enums.AbecsCommands +import br.com.aditum.data.v2.enums.InstallmentType +import br.com.aditum.data.v2.enums.PayOperationType +import br.com.aditum.data.v2.enums.PaymentType import br.com.aditum.data.v2.enums.TransactionStatus +import br.com.aditum.data.v2.model.Charge +import br.com.aditum.data.v2.model.MerchantData +import br.com.aditum.data.v2.model.PinpadMessages +import br.com.aditum.data.v2.model.callbacks.GetClearDataFinishedCallback +import br.com.aditum.data.v2.model.callbacks.GetClearDataRequest +import br.com.aditum.data.v2.model.callbacks.GetMenuSelectionFinishedCallback +import br.com.aditum.data.v2.model.callbacks.GetMenuSelectionRequest +import br.com.aditum.data.v2.model.cancelation.CancelationRequest +import br.com.aditum.data.v2.model.cancelation.CancelationResponse +import br.com.aditum.data.v2.model.cancelation.CancelationResponseCallback +import br.com.aditum.data.v2.model.deactivation.DeactivationResponseCallback +import br.com.aditum.data.v2.model.init.InitRequest +import br.com.aditum.data.v2.model.init.InitResponse +import br.com.aditum.data.v2.model.init.InitResponseCallback +import br.com.aditum.data.v2.model.payment.PaymentRequest +import br.com.aditum.data.v2.model.payment.PaymentResponse +import br.com.aditum.data.v2.model.payment.PaymentResponseCallback +import br.com.aditum.data.v2.model.transactions.ConfirmTransactionCallback +import br.com.aditum.data.v2.model.transactions.PendingTransactionsCallback +import com.example.mypos.BuildConfig +import com.example.mypos.data.AditumError import com.example.mypos.data.PaymentRegister -import com.example.mypos.services.AditumSdkService import com.example.mypos.services.PaymentApplication +import com.google.gson.Gson import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -18,35 +43,31 @@ import kotlinx.coroutines.launch class PaymentViewModel( private val application: PaymentApplication, - private val context: Context, - private val aditumSdkService: AditumSdkService + private val context: Context ) : ViewModel() { private val paymentApplication = application + private val gson = Gson() private val TAG = "PaymentViewModel" private val _isServiceConnected = MutableStateFlow(false) val isServiceConnected: StateFlow = _isServiceConnected.asStateFlow() + private val _messageFlow = MutableStateFlow("") + val messageFlow: StateFlow = _messageFlow.asStateFlow() + private val _pinLengthFlow = MutableStateFlow(0) + val pinLengthFlow: StateFlow = _pinLengthFlow.asStateFlow() init { viewModelScope.launch { paymentApplication.isServiceConnectedFlow.collect { isConnected -> _isServiceConnected.value = isConnected - } - aditumSdkService.register( - listener = object : PaymentRegister { - override fun notification( - message: String?, - transactionStatus: TransactionStatus?, - command: AbecsCommands? - ) { - val notificationMessage = when (command) { - AbecsCommands.Display -> "Exibindo mensagem: $message" - AbecsCommands.GetPin -> "Aguardando digitação do PIN" - else -> message ?: "Processando..." - } - Log.d(TAG, notificationMessage) + if (isConnected) { + try { + paymentApplication.communicationService?.registerPaymentCallback(paymentCallback) + ?: Log.e(TAG, "Failed to register payment callback: communicationService is null") + } catch (e: Exception) { + Log.e(TAG, "Error registering payment callback: ${e.message}") } } - ) + } } } @@ -54,16 +75,285 @@ class PaymentViewModel( paymentApplication.startAditumSdkService() } + val paymentCallback = object : IPaymentCallback.Stub() { + override fun notification( + message: String?, + transactionStatus: TransactionStatus?, + command: AbecsCommands? + ) { + Log.i(TAG, "\nnotification - ${ message ?: "" }") + if (message != null) { + _messageFlow.value = message.replace("\\s+".toRegex(), " ").trim() + } + } + + override fun pinNotification(message: String?, length: Int) { + _pinLengthFlow.value = length + } + + override fun startGetClearData( + clearDataRequest: GetClearDataRequest?, + finished: GetClearDataFinishedCallback? + ) { + TODO("Not yet implemented") + } + + override fun startGetMenuSelection( + menuSelectionRequest: GetMenuSelectionRequest?, + finished: GetMenuSelectionFinishedCallback? + ) { + TODO("Not yet implemented") + } + + override fun qrCodeGenerated(qrCode: String?, expirationTime: Int) { + Log.d(TAG, "\nqrCode - ${ qrCode ?: "" }\nexpirationTime - $expirationTime") + } + } + + fun initAditumSdk( + applicationName: String, + applicationVersion: String, + activationCode: String?, + resolve: (Boolean) -> Unit = {}, + reject: (String, String?) -> Unit = { _, _ -> } + ) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val pinpadMessages = PinpadMessages().apply { + mainMessage = applicationName + } + + val initRequest = InitRequest().apply { + this.pinpadMessages = pinpadMessages + this.activationCode = if (BuildConfig.DEBUG) BuildConfig.ACTIVATION_CODE else activationCode + this.applicationName = applicationName + this.applicationVersion = applicationVersion + this.useOnlySdk = true + this.applicationToken = BuildConfig.APPLICATION_TOKEN + } + + val callback = object : InitResponseCallback.Stub() { + override fun onResponse(initResponse: InitResponse?) { + if (initResponse != null) { + resolve(initResponse.initialized) + } else { + Log.e(TAG, "onResponse - initResponse is null") + reject(AditumError.INIT_RESPONSE_NULL, AditumError.INIT_RESPONSE_NULL_MESSAGE) + } + } + } + + paymentApplication.communicationService?.init(initRequest, callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.INIT_ERROR, "${AditumError.INIT_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun getMerchantData(resolve: (MerchantData) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val merchantData: MerchantData? = paymentApplication.communicationService?.merchantData + if (merchantData != null) { + resolve(merchantData) + } else { + reject(AditumError.MERCHANT_DATA_NULL, AditumError.MERCHANT_DATA_NULL_MESSAGE) + } + } catch (e: Exception) { + reject(AditumError.MERCHANT_DATA_ERROR, "${AditumError.MERCHANT_DATA_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun pay( + amount: Long, + installments: Int? = null, + paymentType: PaymentType, + allowContactless: Boolean = true, + amountSeasoning: ((Long) -> Long)? = null, + resolve: (PaymentResponse) -> Unit = {}, + reject: (String, String?) -> Unit = { _, _ -> } + ) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val adjustedAmount = amountSeasoning?.invoke(amount) ?: amount + if (adjustedAmount <= 0) { + reject(AditumError.INVALID_AMOUNT, AditumError.INVALID_AMOUNT_MESSAGE) + return@launch + } + + val paymentRequest = PaymentRequest().apply { + currency = 986 + operationType = PayOperationType.Authorization + this.paymentType = paymentType + this.amount = amount + this.allowContactless = allowContactless + manualEntry = false + installmentType = if (paymentType == PaymentType.Debit) InstallmentType.Undefined else InstallmentType.Merchant + this.installmentNumber = when { + installments == null -> if (paymentType == PaymentType.Credit) 1 else 0 + installments > 1 -> installments + paymentType == PaymentType.Debit -> 0 + else -> 1 + } + } + + val callback = object : PaymentResponseCallback.Stub() { + override fun onResponse(paymentResponse: PaymentResponse?) { + if (paymentResponse != null) { + val json = gson.toJson(paymentResponse) + Log.d(TAG, "onResponse - $json") + resolve(paymentResponse) + } else { + Log.e(TAG, "onResponse - paymentResponse is null") + reject(AditumError.PAYMENT_RESPONSE_NULL, AditumError.PAYMENT_RESPONSE_NULL_MESSAGE) + } + } + } + + paymentApplication.communicationService?.pay(paymentRequest, callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.PAYMENT_ERROR, "${AditumError.PAYMENT_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun confirm(nsu: String, resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val callback = object : ConfirmTransactionCallback.Stub() { + override fun onResponse(confirmed: Boolean) { + resolve(confirmed) + } + } + + paymentApplication.communicationService?.confirmTransaction(nsu, callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.CONFIRM_ERROR, "${AditumError.CONFIRM_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun cancel(nsu: String, isReversal: Boolean, resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val cancelationRequest = CancelationRequest(nsu, isReversal) + + val callback = object : CancelationResponseCallback.Stub() { + override fun onResponse(cancelationResponse: CancelationResponse?) { + if (cancelationResponse != null) { + resolve(cancelationResponse.canceled) + } else { + Log.e(TAG, "onResponse - cancelationResponse is null") + reject(AditumError.CANCEL_RESPONSE_NULL, AditumError.CANCEL_RESPONSE_NULL_MESSAGE) + } + } + } + + paymentApplication.communicationService?.cancel(cancelationRequest, callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.CANCEL_ERROR, "${AditumError.CANCEL_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun aboutOperation(resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { + viewModelScope.launch { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + paymentApplication.communicationService?.abortOperation() + + } + } + + fun pendingTransactions(resolve: (List?) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ ->}) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val callback = object : PendingTransactionsCallback.Stub() { + override fun onResponse(results: List?) { + val json = gson.toJson(results) + Log.e(TAG, "onResponse - $json") + resolve(results) + } + } + + paymentApplication.communicationService?.pendingTransactions(callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.CONFIRM_ERROR, "${AditumError.CONFIRM_ERROR_MESSAGE}: ${e.message}") + } + } + } + + fun deactivate(resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { + viewModelScope.launch { + try { + if (!paymentApplication.ensureServiceConnected()) { + reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) + return@launch + } + + val callback = object : DeactivationResponseCallback.Stub() { + override fun onResponse(status: Boolean) { + Log.d(TAG, "onDeactivationResponse - deactivationResponse: $status") + resolve(status) + } + } + + paymentApplication.communicationService?.deactivate(callback) + ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) + } catch (e: Exception) { + reject(AditumError.DEACTIVATE_ERROR, "${AditumError.DEACTIVATE_ERROR_MESSAGE}: ${e.message}") + } + } + } + companion object { fun provideFactory( paymentApplication: PaymentApplication, - context: Context, - aditumSdkService: AditumSdkService + context: Context ): ViewModelProvider.Factory = object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { if (modelClass.isAssignableFrom(PaymentViewModel::class.java)) { - return PaymentViewModel(paymentApplication, context, aditumSdkService) as T + return PaymentViewModel(paymentApplication, context) as T } throw IllegalArgumentException("Unknown ViewModel class") } diff --git a/app/src/main/java/com/example/mypos/screen/PaymentScreen.kt b/app/src/main/java/com/example/mypos/screen/PaymentScreen.kt index f731b08..29d709c 100644 --- a/app/src/main/java/com/example/mypos/screen/PaymentScreen.kt +++ b/app/src/main/java/com/example/mypos/screen/PaymentScreen.kt @@ -15,18 +15,17 @@ import androidx.compose.ui.unit.dp import br.com.aditum.data.v2.enums.PaymentType import com.example.mypos.BuildConfig import com.example.mypos.models.PaymentViewModel -import com.example.mypos.services.AditumSdkService import kotlinx.coroutines.flow.collectLatest @Composable -fun PaymentScreen(viewModel: PaymentViewModel, aditumSdkService: AditumSdkService) { +fun PaymentScreen(viewModel: PaymentViewModel) { val context = LocalContext.current var amount by remember { mutableStateOf("") } var installments by remember { mutableStateOf("1") } var paymentType by remember { mutableStateOf(PaymentType.Credit) } val isServiceConnected by viewModel.isServiceConnected.collectAsState() - val message by aditumSdkService.messageFlow.collectAsState() - val pinLength by aditumSdkService.pinLengthFlow.collectAsState() + val message by viewModel.messageFlow.collectAsState() + val pinLength by viewModel.pinLengthFlow.collectAsState() var isInitializing by remember { mutableStateOf(false) } var isPaying by remember { mutableStateOf(false) } var showLoading by remember { mutableStateOf(false) } @@ -69,7 +68,7 @@ fun PaymentScreen(viewModel: PaymentViewModel, aditumSdkService: AditumSdkServic if (!isInitializing) { isInitializing = true showLoading = true - aditumSdkService.initAditumSdk( + viewModel.initAditumSdk( applicationName = "MyPOS", applicationVersion = "1.0.0", activationCode = BuildConfig.ACTIVATION_CODE, @@ -156,7 +155,7 @@ fun PaymentScreen(viewModel: PaymentViewModel, aditumSdkService: AditumSdkServic if (!isPaying) { isPaying = true showLoading = true - aditumSdkService.pay( + viewModel.pay( amount = amountValue, installments = if (paymentType == PaymentType.Credit) installmentCount else null, paymentType = paymentType, diff --git a/app/src/main/java/com/example/mypos/services/AditumSdkService.kt b/app/src/main/java/com/example/mypos/services/AditumSdkService.kt deleted file mode 100644 index b297710..0000000 --- a/app/src/main/java/com/example/mypos/services/AditumSdkService.kt +++ /dev/null @@ -1,331 +0,0 @@ -package com.example.mypos.services - -import android.util.Log -import br.com.aditum.data.v2.IPaymentCallback -import br.com.aditum.data.v2.enums.AbecsCommands -import br.com.aditum.data.v2.enums.InstallmentType -import br.com.aditum.data.v2.enums.PayOperationType -import br.com.aditum.data.v2.enums.PaymentType -import br.com.aditum.data.v2.enums.TransactionStatus -import br.com.aditum.data.v2.model.Charge -import br.com.aditum.data.v2.model.MerchantData -import br.com.aditum.data.v2.model.PinpadMessages -import br.com.aditum.data.v2.model.callbacks.GetClearDataFinishedCallback -import br.com.aditum.data.v2.model.callbacks.GetClearDataRequest -import br.com.aditum.data.v2.model.callbacks.GetMenuSelectionFinishedCallback -import br.com.aditum.data.v2.model.callbacks.GetMenuSelectionRequest -import br.com.aditum.data.v2.model.cancelation.CancelationRequest -import br.com.aditum.data.v2.model.cancelation.CancelationResponse -import br.com.aditum.data.v2.model.cancelation.CancelationResponseCallback -import br.com.aditum.data.v2.model.deactivation.DeactivationResponseCallback -import br.com.aditum.data.v2.model.init.InitRequest -import br.com.aditum.data.v2.model.init.InitResponse -import br.com.aditum.data.v2.model.init.InitResponseCallback -import br.com.aditum.data.v2.model.payment.PaymentRequest -import br.com.aditum.data.v2.model.payment.PaymentResponse -import br.com.aditum.data.v2.model.payment.PaymentResponseCallback -import br.com.aditum.data.v2.model.transactions.ConfirmTransactionCallback -import br.com.aditum.data.v2.model.transactions.PendingTransactionsCallback -import com.example.mypos.BuildConfig -import com.example.mypos.data.AditumError -import com.example.mypos.data.PaymentRegister -import com.google.gson.Gson -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch - -class AditumSdkService(private val paymentApplication: PaymentApplication) { - companion object { - private const val TAG = "AditumSdkModule" - } - - private val gson = Gson() - private val coroutineScope = CoroutineScope(Dispatchers.IO) - - fun getName(): String = "AditumSdkModule" - - private val _messageFlow = MutableStateFlow("") - val messageFlow: StateFlow = _messageFlow.asStateFlow() - - private val _pinLengthFlow = MutableStateFlow(0) - val pinLengthFlow: StateFlow = _pinLengthFlow.asStateFlow() - - init { - coroutineScope.launch { - paymentApplication.communicationService?.registerPaymentCallback(paymentCallback) - } - } - - val paymentCallback = object : IPaymentCallback.Stub() { - override fun notification( - message: String?, - transactionStatus: TransactionStatus?, - command: AbecsCommands? - ) { - Log.i(TAG, "\nnotification - ${ message ?: "" }") - if (message != null) { - _messageFlow.value = message.replace("\\s+".toRegex(), " ").trim() - } - } - - override fun pinNotification(message: String?, length: Int) { - _pinLengthFlow.value = length - } - - override fun startGetClearData( - clearDataRequest: GetClearDataRequest?, - finished: GetClearDataFinishedCallback? - ) { - TODO("Not yet implemented") - } - - override fun startGetMenuSelection( - menuSelectionRequest: GetMenuSelectionRequest?, - finished: GetMenuSelectionFinishedCallback? - ) { - TODO("Not yet implemented") - } - - override fun qrCodeGenerated(qrCode: String?, expirationTime: Int) { - Log.d(TAG, "\nqrCode - ${ qrCode ?: "" }\nexpirationTime - $expirationTime") - } - } - - fun initAditumSdk( - applicationName: String, - applicationVersion: String, - activationCode: String?, - resolve: (Boolean) -> Unit = {}, - reject: (String, String?) -> Unit = { _, _ -> } - ) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val pinpadMessages = PinpadMessages().apply { - mainMessage = applicationName - } - - val initRequest = InitRequest().apply { - this.pinpadMessages = pinpadMessages - this.activationCode = if (BuildConfig.DEBUG) BuildConfig.ACTIVATION_CODE else activationCode - this.applicationName = applicationName - this.applicationVersion = applicationVersion - this.useOnlySdk = true - this.applicationToken = BuildConfig.APPLICATION_TOKEN - } - - val callback = object : InitResponseCallback.Stub() { - override fun onResponse(initResponse: InitResponse?) { - if (initResponse != null) { - resolve(initResponse.initialized) - } else { - Log.e(TAG, "onResponse - initResponse is null") - reject(AditumError.INIT_RESPONSE_NULL, AditumError.INIT_RESPONSE_NULL_MESSAGE) - } - } - } - - paymentApplication.communicationService?.init(initRequest, callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.INIT_ERROR, "${AditumError.INIT_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun getMerchantData(resolve: (MerchantData) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val merchantData: MerchantData? = paymentApplication.communicationService?.merchantData - if (merchantData != null) { - resolve(merchantData) - } else { - reject(AditumError.MERCHANT_DATA_NULL, AditumError.MERCHANT_DATA_NULL_MESSAGE) - } - } catch (e: Exception) { - reject(AditumError.MERCHANT_DATA_ERROR, "${AditumError.MERCHANT_DATA_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun pay( - amount: Long, - installments: Int? = null, - paymentType: PaymentType, - allowContactless: Boolean = true, - amountSeasoning: ((Long) -> Long)? = null, - resolve: (PaymentResponse) -> Unit = {}, - reject: (String, String?) -> Unit = { _, _ -> } - ) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val adjustedAmount = amountSeasoning?.invoke(amount) ?: amount - if (adjustedAmount <= 0) { - reject(AditumError.INVALID_AMOUNT, AditumError.INVALID_AMOUNT_MESSAGE) - return@launch - } - - val paymentRequest = PaymentRequest().apply { - currency = 986 - operationType = PayOperationType.Authorization - this.paymentType = paymentType - this.amount = amount - this.allowContactless = allowContactless - manualEntry = false - installmentType = if (paymentType == PaymentType.Debit) InstallmentType.Undefined else InstallmentType.Merchant - this.installmentNumber = when { - installments == null -> if (paymentType == PaymentType.Credit) 1 else 0 - installments > 1 -> installments - paymentType == PaymentType.Debit -> 0 - else -> 1 - } - } - - val callback = object : PaymentResponseCallback.Stub() { - override fun onResponse(paymentResponse: PaymentResponse?) { - if (paymentResponse != null) { - val json = gson.toJson(paymentResponse) - Log.d(TAG, "onResponse - $json") - resolve(paymentResponse) - } else { - Log.e(TAG, "onResponse - paymentResponse is null") - reject(AditumError.PAYMENT_RESPONSE_NULL, AditumError.PAYMENT_RESPONSE_NULL_MESSAGE) - } - } - } - - paymentApplication.communicationService?.pay(paymentRequest, callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.PAYMENT_ERROR, "${AditumError.PAYMENT_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun confirm(nsu: String, resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val callback = object : ConfirmTransactionCallback.Stub() { - override fun onResponse(confirmed: Boolean) { - resolve(confirmed) - } - } - - paymentApplication.communicationService?.confirmTransaction(nsu, callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.CONFIRM_ERROR, "${AditumError.CONFIRM_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun cancel(nsu: String, isReversal: Boolean, resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val cancelationRequest = CancelationRequest(nsu, isReversal) - - val callback = object : CancelationResponseCallback.Stub() { - override fun onResponse(cancelationResponse: CancelationResponse?) { - if (cancelationResponse != null) { - resolve(cancelationResponse.canceled) - } else { - Log.e(TAG, "onResponse - cancelationResponse is null") - reject(AditumError.CANCEL_RESPONSE_NULL, AditumError.CANCEL_RESPONSE_NULL_MESSAGE) - } - } - } - - paymentApplication.communicationService?.cancel(cancelationRequest, callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.CANCEL_ERROR, "${AditumError.CANCEL_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun aboutOperation(resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { - coroutineScope.launch { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - paymentApplication.communicationService?.abortOperation() - - } - } - - fun pendingTransactions(resolve: (List?) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ ->}) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val callback = object : PendingTransactionsCallback.Stub() { - override fun onResponse(results: List?) { - val json = gson.toJson(results) - Log.e(TAG, "onResponse - $json") - resolve(results) - } - } - - paymentApplication.communicationService?.pendingTransactions(callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.CONFIRM_ERROR, "${AditumError.CONFIRM_ERROR_MESSAGE}: ${e.message}") - } - } - } - - fun deactivate(resolve: (Boolean) -> Unit = {}, reject: (String, String?) -> Unit = { _, _ -> }) { - coroutineScope.launch { - try { - if (!paymentApplication.ensureServiceConnected()) { - reject(AditumError.SERVICE_NOT_AVAILABLE, AditumError.SERVICE_NOT_AVAILABLE_MESSAGE) - return@launch - } - - val callback = object : DeactivationResponseCallback.Stub() { - override fun onResponse(status: Boolean) { - Log.d(TAG, "onDeactivationResponse - deactivationResponse: $status") - resolve(status) - } - } - - paymentApplication.communicationService?.deactivate(callback) - ?: reject(AditumError.SERVICE_NULL, AditumError.SERVICE_NULL_MESSAGE) - } catch (e: Exception) { - reject(AditumError.DEACTIVATE_ERROR, "${AditumError.DEACTIVATE_ERROR_MESSAGE}: ${e.message}") - } - } - } -} \ No newline at end of file