Skip to main content

OzVault

The main SDK entry point. Manages all payment fields and vault credentials.
Always create OzVault via the async static factory OzVault.create(). Never call new OzVault(...) directly.

OzVault.create

OzVault.create(options: VaultOptions, signal?: AbortSignal): Promise<OzVault>
Initializes the vault and calls fetchWaxKey. Resolves once the wax key is obtained — you can create and mount elements immediately after. The vault is ready to tokenize once onReady fires (or vault.isReady === true); the underlying iframe load happens concurrently and may already be complete by the time create() resolves. The optional signal parameter is an AbortSignal for advanced teardown scenarios. The React <OzElements> provider handles this automatically.
onReady fires before OzVault.create() resolves. Because the tokenizer iframe loads concurrently with your fetchWaxKey call, the onReady callback may fire while await OzVault.create(...) is still pending. At that moment, the vault variable in the surrounding code is still undefined. Do not reference vault (or call vault.createElement()) inside the onReady callback. Declare readiness flags before calling create() so they are accessible when the callback runs.

VaultOptions

type VaultOptions = {
  pubKey:             string;                                    // required
  fetchWaxKey:        (tokenizationSessionId: string) => Promise<string>;  // required
  frameBaseUrl?:      string;                                    // default: 'https://elements.ozura.com'
  fonts?:             FontSource[];
  appearance?:        Appearance;
  onLoadError?:       () => void;
  loadTimeoutMs?:     number;                                    // default: 10000 (ms); requires onLoadError
  onWaxRefresh?:      () => void;
  onReady?:           () => void;
  maxTokenizeCalls?:  number;                                    // default: 3; must match server mintWaxKey call
};
OptionTypeRequiredDefaultDescription
pubKeystringYour Vault pub key
fetchWaxKey(tokenizationSessionId: string) => Promise<string>Callback to obtain a session wax key from your backend
frameBaseUrlstringhttps://elements.ozura.comOverride where iframe assets are served from
fontsFontSource[][]Custom web fonts to load inside iframes
appearanceAppearanceGlobal theme and CSS variable overrides
onLoadError() => voidCalled if the vault fails to load within loadTimeoutMs
loadTimeoutMsnumber10000Requires onLoadError to be set. Setting this without onLoadError is silently ignored.
onWaxRefresh() => voidCalled when the SDK silently re-mints the wax key during a tokenization attempt
onReady() => voidCalled once when the vault is ready (vanilla JS). In React use useOzElements().ready instead.
maxTokenizeCallsnumber3Max successful createToken/createBankToken calls per wax key before proactive refresh. Must match the maxTokenizeCalls value passed to ozura.mintWaxKey() on your server.

Properties

PropertyTypeDescription
isReadybooleantrue once the vault is ready to tokenize. In vanilla JS, gate your submit button on this plus each element’s 'ready' event. In React, use useOzElements().ready instead — it combines both checks automatically.
tokenizeCountnumberCount of successful createToken()/createBankToken() calls against the current wax key. Resets to 0 on every wax key refresh. Use this to display remaining-attempt feedback or gate the submit button once maxTokenizeCalls is exhausted. In React, prefer useOzElements().tokenizeCount — it is reactive state.

Methods

createElement

vault.createElement(type: ElementType, options?: ElementOptions): OzElement
Creates a card input element. Call .mount() on the result to attach it to the DOM. ElementType values: 'cardNumber' | 'expirationDate' | 'cvv'

getElement

vault.getElement(type: ElementType): OzElement | null
Returns the existing element of the given type, or null.

createBankElement

vault.createBankElement(type: BankElementType, options?: ElementOptions): OzElement
Creates a bank account input element. BankElementType values: 'accountNumber' | 'routingNumber'

getBankElement

vault.getBankElement(type: BankElementType): OzElement | null
Returns the existing bank element of the given type, or null.

createToken

vault.createToken(options?: TokenizeOptions): Promise<TokenResponse>
Tokenizes all mounted card elements. Throws OzError on failure.
Tokenization timeout: If the vault does not respond within 30 seconds, createToken() rejects with an OzError (errorCode: 'timeout'). This timeout is separate from the element iframe load timeout (loadTimeoutMs) and is not configurable.

createBankToken

vault.createBankToken(options: BankTokenizeOptions): Promise<BankTokenResponse>
Tokenizes all mounted bank elements. Throws OzError on failure. Same 30-second timeout applies.

destroy

