Tokenization Demo

Take a look at the following examples:

Example A

Example B

Standard Tokenization

<!-- The Payment Form -->
<form id="standard" action="" method="GET">
	<div class="form-group">
		<label for="standardCardNumber">Card Number:</label>
		<input class="form-control" type="tel" id="standardCardNumber" placeholder="•••• •••• •••• ••••" />
	</div>
	<div class="form-group">
		<label for="standardCardExpiration">Card Expiration:</label>
		<input class="form-control" type="tel" id="standardCardExpiration" placeholder="MM / YYYY" />
	</div>
	<div class="form-group">
		<label for="standardCardCvv">Card CVV:</label>
		<input class="form-control" type="tel" id="standardCardCvv" placeholder="CVV" />
	</div>
  
	<input type="submit" class="btn btn-primary" value="Submit" />
	
	<p><button class="btn btn-xs btn-link" id="standardShowCode" type="button">Show Code</button></p>
</form>


<!-- The SecureSubmit Javascript Library -->
<script type="text/javascript" src="https://api2.heartlandportico.com/SecureSubmit.v1/token/2.1/securesubmit.js"></script>
<!-- The Integration Code -->
<script type="text/javascript">
  (function (document, Heartland) {
    // Enhance the payment fields
    Heartland.Card.attachNumberEvents('#standardCardNumber');
    Heartland.Card.attachExpirationEvents('#standardCardExpiration');
    Heartland.Card.attachCvvEvents('#standardCardCvv');

    // Attach a handler to interrupt the form submission
    Heartland.Events.addHandler(document.getElementById('standard'), 'submit', function (e) {
      // Prevent the form from continuing to the `action` address
      e.preventDefault();

      try {
        // Grab references to the field elements
        var card       = document.getElementById('standardCardNumber');
        var expiration = document.getElementById('standardCardExpiration');
        var cvv        = document.getElementById('standardCardCvv');

        // Parse the expiration date
        var split = expiration.value.split(' / ');
        var month = split[0].replace(/^\s+|\s+$/g, '');
        var year  = split[1].replace(/^\s+|\s+$/g, '');

        // Create a new `HPS` object with the necessary configuration
        (new Heartland.HPS({
          publicKey:    'pkapi_cert_jKc1FtuyAydZhZfbB3',
          cardNumber:   card.value.replace(/\D/g, ''),
          cardCvv:      cvv.value.replace(/\D/g, ''),
          cardExpMonth: month.replace(/\D/g, ''),
          cardExpYear:  year.replace(/\D/g, ''),
          // Callback when a token is received from the service
          success: function (resp) {
            alert('Here is a single-use token: ' + resp.token_value);
          },
          // Callback when an error is received from the service
          error: function (resp) {
            alert('There was an error: ' + resp.error.message);
          }
        // Immediately call the tokenize method to get a token
        })).tokenize();
      } catch (e) {
        alert('There was an issue submitting. Are all of the fields filled out?');
      }
    });
  }(document, Heartland));
</script>

iFrames Tokenization

<!-- make iframes styled like other form -->
<style type="text/css">
	#iframes iframe{
		float:left;
		width:100%;
	}
	.iframeholder:after,
	.iframeholder::after{
		content:'';
		display:block;
		width:100%;
		height:0px;
		clear:both;
		position:relative;
	}
</style>


<!-- The Payment Form -->
<form id="iframes" action="" method="GET">
	<div class="form-group">
		<label for="iframesCardNumber">Card Number:</label>
		<div class="iframeholder" id="iframesCardNumber"></div>
	</div>
	<div class="form-group">
		<label for="iframesCardExpiration">Card Expiration:</label>
		<div class="iframeholder" id="iframesCardExpiration"></div>
	</div>
	<div class="form-group">
		<label for="iframesCardCvv">Card CVV:</label>
		<div class="iframeholder" id="iframesCardCvv"></div>
	</div>

	<input type="submit" class="btn btn-primary" value="Submit" />

	<p><button class="btn btn-xs btn-link" id="iframesShowCode" type="button">Show Code</button></p>
</form>





