braintree / braintree_android

Braintree SDK for Android
https://developer.paypal.com/braintree/docs/start/hello-client/android/v4
MIT License
409 stars 234 forks source link

TransactionTooLargeException in com.braintreepayments.api.ThreeDSecureActivity #642

Closed IgorButirsky closed 1 year ago

IgorButirsky commented 1 year ago

Integration Details (please complete the following information):

Describe the bug The app crashes during the 3D Secure payment with TransactionTooLargeException.

Stacktrace:

Transaction too large, intent: Intent { cmp=com.main.gopuff/com.braintreepayments.api.ThreeDSecureActivity (has extras) }, extras size: 683584, icicle size: 0
Second failure launching com.main.gopuff/com.braintreepayments.api.ThreeDSecureActivity, giving up
                                           android.os.TransactionTooLargeException: data parcel size 686688 bytes.   
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(BinderProxy.java:571)
    at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:2732)
    at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:136)
    at com.android.server.wm.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:47)
    at com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked(ActivityTaskSupervisor.java:868)
    at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:986)
    at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:6561)
    at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:6132)
    at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:6177)
    at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2364)
    at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2311)
    at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2306)
    at com.android.server.wm.ActivityTaskManagerService$LocalService.handleAppDied(ActivityTaskManagerService.java:5760)
    at com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java:3026)
    at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:3122)
    at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1437)
    at android.os.IBinder$DeathRecipient.binderDied(IBinder.java:314)
    at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:685)

Stacktrace at the moment of starting ThreeDSecureActivity:

    at com.braintreepayments.api.ThreeDSecureLifecycleObserver.launch(ThreeDSecureLifecycleObserver.java:39) 
    at com.braintreepayments.api.ThreeDSecureClient.startVerificationFlow(ThreeDSecureClient.java:423).   
    at com.braintreepayments.api.ThreeDSecureClient.access$400(ThreeDSecureClient.java:32)
    at com.braintreepayments.api.ThreeDSecureClient$6.onResult(ThreeDSecureClient.java:334)
    at com.braintreepayments.api.ConfigurationLoader.loadConfiguration(ConfigurationLoader.java:41)
    at com.braintreepayments.api.BraintreeClient$1.onAuthorizationResult(BraintreeClient.java:183)
    at com.braintreepayments.api.AuthorizationLoader.loadAuthorization(AuthorizationLoader.java:20)
    at com.braintreepayments.api.BraintreeClient.getAuthorization(BraintreeClient.java:192)
    at com.braintreepayments.api.BraintreeClient.getConfiguration(BraintreeClient.java:179)
    at com.braintreepayments.api.ThreeDSecureClient.continuePerformVerification(ThreeDSecureClient.java:331)
    at com.braintreepayments.api.ThreeDSecureClient.continuePerformVerification(ThreeDSecureClient.java:260)
    at com.gopuff.features.payments.providers.threedsecure.ThreeDSecureNonceProvider$getThreeDSecureResult$1.invokeSuspend$lambda-0(ThreeDSecureNonceProvider.kt:92)
    at com.gopuff.features.payments.providers.threedsecure.ThreeDSecureNonceProvider$getThreeDSecureResult$1.$r8$lambda$R2DTCDskc4dt7gyI8INz-AWa-yA(Unknown Source:0)
    at com.gopuff.features.payments.providers.threedsecure.ThreeDSecureNonceProvider$getThreeDSecureResult$1$$ExternalSyntheticLambda0.onResult(Unknown Source:6)
    at com.braintreepayments.api.ThreeDSecureAPI$1.onResult(ThreeDSecureAPI.java:25)                                      
    at com.braintreepayments.api.HttpClient$2.run(HttpClient.java:123)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7839)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

The crash happens not always and most likely depends on the payload that is transferred to the ThreeDSecureActivity within the extras.

sshropshire commented 1 year ago

Hi @IgorButirsky thanks for using the Braintree SDK for Android. Is this reproducible every time the app attempts a 3DS transaction?

IgorButirsky commented 1 year ago

