Skip to content

Commit

Permalink
Move common confirmation option parameters to `ConfirmationHandler.Ar…
Browse files Browse the repository at this point in the history
…gs` (#9758)
  • Loading branch information
samer-stripe authored Dec 9, 2024
1 parent c13fae8 commit 6749823
Show file tree
Hide file tree
Showing 41 changed files with 492 additions and 481 deletions.
8 changes: 8 additions & 0 deletions paymentsheet/api/paymentsheet.api
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ public final class com/stripe/android/paymentelement/EmbeddedPaymentElement$Conf
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/paymentelement/confirmation/ConfirmationDefinition$Parameters$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentelement/confirmation/ConfirmationDefinition$Parameters;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/stripe/android/paymentelement/confirmation/ConfirmationDefinition$Parameters;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/paymentelement/confirmation/ConfirmationHandler$Args$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentelement/confirmation/ConfirmationHandler$Args;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1032,15 +1032,16 @@ internal class CustomerSheetViewModel(
) {
confirmationHandler.start(
arguments = ConfirmationHandler.Args(
intent = stripeIntent,
confirmationOption = PaymentMethodConfirmationOption.Saved(
initializationMode = PaymentElementLoader.InitializationMode.SetupIntent(
clientSecret = clientSecret
),
shippingDetails = null,
paymentMethod = paymentMethod,
optionsParams = null,
),
intent = stripeIntent,
initializationMode = PaymentElementLoader.InitializationMode.SetupIntent(
clientSecret = clientSecret
),
shippingDetails = null,
appearance = configuration.appearance,
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import androidx.activity.result.ActivityResultCaller
import com.stripe.android.core.strings.ResolvableString
import com.stripe.android.model.StripeIntent
import com.stripe.android.paymentelement.confirmation.intent.DeferredIntentConfirmationType
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.addresselement.AddressDetails
import com.stripe.android.paymentsheet.state.PaymentElementLoader
import kotlinx.parcelize.Parcelize

internal interface ConfirmationDefinition<
TConfirmationOption : ConfirmationHandler.Option,
Expand All @@ -20,14 +24,14 @@ internal interface ConfirmationDefinition<

suspend fun action(
confirmationOption: TConfirmationOption,
intent: StripeIntent,
confirmationParameters: Parameters,
): Action<TLauncherArgs>

fun launch(
launcher: TLauncher,
arguments: TLauncherArgs,
confirmationOption: TConfirmationOption,
intent: StripeIntent,
confirmationParameters: Parameters,
)

fun createLauncher(
Expand All @@ -41,11 +45,19 @@ internal interface ConfirmationDefinition<

fun toResult(
confirmationOption: TConfirmationOption,
confirmationParameters: Parameters,
deferredIntentConfirmationType: DeferredIntentConfirmationType?,
intent: StripeIntent,
result: TLauncherResult,
): Result

@Parcelize
data class Parameters(
val intent: StripeIntent,
val appearance: PaymentSheet.Appearance,
val initializationMode: PaymentElementLoader.InitializationMode,
val shippingDetails: AddressDetails?
) : Parcelable

sealed interface Result {
data class Canceled(
val action: ConfirmationHandler.Result.Canceled.Action,
Expand All @@ -57,8 +69,8 @@ internal interface ConfirmationDefinition<
) : Result

data class NextStep(
val intent: StripeIntent,
val confirmationOption: ConfirmationHandler.Option,
val parameters: Parameters,
) : Result

data class Failed(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import androidx.lifecycle.LifecycleOwner
import com.stripe.android.core.strings.ResolvableString
import com.stripe.android.model.StripeIntent
import com.stripe.android.paymentelement.confirmation.intent.DeferredIntentConfirmationType
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.addresselement.AddressDetails
import com.stripe.android.paymentsheet.state.PaymentElementLoader
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -69,7 +72,22 @@ internal interface ConfirmationHandler {
/**
* The confirmation option used to in order to potentially confirm the intent
*/
val confirmationOption: Option
val confirmationOption: Option,

/**
* Appearance values to be used when styling the launched activities
*/
val appearance: PaymentSheet.Appearance,

/**
* The mode that a Payment Element product was initialized with
*/
val initializationMode: PaymentElementLoader.InitializationMode,

/**
* The shipping details of the customer that can be attached during the confirmation flow
*/
val shippingDetails: AddressDetails?
) : Parcelable

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal class ConfirmationMediator<
val confirmationResult = persistedParameters?.let { params ->
definition.toResult(
confirmationOption = params.confirmationOption,
intent = params.intent,
confirmationParameters = params.confirmationParameters,
result = result,
deferredIntentConfirmationType = params.deferredIntentConfirmationType
)
Expand Down Expand Up @@ -76,7 +76,7 @@ internal class ConfirmationMediator<

suspend fun action(
option: ConfirmationHandler.Option,
intent: StripeIntent
parameters: ConfirmationDefinition.Parameters,
): Action {
val confirmationOption = definition.option(option)
?: return Action.Fail(
Expand All @@ -88,22 +88,22 @@ internal class ConfirmationMediator<
errorType = ConfirmationHandler.Result.Failed.ErrorType.Internal,
)

return when (val action = definition.action(confirmationOption, intent)) {
return when (val action = definition.action(confirmationOption, parameters)) {
is ConfirmationDefinition.Action.Launch -> {
launcher?.let {
Action.Launch(
launch = {
persistedParameters = Parameters(
confirmationOption = confirmationOption,
intent = intent,
confirmationParameters = parameters,
deferredIntentConfirmationType = action.deferredIntentConfirmationType,
)

definition.launch(
launcher = it,
arguments = action.launcherArguments,
confirmationOption = confirmationOption,
intent = intent,
confirmationParameters = parameters,
)
},
receivesResultInProcess = action.receivesResultInProcess,
Expand Down Expand Up @@ -159,7 +159,7 @@ internal class ConfirmationMediator<
@Parcelize
internal data class Parameters<TConfirmationOption : ConfirmationHandler.Option>(
val confirmationOption: TConfirmationOption,
val intent: StripeIntent,
val confirmationParameters: ConfirmationDefinition.Parameters,
val deferredIntentConfirmationType: DeferredIntentConfirmationType?,
) : Parcelable

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,14 @@ import com.stripe.android.paymentelement.confirmation.bacs.BacsConfirmationOptio
import com.stripe.android.paymentelement.confirmation.epms.ExternalPaymentMethodConfirmationOption
import com.stripe.android.paymentelement.confirmation.gpay.GooglePayConfirmationOption
import com.stripe.android.paymentelement.confirmation.link.LinkConfirmationOption
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.model.PaymentSelection
import com.stripe.android.paymentsheet.state.PaymentElementLoader

internal fun PaymentSelection.toConfirmationOption(
initializationMode: PaymentElementLoader.InitializationMode,
configuration: CommonConfiguration,
appearance: PaymentSheet.Appearance,
linkConfiguration: LinkConfiguration?,
): ConfirmationHandler.Option? {
return when (this) {
is PaymentSelection.Saved -> PaymentMethodConfirmationOption.Saved(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
paymentMethod = paymentMethod,
optionsParams = paymentMethodOptionsParams,
)
Expand All @@ -34,15 +28,11 @@ internal fun PaymentSelection.toConfirmationOption(
// For Instant Debits, we create the PaymentMethod inside the bank auth flow. Therefore,
// we can just use the already created object here.
PaymentMethodConfirmationOption.Saved(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
paymentMethod = instantDebits.paymentMethod,
optionsParams = paymentMethodOptionsParams,
)
} else {
PaymentMethodConfirmationOption.New(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
createParams = paymentMethodCreateParams,
optionsParams = paymentMethodOptionsParams,
shouldSave = customerRequestedSave == PaymentSelection.CustomerRequestedSave.RequestReuse,
Expand All @@ -52,16 +42,11 @@ internal fun PaymentSelection.toConfirmationOption(
is PaymentSelection.New -> {
if (paymentMethodCreateParams.typeCode == PaymentMethod.Type.BacsDebit.code) {
BacsConfirmationOption(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
createParams = paymentMethodCreateParams,
optionsParams = paymentMethodOptionsParams,
appearance = appearance,
)
} else {
PaymentMethodConfirmationOption.New(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
createParams = paymentMethodCreateParams,
optionsParams = paymentMethodOptionsParams,
shouldSave = customerRequestedSave == PaymentSelection.CustomerRequestedSave.RequestReuse,
Expand All @@ -70,8 +55,6 @@ internal fun PaymentSelection.toConfirmationOption(
}
is PaymentSelection.GooglePay -> configuration.googlePay?.let { googlePay ->
GooglePayConfirmationOption(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
config = GooglePayConfirmationOption.Config(
environment = googlePay.environment,
merchantName = configuration.merchantDisplayName,
Expand All @@ -85,11 +68,7 @@ internal fun PaymentSelection.toConfirmationOption(
)
}
is PaymentSelection.Link -> linkConfiguration?.let {
LinkConfirmationOption(
initializationMode = initializationMode,
shippingDetails = configuration.shippingDetails,
configuration = linkConfiguration,
)
LinkConfirmationOption(configuration = linkConfiguration)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.SavedStateHandle
import com.stripe.android.core.exception.StripeException
import com.stripe.android.core.strings.resolvableString
import com.stripe.android.model.StripeIntent
import com.stripe.android.payments.core.analytics.ErrorReporter
import com.stripe.android.paymentsheet.R
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -90,10 +89,7 @@ internal class DefaultConfirmationHandler(
_state.value = ConfirmationHandler.State.Confirming(arguments.confirmationOption)

coroutineScope.launch {
confirm(
intent = arguments.intent,
confirmationOption = arguments.confirmationOption,
)
confirm(arguments)
}
}

Expand All @@ -110,9 +106,10 @@ internal class DefaultConfirmationHandler(
}

private suspend fun confirm(
confirmationOption: ConfirmationHandler.Option,
intent: StripeIntent,
arguments: ConfirmationHandler.Args,
) {
val confirmationOption = arguments.confirmationOption

_state.value = ConfirmationHandler.State.Confirming(confirmationOption)

val mediator = mediators.find { mediator ->
Expand Down Expand Up @@ -142,7 +139,7 @@ internal class DefaultConfirmationHandler(
return
}

when (val action = mediator.action(confirmationOption, intent)) {
when (val action = mediator.action(confirmationOption, arguments.toParameters())) {
is ConfirmationMediator.Action.Launch -> {
storeIsAwaitingForResult(
key = mediator.key,
Expand Down Expand Up @@ -178,9 +175,16 @@ internal class DefaultConfirmationHandler(
removeIsAwaitingForResult()

coroutineScope.launch {
val parameters = result.parameters

confirm(
intent = result.intent,
confirmationOption = result.confirmationOption,
arguments = ConfirmationHandler.Args(
intent = parameters.intent,
shippingDetails = parameters.shippingDetails,
appearance = parameters.appearance,
initializationMode = parameters.initializationMode,
confirmationOption = result.confirmationOption,
)
)
}

Expand Down Expand Up @@ -229,6 +233,15 @@ internal class DefaultConfirmationHandler(
return savedStateHandle.get<AwaitingConfirmationResultData>(AWAITING_CONFIRMATION_RESULT_KEY)
}

private fun ConfirmationHandler.Args.toParameters(): ConfirmationDefinition.Parameters {
return ConfirmationDefinition.Parameters(
appearance = appearance,
shippingDetails = shippingDetails,
initializationMode = initializationMode,
intent = intent
)
}

private suspend inline fun <reified T> Flow<*>.firstInstanceOf(): T {
return first {
it is T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@ package com.stripe.android.paymentelement.confirmation

import com.stripe.android.model.PaymentMethodCreateParams
import com.stripe.android.model.PaymentMethodOptionsParams
import com.stripe.android.paymentsheet.addresselement.AddressDetails
import com.stripe.android.paymentsheet.state.PaymentElementLoader
import kotlinx.parcelize.Parcelize

internal sealed interface PaymentMethodConfirmationOption : ConfirmationHandler.Option {
val initializationMode: PaymentElementLoader.InitializationMode
val shippingDetails: AddressDetails?

@Parcelize
data class Saved(
override val initializationMode: PaymentElementLoader.InitializationMode,
override val shippingDetails: AddressDetails?,
val paymentMethod: com.stripe.android.model.PaymentMethod,
val optionsParams: PaymentMethodOptionsParams?,
) : PaymentMethodConfirmationOption

@Parcelize
data class New(
override val initializationMode: PaymentElementLoader.InitializationMode,
override val shippingDetails: AddressDetails?,
val createParams: PaymentMethodCreateParams,
val optionsParams: PaymentMethodOptionsParams?,
val shouldSave: Boolean
Expand Down
Loading

0 comments on commit 6749823

Please sign in to comment.