Skip to main content

Bank Info Tokenization Guide

Overview

Compared to Card's PCI DSS compliance requirements, bank information such as account numbers and routing numbers are not as sensitive. However, it is still recommended to use our tokenization service to securely store and process bank data. This guide will walk you through the process of tokenizing bank information.

How Tokenization Works for Bank Info

For bank info, we will tokenize and encrypt the bank info of the users on the client side and send it to our servers. The information should be encrypted on-transit and at-rest. The tokenized bank info will be stored in our servers and can be used for future transactions.

Steps to Tokenize a Bank Info

Step 1: Setup Variables

This step initializes the essential configuration needed for the tokenization process:

  • TOKEN: Your public key for authentication
  • PAGE_ROOT_URL: The base URL of the payment service
  • PAGE_URL: The specific URL for the payment field iframe
const ENV_VARS = {
TOKEN: 'a743ca68-a550-47a2-b171-adde1840c31e', // Public Key
PAGE_ROOT_URL: 'https://demo.ngnair.com',
PAGE_URL: 'https://demo.ngnair.com/ach-field',
}

Step 2: Setup Event Listeners

Three critical event handlers are implemented:

  1. onEvent: General purpose event handler for monitoring form interactions
  2. onToken: Processes the tokenization response, storing:
    • accountNumber: The bank account number tokenized
    • routingNumber: The bank routing number
    • accountType: The bank account type (checking/savings)
    • holderType: The account holder type (personal/business)
  3. Message Event Listener: Manages communication between iframe and parent window
// Generic event handler
const onEvent = (event, data) => {
console.log(event, data);
}

// Token event handler
const onToken = (data) => {
console.log(data);
if (data.accountNumber) {
APP_STATE.accountNumber = token.accountNumber;
APP_STATE.routingNumber = token.routingNumber;
APP_STATE.accountType = token.accountType;
APP_STATE.holderType = token.holderType;
}
};

// Setup message listener
document.addEventListener('DOMContentLoaded', () => {
window.addEventListener("message", function(event) {
if (event.origin !== ENV_VARS.PAGE_ROOT_URL) return;

const eventType = event.data.type;
const data = event.data.data;

switch (eventType) {
case 'event': onEvent(data.event, data.data); break;
case 'token': onToken(data); break;
case 'error': onEvent(data); break;
}
});

setIFrameURL();
});

Step 3: Create and Configure iFrame

The iFrame setup involves:

  1. URL Generation: Creates a unique URL with:
    • Random hash for security
    • Custom form labels configuration
    • Optional fields settings
    • Custom CSS styling
  2. iFrame Implementation: Embeds the payment form in your page
const getIFrameURL = () => {
const baseURL = ENV_VARS.PAGE_URL;
if (!baseURL) return '';

const hash = Math.random().toString(36).substring(7);

// Customize form labels and optional fields
const settingsString = JSON.stringify({
labels: {
// these are all optionals
accountNumber: 'Account Number',
routingNumber: 'Routing Number',
accountType: 'Account Type',
holderType: 'Holder Type',
},
});

// Custom CSS for the form
const cssString = `
#ach-parent {
background-color: gray;
}

#accountNumber {
color: red;
}
`;

const url = new URL(baseURL);
url.searchParams.append('hash', hash);
url.searchParams.append('settings', settingsString);
url.searchParams.append('css', cssString);

return url.toString();
}

const setIFrameURL = () => {
const iframe = document.getElementById('payFrame');
iframe.src = getIFrameURL();
}

Sample View

alt text

Sample Token Response

This is a sample data as received from the onToken function:

Token Response
{
"accountNumber": "eyJlbmNyeXB0ZWQiOiJhN2VkYjFjMWM2MjVhYmNhMmRjYjYyNTEyMmM4NjBhNiIsImVwaGVtZXJhbFB1YmxpY0tleSI6IjA0NzQzNGNhMzRjZjI0Mzg0YTg4OTMxYmEwNzE2NGJlMzhjZjVmMThiOWNkNDFmNjE5MDZhYzMzYTg2ZWNjZDY0OTJjYmJkMzhjMDNiNzk5NGIwMjFmMTdlNDk4M2U2ZWRiZGFjYmY0NjA0YTNiMzQzOGYyMjUyZTFkNjg5NDk0YWQiLCJhdXRoVGFnIjoiZWUyM2YzYzk5YWExYTgxNzk4ODdjZmM2ODc1YmU5N2UiLCJzYWx0IjoiMjM4MjExMmRkYWMyMGQxOTc0ZDczMTg3ZWYyMWE0NmJlOGE5ODY1ZjBlZWI1Y2ZiMjQxNTc5MzMyOGIyZTU5MyJ9", // JWT tokenized of the account number including other fields
"routingNumber": "111111111",
"accountType": "CHECKING",
"holderType": "PERSONAL"
}

All of the tokeni response fields are important for use when processing payments.

Complete Implementation Example

Here's a full HTML implementation combining all the steps:

<!DOCTYPE html>
<html>
<head>
<title>Bank Info Tokenization Example</title>
</head>
<body>
<div id="payment-container">
<iframe id="payFrame" frameborder="0" width="100%" height="250px"></iframe>
</div>

<script>
// Environment configuration
const ENV_VARS = {
TOKEN: 'a743ca68-a550-47a2-b171-adde1840c31e',
PAGE_ROOT_URL: 'https://demo.ngnair.com',
PAGE_URL: 'https://demo.ngnair.com/ach-field',
};

// Application state
const APP_STATE = {
accountNumber: null,
routingNumber: null,
accountType: null,
holderType: null
};

// Event handlers
const onEvent = (event, data) => {
console.log('Form Event:', event, data);
};

const onToken = (data) => {
console.log('Received Token:', data);
if (data.accountNumber) {
APP_STATE.accountNumber = data.accountNumber;
APP_STATE.routingNumber = data.routingNumber;
APP_STATE.accountType = data.accountType;
APP_STATE.holderType = data.holderType;

console.log('Token stored in APP_STATE:', APP_STATE);
}
};

// iFrame URL generator
const getIFrameURL = () => {
const baseURL = ENV_VARS.PAGE_URL;
if (!baseURL) return '';

const hash = Math.random().toString(36).substring(7);
const settings = {
labels: {
accountNumber: 'Account Number',
routingNumber: 'Routing Number',
accountType: 'Account Type',
holderType: 'Holder Type'
}
};

const cssString = `
#ach-parent {
background-color: gray;
}

#accountNumber {
color: red;
}
`;

const url = new URL(baseURL);
url.searchParams.append('hash', hash);
url.searchParams.append('settings', JSON.stringify(settings));
url.searchParams.append('css', cssString);

return url.toString();
};

// Initialize iFrame
const setIFrameURL = () => {
const iframe = document.getElementById('payFrame');
iframe.src = getIFrameURL();
};

// Setup event listeners
document.addEventListener('DOMContentLoaded', () => {
window.addEventListener("message", function(event) {
if (event.origin !== ENV_VARS.PAGE_ROOT_URL) return;

const eventType = event.data.type;
const data = event.data.data;

switch (eventType) {
case 'event': onEvent(data.event, data.data); break;
case 'token': onToken(data); break;
case 'error': onEvent(data); break;
}
});

setIFrameURL();
});
</script>
</body>
</html>