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
};
| Option | Type | Required | Default | Description |
|---|
pubKey | string | ✅ | — | Your Vault pub key |
sessionUrl | string | ✅ ¹ | — | 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. |
frameBaseUrl | string | — | https://elements.ozura.com | Override where iframe assets are served from |
fonts | FontSource[] | — | [] | Custom web fonts to load inside iframes |
appearance | Appearance | — | — | Global theme and CSS variable overrides |
onLoadError | () => void | — | — | Called if the vault fails to load within loadTimeoutMs |
loadTimeoutMs | number | — | 10000 | Requires onLoadError to be set. Setting this without onLoadError is silently ignored. |
onSessionRefresh | () => void | — | — | Called when the SDK silently refreshes the session during a tokenization attempt |
onReady | () => void | — | — | Called once when the vault is ready (vanilla JS). In React use useOzElements().ready instead. |
sessionLimit | number | null | — | 3 | Max 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. |
debug | boolean | — | false | Enables 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
| Property | Type | Description |
|---|
isReady | boolean | true 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. |
tokenizeCount | number | Count 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
Cleans up all payment field iframes and listeners. Call this when the checkout component unmounts.
reset
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
| Property | Type | Description |
|---|
type | ElementType | BankElementType | The element type |
isReady | boolean | true 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
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.
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
Programmatically focuses the input inside the iframe.
blur
Programmatically blurs the input.
clear
Clears the current value.
destroy
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:
| Event | Description |
|---|
vault created | Constructor completes |
wax key received — vault ready | Session key resolved and stored; vault is ready to tokenize |
mounting tokenizer iframe | Tokenizer iframe creation begins |
tokenizer iframe ready | Tokenizer handshake complete |
element iframe ready | A card/bank input iframe loads |
field changed | Per-field value or state change |
auto-advance | Focus moves between card fields automatically |
createToken() called | Entry to createToken() |
OZ_TOKENIZE sent | Tokenize request dispatched |
token received | Token result returned (includes elapsedMs) |
token error | Vault or network error during tokenize |
proactive session key refresh triggered | Session budget exhausted; refresh starting |
wax key refresh started / succeeded / failed | Session key refresh lifecycle |
tab hidden / tab visible | visibilitychange events |
reset() called | vault.reset() entry |
destroy() called | vault.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,
};