‘Your Page’ with JavaScript

What it is

This technology allows you to place HTML pages on your site that are completely under your design and revision control, while remaining out of scope for PCI. These pages can be out of scope because they are displayed on the consumer’s browser and the consumer enters their own data on the consumer’s own PC or mobile device.

When the consumer submits the form, data from the pages is transmitted twice, first to SLIM CD to collect the credit card data and then to your server to receive the tokenized version of the data.

The tokenized version of the data contains none of the customer’s private information, so your webserver is allowed to see and store it, without having to be PCI compliant. Your servers never receive the actual credit card data, as it is transmitted from the consumer’s PC to SLIM CD. This “double-posting” from a single “form submit” is accomplished with JavaScript.

A complete sample code example is provided below.

How it works

HTML forms transmit data to servers for each <input> tag on the form, but only if that <input> tag contains a “name=” identifier. If the <input> tag does not have a name, the data contained inside that tag cannot be coded as a “name=value” pair on an HTTP GET/POST, so it is ignored by the browser.

JavaScript provides a way to access the data in an <input> tag by giving each <input> field an “id=” identifier string. The <input> field does not need to have a “name=” tag, but simply an “id=” tag for JavaScript to be able to access the value entered into it.

JavaScript also allows interception of the <form> tag’s submission. This is done by using the “OnSubmit=” attribute of the <form> tag which points to a JavaScript routine which is run when the form is submitted. The interception occurs before any name value pairs are posted to your webserver, so the JavaScript can perform it’s work of determining whether the form should be submitted to your webserver, as specified in the “action=” attribute of the <form> tag.

The goal is to remove your server (the target specified in the “action=” attribute) from receiving the cardholder data. To do this, we must:

  1. Place “id=” attributes on each <input> field for which we need to extract the PCI-sensitive data.Avoid using “name=” values on any fields containing data considered to be sensitive by PCI security. These include card number, CVV2, magnetic swipe or track data, PIN debit pin data, etc.

    You are allowed to store expiration date unencrypted if you do not store the card number, but you are NEVER allowed to store CVV2 values.

  2. Use an “id” attribute on the form itself. This will allow us to access the <form> tag and resubmit the data once we get a response back from SLIMCD.COM. The Asynchronous Considerations topic below discusses this in more detail.

  3. The “OnSubmit” of the form calls a JavaScript function that will intercept the form’s submission so that we can divert some of the values to SLIM CD in trade for tokenized versions of that data, which can be safely posted back to your server in named, hidden fields.

Asynchronous Considerations

When the form is submitted, the JavaScript OnSubmit handler will step in to intercept the flow of events. The transmission of name value pairs to your server (as specified in the “action=”) will only occur if the OnSubmit returns “true”. Before that occurs, the OnSubmit handler sends the data to SLIM CD for credit card authorization and then wait to get a response.

The waiting step can take a few moments, and since the typical user won’t tolerate an unresponsive browser, the best way to handle the waiting is to set up an Asynchronous call back method. This occcurs prior to sending the data to SLIM CD and then cancels the user-initiated submission. Your website can then return to performing other tasks, such as letting the user know that credit card authorization is underway. When an answer becomes available, your callback function will be called to handle the results of the credit card authorization. If the credit card transaction has been successful, the callback function will submit your form, passing the now-tokenized authorization information on to your webserver.

To accomplish this feat, we’ll rely on how JavaScript and browsers work together. The OnSubmit function must return either true or false. In our case, we will ALWAYS want to return FALSE. This stops the <form> tag from submitting to your server. We need to stop the flow because we don’t yet know if the credit card authorization has been successful. We only want to submit back to your webserver when we are certain that a payment has been made. The callback routine will run with the response from SLIM CD and this callback can then be responsible for re-submitting the form.

This is a point worth repeating. The JavaScript function called on OnSubmit will always return false, stopping the form from submission. The callback will be called once the connection to SLIMCD.COM returns a result. The callback will then be responsible for re-submitting the form. One initial concern might be that submitting the form might cause the OnSubmit to be triggered again and cause an infinite loop. Thankfully, submitting the form within JavaScript does not trigger the OnSubmit, it just sends the data to the target server.

