GarDavis
GarDavis

Reputation: 1399

PayPal Express Checkout button with validation when button is clicked

I am coding the new PayPal Express Checkout JavaScript button so when it is clicked, some validation is run and based on the validation, the button experience is continued or suppressed.

This demo shows some validation but not exactly what I need. https://developer.paypal.com/demo/checkout/#/pattern/validation

I have this test case you can try: https://jsfiddle.net/gardavis/51kvtjax - this code uses PayPal's script: https://www.paypalobjects.com/api/checkout.js.

This is the part of the jsfiddle I am attempting to get working...

// Called when page displays
validate: function(actions) {
    console.log("validate called");
    actions.disable(); // Allow for validation in onClick()
    paypalActions = actions; // Save for later enable()/disable() calls
},

// Called for every click on the PayPal button even if actions.disabled
onClick: function() {
    console.log('onClick called');
    // Do validations and if OK, continue on to PayPal popup
    var zip = document.querySelector('#zipcode').value;
    var isValid = zip.length >= 5;
    // Issue: fix to continue if valid, suppress popup if invalid
    if (isValid) {
        document.querySelector('#msg').style.display = 'none';
        paypalActions.enable();
        // TODO: Simulate click of PayPal button to display popup
    } else {
        document.querySelector('#msg').style.display = 'block';
        paypalActions.disable(); // Too late
    }
},

The validate() is called once, basically when the page is loaded. That's too early to validate. The onClick() function is called when the button is clicked and a good place to do my validation but I don't have a way to continue if valid and display the error if not.

The demo uses a checkbox event within the scope of the validate() function so it is able to enable/disable the PayPal popup (onClick() still works if disabled). The demo's onClick() simply shows/hides the error message.

Does anyone know how to do validation within onClick()?

Upvotes: 4

Views: 8915

Answers (4)

aryeh
aryeh

Reputation: 1040

If you pass actions into the onClick function then you can call actions.reject() to stop the popup being shown, or actions.resolve() to continue with the payment.

Upvotes: 0

Martin Zvarík
Martin Zvarík

Reputation: 2479

It's too late to disable/allow the buttons, so you have to validate everything on every INPUT change and ENABLE/DISALLOW the PayPal Buttons before user makes an actual click.

Upvotes: 0

Darko Nedic
Darko Nedic

Reputation: 26

The remaining problem is that you have to click the button 2 times because first time you do actions.enable(); to enable the buttons action. So you start the checkout process after you click a second time.

To solve this I used a/multiple event listeners and enable or disable the action from there:

validate: function(actions) {
  actions.disable();
  // i added a 'validate' class value for each element i track
  document.querySelectorAll('.validate').forEach(item => {
    item.addEventListener('change', event => {
      var valid = true; // set it to false if any rule is violated
      /**********************************/
      /* set your validation rules here */
      /**********************************/
      if (valid) {
        actions.enable();
      } else {
        actions.disable();
      }
    });
  });
}

You still can do some CSS style changes (like red borders for the input fields) in the onClick function

Upvotes: 0

mbadeveloper
mbadeveloper

Reputation: 1270

I added a new field to validate which is customer name I add a validation and its show the paypal popup if its valid, you can copy the code and update the fiddle and check it:

<div style="font-family:arial;font-size:14px;">
<p id="msgZip" style="display:none;color:#c00">Please enter a 5-digit zip code</p>
<p><label><input id="zipcode" style="width:50px"> Zip Code</label></p>

<p id="msgName" style="display:none;color:#c00">Please enter your name</p>
<p><label><input id="customername" style="width:50px"> Customer name</label></p>

<div id="paypal-button-container"></div>

<hr/>
<p>
Enter a 5-character zip code and click the checkout button. Validation takes place and since
it is valid, the PayPal experience should display.</p>
<p>A second click on the button does so since the earlier successful validation enabled the button.
</p>
</div>

Javascript

var paypalActions;
// Render the PayPal button
paypal.Button.render({
  env: 'sandbox', // sandbox | production
  commit: true, // Show Pay Now button

  style: {
    label: 'checkout',
    size: 'medium', // small | medium | large | responsive
    shape: 'rect', // pill | rect
    color: 'gold' // gold | blue | silver | black
  },

  client: {
    sandbox: 'AZDxjDScFpQtjWTOUtWKbyN_bDt4OgqaF4eYXlewfBP4-8aqX3PiV8e1GWU6liB2CUXlkA59kJXE7M6R',
    production: '--not used--'
  },

  // Called when page displays
  validate: function(actions) {
    console.log("validate called");
    actions.disable(); // Allow for validation in onClick()
    paypalActions = actions; // Save for later enable()/disable() calls
  },

  // Called for every click on the PayPal button even if actions.disabled
  onClick: function(e) {
    console.log('onClick called');

    var msgErrors = 0;

    // Do validations and if OK, continue on to PayPal popup
    var zip = document.querySelector('#zipcode').value;
    var isValid = zip.length >= 5;

            // Issue: fix to continue if valid, suppress popup if invalid
    if (isValid) {
      document.querySelector('#msgZip').style.display = 'none';          
      // TODO: Simulate click of PayPal button to display popup
    } else {
      document.querySelector('#msgZip').style.display = 'block'; 
      msgErrors +=1;
    }

     var name = document.querySelector('#customername').value;
    isValid = name.length > 0;
    formValid = isValid;

    if (isValid) {
      document.querySelector('#msgName').style.display = 'none';          
    } else {
      document.querySelector('#msgName').style.display = 'block';
      msgErrors +=1;
    }   

    if (msgErrors == 0) {
      paypalActions.enable();
      // TODO: Simulate click of PayPal button to display popup
    } else {
      paypalActions.disable(); // Too late
    }        

  },

  // Buyer clicked the PayPal button.
  payment: function(data, actions) {
    console.log('payment called');
    return actions.payment.create({
      payment: {
        transactions: [{
          amount: {
            total: '0.01',
            currency: 'USD'
          }
        }]
      }
    });
  },

  // Buyer logged in and authorized the payment
  onAuthorize: function(data, actions) {
    console.log('onAuthorize called');
    return actions.payment.execute().then(function() {
      window.alert('Payment Complete!');
    });
  },

}, '#paypal-button-container');

Upvotes: 2

Related Questions