braintree / braintree-web

A suite of tools for integrating Braintree in the browser
https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3
MIT License
444 stars 134 forks source link

Subsequent 3DS lookup failure #645

Open NabilShahid opened 2 years ago

NabilShahid commented 2 years ago

General information

Issue description

We have a payment form where user can pay either through hosted fields or a saved payment method.

When the user proceeds to payment screen, we fetch client token from backend to create braintree client on browser. We pass merchant account id while generating the token on backend. We have different merchant accounts for different currencies. The merchant account id we pass, depends upon a currency selection control we have on one of the forms that users have to fill before proceeding to payment screen.

After fetching the client token for a specific merchant account, we create braintee client using the token and then we initialize a 3DS client using the same token. We use braintree.threeDSecure.create function provided by the SDK and pass "2" as 3DS version value.

When we use the 3ds client to perform 3DS, it works fine the first time. However staying in the same browser session, when user places another order with a different currency selected(and hence different merchant account), we get a 3DS lookup error from the 3ds client's verifyCard function. If the browser page is reloaded before making the second order, then it works fine. Also, this happens for payment via hosted fields and for saved card where we generate nonce at backed from vaulted payment method. This is the error message that we get from the verifyCard function:

 "code": "THREEDS_CARDINAL_SDK_ERROR",
        "details": {
          "originalError": {
            "code": 1355,
            "description": "Transaction Lookup Not Successful, Check Transaction Id"
          }
        },
 "message": "A general error has occurred with Cardinal. See description for more information.",

So it seems like, the 3DS lookup fails when we initialize another 3DS client with different merchant account having different currency in the same browser session. Please note that we are properly using the teardown methods provided on 3DS, braintree and hosted fields clients after performing each payment.

We found a workaround for this that seems to be working for us for now. We noticed that when initiate the 3DS client, the SDK loads a songbird.js script, and sets a global Cardinal object in browser's window i.e. window.Cardinal. Deleting this object after performing each payment is working for us.

We would really appreciate any guidance here. Is the workaround correct? Would it be a good idea to fix this at the sdk level?

SancSalix commented 2 years ago

For clarification purposes, are you getting a new client token and creating a new braintree client when the currency is changed?

NabilShahid commented 2 years ago

For clarification purposes, are you getting a new client token and creating a new braintree client when the currency is changed?

That is correct, we get new client token every time before generating the braintree client.

SancSalix commented 2 years ago

So digging in, the window.Cardinal is setup and managed by the Cardinal SDK that is loaded at runtime. The client token from the first transaction is used in the initialization configuration.

There seems to be no way to forcibly teardown/destroy within the Cardinal SDK. I did update the documentation to point out that window.Cardinal will not be deleted using .teardown. We've reached out to Cardinal for a more official solution, and are still working on this. In the meantime, the workaround you have should be fine.