Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ozura.com/llms.txt

Use this file to discover all available pages before exploring further.


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, fetches a session, and loads the payment iframes. Resolves once the session is ready — you can create and mount elements immediately after. The vault is ready to tokenize once onReady fires (or vault.isReady === true). The optional signal parameter is an AbortSignal for advanced teardown scenarios. The React <OzElements> provider handles this automatically.
onReady fires before OzVault.create() resolves. Vault initialization runs multiple steps in parallel. The onReady callback may fire while await OzVault.create(...) is still pending, at which point the vault variable is still undefined. Do not reference vault (or call vault.createElement()) inside onReady. Declare readiness flags before calling create() so they are accessible when the callback runs.

VaultOptions

type VaultOptions = {
  pubKey:              string;                                   // required
  sessionUrl?:         string;                                   // required (one of these three)
  getSessionKey?:      (sessionId: string) => Promise<string>;  // required (one of these three)
  fetchWaxKey?:        (sessionId: string) => Promise<string>;  // deprecated — use sessionUrl or getSessionKey
  frameBaseUrl?:       string;                                   // default: 'https://elements.ozura.com'
  fonts?:              FontSource[];
  appearance?:         Appearance;
  onLoadError?:        () => void;
  loadTimeoutMs?:      number;                                   // default: 10000 (ms); requires onLoadError
  onSessionRefresh?:   () => void;
  onReady?:            () => void;
  sessionLimit?:       number | null;                            // default: 3; null = no cap; must match server createSession call
  debug?:              boolean;                                  // default: false; enables [OzVault] console.log output
};
OptionTypeRequiredDefaultDescription
pubKeystringYour Vault pub key
sessionUrlstring✅ ¹URL of your session endpoint. Simplest option — pass the path and the SDK handles everything.
getSessionKey(sessionId: string) => Promise<string>✅ ¹Custom callback for obtaining a session key. Use when you need custom headers or auth logic.
fetchWaxKey(sessionId: string) => Promise<string>✅ ¹Deprecated. Use sessionUrl or getSessionKey instead.
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.
onSessionRefresh() => voidCalled when the SDK silently refreshes the session during a tokenization attempt
onReady() => voidCalled once when the vault is ready (vanilla JS). In React use useOzElements().ready instead.
sessionLimitnumber | null3Max successful createToken/createBankToken calls per session before auto-refresh. Pass null to remove the cap. Must match the sessionLimit value passed to ozura.createSession() on your server.
debugbooleanfalseEnables structured [OzVault]-prefixed console.log output at every lifecycle event. Safe to use in production — no sensitive data is ever logged. See Debug mode.
¹ Exactly one of sessionUrl, getSessionKey, or fetchWaxKey is required.

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 in the current session. Resets to 0 on every session refresh. Use this to display remaining-attempt feedback or gate the submit button once sessionLimit 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.

reset

vault.reset(): void
Clears all mounted card and bank element fields without destroying the vault, refreshing the session, or resetting the tokenization budget. Call this after a declined or failed payment so the customer can re-enter their card details on the same checkout screen. The session key, its remaining budget, and all mounted iframes are fully preserved — no network calls are made.
Session model: by design, one session covers the full checkout. The default sessionLimit: 3 gives you two declined attempts and one final attempt on the same session. Use vault.reset() between declines instead of vault.destroy() + recreate — that would unnecessarily refresh the session and discard remaining budget.
try {
  const { token, cvcSession } = await vault.createToken({ billing });
  await chargeCard(token, cvcSession);
} catch (err) {
  vault.reset();                   // clear fields; let the customer re-enter
  showError(err instanceof OzError ? err.message : 'Payment failed.');
}

debugState