<!-- The SecureSubmit Javascript Library -->
<script type="text/javascript" src="https://api2.heartlandportico.com/SecureSubmit.v1/token/2.1/securesubmit.js"></script>
<!-- The Integration Code -->
<script type="text/javascript">
  (function (document, Heartland) {
    // Create a new `HPS` object with the necessary configuration
    var hps = new Heartland.HPS({
      publicKey: 'pkapi_cert_jKc1FtuyAydZhZfbB3',
      type:      'iframe',
      // Configure the iframe fields to tell the library where
      // the iframe should be inserted into the DOM and some
      // basic options
      fields: {
        cardNumber: {
          target:      'iframesCardNumber',
          placeholder: '•••• •••• •••• ••••'
        },
        cardExpiration: {
          target:      'iframesCardExpiration',
          placeholder: 'MM / YYYY'
        },
        cardCvv: {
          target:      'iframesCardCvv',
          placeholder: 'CVV'
        }
      },
      // Collection of CSS to inject into the iframes.
      // These properties can match the site's styles
      // to create a seamless experience.
      style: {
        'input[type=text],input[type=tel]': {
        	'box-sizing':'border-box',
           'display': 'block',
            'width': '100%',
            'height': '34px',
            'padding': '6px 12px',
            'font-size': '14px',
            'line-height': '1.42857143',
            'color': '#555',
            'background-color': '#fff',
            'background-image': 'none',
            'border': '1px solid #ccc',
            'border-radius': '4px',
            '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
            'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
            '-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s',
            '-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
            'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s'
        },
        'input[type=text]:focus,input[type=tel]:focus': {
        	'border-color': '#66afe9',
          'outline': '0',
          '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)',
          'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)'
        },
        'input[type=submit]' : {
        			'box-sizing':'border-box',
        	    'display': 'inline-block',
              'padding': '6px 12px',
              'margin-bottom': '0',
              'font-size': '14px',
              'font-weight': '400',
              'line-height': '1.42857143',
              'text-align': 'center',
              'white-space': 'nowrap',
              'vertical-align': 'middle',
              '-ms-touch-action': 'manipulation',
              'touch-action': 'manipulation',
              'cursor': 'pointer',
              '-webkit-user-select': 'none',
              '-moz-user-select': 'none',
              '-ms-user-select': 'none',
              'user-select': 'none',
              'background-image': 'none',
              'border': '1px solid transparent',
              'border-radius': '4px',
              'color': '#fff',
              'background-color': '#337ab7',
              'border-color': '#2e6da4'
        },
        'input[type=submit]:hover':{
        		'color': '#fff',
            'background-color': '#286090',
            'border-color': '#204d74'
        },
        'input[type=submit]:focus, input[type=submit].focus':{
            'color': '#fff',
            'background-color': '#286090',
            'border-color': '#122b40',
            'text-decoration': 'none',
            'outline': '5px auto -webkit-focus-ring-color',
    				'outline-offset': '-2px'
        }
      },
      // Callback when a token is received from the service
      onTokenSuccess: function (resp) {
        alert('Here is a single-use token: ' + resp.token_value);
      },
      // Callback when an error is received from the service
      onTokenError: function (resp) {
        alert('There was an error: ' + resp.error.message);
      }
    });

    // Attach a handler to interrupt the form submission
    Heartland.Events.addHandler(document.getElementById('iframes'), 'submit', function (e) {
      // Prevent the form from continuing to the `action` address
      e.preventDefault();
      // Tell the iframes to tokenize the data
      hps.Messages.post(
        {
          accumulateData: true,
          action: 'tokenize',
          message: 'pkapi_cert_jKc1FtuyAydZhZfbB3'
        },
        'cardNumber'
      );
    });
  }(document, Heartland));
</script>

To a customer, both examples are the same, but according to PCI-DSS, only Example B will help keep you PCI compliant with as little scope as possible. The fields in Example A are your typical input elements that are hosted on your payment page. The fields in Example B are also your typical input elements, but they are wrapped inside of iframe elements that are hosted on Heartland’s payment gateway.

While there are some limitations to using iframe elements, our Javascript library has tried to remove most pain points for integrators wishing to embed these fields seamlessly into their existing solutions.

Feel free to click the Show Code buttons in the samples, if you haven’t already, to view the necessary HTML and Javascript for each solution.

Other Examples

Angular.js 1.5

React

Vue