@ozura/elements 1.2.0 → 1.2.3

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.
Files changed (60) hide show
  1. package/README.md +105 -0
  2. package/dist/frame/element-frame.js +60 -4
  3. package/dist/frame/element-frame.js.map +1 -1
  4. package/dist/frame/tokenizer-frame.js +145 -61
  5. package/dist/frame/tokenizer-frame.js.map +1 -1
  6. package/dist/oz-elements.esm.js +221 -97
  7. package/dist/oz-elements.esm.js.map +1 -1
  8. package/dist/oz-elements.umd.js +221 -97
  9. package/dist/oz-elements.umd.js.map +1 -1
  10. package/dist/react/frame/elementFrame.d.ts +9 -0
  11. package/dist/react/frame/tokenizerFrame.d.ts +17 -1
  12. package/dist/react/index.cjs.js +221 -97
  13. package/dist/react/index.cjs.js.map +1 -1
  14. package/dist/react/index.esm.js +221 -97
  15. package/dist/react/index.esm.js.map +1 -1
  16. package/dist/react/sdk/OzElement.d.ts +4 -1
  17. package/dist/react/sdk/OzVault.d.ts +3 -9
  18. package/dist/react/sdk/createSessionFetcher.d.ts +2 -2
  19. package/dist/react/server/index.d.ts +26 -0
  20. package/dist/react/types/index.d.ts +37 -14
  21. package/dist/react/utils/billingUtils.d.ts +2 -1
  22. package/dist/react/vue/index.d.ts +88 -0
  23. package/dist/server/frame/elementFrame.d.ts +9 -0
  24. package/dist/server/frame/tokenizerFrame.d.ts +17 -1
  25. package/dist/server/index.cjs.js +77 -27
  26. package/dist/server/index.cjs.js.map +1 -1
  27. package/dist/server/index.esm.js +77 -27
  28. package/dist/server/index.esm.js.map +1 -1
  29. package/dist/server/sdk/OzElement.d.ts +4 -1
  30. package/dist/server/sdk/OzVault.d.ts +3 -9
  31. package/dist/server/sdk/createSessionFetcher.d.ts +2 -2
  32. package/dist/server/server/index.d.ts +26 -0
  33. package/dist/server/types/index.d.ts +37 -14
  34. package/dist/server/utils/billingUtils.d.ts +2 -1
  35. package/dist/server/vue/index.d.ts +88 -0
  36. package/dist/types/frame/elementFrame.d.ts +9 -0
  37. package/dist/types/frame/tokenizerFrame.d.ts +17 -1
  38. package/dist/types/sdk/OzElement.d.ts +4 -1
  39. package/dist/types/sdk/OzVault.d.ts +3 -9
  40. package/dist/types/sdk/createSessionFetcher.d.ts +2 -2
  41. package/dist/types/server/index.d.ts +26 -0
  42. package/dist/types/types/index.d.ts +37 -14
  43. package/dist/types/utils/billingUtils.d.ts +2 -1
  44. package/dist/types/vue/index.d.ts +88 -0
  45. package/dist/vue/frame/protocol.d.ts +12 -0
  46. package/dist/vue/index.cjs.js +2335 -0
  47. package/dist/vue/index.cjs.js.map +1 -0
  48. package/dist/vue/index.esm.js +2327 -0
  49. package/dist/vue/index.esm.js.map +1 -0
  50. package/dist/vue/sdk/OzElement.d.ts +99 -0
  51. package/dist/vue/sdk/OzVault.d.ts +250 -0
  52. package/dist/vue/sdk/createSessionFetcher.d.ts +29 -0
  53. package/dist/vue/sdk/errors.d.ts +65 -0
  54. package/dist/vue/sdk/index.d.ts +14 -0
  55. package/dist/vue/types/index.d.ts +667 -0
  56. package/dist/vue/utils/appearance.d.ts +22 -0
  57. package/dist/vue/utils/billingUtils.d.ts +61 -0
  58. package/dist/vue/utils/uuid.d.ts +12 -0
  59. package/dist/vue/vue/index.d.ts +88 -0
  60. package/package.json +15 -3