vault.debugState(): Record<string, unknown>
Returns a structured snapshot of the vault’s internal state. Always available regardless of whether debug: true is set. Safe to log or attach to a support ticket — no sensitive data is returned.
console.log(vault.debugState());
// {
//   vaultId: 'vault_abc12...',
//   isReady: true,
//   tokenizing: null,
//   destroyed: false,
//   waxKeyPresent: true,
//   tokenizeSuccessCount: 1,
//   maxTokenizeCalls: 3,
//   resetCount: 0,
//   elements: ['cardNumber', 'expirationDate', 'cvv'],
//   bankElements: [],
//   completionState: { 'a1b2c3d4': true, 'e5f6a7b8': true, 'c9d0e1f2': false },
//   pendingTokenizations: 0,
//   pendingBankTokenizations: 0,
// }

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
  sessionUrl?:         string;                                   // required (one of these three)
  getSessionKey?:      (sessionId: string) => Promise<string>;  // required (one of these three)
  fetchWaxKey?:        (sessionId: string) => Promise<string>;  // deprecated — use sessionUrl or getSessionKey
  children:            ReactNode;                                // required
  frameBaseUrl?:       string;
  fonts?:              FontSource[];
  appearance?:         Appearance;
  onLoadError?:        () => void;
  loadTimeoutMs?:      number;
  onSessionRefresh?:   () => void;
  onReady?:            () => void;
  sessionLimit?:       number | null;  // default 3; null = no cap; must match server createSession call
  debug?:              boolean; // default false; enables [OzVault] console.log output
};

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 in the current session
  reset:           () => void;      // clear all fields without destroying the vault or refreshing the session
};

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;
  };
};

createSessionFetcher

import { createSessionFetcher } from '@ozura/elements';
A helper factory that creates a getSessionKey callback for a given backend URL. You rarely need to call this directly — pass sessionUrl to OzVault.create() or <OzElements> and the SDK calls it internally.
createSessionFetcher(url: string): (sessionId: string) => Promise<string>
POSTs { sessionId } to the URL and reads sessionKey from the response. Useful when you need the callback form for custom headers or auth tokens:
const vault = await OzVault.create({
  pubKey: 'YOUR_PUB_KEY',
  getSessionKey: createSessionFetcher('/api/oz-session'),
});
Errors are OzError instances with a structured errorCode ('timeout' | 'network' | 'auth' | 'validation' | 'server').
createFetchWaxKey is a deprecated alias for createSessionFetcher. Both are exported and work identically.

Debug mode

Pass debug: true to VaultOptions (or as a prop on <OzElements debug>) to activate structured console logging.
const vault = await OzVault.create({
  pubKey: 'pk_live_...',
  sessionUrl: '/api/oz-session',
  debug: true,
});
Each log is a [OzVault] <event> prefixed console.log entry. Events covered:
EventDescription
vault createdConstructor completes
wax key received — vault readySession key resolved and stored; vault is ready to tokenize
mounting tokenizer iframeTokenizer iframe creation begins
tokenizer iframe readyTokenizer handshake complete
element iframe readyA card/bank input iframe loads
field changedPer-field value or state change
auto-advanceFocus moves between card fields automatically
createToken() calledEntry to createToken()
OZ_TOKENIZE sentTokenize request dispatched
token receivedToken result returned (includes elapsedMs)
token errorVault or network error during tokenize
proactive session key refresh triggeredSession budget exhausted; refresh starting
wax key refresh started / succeeded / failedSession key refresh lifecycle
tab hidden / tab visiblevisibilitychange events
reset() calledvault.reset() entry
destroy() calledvault.destroy() entry
No sensitive data is ever logged. Session keys, tokens, CVC sessions, and billing fields appear only as boolean presence flags. Output is safe to paste directly into bug reports. vault.debugState() is always available regardless of this flag — see vault.debugState() above.

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 { createSessionFetcher };
export { createFetchWaxKey };   // deprecated alias for createSessionFetcher
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 { createSessionFetcher };
export { createFetchWaxKey };   // deprecated alias for createSessionFetcher
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 { createSessionHandler, createSessionMiddleware };
/** @deprecated use createSessionHandler / createSessionMiddleware */
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 CreateSessionOptions {
  sessionId?:    string;                 // SDK-generated UUID; forwarded by your session endpoint
  sessionLimit?: number | null;          // default 3; null = no cap; must match VaultOptions.sessionLimit
  maxProxyCalls?: number | null;         // vault proxy call limit; omit for most integrations
  orderId?:      string;                 // your order ID — stored for transaction correlation
  customerId?:   string;                 // your customer ID — stored for transaction correlation
  cartId?:       string;                 // your cart ID — stored for transaction correlation
  metadata?:     Record<string, string>; // max 16 keys, 64-char keys, 256-char values
  ttlSeconds?:   number;                 // session TTL 60–1800s; default 1800 (30 min)
}
export interface CreateSessionResult { … }
export interface MintWaxKeyOptions { … }  // deprecated
export interface MintWaxKeyResult { … }   // deprecated
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,
};