Revaly Vault Iframe
Bring Revaly into your checkout so every customer-initiated payment is optimized for approval from the very first attempt.
To optimize a payment, Revaly needs to see it before it reaches your gateway. For customer-initiated transactions (CIT), this means Revaly must be part of your checkout flow. If your checkout uses payment fields hosted by your gateway, card details go directly to the gateway, and Revaly can't apply its treatments until it's too late.
The Revaly Vault Iframe solves this. It lets you capture card details on your checkout page with Revaly instead, so every customer-initiated payment can be routed through Revaly, optimized with Upfront Approval treatments, and then forwarded to your gateway.
The card number and CVV fields sit inside your checkout page but are hosted securely by the Revaly Vault. Your customer types their card details as they would into any other form, but the data goes straight to the vault. In return, your page receives a token, a secure stand-in for the card that you use to send the payment to Revaly, both at checkout and for any later retries. Your checkout page stays fully under your control, and your systems never receive, transmit, store, or log the full card number (PAN) or CVV.
This integration offers:
- Upfront Approval for customer-initiated payments: Revaly sees and optimizes each checkout payment before it reaches your gateway, on the first attempt.
- Gateway-agnostic tokens: The card is not tied to a single gateway's vault. Vault tokens can be processed on any gateway connected to your Revaly account.
- Seamless checkout experience: The secure fields sit inside your page and can be styled to match your design.
- Reduced PCI scope: Card data is captured and stored by the Revaly Vault, not by your servers.
This guide covers setting up the secure fields, tokenizing the card, and verifying the token. Once you have a verified token, you are ready to send the payment to Revaly.
NoteTo get started, you'll need an active Revaly account with a Revaly Vault provisioned. Please contact your Customer Success Manager (CSM) or Integration Manager to request your Vault credentials.
How It Works
The integration involves three parties: your checkout page (in the customer's browser), your server, and Revaly.
- Your checkout page loads and asks your server for the iframe configuration.
- Your server signs the configuration with your Vault Primary API Key and returns it to the page.
- The page passes the signed configuration to the Revaly Vault, which verifies the signature and renders the secure card number and CVV fields inside your page.
- Your customer enters their card details and clicks Pay. Your page asks the secure fields to tokenize.
- The card data goes directly to the Revaly Vault, which stores it and returns a token, card metadata, and a signature for the token (
tokenHMAC). - Your page sends the token to your server, which verifies the
tokenHMACsignature. - Your server sends the payment to Revaly with the token. Revaly applies its treatments and forwards the payment to your gateway.
NoteThe secure fields render inside your page, but they are served by the Revaly Vault. Your customer sees a seamless checkout, while your page and servers never have access to what is typed in the card number and CVV fields.
Two signatures protect this flow, and both use your Vault Primary API Key:
| Signature | Created by | Verified by | Purpose |
|---|---|---|---|
| Authentication Key | Your server | Revaly Vault | Proves the request to render the secure fields comes from you. |
| tokenHMAC | Revaly Vault | Your server | Proves the token was issued by the vault and was not altered in the browser. |
Before You Begin
What Revaly provides
| Item | Purpose |
|---|---|
Vault ID (tokenExID) | Identifies your vault. |
| Vault Primary API Key | Used server-side only to generate the iframe Authentication Key and to verify the returned tokenHMAC. |
| Token Scheme | Controls the format of the tokens issued by the vault (for example, PCI). |
What you provide
- Server IP addresses: Share the IP addresses of your checkout and servers with your Revaly contact so they can be whitelisted.
- An HTTPS checkout page: In production, the page hosting the secure fields must be served over HTTPS.
- A server-side endpoint that generates the iframe configuration, so your API key never reaches the browser.
Security Requirements
- Never expose your Vault Primary API Key in browser code, and never commit it to source control.
- Always generate the Authentication Key server-side.
- Always verify the
tokenHMACserver-side before using a token.- Use the Primary API Key only. The
tokenHMACis computed with the Primary key, so verification with any other key will always fail.- Never log, store, or attempt to read the PAN or CVV. Only log safe values such as
referenceNumber,cardType,firstSix, andlastFour.
Step 1: Generate the Iframe Configuration on Your Server
Create a server-side endpoint (for example, GET /vault/iframe-config) that your checkout page calls before rendering the secure fields. This endpoint returns the configuration values the iframe needs, including a short-lived Authentication Key.
The Authentication Key is a Base64-encoded HMAC-SHA256 hash, computed with your Vault Primary API Key over the following pipe-delimited string:
{tokenExID}|{origin}|{timestamp}|{tokenScheme}| Field | Description |
|---|---|
tokenExID | Your Vault ID. |
origin | The exact origin of the checkout page loading the iframe (for example, https://checkout.example.com). Must use HTTPS in production. |
timestamp | Current UTC time in yyyyMMddHHmmss format. The Authentication Key is valid for 20 minutes. |
tokenScheme | Your Token Scheme. Must exactly match the tokenScheme value used in the iframe configuration. |
const crypto = require('crypto');
function generateIframeConfig() {
const tokenExID = process.env.REVALY_VAULT_ID;
const primaryKey = process.env.REVALY_VAULT_PRIMARY_API_KEY;
const tokenScheme = process.env.REVALY_VAULT_TOKEN_SCHEME; // e.g. 'PCI'
const origin = 'https://checkout.example.com'; // your checkout page origin
// UTC timestamp in yyyyMMddHHmmss format
const timestamp = new Date().toISOString().replace(/[^0-9]/g, '').slice(0, 14);
const payload = `${tokenExID}|${origin}|${timestamp}|${tokenScheme}`;
const authenticationKey = crypto
.createHmac('sha256', primaryKey)
.update(payload)
.digest('base64');
return { tokenExID, origin, timestamp, tokenScheme, authenticationKey };
}Example response from your endpoint:
{
"tokenExID": "123456789",
"origin": "https://checkout.example.com",
"timestamp": "20260925143000",
"tokenScheme": "PCI",
"authenticationKey": "Base64HmacFromServer=="
}
NoteGenerate a fresh Authentication Key on every page load. A key older than 20 minutes will be rejected.
Step 2: Add the Card Field Containers to Your Checkout Page
Add two empty containers where the secure card number and CVV fields will render. Other fields that are not sensitive, such as cardholder name and expiry date, can remain regular fields on your page.
<form id="checkoutForm">
<label>Card number</label>
<div id="cardNumberContainer"></div>
<label>CVV</label>
<div id="cvvContainer"></div>
<button type="button" id="payBtn">Pay</button>
</form>You can style the rest of your checkout page as usual. The inputs inside the secure fields are styled through the iframe configuration (see Step 4).
Step 3: Load the Iframe Library
Add the iframe library to your checkout page, using the script URL for your vault's environment.
| Environment | Script URL |
|---|---|
| US Production | https://htp.tokenex.com/iframe/iframe-v3.min.js |
| EU Production | https://eu1-htp.tokenex.com/iframe/iframe-v3.min.js |
<script src="https://htp.tokenex.com/iframe/iframe-v3.min.js"></script>
ImportantThe script URL must match the environment of your vault. Loading the test library with a production vault (or the reverse) will cause the secure fields to fail with an
Invalid Authentication Keyerror.
Step 4: Initialize the Secure Fields
Fetch the configuration from your server, then create and load the iframe.
fetch('/vault/iframe-config')
.then(response => response.json())
.then(config => {
const iframe = new TokenEx.Iframe('cardNumberContainer', {
...config, // tokenExID, origin, timestamp, tokenScheme, authenticationKey
pci: true, // capture the card number
cvv: true, // also capture the CVV
cvvContainerID: 'cvvContainer', // where the CVV field renders
useExtendedBIN: true, // return firstEight in the tokenize response
styles: {
base: 'font-family: Arial, sans-serif; padding: 0 8px; border: 1px solid rgba(0,0,0,0.2); margin: 0; width: 100%; font-size: 13px; line-height: 30px; height: 32px; box-sizing: border-box;',
focus: 'box-shadow: 0 0 6px 0 rgba(0,132,255,0.5); border: 1px solid rgba(0,132,255,0.5); outline: 0;',
error: 'box-shadow: 0 0 6px 0 rgba(224,57,57,0.5); border: 1px solid rgba(224,57,57,0.5);',
placeholder: 'color: #aaa;'
}
});
iframe.on('load', () => {
// Secure fields are ready: enable your Pay button
});
iframe.on('validate', data => {
console.log('Validation result', data);
});
iframe.on('tokenize', data => {
submitTokenToServer(data); // see Step 5
});
iframe.on('error', error => {
// Show a friendly message and log error.referenceNumber
});
iframe.on('expired', () => {
// The Authentication Key expired: fetch a new config and reload the fields
});
iframe.load();
document.getElementById('payBtn').addEventListener('click', () => {
iframe.tokenize();
});
});Configuration options
| Option | Description |
|---|---|
tokenExID, origin, timestamp, tokenScheme, authenticationKey | Values returned by your server in Step 1. |
pci | Set to true to capture the card number. |
cvv | Set to true to also capture the CVV. |
cvvContainerID | The ID of the container where the CVV field renders. |
useExtendedBIN | Set to true to receive the first eight digits of the card (firstEight), which improves routing and optimization. |
styles | CSS applied to the inputs inside the secure fields: base, focus, error, and placeholder. The CVV field is styled through the nested cvv object. If it is omitted, the CVV field renders unstyled. |
Iframe events
| Event | When it happens | Recommended action |
|---|---|---|
load | The secure fields have rendered. | Enable the Pay button or hide your loading indicator. |
validate | Field validation runs. | Display validation errors to the customer. |
cardTypeChange | The card brand is detected. | Optionally display the card brand icon. |
tokenize | Tokenization succeeded. | Send the full tokenization payload to your server. |
error | An iframe command failed. | Show a friendly message and log the referenceNumber. |
expired | The Authentication Key expired. | Request a new configuration and reload the secure fields. |
Step 5: Send the Token to Your Server
When tokenization succeeds, the tokenize event returns the token and card metadata:
{
"firstSix": "545454",
"firstEight": "54545454",
"lastFour": "5454",
"cardType": "masterCard",
"token": "545454R5F6RR5454",
"referenceNumber": "18022410572868097790",
"tokenHMAC": "RqMhITN57i2WkDZLeoUc0MK71zT8zLnonzTKdyeCq0k="
}{
"firstSix": "378282",
"lastFour": "0005",
"cardType": "americanExpress",
"token": "378282R5F6RR0005",
"referenceNumber": "18022410572868097791",
"tokenHMAC": "abc123...="
}Send the full payload to your server, not only the token:
function submitTokenToServer(data) {
fetch('/api/pay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: data.token,
firstSix: data.firstSix,
firstEight: data.firstEight,
lastFour: data.lastFour,
cardType: data.cardType,
referenceNumber: data.referenceNumber,
tokenHMAC: data.tokenHMAC
})
});
}| Field | Required | Notes |
|---|---|---|
token | Yes | The vault token. |
tokenHMAC | Yes | Must be verified server-side before trusting the token (see Step 6). |
cardType | Yes | Card brand. |
firstSix | Yes | Standard BIN. |
lastFour | Yes | Last four digits, for support and receipts. |
firstEight | When present | Extended BIN used by Revaly for routing and optimization. It is expected to be missing for American Express cards. |
referenceNumber | Recommended | Useful when troubleshooting with Revaly support. |
Step 6: Verify the tokenHMAC on Your Server
Because tokenization happens in the browser, your server must confirm the token is genuine before using it:
- Take the returned
token. - Compute an HMAC-SHA256 of the token using your Vault Primary API Key.
- Base64-encode the result.
- Compare it to the returned
tokenHMAC. - Reject the token if the values do not match.
const crypto = require('crypto');
function isTokenValid(token, tokenHMAC) {
const expected = crypto
.createHmac('sha256', process.env.REVALY_VAULT_PRIMARY_API_KEY)
.update(token)
.digest('base64');
const a = Buffer.from(expected);
const b = Buffer.from(tokenHMAC || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Next Step: Send the Payment to Revaly
Once the tokenHMAC is verified, your server sends the customer-initiated payment to Revaly, which applies its treatments and forwards it to your gateway. See the integration guides for the full flow.
Pass the token to the Revaly API as a vault token payment method, mapping the tokenization payload as follows:
| Tokenize payload | Revaly API field |
|---|---|
token | paymentMethod.vaultPaymentMethod.vaultToken |
firstEight (or firstSix when firstEight is not returned) | paymentMethod.vaultPaymentMethod.bin |
lastFour | paymentMethod.vaultPaymentMethod.lastFourDigits |
{
"paymentMethodType": "vaultToken",
"amount": 3000,
"currency": "USD",
"merchantTransactionId": "checkout_txn_111",
"orderId": "order_98765",
"customerId": "customer_456789",
"customerIp": "172.16.0.25",
"initiatedBy": "CIT",
"description": "Premium Monthly Plan - first payment",
"paymentMethod": {
"fullName": "John Doe",
"email": "[email protected]",
"merchantAccountReferenceId": "Test-USD",
"vaultPaymentMethod": {
"vaultToken": "545454R5F6RR5454",
"bin": "54545454",
"lastFourDigits": "5454",
"expiryMonth": "12",
"expiryYear": "2028"
}
},
"recovery": {
"customerAccountNumber": "ACC-456789",
"customerBalance": 1922,
"retryCount": 0
},
"paymentPlanData": {
"sku": "PREMIUM_MONTHLY",
"category": "FDT",
"billingPlan": "monthly",
"billingCycle": 1,
"productDisplayName": "Premium Monthly Plan",
"paymentModel": "recurring",
"subscriptionId": "sub_def456ghi789"
}
}
NoteThe secure fields capture the card number and CVV only. Collect the cardholder name and expiry date in your own form fields and include them in your payment request.
For the complete request, required fields, and responses, refer to Process a payment (charge).
Keep the Token for Retries
The token is not only for the checkout payment. If the payment is declined and enters recovery, the same token is the payment method used for the subsequent attempts, so store it securely.
Revaly also returns the vault token in the payment response (paymentMethod.vaultToken). If the card is replaced through the Account Updater, the returned value may differ from the token you sent, so when a value is returned, store the latest one.
How the token is used for retries depends on your integration:
- Enterprise: You retry the payment. Send each retry to Revaly with the stored token following the retry timing recommended by Revaly.
- Enterprise with Scheduler: Revaly schedules and processes the retries for you using the token, and notifies you of the outcome through webhooks. No retry requests are needed from your side.
CVV Retention
By default, the Revaly Vault retains the CVV for 7 days from tokenization to support authorization retries and recovery flows.
- No configuration is required in the iframe or in your requests.
- The CVV is never returned to you and should never be logged.
- Revaly uses the retained CVV only within the secure vault environment.
If an acquirer, regulatory, or internal policy requirement does not allow this retention window, let your Revaly contact know during onboarding.
Testing Your Integration
Before going live, confirm that you have tested:
- Successful tokenization for each card brand you support.
- Validation errors for an empty or invalid card number and an invalid CVV length.
- The
expiredevent and reloading the secure fields. - Server-side
tokenHMACverification, including rejection of an invalid value. - That the full tokenization payload reaches your server.
- User-friendly error messages at checkout.
- That your logs never contain the PAN or CVV.
Go-Live Checklist
- Production Vault ID, Vault Primary API Key, and Token Scheme received from Revaly and stored securely on your server.
- Server IP addresses whitelisted with Revaly.
- Checkout page served over HTTPS, with the
originin your configuration matching it exactly. - Production iframe script URL in use.
pci: true,cvv: true,cvvContainerID, anduseExtendedBIN: trueconfigured.- Secure field styles defined, including the nested
cvvstyles. - Server verifies every
tokenHMACusing the Primary API Key. - Server sends the verified token and card metadata to Revaly.
- Token and
customerIdstored for retries (Enterprise integrations). expiredanderrorevents handled.- Logs contain no PAN or CVV.
Troubleshooting
| Symptom | Likely cause | Resolution |
|---|---|---|
| Secure fields do not appear | The iframe library did not load, or your IP addresses are not whitelisted. | Check the browser console for errors and confirm your IPs are whitelisted with Revaly. |
Invalid Authentication Key | The signed values do not match what the vault expects. | Confirm the script URL matches your vault's environment, and check tokenExID, origin, timestamp, tokenScheme, and that the Primary API Key was used. |
Origin must use HTTPs | The checkout page is served over HTTP in production. | Serve the checkout page over HTTPS and use the HTTPS origin in your configuration. |
| Authentication works at first, then fails | The Authentication Key is older than 20 minutes. | Generate a fresh Authentication Key on each page load and handle the expired event. |
firstEight is missing | The card number is shorter than 16 digits (for example, American Express), or useExtendedBIN is not enabled. | Set useExtendedBIN: true. A missing firstEight is expected for American Express. |
| Token rejected by your server | The tokenHMAC was verified with a key other than the Primary API Key. | Use the Vault Primary API Key for both the Authentication Key and tokenHMAC verification. |
| Works in test but not in production | The script URL, credentials, or whitelisting are still set for test. | Confirm production credentials, the production script URL, and IP whitelisting. |
Support
For integration assistance, contact your Revaly Customer Success Manager or Revaly Support. To help us troubleshoot quickly, please include:
- Your Vault ID.
- The date and time of the issue.
- The
referenceNumberfrom the iframe event. - The error message.
- The card brand used.
- Whether the issue occurred during iframe load, validation, or tokenization.
Updated about 8 hours ago

