Clover iframe—Create a payment form

North America—United States and Canada

The Clover in-line frame (iframe) lets you insert an HTML payment form into another HTML-based webpage, such as your merchant's website. With the Clover iframe integration, your ecommerce website can communicate with the Clover Ecommerce APIs.

You can build a secure payment experience on your website using iframe fields and elements to get the customer's payment information securely from the merchant browser to the Clover server. The Clover iframe handles the customer's card tokenization and is also known as an iframe tokenizer.

Prerequisites

  1. Create a global developer account and select the Hosted iFrame checkbox in the Ecommerce Settings.
  2. Generate the merchant public token or apiAccessKey to make calls to the card tokenization server to tokenize a card, as follows:
  1. Locate the merchant identifier as the merchantId is required to configure the iframe SDK.

Before you begin

Browser support—Apple Safari, Google Chrome, Mozilla Firefox, and Microsoft Edge browsers support the Clover iframe.

❗️

Secure your site

Developers using the Clover-hosted iframe integration are advised to check their code and remove any reference to cdn.polyfill.io.

For example:

<head>

...

delete this→ <script src="https://cdn.polyfill.io/v3/polyfill.min.js"></script>

<script src="https://checkout.sandbox.dev.clover.com/sdk.js"></script>

</head>

For additional information about the security concern with using polyfill script, see the related announcement.

Set up a payment form

Step 1: Add the Clover SDK to your webpage

To use the Clover iframe features, you need to import the Clover SDK to your webpage. The Clover SDK is a JavaScript library.

  1. Add a <script> block to the <head> block of your webpage.
  2. Use the sandbox or production sdk.js file to define the source (src).
https://checkout.sandbox.dev.clover.com/sdk.js
https://checkout.clover.com/sdk.js
<head>
  ...
  <script src="https://checkout.sandbox.dev.clover.com/sdk.js"></script>
</head>

Step 2: Configure the SDK

To make payment requests on a merchant's behalf, set up the Clover SDK to use the merchant's public API key or apiAccessKey retrieved using the PAKMS/apikey endpoint.

  1. Create a constant (const) for clover and pass the merchant's apiAccessKey as the parameter of a new Clover object.
  2. Create another constant (const) for clover.elements(). This constant creates card tokens based on information entered in the iframe. Each entity in the iframe is an element.
  3. To support the reCAPTCHA verification service, street address input field, or other optional features, add merchantId to the iframe configuration.
const clover = new Clover('12a3b456789c12345d67891234e56f78', {
    merchantId: 'xxxxxxxxxxxxx'
});
const elements = clover.elements();
  1. To configure a language, add a locale to const clover. Clover supports:
  • English USA (en-US) by default
  • English Canadian (en-CA)
  • French Canadian (fr-CA). For example, the following appended command supports French Canadian:
const clover = new Clover('12a3b456789c12345d67891234e56f78', {
    merchantId: 'xxxxxxxxxxxxx',
    locale: 'fr-CA'
});
const elements = clover.elements();

Step 3: Create an HTML payment form

Create an HTML <form> where customers enter their credit card information. See Clover iframe—Use card and page elements.

To set up your payment form:

  1. Add a <form> to contain card data fields on your webpage.
  2. Set the id attribute and make a note of this value. Example: payment-form.
<body>

  <form action="/charge" method="post" id="payment-form">
    <!-- this form contains the card data fields -->
  </form>
 
</body>
  1. In the <form>, create an <input> field to enter the amount of the charge.
<form action="/charge" method="post" id="payment-form">
	  
  <div class="form-row top-row">
    <div id="amount" class="field card-number">
      <input name="amount" placeholder="Amount">
    </div>
  </div>
  
</form>
  1. Add <div> containers to enable customers to enter their card details. For each card data field, add a <div> to display error messages (class="input-errors").
<form action="/charge" method="post" id="payment-form">
  ...
  
  <div class="form-row top-row">
    <div id="amount" class="field card-number">
      <input name="amount" placeholder="Amount">
    </div>
  </div>

  <div class="form-row top-row">
    <div id="card-number" class="field card-number"></div>
    <div class="input-errors" id="card-number-errors" role="alert"></div>
  </div>

  <div class="form-row">
    <div id="card-date" class="field third-width"></div>
    <div class="input-errors" id="card-date-errors" role="alert"></div>
  </div>
  
  <div class="form-row">
    <div id="card-cvv" class="field third-width"></div>
    <div class="input-errors" id="card-cvv-errors" role="alert"></div>
  </div>
    
  <div class="form-row">
    <div id="card-postal-code" class="field third-width"></div>
    <div class="input-errors" id="card-postal-code-errors" role="alert"></div>
  </div>
    
  <div id="card-response" role="alert"></div>
    
  ...
</form>
  1. Add a <button> for the users to finalize their payment.
<form action="/charge" method="post" id="payment-form">
  ...
  
  <div class="button-container">
    <button>Submit Payment</button>
  </div>
  
</form>

Click to view the complete HTML code block to create a payment form
This is a sample code. You can also customize the payment form using CSS.

<form action="/charge" method="post" id="payment-form">
    <!-- this form contains the card data fields -->
    <div style="display: flex; justify-content: center">
        <div style="padding: 5px" class="form-row top-row">
            <div id="card-number" class="field card-number"></div>
            <div class="input-errors" id="card-number-errors" role="alert"></div>
        </div>

        <div style="padding: 5px" class="form-row">
            <div id="card-date" class="field third-width"></div>
            <div class="input-errors" id="card-date-errors" role="alert"></div>
        </div>
    </div>

    <div style="display: flex; justify-content: center">
        <div style="padding: 5px" class="form-row">
            <div id="card-cvv" class="field third-width"></div>
            <div class="input-errors" id="card-cvv-errors" role="alert"></div>
        </div>

        <div style="padding: 5px" class="form-row">
            <div id="card-postal-code" class="field third-width"></div>
            <div class="input-errors" id="card-postal-code-errors" role="alert"></div>
        </div>
    </div>

    <div id="card-response" role="alert"></div>
    
    <div style="display: flex; justify-content: center" class="button-container">
        <button style="margin-bottom: 20px">Submit Payment</button>
    </div>
</form>

Click to view the complete HTML and JavaScript code block with a custom CSS

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment Form</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Open+Sans">
    <style>
        body {
            font-family: 'Roboto', 'Open Sans', sans-serif;
            font-size: 16px;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 20px;
        }
        input {
            font-size: 20px;
            margin: 10px 0;
            padding: 10px;
            width: 300px;
        }
        #payment-request-button {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Payment Form</h1>
    <div id="card-number"></div>
    <div id="card-name"></div>
    <div id="card-date"></div>
    <div id="card-cvv"></div>
    <div id="card-postal-code"></div>
    <div id="card-street-address"></div>
    <div id="payment-request-button"></div>

    <script src="path/to/clover.js"></script>
    <script>
        const clover = new Clover('080391318a9041e4d122082d369b64c7', {
            merchantId: 'M1V5CF1WV0FSJ'
        });
        const elements = clover.elements();

        const styles = {
            input: {
                fontSize: '20px'
            }
        };

        const cardNumber = elements.create('CARD_NUMBER', styles);
        const cardName = elements.create('CARD_NAME', styles);
        const cardDate = elements.create('CARD_DATE', styles);
        const cardCvv = elements.create('CARD_CVV', styles);
        const cardPostalCode = elements.create('CARD_POSTAL_CODE', styles);
        const cardStreetAddress = elements.create('CARD_STREET_ADDRESS', styles);

        cardNumber.mount('#card-number');
        cardName.mount('#card-name');
        cardDate.mount('#card-date');
        cardCvv.mount('#card-cvv');
        cardPostalCode.mount('#card-postal-code');
        cardStreetAddress.mount('#card-street-address');

        const paymentReqData = {
            // Define your payment request data here
        };

        const paymentRequestButton = elements.create('PAYMENT_REQUEST_BUTTON', {
            paymentReqData
        });
        paymentRequestButton.mount('#payment-request-button');

        paymentRequestButton.addEventListener('paymentMethod', function(ev) {
            alert(JSON.stringify(ev));
        });

        paymentRequestButton.addEventListener('paymentMethodStart', function(ev) {
            console.log("Gpay in progress");
        });
    </script>
</body>
</html>

After the payment <form> is set up, you can use JavaScript components to make it interactive, as seen in the next procedure.


Generate a Clover token and create a charge using a payment form

To make the payment <form> interactive, add JavaScript components provided with the Clover iframe.

Step 1: Create an interactive payment form

  1. Complete the steps to set up the payment form.
  2. Use the <form> element ID to create a constant to access the payment form.
const form = document.getElementById('payment-form');
  1. Create instances of the card elements and insert (mount) them in the <div> containers. You can add CSS styling as the second parameter to match your website branding. See Clover iframe—Customize iframe elements with CSS.
const cardNumber = elements.create('CARD_NUMBER', styles);
const cardDate = elements.create('CARD_DATE', styles);
const cardCvv = elements.create('CARD_CVV', styles);
const cardPostalCode = elements.create('CARD_POSTAL_CODE', styles);
  
cardNumber.mount('#card-number');
cardDate.mount('#card-date');
cardCvv.mount('#card-cvv');
cardPostalCode.mount('#card-postal-code');
  1. Add change and blur event listeners (addEventListener) to display any error messages to the user. These event listeners allow real-time validation for the card data entered in the input fields in the iframe.
const cardResponse = document.getElementById('card-response');
const displayCardNumberError = document.getElementById('card-number-errors');
const displayCardDateError = document.getElementById('card-date-errors');
const displayCardCvvError = document.getElementById('card-cvv-errors');
const displayCardPostalCodeError = document.getElementById('card-postal-code-errors');

  // Handle real-time validation errors from the card element
  cardNumber.addEventListener('change', function(event) {
    console.log(`cardNumber changed ${JSON.stringify(event)}`);
  });

  cardNumber.addEventListener('blur', function(event) {
    console.log(`cardNumber blur ${JSON.stringify(event)}`);
  });

  cardDate.addEventListener('change', function(event) {
    console.log(`cardDate changed ${JSON.stringify(event)}`);
  });

  cardDate.addEventListener('blur', function(event) {
    console.log(`cardDate blur ${JSON.stringify(event)}`);
  });

  cardCvv.addEventListener('change', function(event) {
    console.log(`cardCvv changed ${JSON.stringify(event)}`);
  });

  cardCvv.addEventListener('blur', function(event) {
    console.log(`cardCvv blur ${JSON.stringify(event)}`);
  });

  cardPostalCode.addEventListener('change', function(event) {
    console.log(`cardPostalCode changed ${JSON.stringify(event)}`);
  });

  cardPostalCode.addEventListener('blur', function(event) {
    console.log(`cardPostalCode blur ${JSON.stringify(event)}`);
  });
{
  "CARD_NUMBER": {
    "error":"Card number is invalid.",
    "touched":true // whether there was any interaction with the field
  },
  "CARD_DATE": {
    "error":"Card expiry is invalid.",
    "touched":true
  },
  "CARD_CVV": {
    "touched":true
  },
  "CARD_POSTAL_CODE": {
    "touched":false
  }
}
  1. Add the submit event listener (addEventListener). This listener takes the validated card data from the payment form and calls the clover.createToken() method to generate a Clover card token. The method calls the /v1/tokens endpoint to generate the source token for the entered card data. Here, the Clover iframe acts as a tokenizer.
    The Clover server returns a source token that begins with clv_. With a source token, you can create a charge or set up recurring payments.
// Listen for form submission
form.addEventListener('submit', function(event) {
  event.preventDefault();
  // Use the iframe's tokenization method with the user-entered card details
  clover.createToken()
    .then(function(result) {
    if (result.errors) {
      Object.values(result.errors).forEach(function (value) {
        displayError.textContent = value;
      });
    } else {
      cloverTokenHandler(result.token);
    }
  });
});
{
	"token": "clv_1TST39I92..."
}
  1. Create cloverTokenHandler to indicate how your app can handle the returned token. For the Clover iframe, add the generated clv_ token to the server application to charge the tokenized card.
function cloverTokenHandler(token) {
  // Insert the token ID into the form so it gets submitted to the server
  var form = document.getElementById('payment-form');
  var hiddenInput = document.createElement('input');
  hiddenInput.setAttribute('type', 'hidden');
  hiddenInput.setAttribute('name', 'cloverToken');
  hiddenInput.setAttribute('value', token);
  form.appendChild(hiddenInput);
  form.submit();
}

Step 2: Create a charge

Once you create an interactive payment form and generate a source card token, you can now create a charge.

Prerequisites

Steps

  1. On the payment form, enter the customer's card details to pay for an order.
  2. Send a POST request to the v1/charges endpoint to create a charge.
  3. Enter the required parameters in the request:
  • amount
  • currency
  • source, which is the clv_ card token generated using the Clover iframe.
  1. Set the authorization: Bearer as your OAuth-generated access_token.
curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key: {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{
    "amount": 4500,
    "currency": "usd",
    "source": "clv_1ABCD7234efghDIJKlMNOp5qrS"
  }'

The Clover iframe sends the sourcetoken to the app to make a charge request. The app creates a charge and processes the charge using the source token and the amount in the POST request to v1\charges endpoint.


Related topics