question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"requestPaymentMethod()" Intermittently Throws an Error When Called in "braintree.dropin.create()" Callback

See original GitHub issue

General information

  • SDK/Library version: 1.10.0
  • Environment: Sandbox
  • Browser and OS: Chrome Version 66.0.3359.139 (Official Build) (64-bit) on MacOS MacOS 10.12.3

How I Arrived at the Issue

A user who has a “requestable” payment (a payment method available from the vault) arrives on a page and is presented with the below UI (note the Pay button is coming from my application):

screen shot 2018-05-15 at 10 34 56 am

This is based on the example code as shown in the README.md file of this repo:

var submitButton = document.querySelector('#submit-button');

braintree.dropin.create({
  authorization: 'CLIENT_AUTHORIZATION',
  selector: '#dropin-container'
}, function (err, dropinInstance) {
  if (err) {
    // Handle any errors that might've occurred when creating Drop-in
    console.error(err);
    return;
  }
  submitButton.addEventListener('click', function () {
    dropinInstance.requestPaymentMethod(function (err, payload) {
      if (err) {
        // Handle errors in requesting payment method
      }

      // Send payload.nonce to your server
    });
  });
});

Below is the flow that seems awkward to me for this type of user:

  1. The user clicks the “Pay” button which calls instance.requestPaymentMethod() even though the user already has a payment method… so we can get the payment nonce.
  2. The user has to interact with the application again in order to submit the payment. My app is using the same button and changing the text to “Confirm” (see below).
screen shot 2018-05-15 at 10 56 54 am

This a bit awkward because nothing changes except the text of the button from “Pay” to “Confirm” and requires one extra unnecessary click to complete the order. I’m only doing that so the user sees something change.

So, I thought I could simply check if we have a requestable payment on the callback of dropin.create(), and if so - just execute instance.requestPaymentMethod() without any user interaction. Something like the below code is what could accomplish that and is where the bug is reproducible:

var submitButton = document.querySelector('#submit-button');

braintree.dropin.create({
  authorization: 'CLIENT_AUTHORIZATION',
  selector: '#dropin-container'
}, function (err, dropinInstance) {
  if (err) {
    // Handle any errors that might've occurred when creating Drop-in
    console.error(err);
    return;
  }
  
  if (dropinInstance.isPaymentMethodRequestable()) {
    dropinInstance.requestPaymentMethod(function (err, payload) {
      if (err) {
        // Handle errors in requesting payment method
      }

      // Send payload.nonce to your server
    });
  }

  // do whatever you want...
  // ...
});

Issue description

When calling instance.requestPaymentMethod() within the braintree.dropin.create() callback function an error intermittently occurs (I can reproduce approximately 1 out of every 5 page loads). Above is an example of code that reproduces the issue.

Below is the error output from Chrome Developer Tools:

dropin-1.10.0.min.js:7 Uncaught TypeError: Cannot read property 'requestPaymentMethod' of undefined
at i.requestPaymentMethod (dropin-1.10.0.min.js:7)
at i.requestPaymentMethod (dropin-1.10.0.min.js:5)
at i.requestPaymentMethod (dropin-1.10.0.min.js:1)
at requestPaymentMethod (braintree.js:23)
at braintree.js:50
at dropin-1.10.0.min.js:1 

Strange (probably unreliable) workaround

I did discover that when I change this from the example above:

if (dropinInstance.isPaymentMethodRequestable()) {
  dropinInstance.requestPaymentMethod(function (err, payload) {
    // ...
  });
}

To this:

if (dropinInstance.isPaymentMethodRequestable()) {
  setTimeout(function() {
    dropinInstance.requestPaymentMethod(function (err, payload) {
      // ...
    });
  }, 200);
}

… The issue is no longer reproducible (in my testing with Chrome). This tells me there is probably some kind of race condition in the dropin UI library.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:15 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
a-bormarkcommented, Apr 1, 2020

Please fix this finally!!!

1reaction
crookedneighborcommented, Mar 5, 2020

Thanks for the info. I’ll take another look at this soon.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Dropin - Documentation - Braintree Open Source
Returns a boolean indicating if a payment method is available through requestPaymentMethod. Particularly useful for detecting if using a client token with a ......
Read more >
Customization | JavaScript - Braintree Developer Documentation
This is useful when the transaction fails and you want to show an error message that prompts the customer to select a different...
Read more >
Falcon Sandbox v8.30 © Hybrid Analysis
Guest System: Windows 7 32 bit, Professional, 6.1 (build 7601), Service Pack 1 ... Spawns new processes that are not known child processes....
Read more >
javascript - Braintree Payments requestPaymentMethod hangs
There is no error - the debugger shows the dropinInstance.requestPaymentMethod() call being made, but never returns. I think the issue is with ...
Read more >
braintree-web-drop-in | Yarn - Package Manager
Braintree Web Drop-in. Build Status. npm version. A pre-made payments UI for accepting cards and alternative payments in the browser built using version...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found