From 8d2b51d057735f3c22338ec87da7e5a4f0282753 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 14 May 2026 18:24:14 +0300 Subject: [PATCH 1/2] Redirect automatically when it's a fallback --- .../napm/v2/PONativeAlternativePaymentRedirect.kt | 5 ++++- .../ui/napm/NativeAlternativePaymentInteractor.kt | 12 +++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt index 8896d93d..edf8e686 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt @@ -33,7 +33,10 @@ data class PONativeAlternativePaymentRedirect( @Json(name = "confirmation_required") val confirmationRequired: Boolean, @Json(name = "deep_link") - val deepLinkConfiguration: DeepLinkConfiguration? + val deepLinkConfiguration: DeepLinkConfiguration?, + @Json(ignore = true) + @ProcessOutInternalApi + val isFallback: Boolean = false ) : Parcelable { /** Redirect type. */ diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt index ebbfa878..dcb9c521 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt @@ -327,7 +327,7 @@ internal class NativeAlternativePaymentInteractor( val fields = parameters.toFields() val updatedStateValue = stateValue.copy( uuid = UUID.randomUUID().toString(), - redirect = redirect, + redirect = redirect?.copy(isFallback = stateValue.redirect != null), elements = elements, fields = fields, focusedFieldId = fields.firstFocusableFieldId() @@ -453,17 +453,19 @@ internal class NativeAlternativePaymentInteractor( private fun handleAutoRedirect() { _state.whenNextStep { stateValue -> - if (stateValue.redirect != null && shouldAutoRedirect()) { + val redirect = stateValue.redirect + if (redirect != null && redirect.shouldAutoRedirect()) { redirect( stateValue = stateValue, - redirect = stateValue.redirect + redirect = redirect ) } } } - private fun shouldAutoRedirect(): Boolean = - configuration.redirect?.enableHeadlessMode == true || + private fun PONativeAlternativePaymentRedirect.shouldAutoRedirect(): Boolean = + isFallback || + configuration.redirect?.enableHeadlessMode == true || configuration.redirect?.redirectButton == null //endregion From ec7745d66c3f6b0480cf1258993e9c92fcd25f76 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 14 May 2026 19:21:31 +0300 Subject: [PATCH 2/2] Internal wrapper data class Redirect() --- .../v2/PONativeAlternativePaymentRedirect.kt | 5 +---- .../NativeAlternativePaymentInteractor.kt | 21 ++++++++++++------- ...NativeAlternativePaymentInteractorState.kt | 9 ++++++-- .../napm/NativeAlternativePaymentViewModel.kt | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt index edf8e686..8896d93d 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentRedirect.kt @@ -33,10 +33,7 @@ data class PONativeAlternativePaymentRedirect( @Json(name = "confirmation_required") val confirmationRequired: Boolean, @Json(name = "deep_link") - val deepLinkConfiguration: DeepLinkConfiguration?, - @Json(ignore = true) - @ProcessOutInternalApi - val isFallback: Boolean = false + val deepLinkConfiguration: DeepLinkConfiguration? ) : Parcelable { /** Redirect type. */ diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt index dcb9c521..ca402ff3 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt @@ -327,7 +327,12 @@ internal class NativeAlternativePaymentInteractor( val fields = parameters.toFields() val updatedStateValue = stateValue.copy( uuid = UUID.randomUUID().toString(), - redirect = redirect?.copy(isFallback = stateValue.redirect != null), + redirect = redirect?.let { + Redirect( + data = it, + isFallback = stateValue.redirect != null + ) + }, elements = elements, fields = fields, focusedFieldId = fields.firstFocusableFieldId() @@ -457,13 +462,13 @@ internal class NativeAlternativePaymentInteractor( if (redirect != null && redirect.shouldAutoRedirect()) { redirect( stateValue = stateValue, - redirect = redirect + redirect = redirect.data ) } } } - private fun PONativeAlternativePaymentRedirect.shouldAutoRedirect(): Boolean = + private fun Redirect.shouldAutoRedirect(): Boolean = isFallback || configuration.redirect?.enableHeadlessMode == true || configuration.redirect?.redirectButton == null @@ -556,12 +561,12 @@ internal class NativeAlternativePaymentInteractor( return@subscribe } _state.whenNextStep { stateValue -> - if (stateValue.redirect?.type == RedirectType.DEEP_LINK) { + if (stateValue.redirect?.data?.type == RedirectType.DEEP_LINK) { handleDeepLink(event.uri) } } _state.whenPending { stateValue -> - if (stateValue.redirect?.type == RedirectType.DEEP_LINK) { + if (stateValue.redirect?.data?.type == RedirectType.DEEP_LINK) { handleDeepLink(event.uri) } } @@ -700,7 +705,7 @@ internal class NativeAlternativePaymentInteractor( if (stateValue.redirect != null) { redirect( stateValue = stateValue, - redirect = stateValue.redirect + redirect = stateValue.redirect.data ) return@whenNextStep } @@ -795,7 +800,7 @@ internal class NativeAlternativePaymentInteractor( private fun handleWebRedirect(result: ProcessOutResult) { result.onSuccess { _state.whenNextStep { stateValue -> - val redirectConfirmation = if (stateValue.redirect?.confirmationRequired == true) + val redirectConfirmation = if (stateValue.redirect?.data?.confirmationRequired == true) PONativeAlternativePaymentRedirectConfirmation(success = true) else null continuePayment(redirectConfirmation) } @@ -821,7 +826,7 @@ internal class NativeAlternativePaymentInteractor( url = redirectUrl, packageNames = deepLinkConfiguration?.packageNames ) - val redirectConfirmation = if (stateValue.redirect?.confirmationRequired == true) + val redirectConfirmation = if (stateValue.redirect?.data?.confirmationRequired == true) PONativeAlternativePaymentRedirectConfirmation(success = didOpenUrl) else null continuePayment(redirectConfirmation) } diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt index 1e147e46..86514c14 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt @@ -49,7 +49,7 @@ internal sealed interface NativeAlternativePaymentInteractorState { val uuid: String, val paymentMethod: PONativeAlternativePaymentMethodDetails, val invoice: Invoice?, - val redirect: PONativeAlternativePaymentRedirect?, + val redirect: Redirect?, val elements: List, val fields: List, val focusedFieldId: String?, @@ -63,7 +63,7 @@ internal sealed interface NativeAlternativePaymentInteractorState { val uuid: String, val paymentMethod: PONativeAlternativePaymentMethodDetails, val invoice: Invoice?, - val redirect: PONativeAlternativePaymentRedirect?, + val redirect: Redirect?, val stepper: Stepper?, val elements: List?, val primaryActionId: String?, @@ -75,6 +75,11 @@ internal sealed interface NativeAlternativePaymentInteractorState { val activeStepIndex: Int ) + data class Redirect( + val data: PONativeAlternativePaymentRedirect, + val isFallback: Boolean + ) + sealed interface Element { data class Form( diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentViewModel.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentViewModel.kt index 7526b6e5..71e900ff 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentViewModel.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentViewModel.kt @@ -571,7 +571,7 @@ internal class NativeAlternativePaymentViewModel private constructor( return if (redirect != null) { configuration.redirect?.redirectButton?.let { submitAction.copy( - text = it.text ?: redirect.hint, + text = it.text ?: redirect.data.hint, icon = it.icon ) }