Sample Code

<!DOCTYPE html>
<html>
<head>
<!-- Use the following src for the script on your form and replace ****version**** with the desired version: src="https://cdn.cardknox.com/ifields/****version****/ifields.min.js" -->
<script src="ifields.min.js"></script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
let defaultStyle = {
border: '1px solid black',
'font-size': '14px',
padding: '3px',
width: '250px'
};
let validStyle = {
border: '1px solid green',
'font-size': '14px',
padding: '3px',
width: '250px'
};
let invalidStyle = {
border: '1px solid red',
'font-size': '14px',
padding: '3px',
width: '250px'
};
/*
* [Contitional]
* Required if you want to enable Google Pay payment method on your website
* For more information please refer to documentation
*/
enableGooglePay('amount');
/*
* [Optional]
* You can enable allowing the user to submit the form by pressing the 'enter' key on their keyboard when the ifield is focused by calling
* enableAutoSubmit(formElementId)
*
* The formElementId is the id of your form that gets submit when the user presses 'enter' on their keyboard.
*
* Note: If this feature is enabled, the getTokens must be handled in a submit event listener for the form as that event is what gets triggered.
*/
enableAutoSubmit('payment-form');
/*
* [Optional]
* You can enable 3DS Protection using enable3DS(amountElementId, monthElementId, yearElementId, waitForResponse, waitForResponseTimeout)
*
* The amountElementId, monthElementId, and yearElementId parameters are the ids for the html elements that contain the resepective values for those fields.
*
* The waitForResponse parameter is an optional flag that indicates whether the getToken function should wait for 3DS data if it did not yet
* recieve it before generating the tokens (the default value is true). If the value is set to false, the tokens will be created without 3DS protection.
*
* The waitForResponseTimeout parameter is how long it should wait for a 3DS response before creating the token without it (the default value is 20,000ms).
*
* Note: The timeout for waitForResponse and getToken are not cumulative. If they are the same value and the waitForResponse timeout is hit, the getToken timeout
* will trigger as well.
*/
enable3DS('amount', 'month', 'year', true, 20000);
/*
* [Optional]
* You can customize the iFields by passing in the appropriate css as JSON using setIfieldStyle(ifieldName, style)
*/
setIfieldStyle('ach', defaultStyle);
setIfieldStyle('card-number', defaultStyle);
setIfieldStyle('cvv', defaultStyle);
/*
* [Required]
* Set your account data using setAccount(ifieldKey, yourSoftwareName, yourSoftwareVersion).
*/
setAccount('ifieldssamplekey_7e133696ce254383824cdff436c50c7b', 'iFields_Sample_Form', '1.0');
/*
* [Optional]
* Use enableAutoFormatting(separator) to automatically format the card number field making it easier to read
* The function contains an optional parameter to set the separator used between the card number chunks (Default is a single space)
*/
enableAutoFormatting();
/*
* [Optional]
* Use addIfieldCallback(event, callback) to set callbacks for when the event is triggered inside the ifield
* The callback function receives a single parameter with data about the state of the ifields
* The data returned can be seen by using alert(JSON.stringify(data));
* The available events are ['input', 'click', 'focus', 'dblclick', 'change', 'blur', 'keypress']
*
* The below example shows a use case for this, where you want to visually alert the user regarding the validity of the card number, cvv and ach ifields
*/
addIfieldCallback('input', function(data) {
if (data.ifieldValueChanged) {
setIfieldStyle('card-number', data.cardNumberFormattedLength <= 0 ? defaultStyle : data.cardNumberIsValid ? validStyle : invalidStyle);
if (data.lastIfieldChanged === 'cvv'){
setIfieldStyle('cvv', data.issuer === 'unknown' || data.cvvLength <= 0 ? defaultStyle : data.cvvIsValid ? validStyle : invalidStyle);
} else if (data.lastIfieldChanged === 'card-number') {
if (data.issuer === 'unknown' || data.cvvLength <= 0) {
setIfieldStyle('cvv', defaultStyle);
} else if (data.issuer === 'amex'){
setIfieldStyle('cvv', data.cvvLength === 4 ? validStyle : invalidStyle);
} else {
setIfieldStyle('cvv', data.cvvLength === 3 ? validStyle : invalidStyle);
}
} else if (data.lastIfieldChanged === 'ach') {
setIfieldStyle('ach', data.achLength === 0 ? defaultStyle : data.achIsValid ? validStyle : invalidStyle);
}
}
});
/*
* [Optional]
* You can set focus on an ifield by calling focusIfield(ifieldName), in this case a delay is added to ensure the iframe has time to load
*/
let checkCardLoaded = setInterval(function() {
clearInterval(checkCardLoaded);
focusIfield('card-number');
}, 1000);
/*
* [Optional]
* You can clear the ifield by calling clearIfield(ifieldName)
*/
document.getElementById('clear-btn').addEventListener('click', function(e){
e.preventDefault();
clearIfield('card-number');
clearIfield('cvv');
clearIfield('ach');
setGPPayload("");
});
/*
* [Required]
* Call getTokens(onSuccess, onError, [timeout]) to create the SUTs. * Pass in callback functions for onSuccess and onError. Timeout is an optional
* parameter that will exit the function if the call to retrieve the SUTs take too long. The default timeout is 60 seconds. It takes an number value
* marking the number of milliseconds.
*
* If autoSubmit is enabled, this must be done in a submit event listener for the form element.
*/
document.getElementById('payment-form').addEventListener('submit', function(e){
e.preventDefault();
document.getElementById('transaction-status').innerHTML = 'Processing Transaction...';
let submitBtn = this;
submitBtn.disabled = true;
getTokens(function() {
document.getElementById('transaction-status').innerHTML = '';
document.getElementById('ach-token').innerHTML = document.querySelector("[data-ifields-id='ach-token']").value;
document.getElementById('card-token').innerHTML = document.querySelector("[data-ifields-id='card-number-token']").value;
document.getElementById('cvv-token').innerHTML = document.querySelector("[data-ifields-id='cvv-token']").value;
submitBtn.disabled = false;
//The following line of code has been commented out for the benefit of the sample form. Uncomment this line on your actual webpage.
//document.getElementById('payment-form').submit();
},
function() {
document.getElementById('transaction-status').innerHTML = '';
document.getElementById('ach-token').innerHTML = '';
document.getElementById('card-token').innerHTML = '';
document.getElementById('cvv-token').innerHTML = '';
submitBtn.disabled = false;
},
30000
);
});
if (/[?&]test/.test(window.location.search)) {
showHide("gatewayMerchantId", true);
}
});
//Google Pay
const gpRequest = {
environment: GPEnvironment.test,
merchantInfo: {
merchantName: "Example Merchant"
},
buttonOptions: {
buttonSizeMode: GPButtonSizeMode.fill
},
billingParams: {
billingAddressRequired: true,
billingAddressFormat: GPBillingAddressFormat.full
},
shippingParams: {
emailRequired: true,
onGetShippingCosts: function () {
return {
"shipping-001": "0.00",
"shipping-002": "1.99",
"shipping-003": "10.00"
}
},
onGetShippingOptions: function () {
return {
defaultSelectedOptionId: "shipping-001",
shippingOptions: [
{
"id": "shipping-001",
"label": "Free: Standard shipping",
"description": "Free Shipping delivered in 5 business days."
},
{
"id": "shipping-002",
"label": "$1.99: Standard shipping",
"description": "Standard shipping delivered in 3 business days."
},
{
"id": "shipping-003",
"label": "$10: Express shipping",
"description": "Express shipping delivered in 1 business day."
},
]
};
}
},
onGetTransactionInfo: function () {
let amt = getAmount();
return {
displayItems: [
{
label: "Subtotal",
type: "SUBTOTAL",
price: amt.toString(),
},
{
label: "Tax",
type: "TAX",
price: (0.1 * amt).toString(),
}
],
countryCode: 'US',
currencyCode: "USD",
totalPriceStatus: "FINAL",
totalPrice: (1.1 * amt).toString(),
totalPriceLabel: "Total"
}
},
onBeforeProcessPayment: function () {
return new Promise(function (resolve, reject) {
try {
//Do some validation here
resolve(iStatus.success);
} catch (err) {
reject(err);
}
});
},
onProcessPayment: function (paymentResponse) {
return new Promise(function (resolve, reject) {
try {
// show returned data in developer console for debugging
console.log("paymentResponse", JSON.stringify(paymentResponse));
paymentToken = paymentResponse.paymentData.paymentMethodData.tokenizationData.token;
console.log("paymentToken", paymentToken);
const amt = (paymentResponse && paymentResponse.transactionInfo && paymentResponse.transactionInfo.totalPrice) || 0;
try {
if (amt <= 0) {
throw "Payment is not authorized. Invalid amount. Amount must be greater than 0";
}
const gmid = document.getElementById("gatewayMerchantId");
if (gmid && gmid.value) {
paymentResponse.xGatewayMerchantId = gmid.value;
}
authorizeGPay(paymentResponse)
.then((resp) => {
gpRequest.handleResponse(resp);
setGPPayload(JSON.stringify(paymentResponse, null, 2));
resolve(resp);
})
.catch((rej) => {
console.error("Payment is not authorized", JSON.stringify(rej));
setGPPayload("");
setTimeout(function () { alert("Payment is not authorized. Please check the logs") }, 500);
reject(rej);
});
} catch (err) {
const emsg = JSON.stringify(err);
console.error(emsg);
setGPPayload("");
setTimeout(function () { alert(emsg) }, 500);
reject({error: err});
}
} catch (err) {
setGPPayload("");
reject(err);
}
});
},
onPaymentCanceled: function(respCanceled) {
setTimeout(function () { alert("Payment was canceled") }, 500);
},
handleResponse: function (resp) {
const respObj = JSON.parse(resp);
if (respObj) {
if (respObj.xError) {
setTimeout(function () { alert(`There was a problem with your order (${respObj.xRefNum})!`) }, 500);
} else
setTimeout(function () { alert(`Thank you for your order (${respObj.xRefNum})!`) }, 500);
}
},
};
function initGP() {
return {
merchantInfo: gpRequest.merchantInfo,
buttonOptions: gpRequest.buttonOptions,
onGetTransactionInfo: "gpRequest.onGetTransactionInfo",
environment: gpRequest.environment,
billingParameters: gpRequest.billingParams,
shippingParameters: {
emailRequired: gpRequest.shippingParams.emailRequired,
onGetShippingCosts: "gpRequest.shippingParams.onGetShippingCosts",
onGetShippingOptions: "gpRequest.shippingParams.onGetShippingOptions"
},
onBeforeProcessPayment: "gpRequest.onBeforeProcessPayment",
onProcessPayment: "gpRequest.onProcessPayment",
onPaymentCanceled: "gpRequest.onPaymentCanceled",
onGPButtonLoaded: "gpButtonLoaded",
isDebug: isDebugEnv
};
}
function gpButtonLoaded(resp) {
if (!resp) return;
if (resp.success > 0) {
showHide("igp", true);
showHide("lbGPPayload", true);
} else if (resp.success < 0 && resp.reason) {
alert(resp.reason);
// } else { //Ignore Google Pay not supported
// alert("Google Pay not supported");
}
}
function setGPPayload(value) {
const gpTxt = document.getElementById('gp-payload');
gpTxt.value = value;
showHide(gpTxt, value);
}
function showHide(elem, toShow) {
if (typeof(elem) === "string") {
elem = document.getElementById(elem);
}
if (elem) {
toShow ? elem.classList.remove("hidden") : elem.classList.add("hidden");
}
}
function getAmount () {
return roundToNumber(document.getElementById("amount").value || "0", 2);
}
</script>
<style>
body {
margin: 10px;
}
iframe {
border: 0 solid black;
width: 600px;
height: 28px;
padding: 0px;
margin-bottom: 5px;
}
iframe.gp {
display: block;
border: 0;
width: 250px;
height: 45px;
padding: 0px;
margin: 0px;
}
input {
border: 1px solid black;
font-size: 14px;
padding: 3px;
width: 250px;
margin-bottom: 12px;
}
#card-data-error {
color: red;
}
.hidden {
display: none;
}
textarea {
border: 1px solid black;
width: 350px;
}
</style>
</head>
<body>
<form id="payment-form" method="POST">
<input id="name" name="xName" placeholder="Name" autocomplete="cc-name"></input>
<br/>
<!-- Use the following src for the iframe on your form and replace ****version**** with the desired version: src="https://cdn.cardknox.com/ifields/****version****/ifield.htm" -->
<iframe data-ifields-id="ach" data-ifields-placeholder="Checking Account Number" src="ifield.htm"></iframe>
<input data-ifields-id="ach-token" name="xACH" type="hidden"></input>
<br/>
<!-- Use the following src for the iframe on your form and replace ****version**** with the desired version: src="https://cdn.cardknox.com/ifields/****version****/ifield.htm" -->
<iframe data-ifields-id="card-number" data-ifields-placeholder="Card Number" src="ifield.htm"></iframe>
<input data-ifields-id="card-number-token" name="xCardNum" type="hidden"></input>
<br/>
<!-- Use the following src for the iframe on your form and replace ****version**** with the desired version: src="https://cdn.cardknox.com/ifields/****version****/ifield.htm" -->
<iframe data-ifields-id="cvv" data-ifields-placeholder="CVV" src="ifield.htm"></iframe>
<input data-ifields-id="cvv-token" name="xCVV" type="hidden"></input>
<br/>
<input id="amount" name="xAmount" placeholder="Amount" type="number" inputmode="decimal"></input>
<br/>
<input id="month" name="xMonth" placeholder="Month" autocomplete="cc-exp-month" type="number" pattern="[0-9]*"></input>
<br/>
<input id="year" name="xYear" placeholder="Year" autocomplete="cc-exp-year" type="number" pattern="[0-9]*"></input>
<br/>
<input id="gatewayMerchantId" name="xGatewayMerchantId" class="hidden" placeholder="GatewayMerchantId" autocomplete="gateway-merch-id"></input>
<br/>
<input id="submit-btn" type="submit" value="Submit"></input>
<br/>
<input id="clear-btn" type="button" value="Clear"></input>
<br/>
<iframe id="igp" class="gp hidden" data-ifields-id="igp" data-ifields-oninit="initGP" src="igp.htm"
allowpaymentrequest
sandbox="allow-popups allow-modals allow-scripts allow-same-origin"
title="GPay checkout page">
</iframe>
<br/>
<label id="transaction-status"></label>
<br/>
<label data-ifields-id="card-data-error" style="color: red;"></label>
<br/>
<label>ACH Token: </label><label id="ach-token"></label>
<br/>
<label>Card Token: </label><label id="card-token"></label>
<br/>
<label>CVV Token: </label><label id="cvv-token"></label>
<br/>
<label id="lbGPPayload" class="hidden">Google Pay Payload: </label>
<br />
<textarea id="gp-payload" class="hidden" rows="10" readonly="true"></textarea>
<br/>
<br/>
<label><a href="ifields-diagram.htm" target="_blank">Transaction Flow Diagram</a></label>
</form>
</body>
</html>