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 @@ -17,6 +17,7 @@ import com.processout.sdk.core.onFailure
import com.processout.sdk.core.onSuccess
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.Button
import com.processout.sdk.ui.napm.PONativeAlternativePaymentDelegate
import com.processout.sdk.ui.napm.PONativeAlternativePaymentLauncher
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodConfiguration
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodLauncher
Expand Down Expand Up @@ -48,7 +49,10 @@ class NativeApmFragment : BaseFragment<FragmentNativeApmBinding>(
showAlert(result.toMessage())
}
}
launcherCompose = PONativeAlternativePaymentLauncher.create(from = this) { result ->
launcherCompose = PONativeAlternativePaymentLauncher.create(
from = this,
delegate = object : PONativeAlternativePaymentDelegate {}
) { result ->
viewModel.reset()
result.onSuccess {
showAlert(getString(R.string.success))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.android.gms.wallet.Wallet.WalletOptions
import com.processout.sdk.R
import com.processout.sdk.api.ProcessOut
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.event.POSavedPaymentMethodsEvent
import com.processout.sdk.api.model.event.POSavedPaymentMethodsEvent.DidDeleteCustomerToken
import com.processout.sdk.api.model.request.POInvoiceRequest
Expand Down Expand Up @@ -73,20 +72,18 @@ internal class DynamicCheckoutActivity : BaseTransparentPortraitActivity() {
legacyEventDispatcher = null
)
}
val nativeAlternativePaymentEventDispatcher = PODefaultNativeAlternativePaymentMethodEventDispatcher()
val nativeAlternativePayment: NativeAlternativePaymentViewModel by viewModels {
NativeAlternativePaymentViewModel.Factory(
app = application,
configuration = nativeAlternativePaymentConfiguration(),
eventDispatcher = nativeAlternativePaymentEventDispatcher
legacyEventDispatcher = null
)
}
DynamicCheckoutViewModel.Factory(
app = application,
configuration = configuration,
cardTokenization = cardTokenization,
nativeAlternativePayment = nativeAlternativePayment,
nativeAlternativePaymentEventDispatcher = nativeAlternativePaymentEventDispatcher
nativeAlternativePayment = nativeAlternativePayment
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import coil.request.ImageRequest
import coil.request.ImageResult
import com.processout.sdk.R
import com.processout.sdk.api.dispatcher.POEventDispatcher
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.event.PODynamicCheckoutEvent
import com.processout.sdk.api.model.event.PODynamicCheckoutEvent.*
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent.WillSubmitParameters
import com.processout.sdk.api.model.request.*
import com.processout.sdk.api.model.response.*
Expand Down Expand Up @@ -75,7 +75,6 @@ internal class DynamicCheckoutInteractor(
private val googlePayService: POGooglePayService,
private val cardTokenization: CardTokenizationViewModel,
private val nativeAlternativePayment: NativeAlternativePaymentViewModel,
private val nativeAlternativePaymentEventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher,
private val eventDispatcher: POEventDispatcher = POEventDispatcher,
private var logAttributes: Map<String, String> = logAttributes(
invoiceId = configuration.invoiceRequest.invoiceId
Expand Down Expand Up @@ -123,12 +122,11 @@ internal class DynamicCheckoutInteractor(

private suspend fun start() {
handleCompletions()
dispatchEvents()
dispatchSideEffects()
collectEvents()
collectInvoice()
collectInvoiceAuthorizationRequest()
collectTokenizedCard()
collectDefaultValues()
collectSavedPaymentMethodsConfiguration()
fetchConfiguration()
}
Expand Down Expand Up @@ -995,33 +993,27 @@ internal class DynamicCheckoutInteractor(
}
}

private fun dispatch(event: PODynamicCheckoutEvent) {
interactorScope.launch {
eventDispatcher.send(event)
POLogger.debug("Event has been sent: %s", event)
}
}

private fun dispatchEvents() {
private fun collectEvents() {
eventDispatcher.subscribeForRequest<POCardTokenizationShouldContinueRequest>(
coroutineScope = interactorScope
) { request ->
interactorScope.launch {
eventDispatcher.send(request.toResponse(shouldContinue = false))
}
}
interactorScope.launch {
nativeAlternativePaymentEventDispatcher.events.collect { event ->
if (event is WillSubmitParameters) {
_state.update { it.copy(processingPaymentMethod = _state.value.selectedPaymentMethod) }
}
eventDispatcher.send(event)
eventDispatcher.subscribe<PONativeAlternativePaymentMethodEvent>(
coroutineScope = interactorScope
) { event ->
if (event is WillSubmitParameters) {
_state.update { it.copy(processingPaymentMethod = _state.value.selectedPaymentMethod) }
}
}
}

private fun dispatch(event: PODynamicCheckoutEvent) {
interactorScope.launch {
nativeAlternativePaymentEventDispatcher.defaultValuesRequest.collect { request ->
eventDispatcher.send(request)
}
eventDispatcher.send(event)
POLogger.debug("Event has been sent: %s", event)
}
}

Expand Down Expand Up @@ -1081,16 +1073,6 @@ internal class DynamicCheckoutInteractor(
POLogger.debug("Deleted local customer token: %s", tokenId)
}

private fun collectDefaultValues() {
eventDispatcher.subscribeForResponse<PONativeAlternativePaymentMethodDefaultValuesResponse>(
coroutineScope = interactorScope
) { response ->
interactorScope.launch {
nativeAlternativePaymentEventDispatcher.provideDefaultValues(response)
}
}
}

private fun cancel() {
val failure = ProcessOutResult.Failure(
code = Cancelled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.lifecycle.viewModelScope
import com.google.android.gms.wallet.Wallet.WalletOptions
import com.processout.sdk.R
import com.processout.sdk.api.ProcessOut
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.Display
import com.processout.sdk.api.service.googlepay.PODefaultGooglePayService
import com.processout.sdk.ui.card.tokenization.CardTokenizationViewModel
Expand Down Expand Up @@ -44,8 +43,7 @@ internal class DynamicCheckoutViewModel private constructor(
private val app: Application,
private val configuration: PODynamicCheckoutConfiguration,
private val cardTokenization: CardTokenizationViewModel,
private val nativeAlternativePayment: NativeAlternativePaymentViewModel,
private val nativeAlternativePaymentEventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher
private val nativeAlternativePayment: NativeAlternativePaymentViewModel
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
Expand All @@ -63,8 +61,7 @@ internal class DynamicCheckoutViewModel private constructor(
.build()
),
cardTokenization = cardTokenization,
nativeAlternativePayment = nativeAlternativePayment,
nativeAlternativePaymentEventDispatcher = nativeAlternativePaymentEventDispatcher
nativeAlternativePayment = nativeAlternativePayment
)
) as T
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal class NativeAlternativePaymentBottomSheet : BaseBottomSheetDialogFragme
gatewayConfigurationId = String(),
submitButton = Button()
),
eventDispatcher = PODefaultEventDispatchers.defaultNativeAlternativePaymentMethod
legacyEventDispatcher = PODefaultEventDispatchers.defaultNativeAlternativePaymentMethod
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import coil.request.CachePolicy
import coil.request.ImageRequest
import coil.request.ImageResult
import com.processout.sdk.R
import com.processout.sdk.api.dispatcher.POEventDispatcher
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent.*
Expand Down Expand Up @@ -63,7 +64,8 @@ internal class NativeAlternativePaymentInteractor(
private val barcodeBitmapProvider: BarcodeBitmapProvider,
private val mediaStorageProvider: MediaStorageProvider,
private val captureRetryStrategy: PORetryStrategy,
private val eventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher,
private val legacyEventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher?, // TODO: remove before next major release.
private val eventDispatcher: POEventDispatcher = POEventDispatcher,
private var logAttributes: Map<String, String> = logAttributes(
invoiceId = configuration.invoiceId,
gatewayConfigurationId = configuration.gatewayConfigurationId
Expand Down Expand Up @@ -260,21 +262,14 @@ internal class NativeAlternativePaymentInteractor(
fields = fields,
focusedFieldId = focusedFieldId
)
val isLoading = _state.value is Loading
if (eventDispatcher.subscribedForDefaultValuesRequest()) {
_state.update {
if (isLoading) {
Loaded(updatedStateValue)
} else {
Submitted(updatedStateValue)
}
_state.update {
if (_state.value is Loading) {
Loaded(updatedStateValue)
} else {
Submitted(updatedStateValue)
}
requestDefaultValues(parameters)
} else if (isLoading) {
startUserInput(updatedStateValue)
} else {
continueUserInput(updatedStateValue)
}
requestDefaultValues(parameters)
}

private fun failWithUnknownInputParameter(
Expand Down Expand Up @@ -368,24 +363,39 @@ internal class NativeAlternativePaymentInteractor(
parameters = parameters
)
latestDefaultValuesRequest = request
eventDispatcher.send(request)
if (legacyEventDispatcher?.subscribedForDefaultValuesRequest() == true) {
legacyEventDispatcher.send(request)
} else {
eventDispatcher.send(request)
}
POLogger.debug("Requested to provide default values for payment parameters: %s", request)
}
}

private fun collectDefaultValues() {
interactorScope.launch {
eventDispatcher.defaultValuesResponse.collect { response ->
if (response.uuid == latestDefaultValuesRequest?.uuid) {
latestDefaultValuesRequest = null
POLogger.debug("Collected default values for payment parameters: %s", response)
_state.whenLoaded { stateValue ->
startUserInput(stateValue.updateFieldValues(response.defaultValues))
}
_state.whenSubmitted { stateValue ->
continueUserInput(stateValue.updateFieldValues(response.defaultValues))
}
}
legacyEventDispatcher?.defaultValuesResponse?.collect { response ->
handleDefaultValues(response)
}
}
eventDispatcher.subscribeForResponse<PONativeAlternativePaymentMethodDefaultValuesResponse>(
coroutineScope = interactorScope
) { response ->
handleDefaultValues(response)
}
}

private fun handleDefaultValues(
response: PONativeAlternativePaymentMethodDefaultValuesResponse
) {
if (response.uuid == latestDefaultValuesRequest?.uuid) {
latestDefaultValuesRequest = null
POLogger.debug("Collected default values for payment parameters: %s", response)
_state.whenLoaded { stateValue ->
startUserInput(stateValue.updateFieldValues(response.defaultValues))
}
_state.whenSubmitted { stateValue ->
continueUserInput(stateValue.updateFieldValues(response.defaultValues))
}
}
}
Expand Down Expand Up @@ -922,6 +932,7 @@ internal class NativeAlternativePaymentInteractor(

private fun dispatch(event: PONativeAlternativePaymentMethodEvent) {
interactorScope.launch {
legacyEventDispatcher?.send(event)
eventDispatcher.send(event)
POLogger.debug("Event has been sent: %s", event)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal class NativeAlternativePaymentViewModel private constructor(
class Factory(
private val app: Application,
private val configuration: PONativeAlternativePaymentConfiguration,
private val eventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher
private val legacyEventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher?
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
Expand All @@ -62,7 +62,7 @@ internal class NativeAlternativePaymentViewModel private constructor(
maxDelay = 90 * 1000,
factor = 1.45
),
eventDispatcher = eventDispatcher
legacyEventDispatcher = legacyEventDispatcher
)
) as T
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.processout.sdk.ui.napm

import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent
import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodParameter

/**
* Delegate that allows to handle events during native alternative payments.
*/
interface PONativeAlternativePaymentDelegate {

/**
* Invoked on native alternative payment lifecycle events.
*/
fun onEvent(event: PONativeAlternativePaymentMethodEvent) {}

/**
* Allows to prefill default values for the given parameters during native alternative payment.
* Return a map where key is a [PONativeAlternativePaymentMethodParameter.key] and value is a custom default value.
* It's not mandatory to provide default values for all parameters.
*/
suspend fun defaultValues(
gatewayConfigurationId: String,
parameters: List<PONativeAlternativePaymentMethodParameter>
): Map<String, String> = emptyMap()
}
Loading