@@ -0,0 +1,667 @@
1
+ export interface ElementStyle {
2
+ color?: string;
3
+ fontSize?: string;
4
+ fontFamily?: string;
5
+ fontWeight?: string;
6
+ fontStyle?: string;
7
+ fontVariant?: string;
8
+ fontSmoothing?: string;
9
+ webkitFontSmoothing?: string;
10
+ mozOsxFontSmoothing?: string;
11
+ letterSpacing?: string;
12
+ lineHeight?: string;
13
+ textAlign?: string;
14
+ textDecoration?: string;
15
+ textShadow?: string;
16
+ textTransform?: string;
17
+ padding?: string;
18
+ paddingTop?: string;
19
+ paddingRight?: string;
20
+ paddingBottom?: string;
21
+ paddingLeft?: string;
22
+ backgroundColor?: string;
23
+ opacity?: string;
24
+ border?: string;
25
+ borderColor?: string;
26
+ borderWidth?: string;
27
+ borderStyle?: string;
28
+ borderRadius?: string;
29
+ borderTop?: string;
30
+ borderRight?: string;
31
+ borderBottom?: string;
32
+ borderLeft?: string;
33
+ borderTopColor?: string;
34
+ borderRightColor?: string;
35
+ borderBottomColor?: string;
36
+ borderLeftColor?: string;
37
+ borderTopWidth?: string;
38
+ borderRightWidth?: string;
39
+ borderBottomWidth?: string;
40
+ borderLeftWidth?: string;
41
+ borderTopStyle?: string;
42
+ borderRightStyle?: string;
43
+ borderBottomStyle?: string;
44
+ borderLeftStyle?: string;
45
+ borderTopLeftRadius?: string;
46
+ borderTopRightRadius?: string;
47
+ borderBottomLeftRadius?: string;
48
+ borderBottomRightRadius?: string;
49
+ boxShadow?: string;
50
+ outline?: string;
51
+ outlineColor?: string;
52
+ outlineWidth?: string;
53
+ outlineStyle?: string;
54
+ outlineOffset?: string;
55
+ cursor?: string;
56
+ caretColor?: string;
57
+ height?: string;
58
+ minHeight?: string;
59
+ maxHeight?: string;
60
+ transition?: string;
61
+ }
62
+ export interface ElementStyleConfig {
63
+ /** Default styles applied to the input. */
64
+ base?: ElementStyle;
65
+ /** Styles applied when the input is focused. Merges on top of `base`. */
66
+ focus?: ElementStyle;
67
+ /** Styles applied when the input contains an invalid value (on blur). Merges on top of `base`. */
68
+ invalid?: ElementStyle;
69
+ /** Styles applied when the input contains a valid, complete value (on blur). Merges on top of `base`. */
70
+ complete?: ElementStyle;
71
+ /** Styles applied to the input's placeholder text (::placeholder pseudo-element). */
72
+ placeholder?: ElementStyle;
73
+ }
74
+ export interface ElementOptions {
75
+ style?: ElementStyleConfig;
76
+ placeholder?: string;
77
+ disabled?: boolean;
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. */
80
+ loadTimeoutMs?: number;
81
+ }
82
+ export interface ElementChangeEvent {
83
+ empty: boolean;
84
+ complete: boolean;
85
+ valid: boolean;
86
+ /** Card brand — only present on cardNumber elements */
87
+ cardBrand?: string;
88
+ /** Parsed month (01-12) — only present on expirationDate elements */
89
+ month?: string;
90
+ /** Parsed 2-digit year — only present on expirationDate elements */
91
+ year?: string;
92
+ /** Human-readable error when valid is false and the field has been touched */
93
+ error?: string;
94
+ }
95
+ export type ElementType = 'cardNumber' | 'cvv' | 'expirationDate';
96
+ /** Bank account element types. */
97
+ export type BankElementType = 'accountNumber' | 'routingNumber';
98
+ /** Load a font from a CSS stylesheet URL (e.g. Google Fonts). Must be HTTPS. */
99
+ export interface CssFontSource {
100
+ cssSrc: string;
101
+ }
102
+ /** Load a custom font via @font-face. `src` must be a `url(https://...)` value. */
103
+ export interface CustomFontSource {
104
+ family: string;
105
+ src: string;
106
+ weight?: string;
107
+ style?: string;
108
+ display?: string;
109
+ unicodeRange?: string;
110
+ }
111
+ export type FontSource = CssFontSource | CustomFontSource;
112
+ export type OzTheme = 'default' | 'night' | 'flat';
113
+ /**
114
+ * CSS variable-style overrides. Each key maps to a specific style property
115
+ * across all style states, so merchants can theme with a single flat object
116
+ * instead of manually building full `ElementStyleConfig` objects.
117
+ */
118
+ export interface AppearanceVariables {
119
+ /** Input text color. Maps to `base.color`. */
120
+ colorText?: string;
121
+ /** Input background color. Maps to `base.backgroundColor`. */
122
+ colorBackground?: string;
123
+ /** Primary accent color. Maps to `focus.caretColor` and `base.caretColor`. */
124
+ colorPrimary?: string;
125
+ /** Error/invalid state text color. Maps to `invalid.color`. */
126
+ colorDanger?: string;
127
+ /** Success/complete state text color. Maps to `complete.color`. */
128
+ colorSuccess?: string;
129
+ /** Placeholder text color. Maps to `placeholder.color`. */
130
+ colorPlaceholder?: string;
131
+ /** Font family. Maps to `base.fontFamily`. */
132
+ fontFamily?: string;
133
+ /** Font size. Maps to `base.fontSize`. */
134
+ fontSize?: string;
135
+ /** Font weight. Maps to `base.fontWeight`. */
136
+ fontWeight?: string;
137
+ /** Letter spacing. Maps to `base.letterSpacing`. */
138
+ letterSpacing?: string;
139
+ /** Line height. Maps to `base.lineHeight`. */
140
+ lineHeight?: string;
141
+ /** Inner padding. Maps to `base.padding`. */
142
+ padding?: string;
143
+ }
144
+ /**
145
+ * Global appearance configuration. Applied to all elements created by this vault.
146
+ * Per-element `style` overrides take precedence over appearance settings.
147
+ */
148
+ export interface Appearance {
149
+ /** Preset theme. Applies a complete set of default styles. */
150
+ theme?: OzTheme;
151
+ /** Variable overrides. Merged on top of the theme defaults. */
152
+ variables?: AppearanceVariables;
153
+ }
154
+ export interface VaultOptions {
155
+ /** System pub key required for tokenization. Obtain from Ozura admin.
156
+ * Sent as the `X-Pub-Key` header on tokenize requests. */
157
+ pubKey: string;
158
+ /**
159
+ * URL of your backend session endpoint. The simplest way to connect the SDK
160
+ * to your server — just pass the path and the SDK handles everything else.
161
+ *
162
+ * The endpoint should be created with `createSessionMiddleware` or
163
+ * `createSessionHandler` from `@ozura/elements/server`.
164
+ *
165
+ * @example
166
+ * // Backend (Express)
167
+ * app.post('/api/oz-session', createSessionMiddleware(ozura));
168
+ *
169
+ * // Frontend
170
+ * OzVault.create({ pubKey: 'pk_live_...', sessionUrl: '/api/oz-session' })
171
+ */
172
+ sessionUrl?: string;
173
+ /**
174
+ * Custom async function to obtain a session key from your backend.
175
+ * Use this when you need custom headers, auth tokens, or request logic that
176
+ * `sessionUrl` cannot provide.
177
+ *
178
+ * Receives an SDK-generated session UUID; your implementation passes it to
179
+ * your backend, which calls `ozura.createSession()` and returns the key.
180
+ *
181
+ * For the common case, prefer `sessionUrl` — it wraps this automatically.
182
+ *
183
+ * @example
184
+ * getSessionKey: async (sessionId) => {
185
+ * const res = await fetch('/api/oz-session', {
186
+ * method: 'POST',
187
+ * headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
188
+ * body: JSON.stringify({ sessionId }),
189
+ * });
190
+ * const { sessionKey } = await res.json();
191
+ * return sessionKey;
192
+ * }
193
+ */
194
+ getSessionKey?: (sessionId: string) => Promise<string>;
195
+ /**
196
+ * @deprecated Use `sessionUrl` or `getSessionKey` instead.
197
+ *
198
+ * Legacy callback name. Equivalent to `getSessionKey` — both are supported
199
+ * and work identically. `fetchWaxKey` will be removed in a future major version.
200
+ */
201
+ fetchWaxKey?: (tokenizationSessionId: string) => Promise<string>;
202
+ /** Base URL where the Ozura frame HTML/JS assets are served from.
203
+ * Defaults to the production CDN. Override for local development. */
204
+ frameBaseUrl?: string;
205
+ /**
206
+ * Custom fonts to inject into element iframes. Accepts Google Fonts URLs
207
+ * or @font-face declarations. Fonts are loaded inside each iframe so they
208
+ * render in the card input fields.
209
+ *
210
+ * @example
211
+ * // Google Fonts
212
+ * fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap' }]
213
+ *
214
+ * @example
215
+ * // Custom @font-face
216
+ * fonts: [{ family: 'MyFont', src: 'url(https://cdn.example.com/myfont.woff2)', weight: '400' }]
217
+ */
218
+ fonts?: FontSource[];
219
+ /**
220
+ * Called if the tokenizer iframe fails to signal ready within `loadTimeoutMs`.
221
+ * Use this to show a fallback UI (e.g. "Unable to load payment fields").
222
+ */
223
+ onLoadError?: () => void;
224
+ /** How long to wait (ms) for the tokenizer iframe before calling `onLoadError`. Default: 10 000.
225
+ * Only takes effect when `onLoadError` is also provided — setting this without `onLoadError` has no effect. */
226
+ loadTimeoutMs?: number;
227
+ /**
228
+ * Called when the SDK silently refreshes the payment session mid-checkout
229
+ * (e.g. after the session is consumed or expires). The `createToken()` /
230
+ * `createBankToken()` promise stays pending until the refresh completes.
231
+ * Use this to show a loading indicator while the refresh is in progress.
232
+ */
233
+ onSessionRefresh?: () => void;
234
+ /**
235
+ * @deprecated Use `onSessionRefresh` instead.
236
+ */
237
+ onWaxRefresh?: () => void;
238
+ /**
239
+ * Maximum number of card submissions allowed per session before the SDK
240
+ * automatically refreshes the session in the background. Defaults to `3`.
241
+ *
242
+ * Must match the `sessionLimit` (or `maxTokenizeCalls`) passed to
243
+ * `ozura.createSession()` on your server. Both default to `3` so you only
244
+ * need this if you override the server-side value.
245
+ *
246
+ * Pass `null` to disable the proactive refresh cap entirely (unlimited
247
+ * tokenizations per session). Only use this when your server-side
248
+ * `createSession()` also passes `sessionLimit: null`.
249
+ *
250
+ * @default 3
251
+ */
252
+ sessionLimit?: number | null;
253
+ /**
254
+ * @deprecated Use `sessionLimit` instead.
255
+ * Maximum number of tokenize calls per session. Equivalent to `sessionLimit`.
256
+ * @default 3
257
+ */
258
+ maxTokenizeCalls?: number;
259
+ /**
260
+ * Called once when the tokenizer iframe has loaded and is ready to accept
261
+ * tokenization requests. Useful in vanilla JS to re-evaluate submit-button
262
+ * readiness when the tokenizer becomes ready after all element iframes have
263
+ * already loaded.
264
+ *
265
+ * In React, use `useOzElements().ready` instead — it combines both tokenizer
266
+ * and element readiness automatically.
267
+ */
268
+ onReady?: () => void;
269
+ /**
270
+ * Global appearance configuration. Applies preset themes and/or variable
271
+ * overrides to all elements created by this vault. Per-element `style`
272
+ * overrides take precedence.
273
+ *
274
+ * @example
275
+ * appearance: { theme: 'night' }
276
+ *
277
+ * @example
278
+ * appearance: {
279
+ * theme: 'flat',
280
+ * variables: { colorPrimary: '#6366f1', fontFamily: '"Inter", sans-serif' },
281
+ * }
282
+ */
283
+ appearance?: Appearance;
284
+ /**
285
+ * Enables structured debug logging to the browser console.
286
+ *
287
+ * When `true`, the vault emits a `[OzVault]`-prefixed `console.log` entry at
288
+ * every meaningful lifecycle event: vault creation, tokenizer readiness, element
289
+ * readiness, field changes, tokenization start/result/error, wax key refresh,
290
+ * tab-visibility refreshes, `reset()`, and `destroy()`.
291
+ *
292
+ * **No sensitive data is ever logged.** Wax keys, tokens, CVC sessions, and
293
+ * billing fields are represented only as boolean presence flags. Frame IDs and
294
+ * request IDs are truncated. Output is safe to paste directly into bug reports.
295
+ *
296
+ * Use `vault.debugState()` to capture a full snapshot of internal state at any
297
+ * point, regardless of whether `debug` is enabled.
298
+ *
299
+ * @default false
300
+ */
301
+ debug?: boolean;
302
+ }
303
+ /** Billing address. All string fields are validated to 1–50 characters. */
304
+ export interface BillingAddress {
305
+ line1: string;
306
+ /** Optional. Omitted entirely from cardSale if blank (schema enforces minLength 1 if present). */
307
+ line2?: string;
308
+ city: string;
309
+ /** For US and CA: normalized to the 2-letter abbreviation (e.g. "California" → "CA"). */
310
+ state: string;
311
+ zip: string;
312
+ /** ISO 3166-1 alpha-2, e.g. "US", "CA", "GB". */
313
+ country: string;
314
+ }
315
+ /**
316
+ * Cardholder billing details validated against the Ozura cardSale API schema.
317
+ * Mirrors the `billing_details` object in Stripe's createPaymentMethod API.
318
+ *
319
+ * Pass to `vault.createToken({ billing })` — the SDK validates all fields and
320
+ * returns normalized values in `TokenResponse.billing` ready for the cardSale call.
321
+ */
322
+ export interface BillingDetails {
323
+ /** 1–50 characters. Required for cardSale. */
324
+ firstName: string;
325
+ /** 1–50 characters. Required for cardSale. Must be non-empty. */
326
+ lastName: string;
327
+ /** Valid email address, max 50 characters. */
328
+ email?: string;
329
+ /** E.164 format, e.g. "+15551234567". Max 50 characters. */
330
+ phone?: string;
331
+ address?: BillingAddress;
332
+ }
333
+ export interface TokenizeOptions {
334
+ /**
335
+ * Billing details — validated, normalized, and returned in TokenResponse.billing
336
+ * ready to be passed directly to the cardSale API.
337
+ *
338
+ * If provided, firstName and lastName inside billing take precedence over
339
+ * the top-level firstName/lastName params below.
340
+ */
341
+ billing?: BillingDetails;
342
+ /** @deprecated Pass firstName inside `billing` instead. */
343
+ firstName?: string;
344
+ /** @deprecated Pass lastName inside `billing` instead. */
345
+ lastName?: string;
346
+ }
347
+ /** Options for `vault.createBankToken()`. */
348
+ export interface BankTokenizeOptions {
349
+ /** Account holder first name. Required. */
350
+ firstName: string;
351
+ /** Account holder last name. Required. */
352
+ lastName: string;
353
+ }
354
+ /** Non-sensitive bank account metadata returned alongside the token. */
355
+ export interface BankAccountMetadata {
356
+ /** Last 4 digits of the account number. */
357
+ last4: string;
358
+ /** Last 4 digits of the routing number — sufficient for display and reconciliation. */
359
+ routingNumberLast4: string;
360
+ }
361
+ /** Non-sensitive card metadata returned alongside the token. */
362
+ export interface CardMetadata {
363
+ /** Last 4 digits of the card number. */
364
+ last4: string;
365
+ /** Detected card brand (e.g. "visa", "mastercard", "amex"). */
366
+ brand: string;
367
+ /** 2-digit expiry month (e.g. "09"). */
368
+ expMonth: string;
369
+ /** 4-digit expiry year (e.g. "2027"). */
370
+ expYear: string;
371
+ }
372
+ export interface TokenResponse {
373
+ token: string;
374
+ /**
375
+ * CVC session token returned by the vault alongside the card token.
376
+ *
377
+ * Required by the Ozura Pay API `cardSale` endpoint. The SDK validates this
378
+ * field before resolving `createToken()` — if it is absent the promise rejects
379
+ * with `OZ_TOKEN_ERROR`. In practice this field is always present on a
380
+ * successful tokenization.
381
+ */
382
+ cvcSession: string;
383
+ /**
384
+ * Non-sensitive card metadata — present on successful tokenization when the
385
+ * vault returns all four fields (last4, brand, expMonth, expYear). Absent if
386
+ * the vault response omits any card metadata field.
387
+ */
388
+ card?: CardMetadata;
389
+ /**
390
+ * Validated, normalized billing details — ready to spread into a cardSale request.
391
+ * Only present when billing was passed to createToken().
392
+ */
393
+ billing?: BillingDetails;
394
+ }
395
+ /**
396
+ * Returned by `vault.createBankToken()` after successful ACH tokenization.
397
+ * The token can be passed to any ACH-capable payment processor.
398
+ * Note: OzuraPay does not currently support bank account payments.
399
+ */
400
+ export interface BankTokenResponse {
401
+ /** Vault token representing the bank account. Use with your ACH processor. */
402
+ token: string;
403
+ /** Non-sensitive bank account metadata. */
404
+ bank?: BankAccountMetadata;
405
+ }
406
+ /**
407
+ * Full request body for the Ozura Pay API cardSale endpoint.
408
+ * All string fields are 1–50 characters. billingAddress2 is optional (omit if blank).
409
+ *
410
+ * Headers required:
411
+ * x-api-key: <merchantApiKey>
412
+ */
413
+ export interface CardSaleRequest {
414
+ /** Processor to use. If omitted, the Pay API auto-selects (Elavon → Nuvei → Worldpay). */
415
+ processor?: 'elavon' | 'nuvei' | 'worldpay';
416
+ merchantId: string;
417
+ /** Decimal string, e.g. "49.00". */
418
+ amount: string;
419
+ /** ISO 4217, e.g. "USD". */
420
+ currency: string;
421
+ /**
422
+ * Who initiated the transaction. Required by the Pay API.
423
+ * - `'cit'` — Customer-Initiated Transaction (default for web checkouts).
424
+ * - `'mit'` — Merchant-Initiated (scheduled recurring charge, customer not present).
425
+ * - `'ucof'` — Unscheduled Credential-on-File (threshold billing, account-updater, etc.).
426
+ * - `'refund'` — Voids, returns, reversals (not a stored-credential use).
427
+ */
428
+ transactionInitiationType: 'cit' | 'mit' | 'ucof' | 'refund';
429
+ /**
430
+ * Channel through which the transaction is processed. Required by the Pay API.
431
+ * - `'ecommerce'` — Online, customer self-serve (default for web checkouts).
432
+ * - `'moto'` — Mail order / telephone order.
433
+ * - `'cardPresent'`— POS / in-person.
434
+ * - `'recurring'` — Scheduled MIT charge; never the initial CIT charge.
435
+ */
436
+ transactionChannel: 'cardPresent' | 'ecommerce' | 'moto' | 'recurring';
437
+ /** From TokenResponse.token. The vault token representing the stored card. */
438
+ ozuraVaultToken: string;
439
+ /** From TokenResponse.cvcSession */
440
+ ozuraCvcSession: string;
441
+ billingFirstName: string;
442
+ billingLastName: string;
443
+ /**
444
+ * Required by the Pay API (minLength 1). Optional here so merchants can omit it
445
+ * in rare server-side-only flows, but the Pay API will reject the request if absent.
446
+ */
447
+ billingEmail?: string;
448
+ /** E.164 format, max 50 chars. Required by the Pay API; optional here for flexibility. */
449
+ billingPhone?: string;
450
+ /** Required by the Pay API; optional here for flexibility. Must be non-empty if provided. */
451
+ billingAddress1?: string;
452
+ /** Omit entirely if blank — Pay API schema enforces minLength 1 if present. */
453
+ billingAddress2?: string;
454
+ /** Required by the Pay API; optional here for flexibility. Must be non-empty if provided. */
455
+ billingCity?: string;
456
+ /** 2-letter state/province code. Required by the Pay API; optional here for flexibility. */
457
+ billingState?: string;
458
+ /** Required by the Pay API; optional here for flexibility. Must be non-empty if provided. */
459
+ billingZipcode?: string;
460
+ /** ISO 3166-1 alpha-2. Required by the Pay API. Defaults to 'US' in `Ozura.cardSale()`. */
461
+ billingCountry?: string;
462
+ /** Fetch from your server — use an internal route, not api.ipify.org (ad-blockers block it). */
463
+ clientIpAddress: string;
464
+ salesTaxExempt: boolean;
465
+ /** Defaults to "0.00". Range 0–3. */
466
+ surchargePercent?: string;
467
+ /** Defaults to "0.00". */
468
+ tipAmount?: string;
469
+ }
470
+ /**
471
+ * The `data` object inside a successful cardSale API response.
472
+ *
473
+ * Store `transactionId` in your database immediately after receiving this —
474
+ * it is required for refunds and idempotency checks.
475
+ */
476
+ export interface CardSaleResponseData {
477
+ /** Unique transaction reference — store this in your database. */
478
+ transactionId: string;
479
+ /** Amount charged, decimal string, e.g. "49.00". */
480
+ amount: string;
481
+ /** ISO 4217 currency code, e.g. "USD". */
482
+ currency: string;
483
+ /** Surcharge amount applied, e.g. "1.50". Absent when no surcharge was configured. */
484
+ surchargeAmount?: string;
485
+ /** Sales tax calculated by the Pay API based on billing address. */
486
+ salesTaxAmount?: string;
487
+ /** Tip amount applied, e.g. "5.00". Absent when no tip was included in the request. */
488
+ tipAmount?: string;
489
+ /** Last four digits of the card number. */
490
+ cardLastFour: string;
491
+ /** First six digits of the card number (BIN). */
492
+ cardBin?: string;
493
+ /** Expiry month as 2-digit string, e.g. "09". */
494
+ cardExpMonth: string;
495
+ /** Expiry year as 4-digit string, e.g. "2027". */
496
+ cardExpYear: string;
497
+ /** Card brand returned by processor, e.g. "visa", "mastercard", "amex". */
498
+ cardBrand: string;
499
+ /** Whether the card is a credit card (vs debit). */
500
+ isCreditCard?: boolean;
501
+ /** ISO 8601 transaction timestamp. */
502
+ transDate: string;
503
+ /** Merchant ID echoed back from the request. */
504
+ ozuraMerchantId: string;
505
+ /** Client IP address echoed back. */
506
+ clientIpAddress?: string;
507
+ /** Billing fields echoed back — useful for receipts. */
508
+ billingFirstName: string;
509
+ billingLastName: string;
510
+ billingEmail: string;
511
+ billingPhone: string;
512
+ billingAddress1: string;
513
+ billingAddress2?: string;
514
+ billingCity: string;
515
+ billingState: string;
516
+ billingZipcode: string;
517
+ billingCountry: string;
518
+ }
519
+ /**
520
+ * Full response envelope from the Ozura Pay API cardSale endpoint.
521
+ *
522
+ * On success: `{ success: true, data: CardSaleResponseData }`
523
+ * On failure: HTTP 4xx/5xx with `{ success: false, error: string }` — pass
524
+ * `error` to `normalizeCardSaleError()` to get a user-facing message.
525
+ *
526
+ * Note: the server SDK `Ozura.cardSale()` throws `OzuraError` on failure rather
527
+ * than returning this shape. This type is only needed when calling the Pay API
528
+ * directly via `fetch`.
529
+ */
530
+ export interface CardSaleApiResponse {
531
+ success: boolean;
532
+ data?: CardSaleResponseData;
533
+ error?: string;
534
+ }
535
+ /**
536
+ * Transaction types returned by the Pay API transQuery endpoint.
537
+ * Mirrors the `TransactionType` enum in PayAPI-BE.
538
+ */
539
+ export type TransactionType = 'CreditCardSale' | 'CreditCardReversal' | 'CreditCardReturn' | 'CreditCardVoid' | 'AchSale' | 'AchReversal' | 'AchReturn' | 'AchVoid' | 'CryptoSale' | 'CryptoReturn' | 'CryptoWithdrawal';
540
+ export type CardTransactionType = 'CreditCardSale' | 'CreditCardReversal' | 'CreditCardReturn' | 'CreditCardVoid';
541
+ export type AchTransactionType = 'AchSale' | 'AchReversal' | 'AchReturn' | 'AchVoid';
542
+ export type CryptoTransactionType = 'CryptoSale' | 'CryptoReturn' | 'CryptoWithdrawal';
543
+ /**
544
+ * Shared fields returned by transQuery for all transaction types.
545
+ *
546
+ * Note: transQuery returns billing fields as `firstName`, `lastName`, etc.
547
+ * (the MongoDB field names), NOT the `billingFirstName` format used by the
548
+ * cardSale endpoint response. This is a backend inconsistency — these types
549
+ * reflect what the API actually returns.
550
+ */
551
+ export interface TransactionBase {
552
+ transactionId: string;
553
+ originalTransactionId?: string;
554
+ relatedTransactionIds?: string[];
555
+ transactionType: TransactionType;
556
+ amount: string;
557
+ currentAmount?: string;
558
+ surchargeAmount?: string;
559
+ tipAmount?: string;
560
+ currency: string;
561
+ status: string;
562
+ createdAt: string;
563
+ clientIpAddress?: string;
564
+ isVoided?: boolean;
565
+ isPartiallyReturned?: boolean;
566
+ isFullyReturned?: boolean;
567
+ isReversed?: boolean;
568
+ ozuraUserDetails?: {
569
+ ozuraUserId?: string;
570
+ ozuraMerchantId?: string;
571
+ };
572
+ avsResponseCode?: string;
573
+ cvvResponseCode?: string;
574
+ salesTaxData?: Record<string, unknown>;
575
+ firstName?: string;
576
+ lastName?: string;
577
+ email?: string;
578
+ phone?: string;
579
+ address1?: string;
580
+ address2?: string;
581
+ city?: string;
582
+ state?: string;
583
+ zipcode?: string;
584
+ country?: string;
585
+ }
586
+ /** Card transaction returned by transQuery. */
587
+ export interface CardTransactionData extends TransactionBase {
588
+ transactionType: CardTransactionType;
589
+ cardLastFour?: string;
590
+ cardBin?: string;
591
+ cardExpMonth?: string;
592
+ cardExpYear?: string;
593
+ cardBrand?: string;
594
+ isCreditCard?: boolean;
595
+ }
596
+ /** ACH transaction returned by transQuery. */
597
+ export interface AchTransactionData extends TransactionBase {
598
+ transactionType: AchTransactionType;
599
+ ddaAccountType?: string;
600
+ accountNumber?: string;
601
+ routingNumber?: string;
602
+ }
603
+ /** Crypto transaction returned by transQuery. */
604
+ export interface CryptoTransactionData extends TransactionBase {
605
+ transactionType: CryptoTransactionType;
606
+ originalSourceAddress?: string;
607
+ originalDepositAddress?: string;
608
+ network?: string;
609
+ mintDetails?: {
610
+ mintTransactionHash?: string;
611
+ };
612
+ }
613
+ /**
614
+ * Discriminated union of all transaction types returned by transQuery.
615
+ * Narrow via `transactionType` to access type-specific fields:
616
+ *
617
+ * ```ts
618
+ * if (tx.transactionType === 'CreditCardSale') {
619
+ * console.log(tx.cardLastFour); // TS knows this exists
620
+ * }
621
+ * ```
622
+ */
623
+ export type TransactionData = CardTransactionData | AchTransactionData | CryptoTransactionData;
624
+ /** Query params for GET /api/v1/transQuery. */
625
+ export interface TransactionQueryParams {
626
+ merchantId: string;
627
+ /** Fetch a specific transaction. */
628
+ transactionId?: string;
629
+ /** Date range start, format "YYYY-MM-DD HH:MM:SS". */
630
+ dateFrom?: string;
631
+ /** Date range end, format "YYYY-MM-DD HH:MM:SS". */
632
+ dateTo?: string;
633
+ /** Filter by transaction type, e.g. "CreditCardSale", "AchSale". */
634
+ transactionType?: TransactionType;
635
+ /** 1-based page number. Default: 1. */
636
+ page?: number;
637
+ /** Results per page. Default: 50, max: 100. */
638
+ limit?: number;
639
+ /** Comma-separated field names to return. */
640
+ fields?: string;
641
+ sortBy?: string;
642
+ sortOrder?: 'asc' | 'desc';
643
+ }
644
+ export interface TransactionQueryPagination {
645
+ currentPage: number;
646
+ totalPages: number;
647
+ totalCount: number;
648
+ limit: number;
649
+ hasNextPage: boolean;
650
+ hasPrevPage: boolean;
651
+ nextPage: number | null;
652
+ prevPage: number | null;
653
+ }
654
+ export interface TransactionQueryResponse {
655
+ success: boolean;
656
+ data: TransactionData[];
657
+ pagination: TransactionQueryPagination;
658
+ }
659
+ 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' | 'OZ_DEBUG_LOG';
660
+ export interface OzMessage {
661
+ __oz: true;
662
+ /** Protocol version stamped by the frame on OZ_FRAME_READY. Read by the SDK to detect stale CDN frames. */
663
+ __ozVersion?: number;
664
+ vaultId: string;
665
+ type: OzMessageType;
666
+ [key: string]: unknown;
667
+ }
@@ -0,0 +1,22 @@
1
+ import type { Appearance, ElementStyleConfig } from '../types';
2
+ /**
3
+ * Resolves an `Appearance` config into a flat `ElementStyleConfig`.
4
+ * Resolution order: theme defaults → variable overrides.
5
+ * The returned config is then used as the "base appearance" that
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.
16
+ */
17
+ export declare function resolveAppearance(appearance?: Appearance): ElementStyleConfig | undefined;
18
+ /**
19
+ * Merges a resolved appearance with per-element style overrides.
20
+ * Element styles always win over appearance styles.
21
+ */
22
+ export declare function mergeAppearanceWithElementStyle(appearance: ElementStyleConfig | undefined, elementStyle: ElementStyleConfig | undefined): ElementStyleConfig | undefined;