vault.destroy(): void
Cleans up all payment field iframes and listeners. Call this when the checkout component unmounts.

OzElement

Returned by createElement() and createBankElement(). Represents a single input field.

Properties

PropertyTypeDescription
typeElementType | BankElementTypeThe element type
isReadybooleantrue once the iframe has loaded

Methods

mount

el.mount(target: string | HTMLElement): void
Attaches the iframe to the DOM. target can be a CSS selector string or an HTMLElement.

unmount

el.unmount(): void
Removes the iframe from the DOM and resets internal state, but does not destroy the element. The element can be re-mounted after calling unmount(). Use destroy() for permanent teardown.

on

el.on(event: ElementEvent, callback: (payload?) => void): this
Registers an event listener. Returns this for chaining.

off

el.off(event: ElementEvent, callback: (payload?) => void): this
Removes a previously registered event listener.

once

el.once(event: ElementEvent, callback: (payload?) => void): this
Registers a one-time event listener that fires once then removes itself.

update

el.update(options: Partial<ElementOptions>): void
Updates element options (style, placeholder, disabled) without re-mounting the iframe. Style update semantics:
  • Properties you include are merged into the current style — they replace their previous values.
  • Properties previously set but absent from the new style object retain their current values (no keys are cleared by omission).
  • To reset a specific property, pass it explicitly with an empty string: { base: { color: '' } }.
  • To fully reset all styles, destroy and recreate the element.
  • Vault-level appearance theme styles are always preserved underneath — per-element style merges on top.

focus

el.focus(): void
Programmatically focuses the input inside the iframe.

blur

el.blur(): void
Programmatically blurs the input.

clear

el.clear(): void
Clears the current value.

destroy

el.destroy(): void
Permanently removes the iframe, clears all event handlers, and prevents future use. Distinct from unmount().

Events

type ElementEvent = 'ready' | 'change' | 'focus' | 'blur' | 'loaderror';

change

el.on('change', (event: ElementChangeEvent) => void)
Fired whenever the value or state changes.
type ElementChangeEvent = {
  empty:      boolean;    // true when the field has no input
  complete:   boolean;    // field has reached the required length/format — does NOT imply valid (check `valid` separately)
  valid:      boolean;    // value passes full validation (Luhn, expiry in future, etc.)
  error?:     string;     // human-readable error message, or undefined
  cardBrand?: string;     // card brand (cardNumber element only)
  month?:     string;     // parsed month '01'–'12' (expirationDate element only)
  year?:      string;     // parsed 2-digit year e.g. '27' (expirationDate element only)
};

focus / blur

el.on('focus', () => void)
el.on('blur',  (data: { empty: boolean, complete: boolean, valid: boolean, error: string | undefined }) => void)
Fired when the iframe input gains or loses focus. The blur callback receives the current field state.

ready

el.on('ready', () => void)
Fired once the iframe has fully loaded and is interactive.

loaderror

el.on('loaderror', (data: { elementType: string, error: string }) => void)
Fired if the iframe fails to load within loadTimeoutMs. Receives the element type and an error message.

TokenizeOptions

type TokenizeOptions = {
  billing?:   BillingDetails;
  firstName?: string;   // deprecated — use billing.firstName
  lastName?:  string;   // deprecated — use billing.lastName
};

TokenResponse

type TokenResponse = {
  token:      string;
  cvcSession: string;   // always present on success; SDK rejects before returning if absent
  card?: {              // present when vault returns complete card metadata
    last4:    string;   // last 4 digits of card number
    brand:    string;   // 'visa' | 'mastercard' | 'amex' | ...
    expMonth: string;   // '01'–'12'
    expYear:  string;   // '2026', '2027', …
  };
  billing?: BillingDetails;  // validated+normalized — present only when passed to createToken()
};

BillingDetails

type BillingDetails = {
  firstName: string;          // required, 1–50 chars
  lastName:  string;          // required, 1–50 chars
  email?:    string;          // valid email, max 50 chars
  phone?:    string;          // E.164 format, e.g. '+15551234567'
  address?:  BillingAddress;
};

type BillingAddress = {
  line1:    string;   // required
  line2?:   string;   // optional
  city:     string;   // required
  state:    string;   // required; US/CA normalized to 2-letter code
  zip:      string;   // required
  country:  string;   // ISO 3166-1 alpha-2, e.g. 'US'
};

BankTokenizeOptions

type BankTokenizeOptions = {
  firstName: string;   // required
  lastName:  string;   // required
};

