npm / yarn
Pre-release builds (
@next): The next dist-tag contains unreleased changes before they reach latest. It is intended for Ozura-coordinated testing only — production credentials will not work with it. If you have been given access to pre-release testing, contact ammar@ozura.com for the matching staging credentials and setup instructions.npm install @ozura/elements (no tag) always resolves latest — @next has no impact on production installs.@ozura/elements/react requires React 17 or later as a peer dependency. If React is not already in your project, install it first:CDN (Script Tag)
If you’re not using a bundler, load the UMD build directly from the Ozura CDN:Local Development
The CDN blockslocalhost. For local development you have two options depending on how you load the SDK:
npm install (recommended)
If your project uses a bundler (webpack, Vite, Next.js, etc.),@ozura/elements is imported directly from node_modules — no CDN involved, no workaround needed. The iframes load from elements.ozura.com at runtime, but that uses <iframe src> which is not subject to the same CORS restriction.
CDN script tag on localhost
If you want to use the CDN<script> tag during local development, you need to serve the SDK file from the same origin as your page. Install the npm package and add a single route to your local server:
<script src> in your HTML from:
/frame/tokenizer-frame.js, /frame/element-frame.js) still load from elements.ozura.com — they are fetched via <iframe src>, not fetch, so CORS does not apply.
TypeScript
The package ships with full TypeScript definitions — no@types package needed. Import types directly:
Vault Project Types and the Pub Key
When you sign up at ozuravault.com, your first project is a test project by default. To create a production project, open the project dropdown in the top-left, select Create new project, and enable the Production switch. Test vault API key (test project): No pub key is required. You can omitpubKey entirely from OzVault.create(). This is the easiest way to get started — create an application in your test project and use that key for local development and testing.
Production vault API key:
A pub key is required and is tied to your registered domain. Production pub keys have domain restrictions and will not work on localhost. Contact ammar@ozura.com to obtain a production pub key for your domain.
Frame updates are automatic and backward compatible. The SDK always loads iframe files from
https://elements.ozura.com. Updates are delivered transparently — no npm update is required. frameBaseUrl is a local development option only — do not set it in production code.Credentials
Which credentials do you need?| Goal | Required credentials |
|---|---|
| Tokenize card / bank data only (no charging) | Vault API key (+ pub key for production vault keys) |
| Charge cards via OzuraPay | All four credentials |
| Credential | Format | Where it lives | Required for |
|---|---|---|---|
| Vault pub key | pk_live_… or pk_prod_… | Frontend env var (safe to expose) | Production vault keys only — omit for test/sandbox keys |
| Vault API key | key_… | Server env var only — never in browser | Creating sessions (all integrations) |
| OzuraPay API key | ak_… | Server env var only | OzuraPay merchants (card charging) |
| Merchant ID | ozu_… | Server env var only | OzuraPay merchants (card charging) |
Testing? Use a test vault key (no pub key needed) and fill fields with a test card number. See Test Credentials for card numbers and expected outcomes.
Quick Initialization
OzVault.create() is the public factory method — it sets up the vault and initializes the payment session. It 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).
sessionUrl is the simplest integration option — just pass your session endpoint path and the SDK handles everything. See Server SDK — Session route for the matching backend route.
To provide custom headers or auth tokens, use getSessionKey instead:
OzVault.create() Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
pubKey | string | ² | — | Your Vault pub key |
sessionUrl | string | ✅ ¹ | — | URL of your session endpoint — the simplest option |
getSessionKey | (sessionId: string) => Promise<string> | ✅ ¹ | — | Custom callback for session key retrieval (custom headers, auth, etc.) |
fetchWaxKey | (sessionId: string) => Promise<string> | ✅ ¹ | — | Deprecated — use sessionUrl or getSessionKey instead |
frameBaseUrl | string | — | https://elements.ozura.com | Override where iframe assets are served from. Local development only — do not set in production. |
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 only; in React use useOzElements().ready) |
sessionLimit | number | null | — | 3 | Maximum card submissions per session before auto-refresh. Pass null to remove the cap. Must match sessionLimit in your server-side createSession call — see Server SDK → createSession. |
debug | boolean | — | false | Enables [OzVault]-prefixed console.log output at every lifecycle event. Safe in production — no sensitive data is logged. |
sessionUrl, getSessionKey, or fetchWaxKey is required.
² pubKey is required when using a production vault API key. If your vault API key was created for the test/sandbox environment, you can omit pubKey entirely — see Pub Key for Local Development.
The optional signal parameter is an AbortSignal for advanced teardown scenarios. The React OzElements provider handles this automatically — vanilla JS integrations rarely need it.
Content Security Policy (CSP)
If your site sets aContent-Security-Policy header, you need to allow the Ozura iframe and tokenizer origins. Without this the iframes are blocked before they load and OzVault.create() will reject.
Add these directives to your CSP:
frameBaseUrl to point at a custom or staging deployment, substitute that origin for https://elements.ozura.com.
If you load custom fonts via the fonts option (e.g. Google Fonts), add the font CDN origins too:
The
connect-src entry covers requests made by the Ozura iframe for tokenization.Next.js App Router
When using Next.js with the App Router (app/ directory), the vault and card fields require a client component boundary because they use browser APIs.
The examples below show a production setup with a
pubKey. If you are integrating against a test vault key (from a Test project at ozuravault.com), omit pubKey from OzVault.create() and the <OzElements> provider — no pub key is required.Client component wrapper
Session route (app/api/oz-session/route.ts)
Environment variables (.env.local)
NEXT_PUBLIC_ prefix exposes the pub key to the browser bundle. All other credentials stay server-side only.
Production Checklist
Before you go live, confirm each of the following: Credentials- Production pub key registered to your domain (contact ammar@ozura.com)
-
VAULT_API_KEYset in server environment — never in browser code or committed to git - OzuraPay merchants:
MERCHANT_API_KEYandMERCHANT_IDalso set server-side
-
POST /api/oz-session(or your equivalent path) is deployed and reachable - Route uses
createSessionHandler/createSessionMiddlewareor manually callsozura.createSession() -
sessionLimiton the server matchessessionLimitinVaultOptions(both default to3— only change one if you change the other) - Session route is CSRF-safe (the SDK helpers enforce
POST+Content-Type: application/json)
- CSP includes
frame-srcandconnect-srcforhttps://elements.ozura.com(see CSP above) - Charge route reads
amountfrom your database, not from the request body -
getClientIpused (or equivalent) when callingozura.cardSale()so the OzuraPay API gets the real client IP
-
OzVault.create()is wrapped intry/catchwith a fallback UI - Payment form disables the submit button until
vault.isReadyand all field'ready'events fire -
vault.reset()is called on tokenization error so the customer can re-enter card data -
frameBaseUrlis not set in production code (local development option only)
- Tested end-to-end on localhost using a test vault API key (test project) — no pub key needed
- If using a production vault API key: tested with the production pub key on your staging/preview domain before going live
Next Steps
Card Elements
Mount card number, expiry, and CVV fields.
Bank Elements
Mount account number and routing number fields.
React
OzElements provider and pre-built components.
Server SDK
Process payments and query transactions on your backend.