From 4422cc066441c8da1487538f2a016dc3c1f214af Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Fri, 15 May 2026 17:33:24 +0300 Subject: [PATCH 1/2] Start native UI automatically when headless mode is not supported by the payment method --- .../com/processout/sdk/core/POFailure.kt | 6 ++++- .../NativeAlternativePaymentInteractor.kt | 6 ++--- ...PONativeAlternativePaymentConfiguration.kt | 2 +- .../PONativeAlternativePaymentLauncher.kt | 27 +++++++++++++++---- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/core/POFailure.kt b/sdk/src/main/kotlin/com/processout/sdk/core/POFailure.kt index 36a9a65d..0651d78f 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/core/POFailure.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/core/POFailure.kt @@ -3,6 +3,7 @@ package com.processout.sdk.core import android.os.Parcelable +import com.processout.sdk.core.annotation.ProcessOutInternalApi import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import kotlinx.parcelize.Parcelize @@ -289,7 +290,10 @@ class POFailure private constructor() { resourceNotLinked("resource.not-linked"), routingRulesTransactionBlocked("routing-rules.transaction-blocked"), sandboxNotSupported("sandbox.not-supported"), - serviceNotSupported("service.not-supported") + serviceNotSupported("service.not-supported"), + + @ProcessOutInternalApi + mobileHeadlessModeNotSupported("processout-mobile.generic.headless-mode-not-supported") } /** 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 ca402ff3..85676bc0 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 @@ -36,7 +36,7 @@ import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentS import com.processout.sdk.api.service.POCustomerTokensService import com.processout.sdk.api.service.POInvoicesService import com.processout.sdk.core.POFailure.Code.* -import com.processout.sdk.core.POFailure.GenericCode.mobileOperationNotSupported +import com.processout.sdk.core.POFailure.GenericCode.mobileHeadlessModeNotSupported import com.processout.sdk.core.POFailure.InvalidField import com.processout.sdk.core.POFailure.ValidationCode import com.processout.sdk.core.ProcessOutResult @@ -352,10 +352,10 @@ internal class NativeAlternativePaymentInteractor( ): Boolean { if (configuration.redirect?.enableHeadlessMode == true && redirect == null) { val failure = ProcessOutResult.Failure( - code = Generic(genericCode = mobileOperationNotSupported), + code = Generic(genericCode = mobileHeadlessModeNotSupported), message = "Headless mode is not supported: redirect parameters are missing in the response." ) - POLogger.error( + POLogger.info( message = "Unsupported operation: %s", failure, attributes = configuration.logAttributes ) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentConfiguration.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentConfiguration.kt index 4a0cf086..45e1b7fd 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentConfiguration.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentConfiguration.kt @@ -395,7 +395,7 @@ data class PONativeAlternativePaymentConfiguration( * @param[enableHeadlessMode] Enables headless mode. * The redirect (web or deep link) will be handled directly when it's the first step in the flow, without starting the bottom sheet. * It will also capture the payment in the background when it's required by the flow. - * __Note:__ use only with flows that do not require user input or instructions in the native UI. + * __Note:__ The bottom sheet will still start automatically when the payment method requires user input in the native UI. * @param[redirectButton] Redirect button configuration. * Pass _null_ to hide and redirect automatically, this is a default behaviour. */ diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentLauncher.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentLauncher.kt index 558e5819..d606b5f3 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentLauncher.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/PONativeAlternativePaymentLauncher.kt @@ -16,11 +16,9 @@ import androidx.lifecycle.repeatOnLifecycle import com.processout.sdk.R import com.processout.sdk.api.dispatcher.POEventDispatcher import com.processout.sdk.api.model.response.POAlternativePaymentMethodResponse -import com.processout.sdk.core.POUnit -import com.processout.sdk.core.ProcessOutActivityResult -import com.processout.sdk.core.ProcessOutResult +import com.processout.sdk.core.* +import com.processout.sdk.core.POFailure.GenericCode.mobileHeadlessModeNotSupported import com.processout.sdk.core.logger.POLogger -import com.processout.sdk.core.toActivityResult import com.processout.sdk.ui.apm.POAlternativePaymentMethodCustomTabLauncher import com.processout.sdk.ui.napm.NativeAlternativePaymentCompletion.Failure import com.processout.sdk.ui.napm.NativeAlternativePaymentCompletion.Success @@ -281,7 +279,26 @@ class PONativeAlternativePaymentLauncher private constructor( viewModel.completion.collect { completion -> when (completion) { Success -> complete(result = ProcessOutResult.Success(POUnit)) - is Failure -> complete(result = completion.failure) + is Failure -> { + val isHeadlessModeNotSupported = when (val code = completion.failure.code) { + is POFailure.Code.Generic -> code.genericCode == mobileHeadlessModeNotSupported + else -> false + } + if (isHeadlessModeNotSupported) { + val configuration = viewModel.configuration + viewModel.reset() + launcher.launch( + input = configuration.copy( + redirect = configuration.redirect?.copy( + enableHeadlessMode = false + ) + ), + options = activityOptions + ) + } else { + complete(result = completion.failure) + } + } else -> {} } } From 48523d1dd57e11b2b9ec5130395d4f821efb7121 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Fri, 15 May 2026 17:43:19 +0300 Subject: [PATCH 2/2] Minor libs update --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 2e5c0d7f..0a13d575 100644 --- a/build.gradle +++ b/build.gradle @@ -82,8 +82,8 @@ ext { okhttpVersion = '4.12.0' okioVersion = '3.10.2' coilVersion = '2.7.0' - commonMarkVersion = '0.27.0' - libphonenumberVersion = '9.0.19' + commonMarkVersion = '0.28.0' + libphonenumberVersion = '9.0.30' zxingVersion = '3.5.4' jjwtVersion = '0.13.0' slf4jVersion = '1.7.36'