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.

📘

Note

To 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.

  1. Your checkout page loads and asks your server for the iframe configuration.
  2. Your server signs the configuration with your Vault Primary API Key and returns it to the page.
  3. 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.
  4. Your customer enters their card details and clicks Pay. Your page asks the secure fields to tokenize.
  5. 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).
  6. Your page sends the token to your server, which verifies the tokenHMAC signature.
  7. Your server sends the payment to Revaly with the token. Revaly applies its treatments and forwards the payment to your gateway.
📘

Note

The 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:

SignatureCreated byVerified byPurpose
Authentication KeyYour serverRevaly VaultProves the request to render the secure fields comes from you.
tokenHMACRevaly VaultYour serverProves the token was issued by the vault and was not altered in the browser.

Before You Begin

What Revaly provides

ItemPurpose
Vault ID (tokenExID)Identifies your vault.
Vault Primary API KeyUsed server-side only to generate the iframe Authentication Key and to verify the returned tokenHMAC.
Token SchemeControls 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 tokenHMAC server-side before using a token.
  • Use the Primary API Key only. The tokenHMAC is 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, and lastFour.

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}
FieldDescription
tokenExIDYour Vault ID.
originThe exact origin of the checkout page loading the iframe (for example, https://checkout.example.com). Must use HTTPS in production.
timestampCurrent UTC time in yyyyMMddHHmmss format. The Authentication Key is valid for 20 minutes.
tokenSchemeYour 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=="
}
📘

Note

Generate 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.

EnvironmentScript URL
US Productionhttps://htp.tokenex.com/iframe/iframe-v3.min.js
EU Productionhttps://eu1-htp.tokenex.com/iframe/iframe-v3.min.js
<script src="https://htp.tokenex.com/iframe/iframe-v3.min.js"></script>
🚧

Important

The 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 Key error.


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

OptionDescription
tokenExID, origin, timestamp, tokenScheme, authenticationKeyValues returned by your server in Step 1.
pciSet to true to capture the card number.
cvvSet to true to also capture the CVV.
cvvContainerIDThe ID of the container where the CVV field renders.
useExtendedBINSet to true to receive the first eight digits of the card (firstEight), which improves routing and optimization.
stylesCSS 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

EventWhen it happensRecommended action
loadThe secure fields have rendered.Enable the Pay button or hide your loading indicator.
validateField validation runs.Display validation errors to the customer.
cardTypeChangeThe card brand is detected.Optionally display the card brand icon.
tokenizeTokenization succeeded.Send the full tokenization payload to your server.
errorAn iframe command failed.Show a friendly message and log the referenceNumber.
expiredThe 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
    })
  });
}
FieldRequiredNotes
tokenYesThe vault token.
tokenHMACYesMust be verified server-side before trusting the token (see Step 6).
cardTypeYesCard brand.
firstSixYesStandard BIN.
lastFourYesLast four digits, for support and receipts.
firstEightWhen presentExtended BIN used by Revaly for routing and optimization. It is expected to be missing for American Express cards.
referenceNumberRecommendedUseful 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:

  1. Take the returned token.
  2. Compute an HMAC-SHA256 of the token using your Vault Primary API Key.
  3. Base64-encode the result.
  4. Compare it to the returned tokenHMAC.
  5. 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 payloadRevaly API field
tokenpaymentMethod.vaultPaymentMethod.vaultToken
firstEight (or firstSix when firstEight is not returned)paymentMethod.vaultPaymentMethod.bin
lastFourpaymentMethod.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"
  }
}
📘

Note

The 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 expired event and reloading the secure fields.
  • Server-side tokenHMAC verification, 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 origin in your configuration matching it exactly.
  • Production iframe script URL in use.
  • pci: true, cvv: true, cvvContainerID, and useExtendedBIN: true configured.
  • Secure field styles defined, including the nested cvv styles.
  • Server verifies every tokenHMAC using the Primary API Key.
  • Server sends the verified token and card metadata to Revaly.
  • Token and customerId stored for retries (Enterprise integrations).
  • expired and error events handled.
  • Logs contain no PAN or CVV.

Troubleshooting

SymptomLikely causeResolution
Secure fields do not appearThe 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 KeyThe 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 HTTPsThe 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 failsThe Authentication Key is older than 20 minutes.Generate a fresh Authentication Key on each page load and handle the expired event.
firstEight is missingThe 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 serverThe 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 productionThe 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 referenceNumber from the iframe event.
  • The error message.
  • The card brand used.
  • Whether the issue occurred during iframe load, validation, or tokenization.
🚧

Important

Never include card numbers or CVVs in support requests, screenshots, logs, or emails.


Did this page help you?