@ozura/elements 0.1.0-beta.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1121 -887
- package/dist/frame/element-frame.js +77 -57
- package/dist/frame/element-frame.js.map +1 -1
- package/dist/frame/tokenizer-frame.html +1 -1
- package/dist/frame/tokenizer-frame.js +206 -85
- package/dist/frame/tokenizer-frame.js.map +1 -1
- package/dist/oz-elements.esm.js +806 -230
- package/dist/oz-elements.esm.js.map +1 -1
- package/dist/oz-elements.umd.js +806 -229
- package/dist/oz-elements.umd.js.map +1 -1
- package/dist/react/frame/tokenizerFrame.d.ts +32 -0
- package/dist/react/index.cjs.js +957 -218
- package/dist/react/index.cjs.js.map +1 -1
- package/dist/react/index.esm.js +954 -219
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/react/index.d.ts +148 -6
- package/dist/react/sdk/OzElement.d.ts +34 -3
- package/dist/react/sdk/OzVault.d.ts +68 -4
- package/dist/react/sdk/errors.d.ts +9 -0
- package/dist/react/sdk/index.d.ts +29 -0
- package/dist/react/server/index.d.ts +168 -10
- package/dist/react/types/index.d.ts +65 -16
- package/dist/react/utils/appearance.d.ts +9 -0
- package/dist/react/utils/cardUtils.d.ts +14 -0
- package/dist/react/utils/uuid.d.ts +12 -0
- package/dist/server/frame/tokenizerFrame.d.ts +32 -0
- package/dist/server/index.cjs.js +598 -67
- package/dist/server/index.cjs.js.map +1 -1
- package/dist/server/index.esm.js +596 -68
- package/dist/server/index.esm.js.map +1 -1
- package/dist/server/sdk/OzElement.d.ts +34 -3
- package/dist/server/sdk/OzVault.d.ts +68 -4
- package/dist/server/sdk/errors.d.ts +9 -0
- package/dist/server/sdk/index.d.ts +29 -0
- package/dist/server/server/index.d.ts +168 -10
- package/dist/server/types/index.d.ts +65 -16
- package/dist/server/utils/appearance.d.ts +9 -0
- package/dist/server/utils/cardUtils.d.ts +14 -0
- package/dist/server/utils/uuid.d.ts +12 -0
- package/dist/types/frame/tokenizerFrame.d.ts +32 -0
- package/dist/types/sdk/OzElement.d.ts +34 -3
- package/dist/types/sdk/OzVault.d.ts +68 -4
- package/dist/types/sdk/errors.d.ts +9 -0
- package/dist/types/sdk/index.d.ts +29 -0
- package/dist/types/server/index.d.ts +168 -10
- package/dist/types/types/index.d.ts +65 -16
- package/dist/types/utils/appearance.d.ts +9 -0
- package/dist/types/utils/cardUtils.d.ts +14 -0
- package/dist/types/utils/uuid.d.ts +12 -0
- package/package.json +7 -4
|
@@ -5,6 +5,9 @@ export interface ElementStyle {
|
|
|
5
5
|
fontWeight?: string;
|
|
6
6
|
fontStyle?: string;
|
|
7
7
|
fontVariant?: string;
|
|
8
|
+
fontSmoothing?: string;
|
|
9
|
+
webkitFontSmoothing?: string;
|
|
10
|
+
mozOsxFontSmoothing?: string;
|
|
8
11
|
letterSpacing?: string;
|
|
9
12
|
lineHeight?: string;
|
|
10
13
|
textAlign?: string;
|
|
@@ -55,8 +58,6 @@ export interface ElementStyle {
|
|
|
55
58
|
minHeight?: string;
|
|
56
59
|
maxHeight?: string;
|
|
57
60
|
transition?: string;
|
|
58
|
-
/** Index signature for forward-compatibility with future CSS properties. */
|
|
59
|
-
[key: string]: string | undefined;
|
|
60
61
|
}
|
|
61
62
|
export interface ElementStyleConfig {
|
|
62
63
|
/** Default styles applied to the input. */
|
|
@@ -74,7 +75,8 @@ export interface ElementOptions {
|
|
|
74
75
|
style?: ElementStyleConfig;
|
|
75
76
|
placeholder?: string;
|
|
76
77
|
disabled?: boolean;
|
|
77
|
-
/** How long to wait (ms) for the iframe to load before emitting `loaderror`. Default: 10 000.
|
|
78
|
+
/** How long to wait (ms) for the iframe to load before emitting `loaderror`. Default: 10 000.
|
|
79
|
+
* Only takes effect when this element's `onLoadError` option is provided or when `VaultOptions.onLoadError` is set. */
|
|
78
80
|
loadTimeoutMs?: number;
|
|
79
81
|
}
|
|
80
82
|
export interface ElementChangeEvent {
|
|
@@ -118,7 +120,7 @@ export interface AppearanceVariables {
|
|
|
118
120
|
colorText?: string;
|
|
119
121
|
/** Input background color. Maps to `base.backgroundColor`. */
|
|
120
122
|
colorBackground?: string;
|
|
121
|
-
/** Primary accent color. Maps to `focus.caretColor` and `
|
|
123
|
+
/** Primary accent color. Maps to `focus.caretColor` and `base.caretColor`. */
|
|
122
124
|
colorPrimary?: string;
|
|
123
125
|
/** Error/invalid state text color. Maps to `invalid.color`. */
|
|
124
126
|
colorDanger?: string;
|
|
@@ -162,7 +164,7 @@ export interface VaultOptions {
|
|
|
162
164
|
* It replaces the vault secret on every browser tokenize call — the secret
|
|
163
165
|
* never leaves your server.
|
|
164
166
|
*
|
|
165
|
-
* **Server-side (recommended):** Use `ozura.mintWaxKey()` from
|
|
167
|
+
* **Server-side (recommended):** Use `ozura.mintWaxKey()` from `@ozura/elements/server`:
|
|
166
168
|
* @example
|
|
167
169
|
* // Your API route (e.g. Next.js App Router):
|
|
168
170
|
* // POST /api/mint-wax
|
|
@@ -205,8 +207,40 @@ export interface VaultOptions {
|
|
|
205
207
|
* Use this to show a fallback UI (e.g. "Unable to load payment fields").
|
|
206
208
|
*/
|
|
207
209
|
onLoadError?: () => void;
|
|
208
|
-
/** How long to wait (ms) for the tokenizer iframe before calling `onLoadError`. Default: 10 000.
|
|
210
|
+
/** How long to wait (ms) for the tokenizer iframe before calling `onLoadError`. Default: 10 000.
|
|
211
|
+
* Only takes effect when `onLoadError` is also provided — setting this without `onLoadError` has no effect. */
|
|
209
212
|
loadTimeoutMs?: number;
|
|
213
|
+
/**
|
|
214
|
+
* Called when the SDK silently re-mints the wax key during a tokenization
|
|
215
|
+
* attempt (expiry or consumption). The `createToken()` / `createBankToken()`
|
|
216
|
+
* promise stays pending until the refresh completes and the retry resolves.
|
|
217
|
+
* Use this to show a loading indicator while the re-mint round trip is in flight.
|
|
218
|
+
*/
|
|
219
|
+
onWaxRefresh?: () => void;
|
|
220
|
+
/**
|
|
221
|
+
* Maximum number of tokenize calls each minted wax key accepts before the
|
|
222
|
+
* vault marks it as consumed. Should match the `maxTokenizeCalls` passed to
|
|
223
|
+
* `ozura.mintWaxKey()` on your server (both default to `3`).
|
|
224
|
+
*
|
|
225
|
+
* The SDK uses this value to proactively refresh the wax key after it has been
|
|
226
|
+
* fully consumed — before the next `createToken()` call is made — so users
|
|
227
|
+
* never experience a delay from a reactive re-mint. If the values are out of
|
|
228
|
+
* sync the reactive refresh path still catches consumption errors; this is
|
|
229
|
+
* purely an optimisation.
|
|
230
|
+
*
|
|
231
|
+
* @default 3
|
|
232
|
+
*/
|
|
233
|
+
maxTokenizeCalls?: number;
|
|
234
|
+
/**
|
|
235
|
+
* Called once when the tokenizer iframe has loaded and is ready to accept
|
|
236
|
+
* tokenization requests. Useful in vanilla JS to re-evaluate submit-button
|
|
237
|
+
* readiness when the tokenizer becomes ready after all element iframes have
|
|
238
|
+
* already loaded.
|
|
239
|
+
*
|
|
240
|
+
* In React, use `useOzElements().ready` instead — it combines both tokenizer
|
|
241
|
+
* and element readiness automatically.
|
|
242
|
+
*/
|
|
243
|
+
onReady?: () => void;
|
|
210
244
|
/**
|
|
211
245
|
* Global appearance configuration. Applies preset themes and/or variable
|
|
212
246
|
* overrides to all elements created by this vault. Per-element `style`
|
|
@@ -278,8 +312,8 @@ export interface BankTokenizeOptions {
|
|
|
278
312
|
export interface BankAccountMetadata {
|
|
279
313
|
/** Last 4 digits of the account number. */
|
|
280
314
|
last4: string;
|
|
281
|
-
/**
|
|
282
|
-
|
|
315
|
+
/** Last 4 digits of the routing number — sufficient for display and reconciliation. */
|
|
316
|
+
routingNumberLast4: string;
|
|
283
317
|
}
|
|
284
318
|
/** Non-sensitive card metadata returned alongside the token. */
|
|
285
319
|
export interface CardMetadata {
|
|
@@ -294,6 +328,16 @@ export interface CardMetadata {
|
|
|
294
328
|
}
|
|
295
329
|
export interface TokenResponse {
|
|
296
330
|
token: string;
|
|
331
|
+
/**
|
|
332
|
+
* CVC session token returned by the vault alongside the card token.
|
|
333
|
+
*
|
|
334
|
+
* Required by the Ozura Pay API `cardSale` endpoint. If this is absent it
|
|
335
|
+
* means the vault is not configured to return CVC sessions — `createToken()`
|
|
336
|
+
* will reject with an `OZ_TOKEN_ERROR` before this response is ever returned
|
|
337
|
+
* to the caller. In practice, this field is always present on successful
|
|
338
|
+
* tokenization; the optional type reflects only that the field is not part
|
|
339
|
+
* of the tokenized card data itself.
|
|
340
|
+
*/
|
|
297
341
|
cvcSession?: string;
|
|
298
342
|
/** Non-sensitive card metadata — available immediately without a cardSale call. */
|
|
299
343
|
card?: CardMetadata;
|
|
@@ -368,12 +412,12 @@ export interface CardSaleResponseData {
|
|
|
368
412
|
amount: string;
|
|
369
413
|
/** ISO 4217 currency code, e.g. "USD". */
|
|
370
414
|
currency: string;
|
|
371
|
-
/** Surcharge amount applied, e.g. "
|
|
372
|
-
surchargeAmount
|
|
415
|
+
/** Surcharge amount applied, e.g. "1.50". Absent when no surcharge was configured. */
|
|
416
|
+
surchargeAmount?: string;
|
|
373
417
|
/** Sales tax calculated by the Pay API based on billing address. */
|
|
374
418
|
salesTaxAmount?: string;
|
|
375
|
-
/** Tip amount applied, e.g. "
|
|
376
|
-
tipAmount
|
|
419
|
+
/** Tip amount applied, e.g. "5.00". Absent when no tip was included in the request. */
|
|
420
|
+
tipAmount?: string;
|
|
377
421
|
/** Last four digits of the card number. */
|
|
378
422
|
cardLastFour: string;
|
|
379
423
|
/** First six digits of the card number (BIN). */
|
|
@@ -408,12 +452,17 @@ export interface CardSaleResponseData {
|
|
|
408
452
|
* Full response envelope from the Ozura Pay API cardSale endpoint.
|
|
409
453
|
*
|
|
410
454
|
* On success: `{ success: true, data: CardSaleResponseData }`
|
|
411
|
-
* On failure: HTTP 4xx/5xx with `{ error: string }` — pass
|
|
412
|
-
* `normalizeCardSaleError()` to get a user-facing message.
|
|
455
|
+
* On failure: HTTP 4xx/5xx with `{ success: false, error: string }` — pass
|
|
456
|
+
* `error` to `normalizeCardSaleError()` to get a user-facing message.
|
|
457
|
+
*
|
|
458
|
+
* Note: the server SDK `Ozura.cardSale()` throws `OzuraError` on failure rather
|
|
459
|
+
* than returning this shape. This type is only needed when calling the Pay API
|
|
460
|
+
* directly via `fetch`.
|
|
413
461
|
*/
|
|
414
462
|
export interface CardSaleApiResponse {
|
|
415
463
|
success: boolean;
|
|
416
|
-
data
|
|
464
|
+
data?: CardSaleResponseData;
|
|
465
|
+
error?: string;
|
|
417
466
|
}
|
|
418
467
|
/**
|
|
419
468
|
* Transaction types returned by the Pay API transQuery endpoint.
|
|
@@ -539,7 +588,7 @@ export interface TransactionQueryResponse {
|
|
|
539
588
|
data: TransactionData[];
|
|
540
589
|
pagination: TransactionQueryPagination;
|
|
541
590
|
}
|
|
542
|
-
export type OzMessageType = 'OZ_FRAME_READY' | 'OZ_INIT' | 'OZ_UPDATE' | 'OZ_CLEAR' | 'OZ_CHANGE' | 'OZ_FOCUS' | 'OZ_BLUR' | 'OZ_RESIZE' | '
|
|
591
|
+
export type OzMessageType = 'OZ_FRAME_READY' | 'OZ_INIT' | 'OZ_UPDATE' | 'OZ_CLEAR' | 'OZ_CHANGE' | 'OZ_FOCUS' | 'OZ_BLUR' | 'OZ_RESIZE' | 'OZ_BEGIN_COLLECT' | 'OZ_FIELD_VALUE' | 'OZ_TOKENIZE' | 'OZ_TOKEN_RESULT' | 'OZ_TOKEN_ERROR' | 'OZ_FOCUS_REQUEST' | 'OZ_BLUR_REQUEST' | 'OZ_SET_CVV_LENGTH' | 'OZ_BANK_TOKENIZE' | 'OZ_BANK_TOKEN_RESULT' | 'OZ_TOKENIZE_CANCEL';
|
|
543
592
|
export interface OzMessage {
|
|
544
593
|
__oz: true;
|
|
545
594
|
vaultId: string;
|
|
@@ -4,6 +4,15 @@ import type { Appearance, ElementStyleConfig } from '../types';
|
|
|
4
4
|
* Resolution order: theme defaults → variable overrides.
|
|
5
5
|
* The returned config is then used as the "base appearance" that
|
|
6
6
|
* per-element `style` overrides merge on top of.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* - `appearance: undefined` → no styles injected (element iframes use their
|
|
10
|
+
* own minimal built-in defaults).
|
|
11
|
+
* - `appearance: {}` or `appearance: { variables: {...} }` without an explicit
|
|
12
|
+
* `theme` → the `'default'` theme is used as the base. Omitting `theme`
|
|
13
|
+
* does NOT mean "no theme" — it means `theme: 'default'`. To opt out of
|
|
14
|
+
* the preset themes entirely, use per-element `style` overrides without
|
|
15
|
+
* passing an `appearance` prop at all.
|
|
7
16
|
*/
|
|
8
17
|
export declare function resolveAppearance(appearance?: Appearance): ElementStyleConfig | undefined;
|
|
9
18
|
/**
|
|
@@ -21,6 +21,20 @@ export interface CardValidationResult {
|
|
|
21
21
|
valid: boolean;
|
|
22
22
|
error?: string;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Canonical card number validation: length check then Luhn.
|
|
26
|
+
*
|
|
27
|
+
* **Not called by `elementFrame.ts` at runtime.** The frame needs `complete`
|
|
28
|
+
* and `valid` as separate signals for field UX (show completion indicator
|
|
29
|
+
* before running Luhn), so it implements both checks inline via `isComplete()`
|
|
30
|
+
* and `isValid()`. Those methods MUST stay logically in sync with this
|
|
31
|
+
* function — any change to length bounds or error text here must be mirrored
|
|
32
|
+
* there, and vice-versa.
|
|
33
|
+
*
|
|
34
|
+
* Used by the unit test suite as the authoritative spec for the algorithm.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
24
38
|
export declare function validateCardNumber(digits: string, brand: CardBrand | string): CardValidationResult;
|
|
25
39
|
export interface ExpiryValidationResult {
|
|
26
40
|
complete: boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a RFC 4122 v4 UUID.
|
|
3
|
+
*
|
|
4
|
+
* Uses `crypto.randomUUID()` when available (Chrome 92+, Firefox 95+,
|
|
5
|
+
* Safari 15.4+, Node 14.17+) and falls back to `crypto.getRandomValues()`
|
|
6
|
+
* for older environments (Safari 14, some embedded WebViews, older Node).
|
|
7
|
+
*
|
|
8
|
+
* Both paths use the same CSPRNG — the difference is only in API surface.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function uuid(): string;
|
|
@@ -19,3 +19,35 @@
|
|
|
19
19
|
* Exported for unit testing only — not part of the public SDK API.
|
|
20
20
|
*/
|
|
21
21
|
export declare function isAllowedVaultOrigin(apiUrl: string): boolean;
|
|
22
|
+
/** Exported for unit testing only — not part of the public SDK API. */
|
|
23
|
+
export declare class TokenizerFrame {
|
|
24
|
+
private vaultId;
|
|
25
|
+
private hostOrigin;
|
|
26
|
+
/** Wax key delivered once via OZ_INIT. Used for all tokenize calls. */
|
|
27
|
+
private waxKey;
|
|
28
|
+
private pending;
|
|
29
|
+
private pendingBank;
|
|
30
|
+
constructor();
|
|
31
|
+
private onMessage;
|
|
32
|
+
/**
|
|
33
|
+
* Shared vault POST helper. Handles origin guard, header construction,
|
|
34
|
+
* the fetchWithRetry call, token extraction, empty-token error, and catch.
|
|
35
|
+
*
|
|
36
|
+
* Returns the raw response data augmented with a guaranteed non-empty
|
|
37
|
+
* `token` string, or `null` if an error was already reported via
|
|
38
|
+
* postMessage to `target`.
|
|
39
|
+
*/
|
|
40
|
+
private postToVault;
|
|
41
|
+
private tokenize;
|
|
42
|
+
private tokenizeBank;
|
|
43
|
+
private static classifyHttpStatus;
|
|
44
|
+
/**
|
|
45
|
+
* Fetches with a 30s timeout and a single automatic retry for network
|
|
46
|
+
* errors only. 4xx and 5xx responses are not retried — 4xx inputs won't
|
|
47
|
+
* succeed on a second attempt, and 5xx may have already been processed
|
|
48
|
+
* server-side (idempotency cannot be guaranteed for the vault tokenize POST).
|
|
49
|
+
*
|
|
50
|
+
* Throws an Error with an `errorCode` property for downstream classification.
|
|
51
|
+
*/
|
|
52
|
+
private fetchWithRetry;
|
|
53
|
+
}
|
|
@@ -33,10 +33,29 @@ export declare class OzElement {
|
|
|
33
33
|
* (useful when integrating with React refs).
|
|
34
34
|
*/
|
|
35
35
|
mount(target: string | HTMLElement): void;
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to an element event. Returns `this` for chaining.
|
|
38
|
+
* @param event - Event name: `'change'`, `'focus'`, `'blur'`, `'ready'`, or `'loaderror'`.
|
|
39
|
+
* @param callback - Handler invoked with the event payload.
|
|
40
|
+
*/
|
|
36
41
|
on(event: ElementEvent, callback: ElementCallback): this;
|
|
42
|
+
/**
|
|
43
|
+
* Remove a previously registered event handler.
|
|
44
|
+
* Has no effect if the handler is not registered.
|
|
45
|
+
*/
|
|
37
46
|
off(event: ElementEvent, callback: ElementCallback): this;
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to an event for a single invocation. The handler is automatically
|
|
49
|
+
* removed after it fires once.
|
|
50
|
+
*/
|
|
38
51
|
once(event: ElementEvent, callback: ElementCallback): this;
|
|
52
|
+
/**
|
|
53
|
+
* Dynamically update element options (placeholder, style, etc.) without
|
|
54
|
+
* re-mounting the iframe. Only the provided keys are merged; omitted keys
|
|
55
|
+
* retain their current values.
|
|
56
|
+
*/
|
|
39
57
|
update(options: Partial<ElementOptions>): void;
|
|
58
|
+
/** Clear the current field value without removing the element from the DOM. */
|
|
40
59
|
clear(): void;
|
|
41
60
|
/**
|
|
42
61
|
* Removes the iframe from the DOM and resets internal state.
|
|
@@ -53,13 +72,25 @@ export declare class OzElement {
|
|
|
53
72
|
* and prevents future use. Distinct from `unmount()` which allows re-mounting.
|
|
54
73
|
*/
|
|
55
74
|
destroy(): void;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Sends OZ_BEGIN_COLLECT to the element iframe, transferring `port` so the
|
|
77
|
+
* iframe can post its field value directly to the tokenizer without going
|
|
78
|
+
* through the merchant page (no named-window lookup required).
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
beginCollect(requestId: string, port: MessagePort): void;
|
|
82
|
+
/**
|
|
83
|
+
* Tell a CVV element how many digits to expect. Called automatically when card brand changes.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
59
86
|
setCvvLength(length: number): void;
|
|
87
|
+
/** @internal */
|
|
60
88
|
handleMessage(msg: OzMessage): void;
|
|
61
89
|
private emit;
|
|
62
90
|
private post;
|
|
63
91
|
private send;
|
|
92
|
+
/** Posts a message with transferable objects (e.g. MessagePort). Bypasses the
|
|
93
|
+
* pending-message queue — only call when the frame is already ready. */
|
|
94
|
+
private sendWithTransfer;
|
|
64
95
|
}
|
|
65
96
|
export {};
|
|
@@ -10,7 +10,7 @@ import { ElementType, BankElementType, ElementOptions, VaultOptions, TokenizeOpt
|
|
|
10
10
|
* const vault = await OzVault.create({
|
|
11
11
|
* pubKey: 'pk_live_...',
|
|
12
12
|
* fetchWaxKey: async (sessionId) => {
|
|
13
|
-
* // Call your backend — which calls ozura.mintWaxKey() from
|
|
13
|
+
* // Call your backend — which calls ozura.mintWaxKey() from @ozura/elements/server
|
|
14
14
|
* const { waxKey } = await fetch('/api/mint-wax', {
|
|
15
15
|
* method: 'POST',
|
|
16
16
|
* body: JSON.stringify({ sessionId }),
|
|
@@ -41,17 +41,25 @@ export declare class OzVault {
|
|
|
41
41
|
private completionState;
|
|
42
42
|
private tokenizerFrame;
|
|
43
43
|
private tokenizerWindow;
|
|
44
|
-
private tokenizerName;
|
|
45
44
|
private tokenizerReady;
|
|
46
45
|
private _tokenizing;
|
|
47
46
|
private _destroyed;
|
|
47
|
+
private _tokenizeSuccessCount;
|
|
48
|
+
private _maxTokenizeCalls;
|
|
48
49
|
private boundHandleMessage;
|
|
49
50
|
private _pendingMount;
|
|
51
|
+
private _storedFetchWaxKey;
|
|
52
|
+
private _waxRefreshing;
|
|
53
|
+
private _onWaxRefresh;
|
|
54
|
+
private _onReady;
|
|
50
55
|
private loadErrorTimeoutId;
|
|
56
|
+
private _hiddenAt;
|
|
57
|
+
private boundHandleVisibility;
|
|
51
58
|
/**
|
|
52
59
|
* Internal constructor — use `OzVault.create()` instead.
|
|
53
60
|
* The constructor mounts the tokenizer iframe immediately so it can start
|
|
54
61
|
* loading in parallel while `fetchWaxKey` is being awaited.
|
|
62
|
+
* @internal
|
|
55
63
|
*/
|
|
56
64
|
private constructor();
|
|
57
65
|
/**
|
|
@@ -69,15 +77,39 @@ export declare class OzVault {
|
|
|
69
77
|
* The returned vault is ready to create elements immediately. `createToken()`
|
|
70
78
|
* additionally requires `vault.isReady` (tokenizer iframe loaded).
|
|
71
79
|
*
|
|
72
|
-
* @throws {OzError} if `fetchWaxKey` throws or returns an empty string.
|
|
80
|
+
* @throws {OzError} if `fetchWaxKey` throws, returns a non-string value, or returns an empty/whitespace-only string.
|
|
73
81
|
*/
|
|
74
|
-
static create(options: VaultOptions): Promise<OzVault>;
|
|
82
|
+
static create(options: VaultOptions, signal?: AbortSignal): Promise<OzVault>;
|
|
75
83
|
/**
|
|
76
84
|
* True once the hidden tokenizer iframe has loaded and signalled ready.
|
|
77
85
|
* Use this to gate the pay button when building custom UIs without React.
|
|
78
86
|
* React consumers should use the `ready` value returned by `useOzElements()`.
|
|
87
|
+
*
|
|
88
|
+
* Once `true`, remains `true` for the lifetime of this vault instance.
|
|
89
|
+
* It only reverts to `false` after `vault.destroy()` is called, at which
|
|
90
|
+
* point the vault is unusable and a new instance must be created.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* This tracks **tokenizer readiness only** — it says nothing about whether
|
|
94
|
+
* the individual element iframes (card number, CVV, etc.) have loaded.
|
|
95
|
+
* A vault can be `isReady === true` while elements are still mounting.
|
|
96
|
+
* To gate a submit button correctly in vanilla JS, wait for every element's
|
|
97
|
+
* `'ready'` event in addition to this flag. In React, use the `ready` value
|
|
98
|
+
* from `useOzElements()` instead, which combines both checks automatically.
|
|
79
99
|
*/
|
|
80
100
|
get isReady(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Number of successful tokenize calls made against the current wax key.
|
|
103
|
+
*
|
|
104
|
+
* Resets to `0` each time the wax key is refreshed (proactively or reactively).
|
|
105
|
+
* Useful in vanilla JS integrations to display "attempts remaining" UI.
|
|
106
|
+
* In React, use `tokenizeCount` from `useOzElements()` instead.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* const remaining = 3 - vault.tokenizeCount;
|
|
110
|
+
* payButton.textContent = remaining > 0 ? `Pay (${remaining} attempts left)` : 'Pay';
|
|
111
|
+
*/
|
|
112
|
+
get tokenizeCount(): number;
|
|
81
113
|
/**
|
|
82
114
|
* Creates a new OzElement of the given type. Call `.mount(selector)` on the
|
|
83
115
|
* returned element to attach it to the DOM.
|
|
@@ -129,6 +161,17 @@ export declare class OzVault {
|
|
|
129
161
|
* unmounts (e.g. in React's useEffect cleanup or a SPA route change).
|
|
130
162
|
*/
|
|
131
163
|
destroy(): void;
|
|
164
|
+
/**
|
|
165
|
+
* Proactively re-mints the wax key when the page becomes visible again after
|
|
166
|
+
* a long idle period. Wax keys have a fixed TTL (~30 minutes); a user who
|
|
167
|
+
* leaves the tab in the background and returns could have an expired key.
|
|
168
|
+
* Rather than waiting for a failed tokenization to trigger the reactive
|
|
169
|
+
* refresh path, this pre-empts the failure when the vault is idle.
|
|
170
|
+
*
|
|
171
|
+
* Threshold: 20 minutes hidden. Chosen to be comfortably inside the ~30m TTL
|
|
172
|
+
* while avoiding spurious refreshes for brief tab-switches.
|
|
173
|
+
*/
|
|
174
|
+
private handleVisibilityChange;
|
|
132
175
|
private mountTokenizerFrame;
|
|
133
176
|
private handleMessage;
|
|
134
177
|
/**
|
|
@@ -138,5 +181,26 @@ export declare class OzVault {
|
|
|
138
181
|
*/
|
|
139
182
|
private handleElementChange;
|
|
140
183
|
private handleTokenizerMessage;
|
|
184
|
+
/**
|
|
185
|
+
* Returns true when an OZ_TOKEN_ERROR should trigger a wax key refresh.
|
|
186
|
+
*
|
|
187
|
+
* Primary path: vault returns 401/403 → errorCode 'auth'.
|
|
188
|
+
* Defensive path: vault returns 400 → errorCode 'validation', but the raw
|
|
189
|
+
* message contains wax-key-specific language (consumed, expired, invalid key,
|
|
190
|
+
* etc.). This avoids a hard dependency on the vault returning a unified HTTP
|
|
191
|
+
* status for consumed-key vs expired-key failures — both should refresh.
|
|
192
|
+
*
|
|
193
|
+
* Deliberately excludes 'network', 'timeout', and 'server' codes (transient
|
|
194
|
+
* errors are already retried in fetchWithRetry) and 'unknown' (too broad).
|
|
195
|
+
*/
|
|
196
|
+
private isRefreshableAuthError;
|
|
197
|
+
/**
|
|
198
|
+
* Re-mints the wax key using the stored fetchWaxKey callback and updates
|
|
199
|
+
* the tokenizer with the new key. Used for transparent auto-refresh when
|
|
200
|
+
* the vault returns an auth error on tokenization.
|
|
201
|
+
*
|
|
202
|
+
* Only one refresh runs at a time — concurrent retries share the same promise.
|
|
203
|
+
*/
|
|
204
|
+
private refreshWaxKey;
|
|
141
205
|
private sendToTokenizer;
|
|
142
206
|
}
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* errorMapping.ts so the same error strings produce the same user-facing copy.
|
|
11
11
|
*/
|
|
12
12
|
export type OzErrorCode = 'network' | 'timeout' | 'auth' | 'validation' | 'server' | 'config' | 'unknown';
|
|
13
|
+
/** Returns true and narrows to OzErrorCode when `value` is a valid member of the union. */
|
|
14
|
+
export declare function isOzErrorCode(value: unknown): value is OzErrorCode;
|
|
13
15
|
export declare class OzError extends Error {
|
|
14
16
|
/** The raw error string returned by the vault or cardSale API, if available. */
|
|
15
17
|
readonly raw: string;
|
|
@@ -52,5 +54,12 @@ export declare function normalizeBankVaultError(raw: string): string;
|
|
|
52
54
|
* Falls back to the original string when it's under 100 characters, or to a
|
|
53
55
|
* generic message for long/opaque server errors — matching checkout's fallback
|
|
54
56
|
* behaviour exactly.
|
|
57
|
+
*
|
|
58
|
+
* **Trade-off:** Short unrecognised strings (e.g. processor codes like
|
|
59
|
+
* `"PROC_TIMEOUT"`) are passed through verbatim. This intentionally mirrors
|
|
60
|
+
* checkout so the same raw Pay API errors produce the same user-facing text on
|
|
61
|
+
* both surfaces. If the Pay API ever returns internal codes that should never
|
|
62
|
+
* reach the UI, the fix belongs in the Pay API error normalisation layer rather
|
|
63
|
+
* than here.
|
|
55
64
|
*/
|
|
56
65
|
export declare function normalizeCardSaleError(raw: string): string;
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
export { OzVault } from './OzVault';
|
|
2
2
|
export { OzElement } from './OzElement';
|
|
3
3
|
export { OzError, normalizeVaultError, normalizeBankVaultError, normalizeCardSaleError } from './errors';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a ready-to-use `fetchWaxKey` callback for `OzVault.create()` and `<OzElements>`.
|
|
6
|
+
*
|
|
7
|
+
* Calls your backend mint endpoint with `{ sessionId }` and returns the wax key string.
|
|
8
|
+
* Throws on non-OK responses or a missing `waxKey` field so the vault can surface the
|
|
9
|
+
* error through its normal error path.
|
|
10
|
+
*
|
|
11
|
+
* Each call enforces a 10-second per-attempt timeout. On a pure network-level
|
|
12
|
+
* failure (connection refused, DNS failure, etc.) the call is retried once after
|
|
13
|
+
* 750ms before throwing. HTTP errors (4xx/5xx) are never retried — they indicate
|
|
14
|
+
* an endpoint misconfiguration or an invalid key, not a transient failure.
|
|
15
|
+
*
|
|
16
|
+
* The mint endpoint is typically the one-line `createMintWaxHandler` / `createMintWaxMiddleware`
|
|
17
|
+
* from `@ozura/elements/server`.
|
|
18
|
+
*
|
|
19
|
+
* @param mintUrl - Absolute or relative URL of your wax-key mint endpoint, e.g. `'/api/mint-wax'`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Vanilla JS
|
|
23
|
+
* const vault = await OzVault.create({
|
|
24
|
+
* pubKey: 'pk_live_...',
|
|
25
|
+
* fetchWaxKey: createFetchWaxKey('/api/mint-wax'),
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // React
|
|
30
|
+
* <OzElements pubKey="pk_live_..." fetchWaxKey={createFetchWaxKey('/api/mint-wax')}>
|
|
31
|
+
*/
|
|
32
|
+
export declare function createFetchWaxKey(mintUrl: string): (sessionId: string) => Promise<string>;
|
|
4
33
|
export type { OzErrorCode } from './errors';
|
|
5
34
|
export type { ElementType, BankElementType, ElementOptions, ElementStyleConfig, ElementStyle, ElementChangeEvent, VaultOptions, TokenizeOptions, BankTokenizeOptions, TokenResponse, BankTokenResponse, CardMetadata, BankAccountMetadata, FontSource, CssFontSource, CustomFontSource, BillingDetails, BillingAddress, CardSaleRequest, CardSaleResponseData, CardSaleApiResponse, Appearance, AppearanceVariables, OzTheme, TransactionQueryParams, TransactionQueryPagination, TransactionQueryResponse, TransactionType, CardTransactionType, AchTransactionType, CryptoTransactionType, TransactionBase, CardTransactionData, AchTransactionData, CryptoTransactionData, TransactionData, } from '../types';
|