BankTokenResponse

type BankTokenResponse = {
  token: string;
  bank?: {
    last4:              string;  // last 4 digits of account number
    routingNumberLast4: string;  // last 4 digits of routing number
  };
};

CardSaleApiResponse

The raw response envelope from the Pay API cardSale endpoint. Only relevant when calling the API directly via fetch — the server SDK’s Ozura.cardSale() throws OzuraError on failure rather than returning this shape.
interface CardSaleApiResponse {
  success: boolean;
  data?:   CardSaleResponseData;  // present on success only
  error?:  string;                // present on failure — pass to normalizeCardSaleError()
}

ElementOptions

type ElementOptions = {
  style?:         ElementStyleConfig;
  placeholder?:   string;
  disabled?:      boolean;
  loadTimeoutMs?: number;   // ms before loaderror fires on this element; default 10000. Requires onLoadError on this element OR VaultOptions.onLoadError.
};

ElementStyleConfig

type ElementStyleConfig = {
  base?:        ElementStyle;
  focus?:       ElementStyle;
  invalid?:     ElementStyle;
  complete?:    ElementStyle;
  placeholder?: ElementStyle;
};
See the Styling guide for the full list of supported ElementStyle keys.

Appearance

type Appearance = {
  theme?:     OzTheme;              // 'default' | 'night' | 'flat'
  variables?: AppearanceVariables;
};

type OzTheme = 'default' | 'night' | 'flat';

type AppearanceVariables = {
  colorText?:        string;  // maps to base.color
  colorBackground?:  string;  // maps to base.backgroundColor
  colorPrimary?:     string;  // maps to base.caretColor and focus.caretColor
  colorDanger?:      string;  // maps to invalid.color
  colorSuccess?:     string;  // maps to complete.color
  colorPlaceholder?: string;  // maps to placeholder.color
  fontFamily?:       string;  // maps to base.fontFamily
  fontSize?:         string;  // maps to base.fontSize
  fontWeight?:       string;  // maps to base.fontWeight
  letterSpacing?:    string;  // maps to base.letterSpacing
  lineHeight?:       string;  // maps to base.lineHeight
  padding?:          string;  // maps to base.padding
};

FontSource

// Google Fonts / remote CSS
type CssFontSource = { cssSrc: string };

// Self-hosted @font-face
type CustomFontSource = {
  family:        string;
  src:           string;   // url(https://...) value
  weight?:       string;
  style?:        string;
  display?:      string;
  unicodeRange?: string;
};

type FontSource = CssFontSource | CustomFontSource;

OzError

class OzError extends Error {
  message:    string;        // normalized, user-facing message
  errorCode:  OzErrorCode;   // machine-readable code
  raw:        string;        // raw vault API message (use for logging)
  retryable:  boolean;       // true for network, timeout, server errors
}

type OzErrorCode =
  | 'network'
  | 'auth'
  | 'validation'
  | 'server'
  | 'timeout'
  | 'config'
  | 'unknown';

React Types

OzElementsProps

type OzElementsProps = {
  pubKey:             string;                                               // required
  fetchWaxKey:        (tokenizationSessionId: string) => Promise<string>;  // required
  children:           ReactNode;                                            // required
  frameBaseUrl?:      string;
  fonts?:             FontSource[];
  appearance?:        Appearance;
  onLoadError?:       () => void;
  loadTimeoutMs?:     number;
  onWaxRefresh?:      () => void;
  onReady?:           () => void;
  maxTokenizeCalls?:  number;  // default 3; must match server mintWaxKey call
};

UseOzElementsReturn

type UseOzElementsReturn = {
  createToken:     (options?: TokenizeOptions) => Promise<TokenResponse>;
  createBankToken: (options: BankTokenizeOptions) => Promise<BankTokenResponse>;
  ready:           boolean;         // vault + all mounted fields ready
  initError:       Error | null;
  tokenizeCount:   number;          // successful createToken/createBankToken calls since last wax key refresh
};

OzFieldProps

type OzFieldProps = {
  style?:         ElementStyleConfig;
  placeholder?:   string;
  disabled?:      boolean;
  loadTimeoutMs?: number;
  className?:     string;
  onChange?:      (event: ElementChangeEvent) => void;
  onFocus?:       () => void;
  onBlur?:        () => void;
  onReady?:       () => void;
  onLoadError?:   (error: string) => void;
};

OzCardState

