Hosted fields
Collect a PAN in a Tokeni iframe so your origin never sees the card number.
Hosted fields are the default way to tokenize. The cardholder types into a Tokeni iframe. Your JavaScript receives a token ID, never the PAN.
Server: authentication key
The browser SDK does not get your shared secret. Your server builds an HMAC-SHA256 key and hands the browser only that key.
Message:
merchantId|origin|timestamp|tokenSchemetimestampis UTCyyyyMMddHHmmsstokenSchemeisPCIfor PAN collection- The key is valid for 20 minutes
originmust match the page that hosts the iframe (scheme + host)
import crypto from 'node:crypto';
export function iframeAuthKey({ merchantId, origin, sharedSecret, tokenScheme = 'PCI' }) {
const timestamp = new Date()
.toISOString()
.replace(/[-:T.Z]/g, '')
.slice(0, 14);
const message = [merchantId, origin, timestamp, tokenScheme].join('|');
const authenticationKey = crypto
.createHmac('sha256', sharedSecret)
.update(message)
.digest('base64');
return { timestamp, authenticationKey };
}Browser: load the iframe
<div id="cardDiv"></div>
<script type="module">
import { TokenCoreIframe } from '@token-core/payment-js';
const iframe = new TokenCoreIframe('cardDiv', {
tokenExID: 'your_merchant_id',
authenticationKey: auth.authenticationKey,
origin: window.location.origin,
timestamp: auth.timestamp,
tokenScheme: 'PCI',
pci: true,
gatewayUrl: 'https://sandbox-api.tokeni.io',
});
iframe.on('load', () => console.log('ready'));
iframe.on('tokenize', (data) => {
// data.tokenId is what you store. There is no PAN here.
fetch('/pay', { method: 'POST', body: JSON.stringify({ tokenId: data.tokenId }) });
});
iframe.on('error', (err) => console.error(err));
iframe.load();
document.querySelector('#pay').addEventListener('click', () => iframe.tokenize());
</script>payment-js talks to POST /api/v1/iframe/authenticate, which exchanges the HMAC for a one-time hosted-fields session. Card data never hits your origin.
CVV
For CVV-with-PAN, set cvv: true. CVV is used for the authorization in volatile memory and is not stored. Do not log it. Do not send it to your server.
PCI scope
Your page still needs HTTPS and a sane CSP. You do not store or transmit the PAN. That is the point of the iframe. Confirm scope with your QSA. Tokeni is designed as PCI DSS Level 1 tokenization infrastructure with an isolated CDE.