Skip to main content
This explains how to use a checkout page for PCI SAQ A compliance with the Vindicia REST back end. We call this Payment Method Tokenization PMT.
  1. Place a DIV tag in your form. Instead of an input field for sensitive data (credit card number, expiration date, cvn), which would look like this:
    add a DIV tag as follows:
  2. Include vindicia.js on your checkout page. For example:
    Although there is no requirement for JQuery or any other Javascript framework, Vindicia recommends that you include vindicia.js after you include the framework file.This instantiates an object called vindicia.
  3. Call vindicia.setup() with options. Call the vindicia.setup() method to initialize the Hosted Fields on your checkout form. Note: vindicia.setup() will take over the submit event in your form. To validate, you will need to pass in some options to the setup() method.

A vindicia.setup() example

This Javascript example uses all the optional features of the vindicia.setup() method. It initializes the Hosted Fields on the checkout form. See section below for explanations of the values to use.

vindicia.setup() options explained

This setup method takes one argument.

Understanding onVindiciaFieldEvent

Events happen inside the iframes that the parent window will not be allowed to respond to. The onVindiciaFieldEvent property can be used to call your function when validation events are happening inside the iframes.

Merchant FormValidation

When the user clicks the submit button on the form, you will want to validate the form fields before allowing the submit action to complete. Since the vindicia object took over the submit event when you called vindicia.setup(), you cannot call a validation function directly. Instead your validation function will be called for you. Specify the validation function in vindicia.setup like this:
Your validation function should look like this:
You must return true or false.

Iframe Validation

Even though access to iframe field data is restricted, you can validate these iframe fields in the following ways:
  • Inside your own merchant validation function at submit
  • As blur events happen when the user tabs (moves) from field to field in the iframes
  • As a call to vindicia.isValid() for all iframes or for a single iframe
  • Just let the submit button block naturally if the iframe fields are not filled in with valid data
Methods to help you validate iframe fields

Credit Card Validation

PMT automatically attempts to validate the credit card on submit. To turn off this functionality, place a hidden field in the form as follows:
As of version 24.0.0, PMT accepts the following additional form fields for validation:
  • <input name="vin_ignore_avs_policy" value="1" type="hidden" />
  • <input name="vin_ignore_avs_policy" value="1" type="hidden" />
  • <input name="vin_ignore_cvn_policy" value="1" type="hidden" />
  • <input name="vin_min_chargeback_probability" value="100" type="hidden" />
  • <input name="vin_source_ip" value="12.243.28.45" type="hidden" />
  • <input name="vin_currency" value="EUR" type="hidden" />
Note: vin_min_chargeback_probability is a percentage from 0 to 100. Must be integers, or it will be ignored. The preferred currency to use for validation is vin_currency. If not specified, the default merchant currency will be used. If a merchant currency is not set, defaults to USD. Behind The Scenes When the PMT form submits, the REST endpoint POST to https://api.vindicia.com/payment\_methods sends this JSON snippet:
The default value is 1. Therefore if you want validation, do not include the hidden field vin_validate.

The vindicia object: properties and methods

The following properties are supported

Allowed Expiration Date Format

When passing in format via the setup() method, we only allow these specific month and year formats:
  • MM/YY
  • MM-YY
  • MMYY
  • YY/MM
  • YY-MM
  • YYMM
  • YYYY/MM
  • YYYY-MM
  • YYYYMM
  • MM/YYYY
  • MM-YYYY
  • MMYYYY
The default format is MM/YY. Any other format will cause a browser error.

Allowed Styles in vindicia.setup() iframes

When passing in styles via the setup() method, we only allow these specific tags:
  • color
  • width
  • height
  • border
  • border-color
  • border-radius
  • font
  • font-family
  • font-size
  • font-size-adjust
  • font-stretch
  • font-style
  • font-variant
  • font-variant-alternates
  • font-variant-caps
  • font-variant-east-asian
  • font-variant-ligatures
  • font-variant-numeric
  • font-weight
  • line-height
  • opacity
  • outline
  • padding
  • margin
  • text-shadow
  • box-shadow
  • -webkit-box-shadow
  • -moz-osx-font-smoothing
  • -moz-transition
  • -webkit-font-smoothing
  • -webkit-transition
  • transition
All other styles will be ignored. Attempts to send script tags in values will also be ignored.

PCI Compliance Notes

SAQ A compliance: “Card-not-present merchants (e-commerce or mail/telephone-order) that have fully outsourced all cardholder data functions to PCI DSS validated third-party service providers, with no electronic storage, processing, or transmission of any cardholder data on the merchant’s systems or premises.” Vindicia Hosted Fields satisfies the above definition of PCI SAQ A compliance through the use of iframes and browser standard security known as same origin policy.

