diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index 108a6c201d6..2e0fc458475 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -271,11 +271,11 @@ public abstract interface class com/stripe/android/paymentsheet/PaymentSheetResu } public final class com/stripe/android/paymentsheet/PaymentSheetViewModel_Factory : dagger/internal/Factory { - public fun (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)V - public static fun create (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)Lcom/stripe/android/paymentsheet/PaymentSheetViewModel_Factory; + public fun (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)V + public static fun create (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)Lcom/stripe/android/paymentsheet/PaymentSheetViewModel_Factory; public fun get ()Lcom/stripe/android/paymentsheet/PaymentSheetViewModel; public synthetic fun get ()Ljava/lang/Object; - public static fun newInstance (Landroid/app/Application;Lcom/stripe/android/paymentsheet/PaymentSheetContract$Args;Lcom/stripe/android/paymentsheet/analytics/EventReporter;Ldagger/Lazy;Lcom/stripe/android/paymentsheet/repositories/StripeIntentRepository;Lcom/stripe/android/paymentsheet/model/StripeIntentValidator;Lcom/stripe/android/paymentsheet/repositories/CustomerRepository;Ljavax/inject/Provider;Lcom/stripe/android/paymentsheet/PrefsRepository;Lcom/stripe/android/PaymentController;Lcom/stripe/android/googlepaylauncher/GooglePayPaymentMethodLauncherFactory;Lcom/stripe/android/Logger;Lkotlin/coroutines/CoroutineContext;)Lcom/stripe/android/paymentsheet/PaymentSheetViewModel; + public static fun newInstance (Landroid/app/Application;Lcom/stripe/android/paymentsheet/PaymentSheetContract$Args;Lcom/stripe/android/paymentsheet/analytics/EventReporter;Ldagger/Lazy;Lcom/stripe/android/paymentsheet/repositories/StripeIntentRepository;Lcom/stripe/android/paymentsheet/model/StripeIntentValidator;Lcom/stripe/android/paymentsheet/repositories/CustomerRepository;Lcom/stripe/android/paymentsheet/PrefsRepository;Lcom/stripe/android/payments/paymentlauncher/StripePaymentLauncherAssistedFactory;Lcom/stripe/android/googlepaylauncher/GooglePayPaymentMethodLauncherFactory;Lcom/stripe/android/Logger;Lkotlin/coroutines/CoroutineContext;)Lcom/stripe/android/paymentsheet/PaymentSheetViewModel; } public final class com/stripe/android/paymentsheet/address/AddressFieldElementRepository_Factory : dagger/internal/Factory { diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt index a2f46fe655a..5fa3e2e61ba 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt @@ -27,7 +27,6 @@ import com.stripe.android.paymentsheet.model.PaymentSheetViewState import com.stripe.android.paymentsheet.ui.AnimationConstants import com.stripe.android.paymentsheet.ui.BaseSheetActivity import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.view.AuthActivityStarterHost import kotlinx.coroutines.launch internal class PaymentSheetActivity : BaseSheetActivity() { @@ -145,10 +144,7 @@ internal class PaymentSheetActivity : BaseSheetActivity() { val confirmParams = event.getContentIfNotHandled() if (confirmParams != null) { lifecycleScope.launch { - viewModel.confirmStripeIntent( - AuthActivityStarterHost.create(this@PaymentSheetActivity), - confirmParams - ) + viewModel.confirmStripeIntent(confirmParams) } } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt index 2041613373f..e0446e75786 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt @@ -14,21 +14,21 @@ import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.viewModelScope import com.stripe.android.Logger import com.stripe.android.PaymentConfiguration -import com.stripe.android.PaymentController -import com.stripe.android.StripeIntentResult -import com.stripe.android.exception.APIConnectionException import com.stripe.android.googlepaylauncher.GooglePayEnvironment import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherContract import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherFactory +import com.stripe.android.model.ConfirmPaymentIntentParams +import com.stripe.android.model.ConfirmSetupIntentParams import com.stripe.android.model.ConfirmStripeIntentParams import com.stripe.android.model.PaymentIntent import com.stripe.android.model.PaymentMethod import com.stripe.android.model.StripeIntent -import com.stripe.android.networking.ApiRequest -import com.stripe.android.payments.PaymentFlowResult -import com.stripe.android.payments.PaymentFlowResultProcessor import com.stripe.android.payments.core.injection.IOContext +import com.stripe.android.payments.paymentlauncher.PaymentLauncher +import com.stripe.android.payments.paymentlauncher.PaymentLauncherContract +import com.stripe.android.payments.paymentlauncher.PaymentResult +import com.stripe.android.payments.paymentlauncher.StripePaymentLauncherAssistedFactory import com.stripe.android.paymentsheet.analytics.EventReporter import com.stripe.android.paymentsheet.injection.DaggerPaymentSheetViewModelComponent import com.stripe.android.paymentsheet.model.ConfirmStripeIntentParamsFactory @@ -41,13 +41,10 @@ import com.stripe.android.paymentsheet.repositories.CustomerRepository import com.stripe.android.paymentsheet.repositories.StripeIntentRepository import com.stripe.android.paymentsheet.ui.PrimaryButton import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.view.AuthActivityStarterHost import dagger.Lazy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import javax.inject.Inject -import javax.inject.Provider import javax.inject.Singleton import kotlin.coroutines.CoroutineContext @@ -77,10 +74,8 @@ internal class PaymentSheetViewModel @Inject internal constructor( private val stripeIntentRepository: StripeIntentRepository, private val stripeIntentValidator: StripeIntentValidator, customerRepository: CustomerRepository, - private val paymentFlowResultProcessorProvider: - Provider>>, prefsRepository: PrefsRepository, - private val paymentController: PaymentController, + private val paymentLauncherFactory: StripePaymentLauncherAssistedFactory, private val googlePayPaymentMethodLauncherFactory: GooglePayPaymentMethodLauncherFactory, private val logger: Logger, @IOContext workContext: CoroutineContext @@ -155,6 +150,8 @@ internal class PaymentSheetViewModel @Inject internal constructor( } } + internal var paymentLauncher: PaymentLauncher? = null + init { eventReporter.onInit(config) if (googlePayLauncherConfig == null) { @@ -162,19 +159,6 @@ internal class PaymentSheetViewModel @Inject internal constructor( } } - private fun apiThrowableToString(throwable: Throwable): String? { - return when (throwable) { - is APIConnectionException -> { - getApplication().resources.getString( - R.string.stripe_failure_connection_error - ) - } - else -> { - throwable.localizedMessage - } - } - } - fun setupGooglePay( lifecycleScope: CoroutineScope, activityResultLauncher: ActivityResultLauncher @@ -301,29 +285,37 @@ internal class PaymentSheetViewModel @Inject internal constructor( } } - suspend fun confirmStripeIntent( - authActivityStarterHost: AuthActivityStarterHost, - confirmStripeIntentParams: ConfirmStripeIntentParams - ) { - paymentController.startConfirmAndAuth( - authActivityStarterHost, - confirmStripeIntentParams, - ApiRequest.Options( - lazyPaymentConfig.get().publishableKey, - lazyPaymentConfig.get().stripeAccountId - ) + fun confirmStripeIntent(confirmStripeIntentParams: ConfirmStripeIntentParams) { + runCatching { + requireNotNull(paymentLauncher) + }.fold( + onSuccess = { + when (confirmStripeIntentParams) { + is ConfirmPaymentIntentParams -> { + it.confirm(confirmStripeIntentParams) + } + is ConfirmSetupIntentParams -> { + it.confirm(confirmStripeIntentParams) + } + } + }, + onFailure = ::onFatal ) } fun registerFromActivity(activityResultCaller: ActivityResultCaller) { - paymentController.registerLaunchersWithActivityResultCaller( - activityResultCaller, - ::onPaymentFlowResult + paymentLauncher = paymentLauncherFactory.create( + { lazyPaymentConfig.get().publishableKey }, + { lazyPaymentConfig.get().stripeAccountId }, + activityResultCaller.registerForActivityResult( + PaymentLauncherContract(), + ::onPaymentResult + ) ) } fun unregisterFromActivity() { - paymentController.unregisterLaunchers() + paymentLauncher = null } private fun confirmPaymentSelection(paymentSelection: PaymentSelection?) { @@ -340,16 +332,28 @@ internal class PaymentSheetViewModel @Inject internal constructor( } } - private fun onStripeIntentResult( - stripeIntentResult: StripeIntentResult - ) { - when (stripeIntentResult.outcome) { - StripeIntentResult.Outcome.SUCCEEDED -> { + @VisibleForTesting + fun onPaymentResult(paymentResult: PaymentResult) { + viewModelScope.launch { + runCatching { + stripeIntentRepository.get(args.clientSecret) + }.fold( + onSuccess = { + processPayment(it, paymentResult) + }, + onFailure = ::onFatal + ) + } + } + + private fun processPayment(stripeIntent: StripeIntent, paymentResult: PaymentResult) { + when (paymentResult) { + PaymentResult.Completed -> { eventReporter.onPaymentSuccess(selection.value) // SavedSelection needs to happen after new cards have been saved. when (selection.value) { - is PaymentSelection.New -> stripeIntentResult.intent.paymentMethod?.let { + is PaymentSelection.New -> stripeIntent.paymentMethod?.let { PaymentSelection.Saved(it) } PaymentSelection.GooglePay -> selection.value @@ -367,11 +371,14 @@ internal class PaymentSheetViewModel @Inject internal constructor( eventReporter.onPaymentFailure(selection.value) runCatching { - stripeIntentValidator.requireValid(stripeIntentResult.intent) + stripeIntentValidator.requireValid(stripeIntent) }.fold( onSuccess = { resetViewState( - stripeIntentResult.failureMessage + when (paymentResult) { + is PaymentResult.Failed -> paymentResult.throwable.message + else -> null // indicates canceled payment + } ) }, onFailure = ::onFatal @@ -399,29 +406,6 @@ internal class PaymentSheetViewModel @Inject internal constructor( } } - fun onPaymentFlowResult(paymentFlowResult: PaymentFlowResult.Unvalidated) { - viewModelScope.launch { - runCatching { - withContext(workContext) { - paymentFlowResultProcessorProvider.get().processResult( - paymentFlowResult - ) - } - }.fold( - onSuccess = { - onStripeIntentResult(it) - }, - onFailure = { error -> - selection.value?.let { - eventReporter.onPaymentFailure(it) - } - - resetViewState(apiThrowableToString(error)) - } - ) - } - } - override fun onFatal(throwable: Throwable) { logger.error("Payment Sheet error", throwable) _fatal.value = throwable diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt index 411b5fddf95..77f9255c2c5 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt @@ -14,7 +14,6 @@ import com.stripe.android.Logger import com.stripe.android.PaymentConfiguration import com.stripe.android.PaymentController import com.stripe.android.PaymentIntentResult -import com.stripe.android.StripeIntentResult import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherContract import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherFactory @@ -25,8 +24,9 @@ import com.stripe.android.model.PaymentIntentFixtures import com.stripe.android.model.PaymentMethod import com.stripe.android.model.PaymentMethodCreateParamsFixtures import com.stripe.android.model.PaymentMethodFixtures -import com.stripe.android.payments.PaymentFlowResult import com.stripe.android.payments.PaymentFlowResultProcessor +import com.stripe.android.payments.paymentlauncher.PaymentResult +import com.stripe.android.payments.paymentlauncher.StripePaymentLauncherAssistedFactory import com.stripe.android.paymentsheet.PaymentSheetViewModel.CheckoutIdentifier import com.stripe.android.paymentsheet.analytics.EventReporter import com.stripe.android.paymentsheet.databinding.PrimaryButtonBinding @@ -73,6 +73,8 @@ internal class PaymentSheetActivityTest { private val eventReporter = mock() private val googlePayPaymentMethodLauncherFactory = createGooglePayPaymentMethodLauncherFactory() + private val stripePaymentLauncherAssistedFactory = + mock() private val viewModel = createViewModel() @@ -508,13 +510,8 @@ internal class PaymentSheetActivityTest { idleLooper() viewModel.checkoutIdentifier = CheckoutIdentifier.SheetBottomBuy + viewModel.onPaymentResult(PaymentResult.Completed) - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated( - "client_secret", - StripeIntentResult.Outcome.SUCCEEDED - ) - ) idleLooper() assertThat(activity.bottomSheetBehavior.state) @@ -723,7 +720,7 @@ internal class PaymentSheetActivityTest { mock>() whenever(paymentFlowResultProcessor.processResult(any())).thenReturn(paymentIntentResult) - val mockPaymentController: PaymentController = mock() + val mockPaymentLauncher: PaymentController = mock() PaymentSheetViewModel( ApplicationProvider.getApplicationContext(), PaymentSheetFixtures.ARGS_CUSTOMER_WITH_GOOGLEPAY, @@ -732,9 +729,8 @@ internal class PaymentSheetActivityTest { StripeIntentRepository.Static(paymentIntent), StripeIntentValidator(), FakeCustomerRepository(paymentMethods), - { paymentFlowResultProcessor }, FakePrefsRepository(), - mockPaymentController, + stripePaymentLauncherAssistedFactory, googlePayPaymentMethodLauncherFactory, Logger.noop(), testDispatcher diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt index c0af3ee465b..28086712cdf 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt @@ -22,8 +22,7 @@ import com.stripe.android.model.PaymentMethodCreateParamsFixtures import com.stripe.android.model.PaymentMethodFixtures import com.stripe.android.model.StripeIntent import com.stripe.android.networking.StripeRepository -import com.stripe.android.payments.PaymentFlowResult -import com.stripe.android.payments.PaymentIntentFlowResultProcessor +import com.stripe.android.payments.paymentlauncher.PaymentResult import com.stripe.android.paymentsheet.PaymentSheetViewModel.CheckoutIdentifier import com.stripe.android.paymentsheet.analytics.EventReporter import com.stripe.android.paymentsheet.model.FragmentConfig @@ -75,7 +74,6 @@ internal class PaymentSheetViewModelTest { private val prefsRepository = FakePrefsRepository() private val eventReporter = mock() private val viewModel: PaymentSheetViewModel by lazy { createViewModel() } - private val paymentFlowResultProcessor = mock() private val application = ApplicationProvider.getApplicationContext() @Captor @@ -382,10 +380,10 @@ internal class PaymentSheetViewModelTest { } @Test - fun `onPaymentFlowResult() should update ViewState and save preferences`() = + fun `onPaymentResult() should update ViewState and save preferences`() = testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenReturn( - PAYMENT_INTENT_RESULT + val viewModel = createViewModel( + stripeIntentRepository = StripeIntentRepository.Static(PAYMENT_INTENT), ) val selection = PaymentSelection.Saved(PaymentMethodFixtures.CARD_PAYMENT_METHOD) @@ -401,12 +399,8 @@ internal class PaymentSheetViewModelTest { paymentSheetResult = it } - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated( - "client_secret", - StripeIntentResult.Outcome.SUCCEEDED - ) - ) + viewModel.onPaymentResult(PaymentResult.Completed) + assertThat(viewState[1]) .isInstanceOf(PaymentSheetViewState.FinishProcessing::class.java) @@ -426,10 +420,10 @@ internal class PaymentSheetViewModelTest { } @Test - fun `onPaymentFlowResult() should update ViewState and save new payment method`() = + fun `onPaymentResult() should update ViewState and save new payment method`() = testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenReturn( - PAYMENT_INTENT_RESULT_WITH_PM + val viewModel = createViewModel( + stripeIntentRepository = StripeIntentRepository.Static(PAYMENT_INTENT_WITH_PM) ) val selection = PaymentSelection.New.Card( @@ -449,12 +443,8 @@ internal class PaymentSheetViewModelTest { paymentSheetResult = it } - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated( - "client_secret", - StripeIntentResult.Outcome.SUCCEEDED - ) - ) + viewModel.onPaymentResult(PaymentResult.Completed) + assertThat(viewState[1]) .isInstanceOf(PaymentSheetViewState.FinishProcessing::class.java) @@ -480,14 +470,8 @@ internal class PaymentSheetViewModelTest { } @Test - fun `onPaymentFlowResult() with non-success outcome should report failure event`() = + fun `onPaymentResult() with non-success outcome should report failure event`() = testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenReturn( - PAYMENT_INTENT_RESULT.copy( - outcomeFromFlow = StripeIntentResult.Outcome.FAILED - ) - ) - val selection = PaymentSelection.Saved(PaymentMethodFixtures.CARD_PAYMENT_METHOD) viewModel.updateSelection(selection) @@ -496,9 +480,7 @@ internal class PaymentSheetViewModelTest { stripeIntent = it } - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated() - ) + viewModel.onPaymentResult(PaymentResult.Failed(Throwable())) verify(eventReporter) .onPaymentFailure(selection) @@ -506,67 +488,17 @@ internal class PaymentSheetViewModelTest { } @Test - fun `onPaymentFlowResult() with processing status for payment method which has delay should report success event`() = + fun `onPaymentResult() should update emit API errors`() = testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenReturn( - PaymentIntentResult( - PaymentIntentFixtures.PI_WITH_SHIPPING.copy( - paymentMethod = PaymentMethodFixtures.SEPA_DEBIT_PAYMENT_METHOD, - status = StripeIntent.Status.Processing - ), - StripeIntentResult.Outcome.UNKNOWN - ) - ) - - val selection = PaymentSelection.Saved(PaymentMethodFixtures.SEPA_DEBIT_PAYMENT_METHOD) - viewModel.updateSelection(selection) - - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated() - ) - verify(eventReporter) - .onPaymentSuccess(selection) - } - - @Test - fun `onPaymentFlowResult() with processing status for payment method which does not have delay should report failure event`() = - testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenReturn( - PaymentIntentResult( - PaymentIntentFixtures.PI_WITH_SHIPPING.copy( - paymentMethod = PaymentMethodFixtures.CARD_PAYMENT_METHOD, - status = StripeIntent.Status.Processing - ), - StripeIntentResult.Outcome.UNKNOWN - ) - ) - - val selection = PaymentSelection.Saved(PaymentMethodFixtures.CARD_PAYMENT_METHOD) - viewModel.updateSelection(selection) - - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated() - ) - verify(eventReporter) - .onPaymentFailure(selection) - } - - @Test - fun `onPaymentFlowResult() should update emit API errors`() = - testDispatcher.runBlockingTest { - whenever(paymentFlowResultProcessor.processResult(any())).thenThrow( - RuntimeException("Your card was declined.") - ) - viewModel.fetchStripeIntent() val viewStateList = mutableListOf() viewModel.viewState.observeForever { viewStateList.add(it) } - viewModel.onPaymentFlowResult( - PaymentFlowResult.Unvalidated() - ) + + val errorMessage = "very helpful error message" + viewModel.onPaymentResult(PaymentResult.Failed(Throwable(errorMessage))) assertThat(viewStateList[0]) .isEqualTo( @@ -575,7 +507,7 @@ internal class PaymentSheetViewModelTest { assertThat(viewStateList[1]) .isEqualTo( PaymentSheetViewState.Reset( - UserErrorMessage("Your card was declined.") + UserErrorMessage(errorMessage) ) ) } @@ -807,7 +739,6 @@ internal class PaymentSheetViewModelTest { stripeIntentRepository, StripeIntentValidator(), customerRepository, - { paymentFlowResultProcessor }, prefsRepository, mock(), mock(), @@ -826,10 +757,6 @@ internal class PaymentSheetViewModelTest { private val PAYMENT_METHODS = listOf(PaymentMethodFixtures.CARD_PAYMENT_METHOD) val PAYMENT_INTENT = PaymentIntentFixtures.PI_REQUIRES_PAYMENT_METHOD - val PAYMENT_INTENT_RESULT = PaymentIntentResult( - intent = PAYMENT_INTENT, - outcomeFromFlow = StripeIntentResult.Outcome.SUCCEEDED - ) val PAYMENT_INTENT_WITH_PM = PaymentIntentFixtures.PI_SUCCEEDED.copy( paymentMethod = PaymentMethodFixtures.CARD_PAYMENT_METHOD