February 26, 2014

API Best Practices, Part II: Using HTML5 Field Validation

Posted by Craig Christenson Category IconTechnology

In this new blog series, 2Checkout explores the developments and features of its brand new Payment API, currently in BETA. To see the new 2Checkout Payment API BETA and use it as your new checkout, apply here.

Server-side validation is a must for security reasons, but minimal client-side field format validation should always be used to provide immediate feedback and prevent unnecessary roundtrips to your server. For example, to insure that the user has provided all of the requested information on a payment form, it is important to at least validate the format on required data before the request is sent server side. This type of validation is traditionally handled with a combination of JavaScript and CSS to first validate the value, and then display a message to the user. While this is not terribly difficult, the ever-growing adoption of HTML5 has made this process easier than ever. HTML5 attributes can handle this validation directly on the input elements without additional JavaScript validation or UI changes to display error messages. Let’s take a look at how we can add validation to a simple Payment API form in just a couple of steps.

<form id="myCCForm" action="https://www.mysite.com/examplescript.php" method="post">
  <input id="sellerId" type="hidden" value="1817037">
  <input id="publishableKey" type="hidden" value="087F9356-39A3-4CEC-AAEE-0694E4B619EE">
  <input id="token" name="token" type="hidden" value="">
  <div>
    <label>
      <span>Card Number</span>
      <input id="ccNo" type="text" size="20" value="" autocomplete="off" />
    </label>
  </div>
  <div>
    <label>
      <span>Expiration Date (MM/YYYY)</span>
      <input type="text" size="2" id="expMonth"/>
    </label>
    <span> / </span>
    <input type="text" size="2" id="expYear"/>
  </div>
  <div>
    <label>
      <span>CVC</span>
      <input id="cvv" size="4" type="text" value="" autocomplete="off" />
    </label>
  </div>
  <input type="submit" value="Submit Payment">
</form>

We know that all of the input fields in this form are required to create the token, so the first attributes we want to add to each are the “required” and “title” attributes.

# Credit Card Field
<input id="ccNo" required type="text" size="20" title="Credit Card (No spaces no dashes)" value="" autocomplete="off" />

# Expiration Fields
<input type="text" size="2" id="expMonth" title="Expiration Month (2 Digit Month)" required />
<input type="text" size="2" id="expYear" title="Expiration Year (2 Digit Year)" required />

# CVC Field
<input id="cvv" size="4" required type="text" title="CVC (3 or 4 Digit Security Code)" value="" autocomplete="off" />

If a field is left empty, this will display a callout with the field title attribute.

HTML Callout

Next let’s add some format validation for the data that is being entered into the fields. To accomplish this without the use of additional JavaScript we can utilize the “pattern” attribute to specify our rules using regex.

# Credit Card Field
<input id="ccNo" required type="text" size="20" pattern="[0-9]{13,16}" title="Credit Card (No spaces no dashes)" value="" autocomplete="off" />

# Expiration Fields
<input type="text" size="2" id="expMonth" pattern="[0-9]{2}" title="Expiration Month (2 Digit Month)" required />
<input type="text" size="2" id="expYear" pattern="[0-9]{2}" title="Expiration Year (2 Digit Year)" required />

# CVC Field
<input id="cvv" size="4" required type="text" pattern="[0-9]{3,4}" title="CVC (3 or 4 Digit Security Code)" value="" autocomplete="off" >

These attributes will insure that each input value also passes its field validation pattern before the submit event will trigger. To complete the API integration on this form, all we have to do now is add our JavaScript to request the token and pass it to our server.

