stripe-android icon indicating copy to clipboard operation
stripe-android copied to clipboard

[BUG] PaymentRelayActivity is not started and it results in PaymentResult.Failed

Open Lonexera opened this issue 2 years ago • 3 comments

Summary

PaymentRelayActivity is not started on Android 10 and 11 when after paymentLauncher.confirm(params) user collapses app and returns to it few seconds later. This results in payment result as PaymentResult.Failed, when in fact it could've been PaymentResult.Completed.

Code to reproduce

paymentLauncher initialization:

paymentLauncher = PaymentLauncher.create(
            fragment = this,
            publishableKey = paymentConfiguration.publishableKey,
            stripeAccountId = paymentConfiguration.stripeAccountId,
            callback = { paymentResult ->
                viewModel.processPaymentResult(
                    paymentResult = paymentResult
                )
            }
        )

payment confirmation:

private fun PaymentLauncher.confirmPayment(
       clientSecret: String,
        paymentMethodId: String
        ) {
            confirm(
                  ConfirmPaymentIntentParams.createWithPaymentMethodId(
                        paymentMethodId = paymentMethodId,
                        clientSecret = clientSecret,
                    )
             )
}

Android version

Android 10, 11

Impacted devices

Installation method

Gradle Dependecy

Dependency Versions

implementation 'com.stripe:stripe-android:20.2.1'

kotlin: 1.6.10 stripe-android: 20.2.1 Android Gradle Plugin: 7.1.1 Gradle: 7.4

SDK classes

Video

Other information

The error stacktrace on PaymentResult.Failed -

java.lang.IllegalArgumentException: Invalid client_secret value in result Intent.
        at com.stripe.android.payments.PaymentFlowResult$Unvalidated.validate$payments_core_release(PaymentFlowResult.kt:42)
        at com.stripe.android.payments.PaymentFlowResultProcessor$processResult$2.invokeSuspend(PaymentFlowResultProcessor.kt:44)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
        at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Seems like the issue is connected to this android bug - https://issuetracker.google.com/issues/140987255

Lonexera avatar Sep 02 '22 12:09 Lonexera

@Lonexera I will take a look at let you know. Thanks for writing in

michelleb-stripe avatar Sep 07 '22 12:09 michelleb-stripe

@Lonexera

I am having trouble reproducing the behavior.

Also I am not completely clear on the steps you are running to create this issue. Please correct the steps I have below:

  1. Create a PaymentLauncher
  2. Call PaymentLauncher.confirm
  3. Press recent app prior to the authorization activity being launched so the recent app shows the pre-authorization screen.
  4. (The authorization screen will then open in the foreground)
  5. Click recent apps again and switch to another application
  6. Wait for 5 seconds
  7. Click recent apps to switch back to the application

At this point the authorization screen is not shown and it presents a failure to the user rather than the authorization screen.

Do you have example code that I could use to reproduce the behavior? Or are you able to reproduce it with our example application.

michelleb-stripe avatar Sep 07 '22 15:09 michelleb-stripe

@michelleb-stripe To see the issue I am using the card that doesn't require authorization. And the steps to reproduce it: (use Android 10 or 11)

  1. Create a PaymentLauncher
  2. Call PaymentLauncher.confirm
  3. Press recent app or press home (it doesn't matter - only the app must be in background)
  4. Wait for 5 seconds
  5. Click recent apps to switch back to the application

Then the payment is failed with the message "Invalid client_secret value in result Intent.". But on stripe the payment was completed.

I believe the same can be done with the example app on "Simple PaymentMethod Confirmation Example", since it is the closest one to the code I have in the project. But I have some troubles configuring the backend side and I cannot use project's.

When the authorization is required the issue is not relevant because without the authorization screen the payment cannot be completed. But in case where authorization is not required the payment is done on stripe, but the result in this case that is shown to the user is failure (which is confusing at least)

Lonexera avatar Sep 12 '22 09:09 Lonexera

Hi @Lonexera 👋 Sorry that it took us so long to get back to you.

I was able to reproduce the issue on an Android 11 emulator. I’m working on the pull request that fixes it here, and should have it merged for the next release or the one after.

tillh-stripe avatar Oct 04 '22 22:10 tillh-stripe