The JavaScript callback will need to store the data returned from SLIMCD.COM by placing it your form’s hidden fields, and to clear out any card data values as a safety mechanism to insure these data are not sent to the “action=” target of the form.

The callback will then access the <form> object to submit the updated input/hidden field contents to your server. The easiest way to accomplish this is to place an “id=” attribute on the hidden form fields and on the form itself. The results from SLIMCD.COM can be stored in the hidden fields and the form can be submitted using the “id=” value of the <form> tag.

Implementation Choices

The submission to the SLIM CD servers can be done in two ways:

  1. Use JQuery and enable cross-domain resources (CORS). SLIM CD exposes web service entry points that accept either name/value pairs or JSON as input and return JSON. These entry points can either return pure JSON or can return JavaScript that triggers a specified callback with the JSON as an argument to the callback.
  2. Use the SLIM CD library to make the call to SLIMCD.COM. The SLIM CD library provides support for Cross-Domain resources by dynamically modifying the <head> tag of the browser’s DOM and adding a <script>. The SLIM CD library calls the same JSON entry points that you can call directly using JQuery, but for JavaScript purists, the SLIM CD library wraps the implementation, eliminating dependencies.

SLIM CD provides sample code for both approaches. See the RESOURCES section of the website. Each Entry Point contains JSON and JavaScript tabs that provide sample implementations.
Putting it all together

  1. To take what we’ve learned and produce a full working sample, here’s what we need to do. For this example, we’ll use the SLIM CD library:
  2. Obtain “Public” API ACCESS CREDENTIALS from the merchant. Slim CD API calls need either a userid/password or an API Access Credential. You don’t want to place the password inside an HTML file where everyone can View Source, so API Access Credentials are the solution. These are created by the merchant for their login using the SLIM CD website (see the sections on UserNames and on API Access Credentials for more information).
  3. Create a new HTML form
  4. If you are using the SLIMCD JavaScript library, Include “slimcd.js”. (You would not need this if you were using JQuery to call the SLIM CD JSON web services directly)
  5. Add a <form> tag with “id=” and an “onsubmit=” attributes
  6. Add <input> fields for cardnumber, cvv2, etc with appropriate “id=” and (extremely important) without the “name=” attributes.
  7. Add <input type=”hidden”> fields both id and name attributes. These will store the “gateid” and other values returned from SLIMCD.COM
  8. Create the JavaScript callback function for the OnSubmit
    1. Disable the submit button so the user cannot click twice
    2. Have the OnSubmit function retrieve the cardholder data fields and format the call to SLIM CD’s library function or JSON web service
    3. Have the above call define a “callback” function that will
    4. Determine if the call was successful or failed
    5. Enable the submit button so the user can try again if the call to SLIMCD.COM failed, or so the form can be submitted via JavaScript if the call to SLIMCD.COM succeeded.
    6. Upon success:
      1. Retrieve values from the SLIM CD reply block (returned as JSON)
      2. Set the values into the hidden form fields
      3. Clear out the payment form fields (not required, but recommended)
      4. Submit the form again using the form’s “id=” value
    7. Upon fail/error
      1. Display a message box or update the HTML of an area on the page to show the reason for the failure.
      2. Return FALSE so that the OnSubmit stops the browser from submitting the form until the callback runs.
  9. Your server will receive the HTTP POST containing the form <input> fields that have names. This will include any hidden <input> fields whose value has been updated by the JavaScript. Note that you can have <input> fields that are both sent to SLIM CD and are sent to your web server (like ADDRESS, ZIP, etc). Your server will not receive any values for fields with no names. If it does receive these values, the JavaScript will have blanked out any values of concern (like Card Number or CVV2).

Sample Code

More references:

Code Project: PCI-Compliant-Credit-Card-Handling-on-Windows-Azure

GitHub: Open Source sample for LOAD and QUEUEDATA (https://github.com/littleRm/slimcd)