-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PayPal flow errors with UserCanceled error on returning to the Drop In. #419
Comments
Hey @soarb thanks for filing this. Are there multiple build variants present on this test device? Also does the same thing happen on an emulator? |
Thanks for getting back to me @sshropshire ... there's only ever a single build variant on the test device and I tend not to use emulators as I like to see things working on the real thing - especially on Android! I just don't quite understand how the 3DS browser switch back to the device works, but the PayPal browser switch throws up this dialog and then errors with a UserCanceledException if I tap "Just Once"? |
@soarb understood! A real device is the best way to test. I want to rule out some possibilities here though, I'm wondering if this issue could have something to do with a specific device. I'm testing on a Samsung Galaxy S21 5G and I don't get the disambiguation dialog. I'm not sure what would cause "Just Once" to fail either. If possible, I'd |
Hi @sshropshire, I can confirm we have the same issue on the following test devices:- Samsung S22 OS 13 I'll report back when I've debugged the URL from the deep link intent though :) |
So in all cases @sshropshire, when choosing our App and the "Just Once" option the PayPalClient's onBrowserSwitchResult.deepLinkUrl is always null. This is the case on repeated attempts. The only time the url resolves to a value is when selecting "Always" in which case we get the following:- {our app's package name}.braintree://onetouch/v1/success?paymentId=PAYID-MRJ66YI8H858885D1798690T&token=EC-07G27203YY045835S&PayerID=UGR2UJXVNXW7W and everything works. In order to recreate this, please ensure whatever app you're testing on, is removed from your device's Settings -> Apps -> Choose default apps -> Opening links -> {App Name} by clicking on "Clear defaults". This is on our S10 so the location may differ slightly. With this setting removed, we get the OS prompt about how the App should handle links in the future. Selecting "Just Once" always returns a null url, selecting "Always" works. It's worth reiterating, that when we trigger 3DS 2FA via our custom checkout (which performs a similar browser switch) we don't go via the drop-in. Instead we use an instance of ThreeDSecureClient. Once the browser switch is complete, we're returned to our App and everything works as expected (with no OS prompt). |
Hi @sshropshire, any update on this please? I can also add that dismissing the OS prompt leaves us "stuck" on the PayPal "One more step" phase in the browser screen. We never get returned to our app unless we just close the screen. I can provide a video if required? I know this doesn't help much but the drop-in experience on iOS performs without any issue whatsoever. |
Hi, class MainActivity : FragmentActivity(), ClientTokenProvider, DropInListener {
private lateinit var braintreeDropInClient: DropInClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
braintreeDropInClient = DropInClient(
this,
this
)
braintreeDropInClient.setListener(this)
setContent {
TestTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Text("Hello")
Button(content = {
Text("test")
}, onClick = {
launchBraintreeDropIn()
})
}
}
}
}
fun launchBraintreeDropIn() {
braintreeDropInClient.invalidateClientToken()
val request = DropInRequest().apply {
isCardDisabled = true
isVaultManagerEnabled = false
payPalRequest = PayPalVaultRequest().apply {
billingAgreementDescription = "."
}
}
braintreeDropInClient.launchDropIn(request);
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent) // Breakpoint here
}
override fun getClientToken(callback: ClientTokenCallback) {
callback.onSuccess("token_from_server")
}
override fun onDropInSuccess(dropInResult: DropInResult) {
TODO("Not yet implemented") // Breakpoint here
}
override fun onDropInFailure(error: Exception) {
TODO("Not yet implemented") // Breakpoint here (execution stop there first)
}
} manifest: <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Test"
tools:targetApi="34">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleInstance"
android:label="@string/app_name"
android:theme="@style/Theme.Test">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="${applicationId}.braintree" />
</intent-filter>
</activity>
</application>
</manifest> The breakpoint on setIntent shows that the data of the intent contains this url:
Versions of what I use:
I hope thank we can find a solution, don't hesitate to tell me how I can help you investigate. |
@sshropshire Hi any update on this? I need to bump braintree SDK in my project |
Hi @Chaos2805 @kevin68 @soarb apologies for the extreme delay. I'm circling back and I believe I know the root cause of this issue, but will need verification to make sure as I'm unable to reproduce on my end. There seems to be an error in the documentation. For DropIn, you won't need to register an intent filter. We launch It appears that when the DropIn library's If this resolves the issue, I'll update the docs to remove this additional unnecessary step. |
@sshropshire It's working after removing the intent-filter, thanks ! |
@sshropshire It didn't solve my issue, if I remove the intent-filter, drop-in activity not receiving the deeplink. I found the BrainTreeClient constructor able to pass the custom url scheme, but on top DropInClient not able to modify the setting of BrainTreeClient |
Braintree SDK Version
4.27.0
Environment
Sandbox
Android Version & Device
Samsung S10 with Android 12
Braintree dependencies
com.braintreepayments.api:drop-in:6.9.0
Describe the bug
On completion of the PayPal flow triggered by the drop-in, the device presents two options. Our App name - "Just Once" and our App name - "Always".
I assume this is the OS asking the user if our App should be the default App for handling all links of a specific type?
Selecting "Just Once" fires the drop-in onFailure callback with a UserCanceled error?
The only way to get an instance of PayPalAccountNonce to charge the customer with (again this is in Sandbox) is to select "Always".
I'm not even sure why these two options get presented at all by the OS?
Completing a similar browser switch to perform 3DS 2FA auth immediately returns to our App on success or cancellation, no prompt to set the default App is presented.
To reproduce
Present the drop-in UI. Include a PayPalCheckoutRequest instance configured with the correct order total and a request to present the PayPal PayIn3 option.
Complete the PayPal sign in flow, select a test payment instrument and select the "Just Once" option when the OS presents it.
Get returned to our App, but our logs clearly show that the drop-in onFailure method was called with a UserCanceledException.
Expected behavior
The drop-in UI doesn't error with a UserCanceled exception. Instead a PayPalAccountNonce is returned with which we can complete the Sandbox transaction.
Also ideally, the OS shouldn't be presenting the user with the two options requesting how supported links should be handled in the future. The 3DS flow doesn't do this.
Screenshots
Here's a link to a video I posted demonstrating the issue.
The text was updated successfully, but these errors were encountered: