Clover iframe—Create a payment form
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
- Create a global developer account and select the Hosted iFrame checkbox in the Ecommerce Settings.
- Generate the merchant public token or
apiAccessKey
to make calls to the card tokenization server to tokenize a card, as follows:
- For a single merchant or test merchant—Generate an Ecommerce API token on the Clover Merchant Dashboard for a Hosted iframe + API/SDK integration type. Use the public token as the
apiAccessKey
. 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 the Clover Developers Relations (Dev Rel) team. - For multiple merchant businesses—First generate an OAuth
access_token
and then use it to generate an Ecommerce API key (PAKMS key) orapiAccessKey
.
- 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.
- Add a
<script>
block to the<head>
block of your webpage. - 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.
- Create a constant (
const
) forclover
and pass the merchant'sapiAccessKey
as the parameter of anew Clover
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. - 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();
- 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('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:
- 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>
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
- Complete the steps to set up the payment form.
- Use the
<form>
element ID to create a constant to access the payment form.
const form = document.getElementById('payment-form');
- 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');
- Add
change
andblur
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
}
}
- Add the
submit
event listener (addEventListener
). This listener takes the validated card data from the payment form and calls theclover.createToken()
method to generate a Clover card token. The method calls the/v1/tokens
endpoint to generate thesource
token for the entered card data. Here, the Clover iframe acts as a tokenizer.
The Clover server returns a source token that begins withclv_
. With asource
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..."
}
- Create
cloverTokenHandler
to indicate how your app can handle the returned token. For the Clover iframe, add the generatedclv_
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
- Generate a
source
token using the interactive payment form. - Generate an OAuth expiring (access and refresh) token to use as the
authorization: Bearer
token. - Use a server-to-server call to create a charge, as shown in the information flow for a charge request.
- Use an
idempotency
key, which is a required value generated by your app for Clover, to safely retry thev1/charges
request without accidental double charges.
Steps
- On the payment form, enter the customer's card details to pay for an order.
- Send a POST request to the
v1/charges
endpoint to create a charge. - Enter the required parameters in the request:
amount
currency
source
, which is theclv_
card token generated using the Clover iframe.
- Set the
authorization: Bearer
as your OAuth-generatedaccess_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 source
token 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
Updated 2 days ago