Use the Clover-hosted iframe
The in-line frame (iframe) allows you to insert an HTML page into another HTML-based webpage. With the Clover-hosted iframe integration, your website can communicate with the Clover ecomm APIs.
You can combine the Clover-hosted iframe (provided by Clover's sdk.js
) with an Ecommerce software development kit (SDK) to build a secure payment experience on your website. The Clover-hosted iframe includes fields and elements that you need to get the customer information from the merchant browser to the Clover server.
Information flow for a charge request
The following diagram displays the information flow and the software components interaction required to complete a charge request. Add an HTML<form>
to your ecommerce webpage and insert the Clover-hosted elements to collect and process a customer’s card information.
This information is used to create the card token used by the server to complete the payment. This charge operation must be a server-to-server call.

Basic Clover hosted iframe flow
Green: Clover software
Blue: your apps software
Browser support
Apple Safari, Google Chrome, Mozilla Firefox, and Microsoft Edge browsers support the Clover iframe. It does not run on Microsoft Internet Explorer 11 browser by default but you can use polyfills to make the iframe functional in the browser.
<head>
...
<script src="https://cdn.polyfill.io/v3/polyfill.min.js"></script>
<script src="https://checkout.sandbox.dev.clover.com/sdk.js"></script>
</head>
Add the Clover SDK to your webpage
- To use the Clover iframe features, you need to import the Clover SDK to your webpage.
Add a<script>
block to the<head>
block of your webpage. - In your HTML form, add
<script>
to import the Clover SDK and use the Clover iframe features. Use the Sandbox or productionsdk.js
file to define the source (src).
Sandbox:<https://checkout.sandbox.dev.clover.com/sdk.js>
Production:<https://checkout.clover.com/sdk.js>
<head>
...
<script src="https://checkout.sandbox.dev.clover.com/sdk.js"></script>
</head>
Configure the SDK
To make payment requests on a merchant's behalf, set up the Clover SDK to use the merchant's public key retrieved from the PAKMS endpoint.
- Create a
clover
constant (const
) and pass the merchant's key as the parameter of a newClover
object. - Create another constant (
const
) forclover.elements()
. This constant creates card tokens based on information entered in the iframe. Each entity in the iframe is an element.
const clover = new Clover('39c7b87101f44739c823362203d21f89');
const elements = clover.elements();
- If you want to configure a language, add a
locale
toconst 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('39c7b87101f44739c823362203d21f89', {
locale: 'fr-CA'
});
const elements = clover.elements();
- If you want to support the street address input field, add
merchantId to const clover.
const clover = new Clover('39c7b87101f44739c823362203d21f89', {
merchantId: 'xxxxxxxxxxxxx'
});
const elements = clover.elements();
IMPORTANT
Apps for a single merchant can hardcode the public key to initialize the iframe SDK.
If your app uses a model where a customer may expect to use one card token between multiple merchants, send an email to [email protected]
Set up the payment form
You can create an HTML <form>
where customers enter their credit card information. To set up your payment form:
- Add a
<form>
to contain card data fields on your webpage. - 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>
- 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>
- 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>
- 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>
After the payment <form>
is set up, you can use JavaScript components to make it interactive. See Create an interactive payment
Create an interactive payment
To make the payment <form>
interactive, add JavaScript components provided with the iframe.
- Complete the steps to Set up the payment form.
- Use the
<form>
element ID from the Set up the payment form section to create a constant to access the payment form.
const form = document.getElementById('payment-form');
- Create instances of the card elements and mount them to the
<div>
containers. When creating containers, you can add CSS styling as the second parameter to match your website branding. See Customizing 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');
- Add event listeners (
addEventListener
) for displaying any error messages to the user.
The SDK's real-time validation of the card data fields ensures that the customer entries match the expected format. With the change and blur event listeners, you can handle real-time validation 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
}
}
- Add an event listener (
addEventListener
) to the submit event. This listener takes the validated card data from the payment form and calls theclover.createToken()
method. A token is generated.
// 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..."
}
- Add the generated 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();
}
Create a charge
Once you create an interactive payment form and generate a card token (see Generate a card token) you can now create a charge. For detailed information, see Create a charge.
Prerequisites
- Create a charge request must be a server-to-server call as shown in the diagram at the beginning of this topic.
- An
idempotency
key is a required value generated by your app for Clover to safely retry the/v1/charges
request without accidental double charges. See Using idempotency keys for more information.
Steps
- On the payment form, enter the customer card details to pay for an order.
- Send the
amount
and the token (as the value ofsource
) to the/v1/charges
endpoint to complete the transaction. - Set the
authorization: Bearer
as your OAuth-generatedauth_token
. The charge is
processed for the specified amount using the 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' \
--data '{"amount":4500,"currency":"usd","source":"clv_1TSTS778rnkeDPBiFRZc4zuD"}'
Updated 15 days ago