Skip to content
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

threeDSecure.verifyCard(): promise is always pending #655

Open
hitech95 opened this issue Nov 24, 2022 · 7 comments
Open

threeDSecure.verifyCard(): promise is always pending #655

hitech95 opened this issue Nov 24, 2022 · 7 comments

Comments

@hitech95
Copy link

General information

  • SDK version: "braintree-web-drop-in": "^1.33.0",
  • Environment: Production
  • Browser and OS: Firefox & Chrome Windoiws & Mac

Issue description

we have the following code:

import { threeDSecure } from "braintree-web";

const clientToken = "XYZ";

function processTransaction(dsData){
  // Get Enriched NONCE from 3DS Validation
  return threeDSecure
  .create({
    authorization: clientToken,
    version: 2,
  })
  .then((instance) => {
    // This is called once.
    console.log("instance", instance); 
  
    return instance
      .verifyCard({
        onLookupComplete: function (data, next) {
          // This is called once after the "instance" above
          console.log("onLookupComplete", data);
          next();
        },
        amount: dsData.amount,
        nonce: dsData.nonce,
        bin: dsData.bin,
        email: dsData.email,
      })
      .then((payload) => {
        // This is not called
        console.log("payload", payload);
  
        const {
          nonce,
          liabilityShifted,
          liabilityShiftPossible,
        } = payload;
  
        if (liabilityShiftPossible && !liabilityShifted)
          return Promise.reject(
            new Error("3DSecure authorization failed")
          );
        console.log("nonce", nonce);
  
        return nonce;
      })
      .finally(() => {
        // This is not called
        console.log("teardown", instance);  
        instance.teardown();
      });
  })
  .then((nonce) => {
     console.log("processCheckout", nonce);
     // Server side call to create the transaction
  });

In the logs I only get the following messages:

instance Object { _events: {}, _framework: {…} }
onLookupComplete Object { _httpStatus: 201, paymentMethod: {…}, threeDSecureInfo: {…}, lookup: {…}, requiresUserAuthentication: true }

The modal open correctly and it closes correctly once I confirm in the app.
But none of the code seems to execute. The promise is pending indefinetly.

@hitech95
Copy link
Author

hitech95 commented Nov 24, 2022

We tried to rollback the libs/dropin but the result is the same.

We also tried to provide a callback function and wrap the verifyCard in a Promise and using the resolve() reject() to continue our flow. But also in this case the callback is never called.

return new Promise((resolve, reject) => {
  instance.verifyCard(
    {
      onLookupComplete: function (data, next) {
        console.log("onLookupComplete", data);
        next();
      },
      amount: dsData.amount,
      nonce: dsData.nonce,
      bin: dsData.bin,
      email: dsData.email,
    },
    function (err, payload) {
      console.log("callback", { err, payload });
      if (err) {
        return reject(err);
      }

      return resolve(payload);
    }
  );
})

@cgdibble
Copy link
Contributor

cgdibble commented Feb 8, 2023

Can you clarify for me what version/SDK you're using? Your issue snippet says dropin and a dropin version, but this is the underlying SDK and your snippets show using braintree-web. Just hoping to clarify so we can make sure to look in the right area.

As for the problem itself, are you getting any console errors or network failures when you experience this behavior? If the flow is otherwise going fine from a user perspective (in the popup), I'm trying to see where the break down my be happening.

@menseAjit
Copy link

menseAjit commented Feb 16, 2023

@cgdibble any update on this issue, i am also facing the same. with latest versions. @hitech95 Any workaround you found?

@hitech95
Copy link
Author

hitech95 commented Feb 16, 2023

The only workaround I've found is to do the same I'm doing with the dropin.
before creating a new instance I force the teardown. This has been my only solution.
We are also calling the teardown for the dropin. just to be sure that no braintree instances are still in execution.

Even so sometime it still fails, but its a lot rare.

@hitech95
Copy link
Author

Can you clarify for me what version/SDK you're using? Your issue snippet says dropin and a dropin version, but this is the underlying SDK and your snippets show using braintree-web. Just hoping to clarify so we can make sure to look in the right area.

We are using the dependecy from the dropin but importing the braintree-web.
We also tried to manually specify the braintree-web version but with no additional success.

As for the problem itself, are you getting any console errors or network failures when you experience this behavior? If the flow is otherwise going fine from a user perspective (in the popup), I'm trying to see where the break down my be happening.

No no error in console or failure in the network, it simply get stuck when the popup closes I excpect to have the callback called but it is never. I've tried with both Promises or classi callback function. Same result: code is never executed.

@truongnc
Copy link

@cgdibble I have same issue, when user cancel threeD popup, and then payment again. Then user submitted correctly but function verifyCard is never executed.

@aa-chrismcfadyen
Copy link

We are just running into this issue now with the March update to 3DS and the requirement of 3DS 2.2. We were on braintreeweb 3.99.0 when we noticed it start happening, tried upgrading to 3.101.0, but the issue persisted.

To be specific, the issue happens after calling verifyCard, the user gets a 3DS prompt and clicks Cancel:

  • The promise never resolves or rejects if using that, or the callback is never called
  • The customer-canceled event is never fired, even though that's what was clicked
  • The authentication-modal-close event is never fired even when the modal has closed

We have not observed it happening if the 3DS prompt closes from the user successfully confirming.

There is no way to detect a difference between the modal still being open and waiting for user input or this issue happening, so we can't set a timeout to check if the result of verifyCard exists yet, because maybe the user is still fiddling with their phone to input their MFA token.

For us it only happens the very first time a user is setting up their payment with us and if it's also their first time visiting our app. It doesn't even happen every time at that (but some of our developers can make it happen every time, so it is quite possibly impacted by browser/env). Reloading the page has a subsequent 100% success rate, and changing the credit card later is also 100% success. Since it's very unlikely with our app that a user signs up and also makes a payment on their first visit, the issue is nearly non-existent in production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants