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
442 stars 134 forks source link

Drop-In: No way for containing page to know when iframe fails client side validation #38

Closed tjgrathwell closed 9 years ago

tjgrathwell commented 9 years ago

We have a form that contains user registration details as well as a braintree dropin frame.

We would like to disable the outer form's submit button after the user has pressed it once, so they can't double-submit.

If we disable the submit button, we need to re-enable it if the dropin iframe is showing an error (meaning the form did not actually submit).

We see that the braintree.setup for dropin can accept an onPaymentMethodReceived callback, which is a good way to know if the iframe submitted successfully.

Additionally, it seems to accept an onError callback. However, that does not seem to fire when the form is submitted but client side validation fails. I am not sure what circumstances trigger this onError event (probably if the iframe form submit failed when being sent over the network?).

In short, any time the iframe has started doing work, we would like to have an event that tells us when the iframe has stopped doing work, successfully or unsuccessfully.

kyledetella commented 9 years ago

@tjgrathwell thanks for bringing this up, I see the value in some functionality along these lines. I will bring it up with the team and keep you posted.

albygnagna commented 9 years ago

Hello, I just came across the same problem @tjgrathwell has posted. Would be great having more info about that as soon as you have it. Thanks everybody!

mikep commented 9 years ago

Hi, I have also run into this issue, it would be nice if we could have a callback for the iframe validation failed so we could re-enable the button ourselves, or have the dropin ui handle disabling/enabling the parent forms submit button on its own.

kyledetella commented 9 years ago

@tjgrathwell @mikep @albygnagna currently, we expose an onError callback in braintree.setup and we think it makes sense to call that when the iFrame validation fails. We are working on implementing that feature.

What do you think of something like this?

braintree.setup(TOKEN, 'dropin', {
  container: 'my-container',
  onError: function (payload) {
    if (payload.type === 'validation:failed') {
      // re-enable button
    }
  }
});
mikep commented 9 years ago

@kyledetella That looks like it will work for me.

tjgrathwell commented 9 years ago

@kyledetella That looks like it will satisfy our needs nicely, looking forward to it!

albygnagna commented 9 years ago

That solution seems to be what I was looking for and I appreciate your smartness for giving it to us! Anyway I have finally ended up with our custom form!

krasi-georgiev commented 9 years ago

+1 for this feature. I also disable the submit button to avoid double submissions

kyledetella commented 9 years ago

Just wanted to provide an update here. We are going to add this feature in an upcoming release. Sorry for the long wait. I will let you know when it is launched.

niklr commented 9 years ago

+1 it is already described here: https://developers.braintreepayments.com/javascript+ruby/guides/client-sdk#global-setup

unfortunately it does not yet get called. can you confirm this?

Tyrdall commented 9 years ago

@niklr Currently it is only called on initial errors. E.g. if your confirguration is wrong.

kyledetella commented 9 years ago

That is correct.

krasi-georgiev commented 9 years ago

Is there any time scale for this new feature ?

decadecity commented 9 years ago

+1. Could really do with this feature.

decadecity commented 9 years ago

We started with a two second debounce of the form submit but after some experimentation we've found that increasing it to five seconds has reduced these errors to a manageable rate. (Down from over 100 in 24h to around 10.)

kyledetella commented 9 years ago

As of the 2.8.0 release, client-side validation failures in Drop-in are now reported to the onError callback. This version has not been hotlinked yet but is available now via this repo, bower, and npm. Once this has been hotlinked, we will release full documentation. In the meantime you can use this as follows:

Usage

braintree.setup(TOKEN, 'dropin', {
  container: 'dropin-container',
  onError: function (payload) {
    // See below for payload details
  }
});

Error payload for failed client-side validation

{
  type: "VALIDATION",
  message: "Some payment method input fields are invalid.",
  details: {
    invalidFields: [
      { fieldKey: "number", isEmpty: true },
      { fieldKey: "cvv", isEmpty: true }
    ]
  }
}
z-igniter commented 7 years ago

@kyledetella Have you ever hotlinked this version or any other having this correction applied?If so,which one we can use?

crookedneighbor commented 7 years ago

We recommend using the latest version which is 2.32.0.

z-igniter commented 7 years ago

@crookedneighbor Ive been trying with this version already but that doesnt seem to fire onError if i enter wrong cvv or expiry date: var myForm = $('#checkout-form'); braintree.setup( brainTreeClientToken = 'my_token', 'dropin', { container: 'dropin-container', form: 'checkout-form', onError: function (obj) { if (obj.type === 'VALIDATION') { console.log(obj.details); } else if (obj.type == 'SERVER') { console.log(obj.details); } }, / onPaymentMethodReceived: function (obj) { console.log(obj.details); console.log(obj.nonce); console.log(obj.type); //myForm.submit(); } / } );

crookedneighbor commented 7 years ago

Those errors cannot be detected with client side validation.

onError will populate errors for empty or incomplete fields, but for incorrect CVV or expiration dates, there's no way to know that they are incorrect until the card is actually charged.

If you are vaulting the card, you can have cvv verification turned on in your gateway, and that will refuse to vault the card if the cvv verification does not pass.

By the way, the new version of Drop-in was just released. You may want to check out the new version: https://github.com/braintree/braintree-web-drop-in

z-igniter commented 7 years ago

Thank you for the recommendation.Instantly switched to this version, looks and works nice so far.Since i only need to verify the cvv and expiry date before i save the card to the vault (create customer) ,can you suggest me how can i do that on server side (to verify the cvv and expiry date are correct)?I have tried several options and i obviously missed something.Didnt try to charge the card but to verify it like this: $result = Braintree_Customer::create([ 'firstName' => 'Fred', 'lastName' => 'Jones', 'creditCard' => [ 'paymentMethodNonce' => nonceFromTheClient, 'options' => [ 'verifyCard' => true ] ] ]); which ended with invalid argument "expected credit card id to be set" exception.I have cvv verification turned on in my control panel.

crookedneighbor commented 7 years ago

@chengolino Your best bet will be to reach out to our support team to troubleshoot your integration. support@braintreepayments.com

z-igniter commented 7 years ago

@crookedneighbor Sure.Thanks.

ValeriyFromUA commented 6 months ago

Hello everyone! Is there already a solution for this kind of request? I can't find a way to disable the payment button. It's clear that the braintree iframe validates the data, but I would like to disable the button until all fields are marked as "valid" to avoid unnecessary entries in the logs.