From ae1dc82e593120b22dd33bb3ba1bc234bce14e26 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 5 May 2025 12:20:51 +0300 Subject: [PATCH 01/28] POCardTokenizationEligibility --- .../delegate/POCardTokenizationEligibility.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt new file mode 100644 index 000000000..6e4483ffd --- /dev/null +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt @@ -0,0 +1,25 @@ +package com.processout.sdk.ui.card.tokenization.delegate + +import com.processout.sdk.api.model.response.POCardScheme +import com.processout.sdk.core.ProcessOutResult + +/** + * Represents card eligibility for tokenization. + */ +sealed class POCardTokenizationEligibility { + + /** + * Indicates that the card is eligible for tokenization, optionally restricted to the specific card scheme. + */ + data class Eligible( + val scheme: POCardScheme? = null + ) : POCardTokenizationEligibility() + + /** + * Indicates that the card is not eligible for tokenization. + * You may provide a failure with the [ProcessOutResult.Failure.localizedMessage] that will be shown directly to the user. + */ + data class NotEligible( + val failure: ProcessOutResult.Failure? = null + ) : POCardTokenizationEligibility() +} From 937d008163c4da35dcd19af5332b4d956a3e950f Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 5 May 2025 12:32:30 +0300 Subject: [PATCH 02/28] evaluateEligibility() delegate function --- .../delegate/POCardTokenizationDelegate.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationDelegate.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationDelegate.kt index e82df41db..d4b2bc6b8 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationDelegate.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationDelegate.kt @@ -4,6 +4,7 @@ import com.processout.sdk.api.model.event.POCardTokenizationEvent import com.processout.sdk.api.model.response.POCard import com.processout.sdk.api.model.response.POCardIssuerInformation import com.processout.sdk.core.ProcessOutResult +import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationEligibility.Eligible /** * Delegate that allows to handle events during card tokenization. @@ -32,6 +33,17 @@ interface POCardTokenizationDelegate { saveCard: Boolean ): ProcessOutResult = ProcessOutResult.Success(Unit) + /** + * Allows to evaluate card eligibility for tokenization based on issuer information. + * + * @param[iin] Issuer identification number. + * @param[issuerInformation] Resolved issuer information. + */ + suspend fun evaluateEligibility( + iin: String, + issuerInformation: POCardIssuerInformation + ): POCardTokenizationEligibility = Eligible() + /** * Allows to choose default preferred card scheme based on issuer information. * Primary card scheme is used by default. From 00916c81f2d4aa9a69a0f4e7641c16da426f1f0d Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 5 May 2025 12:38:48 +0300 Subject: [PATCH 03/28] CardTokenizationEligibility request/response --- .../delegate/CardTokenizationEligibility.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt new file mode 100644 index 000000000..ca507e550 --- /dev/null +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt @@ -0,0 +1,20 @@ +package com.processout.sdk.ui.card.tokenization.delegate + +import com.processout.sdk.api.dispatcher.POEventDispatcher +import com.processout.sdk.api.model.response.POCardIssuerInformation +import java.util.UUID + +internal data class CardTokenizationEligibilityRequest( + override val uuid: UUID = UUID.randomUUID(), + val iin: String, + val issuerInformation: POCardIssuerInformation +) : POEventDispatcher.Request + +internal data class CardTokenizationEligibilityResponse( + override val uuid: UUID, + val eligibility: POCardTokenizationEligibility +) : POEventDispatcher.Response + +internal fun CardTokenizationEligibilityRequest.toResponse( + eligibility: POCardTokenizationEligibility +) = CardTokenizationEligibilityResponse(uuid, eligibility) From d5fd47adf903ba037fa470f965e18cb8ca39a51c Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 5 May 2025 12:44:38 +0300 Subject: [PATCH 04/28] dispatchEligibility() --- .../tokenization/POCardTokenizationLauncher.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/POCardTokenizationLauncher.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/POCardTokenizationLauncher.kt index 66dbd355f..72d68ae7a 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/POCardTokenizationLauncher.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/POCardTokenizationLauncher.kt @@ -15,7 +15,9 @@ import com.processout.sdk.api.model.request.POCardTokenizationShouldContinueRequ import com.processout.sdk.api.model.response.POCard import com.processout.sdk.api.model.response.toResponse import com.processout.sdk.core.ProcessOutActivityResult +import com.processout.sdk.ui.card.tokenization.delegate.CardTokenizationEligibilityRequest import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationDelegate +import com.processout.sdk.ui.card.tokenization.delegate.toResponse import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -114,6 +116,7 @@ class POCardTokenizationLauncher private constructor( init { dispatchEvents() dispatchTokenizedCard() + dispatchEligibility() dispatchPreferredScheme() dispatchShouldContinue() } @@ -138,6 +141,20 @@ class POCardTokenizationLauncher private constructor( } } + private fun dispatchEligibility() { + eventDispatcher.subscribeForRequest( + coroutineScope = scope + ) { request -> + scope.launch { + val eligibility = delegate.evaluateEligibility( + iin = request.iin, + issuerInformation = request.issuerInformation + ) + eventDispatcher.send(request.toResponse(eligibility)) + } + } + } + private fun dispatchPreferredScheme() { eventDispatcher.subscribeForRequest( coroutineScope = scope From a1a69f2232ddd09225987e4e66b08b68a06b2ad6 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 5 May 2025 18:19:11 +0300 Subject: [PATCH 05/28] Add issuerInformation to CardTokenizationEligibilityResponse --- .../card/tokenization/delegate/CardTokenizationEligibility.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt index ca507e550..a819aca8a 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt @@ -12,9 +12,10 @@ internal data class CardTokenizationEligibilityRequest( internal data class CardTokenizationEligibilityResponse( override val uuid: UUID, + val issuerInformation: POCardIssuerInformation, val eligibility: POCardTokenizationEligibility ) : POEventDispatcher.Response internal fun CardTokenizationEligibilityRequest.toResponse( eligibility: POCardTokenizationEligibility -) = CardTokenizationEligibilityResponse(uuid, eligibility) +) = CardTokenizationEligibilityResponse(uuid, issuerInformation, eligibility) From cd0e634fc70b9c3d62cbec49d7a4201c71183e84 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 12:52:09 +0300 Subject: [PATCH 06/28] Add 'eligibility' to CardTokenizationInteractorState --- .../ui/card/tokenization/CardTokenizationInteractorState.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractorState.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractorState.kt index 1d303a694..a625019b6 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractorState.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractorState.kt @@ -3,6 +3,8 @@ package com.processout.sdk.ui.card.tokenization import androidx.compose.ui.text.input.TextFieldValue import com.processout.sdk.api.model.response.POCard import com.processout.sdk.api.model.response.POCardIssuerInformation +import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationEligibility +import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationEligibility.Eligible import com.processout.sdk.ui.core.state.POAvailableValue import com.processout.sdk.ui.shared.provider.address.AddressSpecification @@ -22,6 +24,7 @@ internal data class CardTokenizationInteractorState( val errorMessage: String? = null, val addressSpecification: AddressSpecification? = null, val issuerInformation: POCardIssuerInformation? = null, + val eligibility: POCardTokenizationEligibility = Eligible(), val tokenizedCard: POCard? = null ) { From fc335bc50373f250fb2cf9a83f3c343682439d39 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 14:39:36 +0300 Subject: [PATCH 07/28] Update CardTokenizationEligibilityResponse --- .../card/tokenization/delegate/CardTokenizationEligibility.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt index a819aca8a..ca507e550 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/CardTokenizationEligibility.kt @@ -12,10 +12,9 @@ internal data class CardTokenizationEligibilityRequest( internal data class CardTokenizationEligibilityResponse( override val uuid: UUID, - val issuerInformation: POCardIssuerInformation, val eligibility: POCardTokenizationEligibility ) : POEventDispatcher.Response internal fun CardTokenizationEligibilityRequest.toResponse( eligibility: POCardTokenizationEligibility -) = CardTokenizationEligibilityResponse(uuid, issuerInformation, eligibility) +) = CardTokenizationEligibilityResponse(uuid, eligibility) From d798bf9335d2522809b867031c5f0c3e9fb084ce Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 15:16:54 +0300 Subject: [PATCH 08/28] scheme type --- .../tokenization/delegate/POCardTokenizationEligibility.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt index 6e4483ffd..808860209 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/delegate/POCardTokenizationEligibility.kt @@ -1,6 +1,5 @@ package com.processout.sdk.ui.card.tokenization.delegate -import com.processout.sdk.api.model.response.POCardScheme import com.processout.sdk.core.ProcessOutResult /** @@ -12,7 +11,7 @@ sealed class POCardTokenizationEligibility { * Indicates that the card is eligible for tokenization, optionally restricted to the specific card scheme. */ data class Eligible( - val scheme: POCardScheme? = null + val scheme: String? = null ) : POCardTokenizationEligibility() /** From f6f8efa62e1526813cbdb89a0f065628b4a697eb Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 19:09:02 +0300 Subject: [PATCH 09/28] Eligibility and preferred scheme --- .../CardTokenizationInteractor.kt | 155 ++++++++++++++---- 1 file changed, 120 insertions(+), 35 deletions(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt index 99d61dc00..4c37ccc97 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt @@ -27,6 +27,10 @@ import com.processout.sdk.ui.card.tokenization.CardTokenizationEvent.* import com.processout.sdk.ui.card.tokenization.CardTokenizationInteractorState.* import com.processout.sdk.ui.card.tokenization.CardTokenizationSideEffect.CardScanner import com.processout.sdk.ui.card.tokenization.POCardTokenizationConfiguration.BillingAddressConfiguration.CollectionMode.* +import com.processout.sdk.ui.card.tokenization.delegate.CardTokenizationEligibilityRequest +import com.processout.sdk.ui.card.tokenization.delegate.CardTokenizationEligibilityResponse +import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationEligibility.Eligible +import com.processout.sdk.ui.card.tokenization.delegate.POCardTokenizationEligibility.NotEligible import com.processout.sdk.ui.core.state.POAvailableValue import com.processout.sdk.ui.shared.extension.currentAppLocale import com.processout.sdk.ui.shared.extension.findBy @@ -59,7 +63,7 @@ internal class CardTokenizationInteractor( ) : BaseInteractor() { private companion object { - const val IIN_LENGTH = 6 + const val IIN_LENGTH = 8 const val EXPIRATION_DATE_PART_LENGTH = 2 const val CARD_SCANNER_DELAY_MS = 350L } @@ -81,6 +85,7 @@ internal class CardTokenizationInteractor( private val cardNumberInputFilter = CardNumberInputFilter() private val cardExpirationInputFilter = CardExpirationInputFilter() + private var latestEligibilityRequest: CardTokenizationEligibilityRequest? = null private var latestPreferredSchemeRequest: POCardTokenizationPreferredSchemeRequest? = null private var latestShouldContinueRequest: POCardTokenizationShouldContinueRequest? = null @@ -98,6 +103,7 @@ internal class CardTokenizationInteractor( dispatch(WillStart) collectFailure() initAddressFields() + collectEligibility() collectPreferredScheme() handleCompletion() shouldContinueOnFailure() @@ -241,7 +247,7 @@ internal class CardTokenizationInteractor( if (isTextChanged) { POLogger.debug(message = "Field is edited by the user: %s", id) dispatch(ParametersChanged) - if (areAllFieldsValid()) { + if (isSubmitAllowed()) { _state.update { it.copy( submitAllowed = true, @@ -334,17 +340,23 @@ internal class CardTokenizationInteractor( //endregion - //region Issuer Information & Preferred Scheme + //region Issuer Information private fun updateIssuerInformation(cardNumber: String, previousCardNumber: String) { val iin = iin(cardNumber) if (iin == iin(previousCardNumber)) { return } - updateState( - issuerInformation = localIssuerInformation(iin), - preferredScheme = null - ) + val localIssuerInformation = localIssuerInformation(iin) + _state.update { + it.copy( + submitAllowed = areAllFieldsValid(), + errorMessage = null, + issuerInformation = localIssuerInformation, + eligibility = Eligible() + ) + } + updatePreferredScheme(scheme = localIssuerInformation?.scheme) if (iin.length == IIN_LENGTH) { updateIssuerInformation(iin) } @@ -361,7 +373,8 @@ internal class CardTokenizationInteractor( issuerInformationJob?.cancel() issuerInformationJob = interactorScope.launch { fetchIssuerInformation(iin)?.let { issuerInformation -> - requestPreferredScheme(issuerInformation) + _state.update { it.copy(issuerInformation = issuerInformation) } + requestEligibility(iin, issuerInformation) } } } @@ -375,15 +388,87 @@ internal class CardTokenizationInteractor( ) }.getOrNull() - private suspend fun requestPreferredScheme(issuerInformation: POCardIssuerInformation) { - val request = POCardTokenizationPreferredSchemeRequest(issuerInformation) - latestPreferredSchemeRequest = request - if (legacyEventDispatcher?.subscribedForPreferredSchemeRequest() == true) { - legacyEventDispatcher.send(request) + //endregion + + //region Eligibility + + private suspend fun requestEligibility( + iin: String, + issuerInformation: POCardIssuerInformation + ) { + val request = CardTokenizationEligibilityRequest( + iin = iin, + issuerInformation = issuerInformation + ) + latestEligibilityRequest = request + eventDispatcher.send(request) + POLogger.info("Requested to evaluate card eligibility: [iin=%s] [issuerInformation=%s]", iin, issuerInformation) + } + + private fun collectEligibility() { + eventDispatcher.subscribeForResponse( + coroutineScope = interactorScope + ) { response -> + if (response.uuid == latestEligibilityRequest?.uuid) { + latestEligibilityRequest = null + handleEligibility(response) + } + } + } + + private fun handleEligibility(response: CardTokenizationEligibilityResponse) { + _state.update { it.copy(eligibility = response.eligibility) } + if (response.eligibility is NotEligible) { + val errorMessage = response.eligibility.failure?.localizedMessage + ?: app.getString(R.string.po_card_tokenization_error_eligibility) + _state.update { + it.copy( + submitAllowed = false, + errorMessage = errorMessage + ) + } + } + val eligibleSchemes = _state.value.eligibleSchemes + if (eligibleSchemes.size > 1) { + _state.value.issuerInformation?.let { + requestPreferredScheme(issuerInformation = it) + } } else { - eventDispatcher.send(request) + eligibleSchemes.firstOrNull()?.let { + updatePreferredScheme(scheme = it) + } + } + } + + private val CardTokenizationInteractorState.eligibleSchemes: List + get() = when (eligibility) { + is Eligible -> + if (eligibility.scheme != null) { + listOf(eligibility.scheme) + } else { + listOfNotNull( + issuerInformation?.scheme, + issuerInformation?.coScheme + ) + } + is NotEligible -> emptyList() + } + + //endregion + + //region Preferred Scheme + + private fun requestPreferredScheme(issuerInformation: POCardIssuerInformation) { + interactorScope.launch { + val request = POCardTokenizationPreferredSchemeRequest(issuerInformation) + latestPreferredSchemeRequest = request + if (legacyEventDispatcher?.subscribedForPreferredSchemeRequest() == true) { + legacyEventDispatcher.send(request) + } else { + eventDispatcher.send(request) + } + POLogger.info("Requested to choose preferred scheme by issuer information: %s", issuerInformation) } - POLogger.info("Requested to choose preferred scheme by issuer information: %s", issuerInformation) } private fun collectPreferredScheme() { @@ -402,32 +487,28 @@ internal class CardTokenizationInteractor( private fun handlePreferredScheme(response: POCardTokenizationPreferredSchemeResponse) { if (response.uuid == latestPreferredSchemeRequest?.uuid) { latestPreferredSchemeRequest = null - updateState( - issuerInformation = response.issuerInformation, - preferredScheme = response.preferredScheme - ) + updatePreferredScheme(scheme = response.preferredScheme) } } - private fun updateState( - issuerInformation: POCardIssuerInformation?, - preferredScheme: String? - ) { - val availableSchemes = listOfNotNull( - availableScheme(issuerInformation?.scheme), - availableScheme(issuerInformation?.coScheme) - ) + private fun updatePreferredScheme(scheme: String?) { + val eligibleSchemes = _state.value.eligibleSchemes.mapNotNull { availableScheme(scheme = it) } + val preferredScheme = availableScheme(scheme)?.let { + if (it in eligibleSchemes) it else { + POLogger.warn("Preferred scheme is not eligible: %s", it.value) + eligibleSchemes.firstOrNull() + } + } _state.update { it.copy( - issuerInformation = issuerInformation, preferredSchemeField = it.preferredSchemeField.copy( - value = TextFieldValue(text = preferredScheme ?: String()), - availableValues = availableSchemes, - shouldCollect = configuration.preferredScheme != null && availableSchemes.size > 1 + value = TextFieldValue(text = preferredScheme?.value ?: String()), + availableValues = eligibleSchemes, + shouldCollect = configuration.preferredScheme != null && eligibleSchemes.size > 1 ) ) } - POLogger.info("State updated: [issuerInformation=%s] [preferredScheme=%s]", issuerInformation, preferredScheme) + POLogger.info("Preferred scheme updated: %s", preferredScheme?.value) } private fun availableScheme(scheme: String?): POAvailableValue? = @@ -569,7 +650,7 @@ internal class CardTokenizationInteractor( //region Submit private fun submit() { - if (!areAllFieldsValid()) { + if (!isSubmitAllowed()) { POLogger.debug("Ignored attempt to tokenize the card with invalid values.") return } @@ -583,12 +664,14 @@ internal class CardTokenizationInteractor( tokenize(tokenizationRequest()) } + private fun isSubmitAllowed() = _state.value.eligibility is Eligible && areAllFieldsValid() + + private fun areAllFieldsValid(): Boolean = allFields().all { it.isValid } + private fun allFields(): List = with(_state.value) { cardFields + addressFields + preferredSchemeField + saveCardField } - private fun areAllFieldsValid(): Boolean = allFields().all { it.isValid } - //endregion //region Tokenization Request @@ -866,6 +949,8 @@ internal class CardTokenizationInteractor( state.copy( cardFields = cardFields, addressFields = addressFields, + preferredSchemeField = preferredSchemeField, + saveCardField = saveCardField, focusedFieldId = firstInvalidFieldId ?: state.focusedFieldId, submitAllowed = allFields.all { it.isValid }, submitting = false, From 80150c13afc27b9c53e59347990a615802d6252b Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 19:38:11 +0300 Subject: [PATCH 10/28] requestEligibility() in separate coroutine --- .../tokenization/CardTokenizationInteractor.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt index 4c37ccc97..446bb5109 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt @@ -392,17 +392,19 @@ internal class CardTokenizationInteractor( //region Eligibility - private suspend fun requestEligibility( + private fun requestEligibility( iin: String, issuerInformation: POCardIssuerInformation ) { - val request = CardTokenizationEligibilityRequest( - iin = iin, - issuerInformation = issuerInformation - ) - latestEligibilityRequest = request - eventDispatcher.send(request) - POLogger.info("Requested to evaluate card eligibility: [iin=%s] [issuerInformation=%s]", iin, issuerInformation) + interactorScope.launch { + val request = CardTokenizationEligibilityRequest( + iin = iin, + issuerInformation = issuerInformation + ) + latestEligibilityRequest = request + eventDispatcher.send(request) + POLogger.info("Requested to evaluate card eligibility: [iin=%s] [issuerInformation=%s]", iin, issuerInformation) + } } private fun collectEligibility() { From 93d68641f818421b4c77b7b098e07e86cea0b84c Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 19:44:07 +0300 Subject: [PATCH 11/28] Log --- .../sdk/ui/card/tokenization/CardTokenizationInteractor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt index 446bb5109..be366bec5 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt @@ -419,6 +419,7 @@ internal class CardTokenizationInteractor( } private fun handleEligibility(response: CardTokenizationEligibilityResponse) { + POLogger.info("Card eligibility evaluation response: %s", response.eligibility) _state.update { it.copy(eligibility = response.eligibility) } if (response.eligibility is NotEligible) { val errorMessage = response.eligibility.failure?.localizedMessage From e590e7e07a5038e412a632679e8be49d866e45f7 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 6 May 2025 19:53:40 +0300 Subject: [PATCH 12/28] Interactor init --- .../sdk/ui/card/tokenization/CardTokenizationInteractor.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt index be366bec5..a54e49d20 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/CardTokenizationInteractor.kt @@ -101,12 +101,12 @@ internal class CardTokenizationInteractor( interactorScope.launch { POLogger.info("Starting card tokenization.") dispatch(WillStart) + handleCompletion() + shouldContinueOnFailure() collectFailure() - initAddressFields() collectEligibility() collectPreferredScheme() - handleCompletion() - shouldContinueOnFailure() + initAddressFields() POLogger.info("Card tokenization is started: waiting for user input.") dispatch(DidStart) } From 02294f1b7edeb2ef4d34fa0e25271febc3331a27 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 7 May 2025 13:28:53 +0300 Subject: [PATCH 13/28] AGP '8.10.0' --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3a42ea54e..69e4530bd 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - androidGradlePluginVersion = '8.9.2' + androidGradlePluginVersion = '8.10.0' kotlinVersion = '2.1.20' kspVersion = '2.1.20-1.0.32' dokkaVersion = '1.9.20' From a67b62c4f8824172ed85a4be9ecb1474c9cf1445 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 7 May 2025 13:46:45 +0300 Subject: [PATCH 14/28] Project.xml --- .idea/codeStyles/Project.xml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index eecc055af..f308f7d75 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -8,6 +8,41 @@ + + +