braintree-web-drop-in: "requestPaymentMethod()" Intermittently Throws an Error When Called in "braintree.dropin.create()" Callback
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):
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:
- 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. - 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).
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.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 16 (6 by maintainers)
Please fix this finally!!!
Thanks for the info. I’ll take another look at this soon.
FWIW, I’m running into this issue every so often in drop-in UI version 1.18.0. Chrome 80. Most of the time it works just fine, other times I’m seeing Cannot read property ‘requestPaymentMethod’ of undefined at initBraintreeAndSubmit.
Thanks for the report. We’ll look into this.