Browser Security Notes

Same Origin Policy dictates that browser windows and iframes cannot share data unless they are loaded from the same domain (origin). This standard security policy in web browsers allows Vindicia to leverage SAQ A PCI compliance for the merchant checkout page. Sensitive credit card fields are loaded in iframes from a Vindicia web server while the other non-sensitive checkout form fields are loaded in the parent window (from the merchant web server). Each iframe represents one secure input box. This will cause the browser to block direct access to the data in each of these iframes. However messages (events) are allowed to be passed back and forth between them. This is how Vindicia coordinates the submit button on the parent window to allow iframes to submit their data.

Internal Notes

Custom field Luhn check If the merchant has set up any custom fields (custom iframes) using the vindicia.setup() method, we must ensure that no credit cards have been entered there. Therefore at each blur event on a custom field, we perform a Luhn check. If the field passes the Luhn check, the field is not valid. When the Submit button Is pressed A three phase submit has been implemented to coordinate the parent window submit event with the iframes. Phase 1: Collect iframe data for the last time.
  • If the form fields pass validation, let the submit process begin.
  • Set submitFormRequest flag to true to trigger phase two when ready.
  • Call clearSyncFlags() which resets all iframe sync flags to false.
  • Call syncData() which sends events to each iframe to simulate a blur event.
  • When the last iframe sends its data to the master iframe, go to phase 2.
Phase 2: AJAX POST to Vindicia REST server from master iframe.
  • If all the data in all the iframes is valid, the parent window collects all the non iframe form fields.
  • This data is sent to the master iframe with a submitForm event
  • The master iframe performs an AJAX POST, with all its collected data in JSON format, back to the Vindicia REST server.
Phase 3: After form submission activity.
  • Master iframe sends submitComplete event to parent window after the AJAX POST finishes.
  • This triggers the event onSubmitCompleteEvent to invoke merchant application Javascript.
Methods of interest The vindicia object has a some interesting and useful methods.

Using AJAX with PMT, the easy way

If you want AJAX to be used, include the following element onSubmitCompleteEvent in your setup method. Control will return to you after the POST.
If this element is missing, the URL returned from the POST will cause the browser to redirect there.

Using AJAX with PMT, the single page app

If you want a single page app, keep in mind that after the POST the One time login string will be invalid. You are allowed only one POST per one-time login. You will have to refresh the one-time login value and the signed value in the hidden fields in the form. You must then call vindicia.clearData() to notify the iframes to reset their data. This also unblocks the submit button.
Note: getNewOTL() is a Javascript method you will have to write that makes an ajax request back to your merchant server. This is useful if you want to allow the user to enter more than one payment method. You do not have to refresh the OTL value on failed POSTs to the REST server.

Basic PMT setup

Use the following procedure to set up PMT.
  1. Include the vindicia javascript file in your page near the bottom.<script src="https://cdn2.vindicia.com/ws/vindicia.js"></script>
  2. Generate a new one time login string. Choose a unique string we call a session id and place it into the form as a hidden field. This string will be used in the payment method object that gets created on form submission. This is your unique identifier. Using your OTL HMAC key that Vindicia provided for you, create a hash using HMAC256 or HMAC512. The format of this string is:
  3. Create a form with some hidden fields. Two forms are required.
  4. Create some input fields not requiring protection.
  5. Create some input fields requiring protection as div tags.
  6. Call vindicia.setup to establish the protected fields inside iframes.
Using Javascript for HMAC hash See Brix Github repository for more information.
vindiciaAuthId: basic auth generation Script Get your login user and password from Vindicia. It must be a special, low privileged user.
Log in to the Basic Auth Generator, at https://www.blitter.se/utils/basic-authentication-header-generator/

PMT Fields list

Allowed form field names for Payment Method Tokenization

Notes on onSubmitCompleteFailedEvent

The callback function onSubmitCompleteFailedEvent is called when the Submit button does not return 200 (success) from the REST server.
If the vindiciaAuthId used in the vindicia.setup() call is not valid, a 403 Forbidden is returned from the REST server. This might appear as a status code of zero in Javascript, depending on the browser. You might receive a status code of 400 if:
  • The id POSTed is already in use
  • The onetime login is reused from a previous successful POST
For example: 400 PaymentMethod already exists: id=“paymeth_100” would be returned from the REST server if you try to create a payment method with an existing payment method id.

PMT Support for Single Page Application using REACT

Vindicia has created its own open source React.js library for merchant developers to use when integrating PMT into a React.js application. This library is available via GitHub. You can use the package managers yarn and npm. Get more information and detailed instructions at PMT Github repository . Parent topic:Payment Method Tokenization