type OzCardState = {
  complete:   boolean;
  cardBrand?: string;
  error?:     string;
  fields: {
    cardNumber: ElementChangeEvent | null;
    expiry:     ElementChangeEvent | null;
    cvv:        ElementChangeEvent | null;
  };
};

OzBankCardState

type OzBankCardState = {
  complete: boolean;
  error?:   string;
  fields: {
    accountNumber: ElementChangeEvent | null;
    routingNumber: ElementChangeEvent | null;
  };
};

createFetchWaxKey

import { createFetchWaxKey } from '@ozura/elements';
// or
import { createFetchWaxKey } from '@ozura/elements/react';
A helper factory that creates a fetchWaxKey callback for a given backend URL:
createFetchWaxKey(url: string): (tokenizationSessionId: string) => Promise<string>
It POSTs { sessionId: tokenizationSessionId } to the URL and expects { waxKey: string } in return.
const vault = await OzVault.create({
  pubKey:      'YOUR_PUB_KEY',
  fetchWaxKey: createFetchWaxKey('/api/mint-wax'),
});
Timeout and retry behavior: Each fetch attempt enforces a 10-second timeout. On pure network failures (connection refused, DNS, offline), the call retries once after 750 ms. HTTP errors (4xx/5xx) are never retried — they indicate endpoint misconfiguration or invalid credentials. Errors thrown by createFetchWaxKey are OzError instances with a structured errorCode ('timeout' | 'network' | 'auth' | 'validation' | 'server').

Exports

@ozura/elements

The browser entry. Exports everything needed to initialize the vault, mount fields, tokenize, and handle errors. The Transaction* and CardSale* types are re-exported here for TypeScript convenience but are primarily used with @ozura/elements/server.
export { OzVault };
export { OzElement };
export { OzError, normalizeVaultError, normalizeBankVaultError, normalizeCardSaleError };
export { createFetchWaxKey };
export type {
  ElementType, BankElementType,
  ElementOptions, ElementStyleConfig, ElementStyle, ElementChangeEvent,
  VaultOptions,
  TokenizeOptions, TokenResponse, CardMetadata,
  BankTokenizeOptions, BankTokenResponse, BankAccountMetadata,
  BillingDetails, BillingAddress,
  CardSaleRequest, CardSaleResponseData, CardSaleApiResponse,
  FontSource, CssFontSource, CustomFontSource,
  Appearance, AppearanceVariables, OzTheme,
  TransactionQueryParams, TransactionQueryPagination, TransactionQueryResponse,
  TransactionType, CardTransactionType, AchTransactionType, CryptoTransactionType,
  TransactionBase, CardTransactionData, AchTransactionData, CryptoTransactionData,
  TransactionData,
  OzErrorCode,
};

@ozura/elements/react

export { OzElements };
export { useOzElements };
export { OzCardNumber, OzExpiry, OzCvv };
export { OzCard };
export { OzBankAccountNumber, OzBankRoutingNumber };
export { OzBankCard };
export { createFetchWaxKey };
export type {
  OzFieldProps,
  OzCardProps, OzCardState,
  OzBankCardProps, OzBankCardState,
  OzElementsProps,
  UseOzElementsReturn,
  ElementChangeEvent,
  TokenizeOptions, TokenResponse, CardMetadata,
  BankTokenizeOptions, BankTokenResponse, BankAccountMetadata,
  BankElementType,
  Appearance, AppearanceVariables, OzTheme,
  OzErrorCode,
};

@ozura/elements/server

Server-side entry — use in your Node.js / Express / Next.js backend only. Do not import in browser code.
export { Ozura };
export { OzuraError };
export { getClientIp };
export { createMintWaxHandler, createMintWaxMiddleware };
export { createCardSaleHandler, createCardSaleMiddleware };
export { normalizeCardSaleError };

// Interfaces declared in this module
export interface OzuraConfig { … }
export class OzuraError { … }        // fields: message, statusCode, raw, retryAfter
export interface MintWaxKeyOptions { … }
export interface MintWaxKeyResult { … }
export interface CardSaleInput { … }
export interface CardSaleHandlerOptions { … }
export interface ListTransactionsInput { … }
export interface ListTransactionsResult { … }

// Types re-exported from shared types
export type {
  BillingDetails,
  CardSaleResponseData,
  TransactionQueryPagination,
  TransactionType,
  TransactionBase,
  CardTransactionData,
  AchTransactionData,
  CryptoTransactionData,
  TransactionData,
};