Hi @sshropshire. No, this is not reproducible on each device. For example, I reproduced it on Pixel 7 Pro, but not on OnePlus 7 Pro. But if this crash happens on some devices, it happens on them all the time. Also, this issue probably depends on the bank. We were able to reproduce it for credit cards emitted by some European banks.

sshropshire commented 1 year ago

@IgorButirsky ok. Are there any banks in particular? And if possible, could you reproduce the error and set a breakpoint here to inspect if the resulting JSON is abnormally large?

IgorButirsky commented 1 year ago

@sshropshire, For us it was Universal Bank. Here is the screenshot: Screenshot 2023-01-05 at 23 31 15 In general, the resulting json looks fine except one value :

{
    ...
    "lookup": {
        ...
        "pareq": "..."
    }
}

the pareq string is a way long - 339268 characters

sshropshire commented 1 year ago

@IgorButirsky interesting. ~I'll reach out to Cardinal, our 3rd party MPI to see if this is a known issue.~ Actually this could also be an issue on the Braintree side. I'll gather more info and report back when I have new details.

sshropshire commented 1 year ago

Hi @IgorButirsky would you mind providing the merchant id and a transaction id for one of these requests that's triggering the Android error? I can forward this to the appropriate team and they can take a more in depth look.

hollabaq86 commented 1 year ago

👋 @IgorButirsky If you can contact Support referencing this issue, your merchant ID and a sample transaction ID, they can coordinate with the appropriate teams at PayPal/Braintree to investigate further. In the meantime, I'm going to go ahead and close this issue since it's been quiet for a few weeks.

IgorButirsky commented 1 year ago

Hi @hollabaq86, the issue is still relevant, we moved the conversation to emails.

sshropshire commented 1 year ago

@IgorButirsky we do have some internal tracking on this issue. Would you prefer us to re-open this for visibility?

IgorButirsky commented 1 year ago

@sshropshire yeah, would be good.

cltnschlosser commented 1 year ago

So it's nice that #711 prevents the crash from happening, but is there more to this than The 3D Secure response returned is too large to continue. Please contact Braintree Support for assistance.? How do we support these users that our trying to use our applications? Is there anyway to make the transactions smaller, so that they don't hit this limit?

sshropshire commented 1 year ago

We now catch this error to prevent a crash and forward it to the merchant in version 4.27.0 of the SDK.

sshropshire commented 1 year ago

@cltnschlosser unfortunately Braintree support will be the best resource since this is technically not an issue with the SDK. The issuing bank is responsible for enforcing a 3DS limit on the PaReq per spec. Support will help route communication to the correct server side team to help identify and fix the root issue.

hollabaq86 commented 1 year ago

Wanted to post one more update, our colleagues who own Braintree's API have updated their logic to screen for abnormally large sized responses like this so that they can cap the size and not send so much info that they crash merchant apps.

This still doesn't resolve the source of these issues - the ACS provider - but we've added as much we can defensively to prevent these type exceptions

cltnschlosser commented 1 year ago

@hollabaq86 I think this is actually causing new crashes, we're getting truncated data <base-64-string>... and then it ends with the ellipse. Results in:

Caused by java.lang.IllegalArgumentException: bad base-64
       at android.util.Base64.decode(Base64.java:163)
       at android.util.Base64.decode(Base64.java:138)
       at android.util.Base64.decode(Base64.java:120)
       at com.cardinalcommerce.cardinalmobilesdk.Cardinal.cca_continue(:16179)
       at com.braintreepayments.api.CardinalClient.continueLookup(CardinalClient.java:44)
       at com.braintreepayments.api.ThreeDSecureActivity.onCreateInternal(ThreeDSecureActivity.java:43)
       at com.braintreepayments.api.ThreeDSecureActivity.onCreate(ThreeDSecureActivity.java:31)
hollabaq86 commented 1 year ago

@cltnschlosser ack, I'd follow #724 for updates on this issue

hollabaq86 commented 1 year ago

quick update: we're also working on reverting our changes to the API that I mentioned in this issue