Tokeni

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|tokenScheme
  • timestamp is UTC yyyyMMddHHmmss
  • tokenScheme is PCI for PAN collection
  • The key is valid for 20 minutes
  • origin must 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.

On this page