Spreedly iFrame Payment Form

There are a variety of ways to send payment data to Spreedly. If you wish to implement a custom checkout experience while still limiting your PCI compliance, the recommended approach is to use the iFrame payment form. Although it is a lower level library than Express, it allows almost unlimited UX customization and behavior while still storing card data in your Spreedly vault without it ever touching your server environment.

If you are looking for specific commands or options, please see the iFrame Javascript API reference

iFrame overview

Spreedly’s iFrame payment form is a Javscript library that provides two, Spreedly-managed, fields for collecting the credit card number and CVV (the two PCI-sensitive fields of a payment method). Your host page places and styles these two fields within the checkout form, and the iFrame returns a tokenized payment method to the host page when the payment method has been successfully submitted. While an invalid PAN will prevent the iFrame from returning a payment method token, an invalid CVV will not. The CVV iFrame field may be hidden if you do not require the CVV to process payments through your gateway.

The following shows a rendered checkout page using the Spreedly iFrame to serve the number and CVV fields. The only parts contained within Spreedly-served iFrames are the individual number and CVV input fields. All the labels and other fields are part of the host checkout page.

Adding iFrame to your checkout page

To add iFrame to your checkout page, include the Javascript library in your host page:

  <script src="https://core.spreedly.com/iframe/iframe-v1.min.js"></script>

Then copy the following checkout form into the checkout page:

<form id="payment-form"
  onsubmit='submitPaymentForm(); return false;'>

  <input type="hidden"  name="payment_method_token" id="payment_method_token">

  <label for="full_name">Name</label>
  <input type="text" id="full_name" name="full_name"><br/>

  <label>Credit Card Number</label>
  <div id="spreedly-number" style="width:225px; height:35px; border: 2px solid"></div><br/>

  <label for="spreedly-exp-month">Expiration Date</label>
  <input type="text" id="month" name="month" maxlength="2">
  <input type="text" id="year" name="year" maxlength="4"><br/>

  <div id="spreedly-cvv" style="width:60px; height:35px; border: 2px solid "></div><br/>

  <input id="submit-button" type="submit" value="Pay Now" disabled>


This will create a very simple (and unstyled) payment form. However, the payment form will not yet contain the number or CVV fields nor will it be functional. It must first be configured before it can successfully tokenize your customers’ payment methods.


Once the host form is on the page, the iFrame is initialized with using the Spreedly Javascript module. Pass in the Spreedly environment key where your customers’ payment methods should be stored along with the id of the form HTML elements where the two card fields are to be placed.

In this example, payment methods will be tokenized in the Ll6fAtoVSTyVMlJEmtpoJV8S Spreedly environment and the number and CVV form fields will render within the spreedly-number and spreedly-cvv elements, respectively (from the form example, above).

