Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,8 @@ internal class NativeAlternativePaymentInteractor(
)
_state.update { Pending(pendingStateValue) }
enablePendingSecondaryAction()
if (pendingStateValue.elements.isNullOrEmpty() ||
if (configuration.redirect?.enableHeadlessMode == true ||
pendingStateValue.elements.isNullOrEmpty() ||
configuration.paymentConfirmation.confirmButton == null
) {
capture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,9 @@ data class PONativeAlternativePaymentConfiguration(
*
* @param[returnUrl] Deep link return URL. Required for the flows that include web redirect.
* @param[enableHeadlessMode] Enables headless mode.
* The web redirect will be handled directly when it's the first step in the flow,
* and if it's the only required step it will complete the flow without starting the bottom sheet.
* 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.
*/
@Parcelize
data class RedirectConfiguration(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.processout.sdk.ui.napm

import android.app.Application
import android.content.Context
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
import androidx.core.app.ActivityOptionsCompat
import androidx.core.net.toUri
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.processout.sdk.R
import com.processout.sdk.api.ProcessOut
import com.processout.sdk.api.dispatcher.POEventDispatcher
Expand Down Expand Up @@ -41,17 +43,35 @@ import kotlinx.coroutines.launch
* Launcher that starts [NativeAlternativePaymentActivity] and provides the result.
*/
class PONativeAlternativePaymentLauncher private constructor(
private val app: Application,
private val scope: CoroutineScope,
private val hostActivity: ComponentActivity,
private val launcher: ActivityResultLauncher<PONativeAlternativePaymentConfiguration>,
private val activityOptions: ActivityOptionsCompat,
private val delegate: PONativeAlternativePaymentDelegate,
private val callback: (ProcessOutActivityResult<POUnit>) -> Unit,
private val eventDispatcher: POEventDispatcher = POEventDispatcher.instance,
private val invoicesService: POInvoicesService = ProcessOut.instance.invoices,
private val customerTokensService: POCustomerTokensService = ProcessOut.instance.customerTokens
) {

private val app: Application = hostActivity.application
private val scope: CoroutineScope = hostActivity.lifecycleScope

private val activityOptions = ActivityOptionsCompat.makeCustomAnimation(
hostActivity, R.anim.po_slide_in_vertical, 0
)

private val viewModel: NativeAlternativePaymentViewModel by hostActivity.viewModels {
NativeAlternativePaymentViewModel.Factory(
app = app,
configuration = PONativeAlternativePaymentConfiguration(
flow = Authorization(
invoiceId = String(),
gatewayConfigurationId = String()
),
header = null
)
)
}

private lateinit var customTabLauncher: POAlternativePaymentMethodCustomTabLauncher

private object LocalCache {
Expand All @@ -68,13 +88,11 @@ class PONativeAlternativePaymentLauncher private constructor(
delegate: PONativeAlternativePaymentDelegate,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.requireActivity().application,
scope = from.lifecycleScope,
hostActivity = from.requireActivity(),
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
callback
),
activityOptions = createActivityOptions(from.requireContext()),
delegate = delegate,
callback = callback
).apply {
Expand All @@ -96,13 +114,11 @@ class PONativeAlternativePaymentLauncher private constructor(
delegate: com.processout.sdk.ui.napm.delegate.PONativeAlternativePaymentDelegate,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.requireActivity().application,
scope = from.lifecycleScope,
hostActivity = from.requireActivity(),
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
callback
),
activityOptions = createActivityOptions(from.requireContext()),
delegate = object : PONativeAlternativePaymentDelegate {},
callback = callback
).apply {
Expand All @@ -121,13 +137,11 @@ class PONativeAlternativePaymentLauncher private constructor(
from: Fragment,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.requireActivity().application,
scope = from.lifecycleScope,
hostActivity = from.requireActivity(),
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
callback
),
activityOptions = createActivityOptions(from.requireContext()),
delegate = object : PONativeAlternativePaymentDelegate {},
callback = callback
).apply {
Expand All @@ -146,14 +160,12 @@ class PONativeAlternativePaymentLauncher private constructor(
delegate: PONativeAlternativePaymentDelegate,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.application,
scope = from.lifecycleScope,
hostActivity = from,
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
from.activityResultRegistry,
callback
),
activityOptions = createActivityOptions(from),
delegate = delegate,
callback = callback
).apply {
Expand All @@ -175,14 +187,12 @@ class PONativeAlternativePaymentLauncher private constructor(
delegate: com.processout.sdk.ui.napm.delegate.PONativeAlternativePaymentDelegate,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.application,
scope = from.lifecycleScope,
hostActivity = from,
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
from.activityResultRegistry,
callback
),
activityOptions = createActivityOptions(from),
delegate = object : PONativeAlternativePaymentDelegate {},
callback = callback
).apply {
Expand All @@ -201,14 +211,12 @@ class PONativeAlternativePaymentLauncher private constructor(
from: ComponentActivity,
callback: (ProcessOutActivityResult<POUnit>) -> Unit
) = PONativeAlternativePaymentLauncher(
app = from.application,
scope = from.lifecycleScope,
hostActivity = from,
launcher = from.registerForActivityResult(
NativeAlternativePaymentActivityContract(),
from.activityResultRegistry,
callback
),
activityOptions = createActivityOptions(from),
delegate = object : PONativeAlternativePaymentDelegate {},
callback = callback
).apply {
Expand All @@ -217,18 +225,30 @@ class PONativeAlternativePaymentLauncher private constructor(
callback = ::handleWebRedirect
)
}

private fun createActivityOptions(context: Context) =
ActivityOptionsCompat.makeCustomAnimation(
context, R.anim.po_slide_in_vertical, 0
)
}

init {
collectViewModelCompletion()
dispatchEvents()
dispatchDefaultValues()
}

private fun collectViewModelCompletion() {
hostActivity.lifecycleScope.launch {
hostActivity.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.completion.collect { completion ->
when (completion) {
NativeAlternativePaymentCompletion.Success ->
completeHeadlessMode(result = ProcessOutResult.Success(value = POUnit))
is NativeAlternativePaymentCompletion.Failure ->
completeHeadlessMode(result = completion.failure)
else -> {}
}
}
}
}
}

private fun dispatchEvents() {
eventDispatcher.subscribe<PONativeAlternativePaymentEvent>(
coroutineScope = scope
Expand Down Expand Up @@ -348,14 +368,11 @@ class PONativeAlternativePaymentLauncher private constructor(
) {
when (state) {
NEXT_STEP_REQUIRED -> handleNextStep(redirect, configuration)
PENDING -> launchActivity(configuration)
SUCCESS ->
if (configuration.success != null) {
launchActivity(configuration)
} else {
POLogger.info("Success: payment completed.")
completeHeadlessMode(result = ProcessOutResult.Success(value = POUnit))
}
PENDING -> viewModel.start(configuration)
SUCCESS -> {
POLogger.info("Success: payment completed.")
completeHeadlessMode(result = ProcessOutResult.Success(value = POUnit))
}
UNKNOWN -> {
val failure = ProcessOutResult.Failure(
code = Internal(),
Expand Down Expand Up @@ -482,6 +499,7 @@ class PONativeAlternativePaymentLauncher private constructor(
}
}
LocalCache.configuration = null
viewModel.reset()
callback(result.toActivityResult())
}
}