<script>
    // Called when token created successfully.
    function successCallback(data) {
      var myForm = document.getElementById('myCCForm');
      myForm.token.value = data.response.token.token;
      myForm.submit();        
    }

    // Called when token creation fails.
    function errorCallback(data) { 
      if (data.errorCode === 200) {
        TCO.requestToken(successCallback, errorCallback, 'myCCForm');  // Resubmit if the ajax request fails
      } else {
        alert("Validation Error: Please enter your full card number, expiration date and your card security code.");
      }       
    } 

    $("#myCCForm").submit(function (e) {
      e.preventDefault(); // this will prevent from submitting the form.
      TCO.requestToken(successCallback, errorCallback, 'myCCForm');  // This is the create token call
    });
</script>
But what if HTML5 is not supported?

Most modern desktop and mobile browsers — such as the latest versions of Chrome, Firefox, and IE10+ — already support HTML5 form attributes. Unfortunately, HTML5 attributes aren’t yet supported on the default android browser, Mobile Safari, or any version of Internet Explorer below IE10. Fortunately, there are some battle tested polyfills available such as h5Validate and Webshims which we can utilized to add HTML5 validation support to these unsupported browsers.

Displaying API errors

The API can also return it’s own validation errors based on the values entered. In the `errorCallback` function above, you can see that we are alerting a message if an error occurs when creating the token. This will work adequately, but it’s more customary to display error messages above the payment form and clear out the sensitive input fields.

HTML Callout

So to finish up this example, let’s add some logic to our `errorCallback` function to clear the credit card fields and display our error message above the form.

<p id="validation-error" style="border: 1px solid red; width: 300px; padding: 0.6em; margin-bottom: 0.7em; color: red; background: #FFF; display: none"></p>
<form id="myCCForm" action="https://www.mysite.com/examplescript.php" method="post">
  <input id="sellerId" type="hidden" value="1817037">
  <input id="publishableKey" type="hidden" value="087F9356-39A3-4CEC-AAEE-0694E4B619EE">
  <input id="token" name="token" type="hidden" value="">
  <div>
    <label>
      <span>Card Number</span>
      <input id="ccNo" required type="text" size="20" pattern="[0-9]{13,16}" title="Credit Card (No spaces no dashes)" value="" autocomplete="off" />
    </label>
  </div>
  <div>
    <label>
      <span>Expiration Date (MM/YY)</span>
      <input type="text" size="2" id="expMonth" pattern="[0-9]{2}" title="Expiration Month (2 Digit Month)" required />
    </label>
    <span> / </span>
    <input type="text" size="2" id="expYear" pattern="[0-9]{2}" title="Expiration Year (2 Digit Year)" required />
  </div>
  <div>
    <label>
      <span>CVC</span>
      <input id="cvv" size="4" required type="text" pattern="[0-9]{3,4}" title="CVC (3 or 4 Digit Security Code)" value="" autocomplete="off" >
    </label>
  </div>
  <input type="submit" value="Submit Payment">
</form>

<script>
  // Clears the credit card fields.
  function clearFields () {
    $('#ccNo').val('');
    $('#expMonth').val('');
    $('#expYear').val('');
    $('#cvv').val('');
  }

  // Called when token created successfully.
  function successCallback(data) {
    var myForm = document.getElementById('myCCForm');
    myForm.token.value = data.response.token.token;
    myForm.submit();        
  }

  // Called when token creation fails.
  function errorCallback(data) { 
    if (data.errorCode === 200) {
      TCO.requestToken(successCallback, errorCallback, 'myCCForm'); // Resubmit if the ajax request fails
    } else {
      // Clear the credit card fields and display an error message
      clearFields();
      $("#validation-error").html("Validation Error: Please enter your full card number, expiration date and your card security code.");
      $("#validation-error").show();
    }       
  } 

  $("#myCCForm").submit(function (e) {
    e.preventDefault(); // this will prevent the form from submitting
    TCO.requestToken(successCallback, errorCallback, 'myCCForm');  // This is the create token call
  });
</script>

In our next post, we’ll dive into JavaScript field validation using jQuery and walk through some of the more popular validation modules. Come back to the 2Checkout Blog for more information on how to optimize your Payment API integration and read the latest tutorials on all things e-commerce.