Spreedly.init("Ll6fAtoVSTyVMlJEmtpoJV8S", {
  "numberEl": "spreedly-number",
  "cvvEl": "spreedly-cvv"

Reload your checkout page to see the number and CVV fields rendered in your form. Once the fields are rendered, you need to tell iFrame when to tokenize a customer’s card data.

Tokenize payment method

iFrame doesn’t automatically hook into any form events. Instead, you must explicitly tell it when you want to send the collected card data to Spreedly for tokenization.

The most straight-forward approach is to create a form onSubmit handler that sets the required fields for a payment method (name and expiration date, in addition to the number and CVV fields which are handled for you) and delegates to Spreedly.tokenizeCreditCard.

Implement a top-level function submitPaymentForm that gets the values from the name and expiration date fields, passes them to the iFrame, and requests tokenization:

function submitPaymentForm() {

  var requiredFields = {};

  // Get required, non-sensitive, values from host page
  requiredFields["full_name"] = document.getElementById("full_name").value;
  requiredFields["month"] = document.getElementById("month").value;
  requiredFields["year"] = document.getElementById("year").value;


When the form’s submit button is clicked, the required values from the host page will be sent to the iFrame and subsequently submitted to Spreedly for tokenization in your Spreedly environment. If the card is successfully tokenized, the token will be sent back to the host page via an event, which you must send back to your backend environment for processsing.

Receiving the tokenized payment method

When a card has been tokenized by Spreedly, an event is fired that includes the generated payment method token as well as the details of the payment method record. It is up to you to receive the token and send it to your backend environment.

This example shows how to register for the onPaymentMethod event, and add the payment method token to the host form which is then submitted to your backend:

Spreedly.on('paymentMethod', function(token, pmData) {

  // Set the token in the hidden form field
  var tokenField = document.getElementById("payment_method_token");
  tokenField.setAttribute("value", token);

  // Submit the form
  var masterForm = document.getElementById('payment-form');

While this exmple shows how to submit the payment method token via a form submission, you could just as easily send the token back via AJAX.

At this point you should have a working payment form that tokenizes the payment method at Spreedly and sends the token to your backend environment. Spreedly has tokenized the payment method, but has not processed a transaction.

Executing the transaction

After the iFrame tokenizes your customer’s payment method and submits the checkout form, it is up to you to execute the actual transaction from your backend server environment. This is necessary because the browser is not a secure environment and should never contain your Spreedly access secret (which is required to invoke the transactional portion of the Spreedly API).

When the checkout form is submitted, extract the payment_method_token parameter and use it to execute a purchase (or auth) against the appropriate gateway using the direct API:

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'Ll6fAtoVSTyVMlJEmtpoJV8S:RKOCG5D8D3fZxDSg504D0IxU2XD4Io5VXmyzdCtTivHFTTSy' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "retain_on_success": true

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'Ll6fAtoVSTyVMlJEmtpoJV8S:RKOCG5D8D3fZxDSg504D0IxU2XD4Io5VXmyzdCtTivHFTTSy' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>

You can review the Spreedly API reference docs for details of the direct API, including the purchase and authorize calls.

Securing iFrame

In order to achieve the highest levels of PCI-DSS v3 compliance with the iFrame, you need to disable the creation of payment methods via the direct API. After confirming you are not using the XML, JSON, JSONP, CORs or transparent direct methods of adding a payment method, enable the “Spreedly iFrame or Express Only option in the Environment Settings page of your environment.

This prevents direct API submission of payment methods which is required to detect malicious attacks and, in general, enforce adherence to the PCI standard. The only way payment methods can be added to this Spreedly environment will be through the iFrame (or Express) payment forms.

Customizing the iFrame

The form and flow you have in place now should be functional, but is rudimentary and unstyled. Next, learn how to customize the iFrame using the iFrame Javascript API reference, which includes the following topics:

Recache existing payment method

Due to PCI compliance requirements, Spreedly is unable to store a card’s CVV past the original transaction. If you have an existing payment method already tokenized in your Spreedly environment, you can have the customer update the CVV for a new transaction without having to re-enter the rest of their card details.

Simply set iFrame to operate in recache mode and handle the recache event:

Spreedly.on('ready', function(){
 Spreedly.setRecache("56wyNnSmuA6CWYP7w0MiYCVIbW6" , {
   'card_type': 'visa',
   'last_four_digits': '1234'

// Invoke Spreedly.recache() to recache CVV. On success,
// the "recache" event will be triggered.
Spreedly.on("recache", function(token, paymentMethod) {

  // Send ping back to server for post-recache transaction processing
  var masterForm = document.getElementById('payment-form');

Find more information about recache in the iFrame reference docs.

Browser compatibility

Spreedly iFrame is compatible with the following browser versions:

  • Internet Explorer 10.0 and above
  • Google Chrome 30 and above
  • Firefox 30 and above
  • Safari 6 and above
  • iOS Safari 3.2 and above


Spreedly iFrame is versioned by major numerical, e.g., v1. Backwards-incompatible new features will cause the major version number to increment and will only be deployed if you update the script reference on your checkout page (meaning you choose when to accept major upgrades).

Any critical bug fixes or security updates will be automatically and deployed as the current version number, making no action required by you to be running on a secure, stable version. For this reason, please do not store a copy of the javsacript library on your servers, always reference the version hosted on spreedly.com.

Previous versions

Documentation for previous versions of the iFrame can be found here. Please note, these versions are deprecated, upgrade as soon as possible.