@ozura/elements 0.1.0-beta.4 → 0.1.0-beta.6

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 (37) hide show
  1. package/README.md +30 -27
  2. package/dist/frame/element-frame.html +1 -1
  3. package/dist/frame/tokenizer-frame.html +1 -1
  4. package/dist/frame/tokenizer-frame.js +33 -34
  5. package/dist/frame/tokenizer-frame.js.map +1 -1
  6. package/dist/oz-elements.esm.js +31 -37
  7. package/dist/oz-elements.esm.js.map +1 -1
  8. package/dist/oz-elements.umd.js +31 -36
  9. package/dist/oz-elements.umd.js.map +1 -1
  10. package/dist/react/frame/tokenizerFrame.d.ts +9 -9
  11. package/dist/react/index.cjs.js +33 -39
  12. package/dist/react/index.cjs.js.map +1 -1
  13. package/dist/react/index.esm.js +33 -39
  14. package/dist/react/index.esm.js.map +1 -1
  15. package/dist/react/react/index.d.ts +1 -3
  16. package/dist/react/sdk/OzVault.d.ts +1 -1
  17. package/dist/react/sdk/errors.d.ts +4 -3
  18. package/dist/react/sdk/index.d.ts +2 -2
  19. package/dist/react/server/index.d.ts +11 -17
  20. package/dist/react/types/index.d.ts +92 -5
  21. package/dist/server/frame/tokenizerFrame.d.ts +9 -9
  22. package/dist/server/index.cjs.js +18 -26
  23. package/dist/server/index.cjs.js.map +1 -1
  24. package/dist/server/index.esm.js +18 -26
  25. package/dist/server/index.esm.js.map +1 -1
  26. package/dist/server/sdk/OzVault.d.ts +1 -1
  27. package/dist/server/sdk/errors.d.ts +4 -3
  28. package/dist/server/sdk/index.d.ts +2 -2
  29. package/dist/server/server/index.d.ts +11 -17
  30. package/dist/server/types/index.d.ts +92 -5
  31. package/dist/types/frame/tokenizerFrame.d.ts +9 -9
  32. package/dist/types/sdk/OzVault.d.ts +1 -1
  33. package/dist/types/sdk/errors.d.ts +4 -3
  34. package/dist/types/sdk/index.d.ts +2 -2
  35. package/dist/types/server/index.d.ts +11 -17
  36. package/dist/types/types/index.d.ts +92 -5
  37. package/package.json +2 -2
@@ -4,17 +4,17 @@
4
4
  * Collects raw card field values sent by element frames (same-origin),
5
5
  * assembles the vault tokenization payload, and POSTs it directly to the
6
6
  * vault API. The merchant page never sees raw card data.
7
+ *
8
+ * The vault URL is determined by __VAULT_API_URL__, injected at build time.
9
+ * The tokenizer ignores any apiUrl sent by the SDK in OZ_TOKENIZE messages —
10
+ * an attacker who XSSes the merchant page cannot redirect where card data is
11
+ * sent because the destination is hardcoded in this Ozura-controlled bundle.
7
12
  */
8
13
  /**
9
- * Returns true when the given URL is a valid target for card data.
10
- *
11
- * The only requirement is that it is a parseable absolute URL using HTTPS
12
- * (or HTTP for localhost in dev). Merchant-specific domain allowlisting is
13
- * intentionally NOT done here — the vault API authenticates every request
14
- * via the merchant's private API key, so there is no security benefit to
15
- * restricting which HTTPS hosts the tokenizer may POST to. Baking a domain
16
- * allowlist into the frame bundle would force an SDK republish on every new
17
- * merchant onboarding, which is the wrong operational model.
14
+ * Defense-in-depth guard: only allows the build-time vault URL origin.
15
+ * The tokenizer already uses VAULT_API_URL directly and never reads
16
+ * the merchant-supplied apiUrl, so this is a secondary safety net
17
+ * not the primary security boundary.
18
18
  *
19
19
  * Exported for unit testing only — not part of the public SDK API.
20
20
  */
@@ -15,7 +15,6 @@ import { ElementType, BankElementType, ElementOptions, VaultOptions, TokenizeOpt
15
15
  export declare class OzVault {
16
16
  private apiKey;
17
17
  private pubKey;
18
- private apiUrl;
19
18
  private frameBaseUrl;
20
19
  private frameOrigin;
21
20
  private fonts;
@@ -63,6 +62,7 @@ export declare class OzVault {
63
62
  createBankElement(type: BankElementType, options?: ElementOptions): OzElement;
64
63
  /** Returns the existing bank element of the given type, or null if none has been created. */
65
64
  getBankElement(type: BankElementType): OzElement | null;
65
+ private createElementInto;
66
66
  /**
67
67
  * Tokenizes mounted bank account elements. Raw account and routing numbers
68
68
  * never leave the Ozura-origin iframes — the tokenizer iframe POSTs directly
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * errors.ts — error types and normalisation for OzElements.
3
3
  *
4
- * Two normalisation functions:
5
- * - normalizeVaultError — maps raw vault /tokenize errors to user-facing messages
6
- * - normalizeCardSaleError — maps raw cardSale API errors to user-facing messages
4
+ * Three normalisation functions:
5
+ * - normalizeVaultError — maps raw vault /tokenize errors to user-facing messages (card flows)
6
+ * - normalizeBankVaultError — maps raw vault /tokenize errors to user-facing messages (bank/ACH flows)
7
+ * - normalizeCardSaleError — maps raw cardSale API errors to user-facing messages
7
8
  *
8
9
  * Error keys in normalizeCardSaleError are taken directly from checkout's
9
10
  * errorMapping.ts so the same error strings produce the same user-facing copy.
@@ -1,5 +1,5 @@
1
1
  export { OzVault } from './OzVault';
2
2
  export { OzElement } from './OzElement';
3
- export { OzError, normalizeVaultError, normalizeCardSaleError } from './errors';
3
+ export { OzError, normalizeVaultError, normalizeBankVaultError, normalizeCardSaleError } from './errors';
4
4
  export type { OzErrorCode } from './errors';
5
- 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, } from '../types';
5
+ 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';
@@ -26,7 +26,7 @@
26
26
  * console.log(result.transactionId);
27
27
  * ```
28
28
  */
29
- import type { BillingDetails, CardSaleResponseData, TransactionQueryPagination } from '../types';
29
+ import type { BillingDetails, CardSaleResponseData, TransactionQueryPagination, TransactionData, TransactionType } from '../types';
30
30
  export interface OzuraConfig {
31
31
  /** Your Ozura merchant ID (e.g. "ozu_..."). */
32
32
  merchantId: string;
@@ -69,9 +69,11 @@ export interface CardSaleInput {
69
69
  tipAmount?: string;
70
70
  }
71
71
  export interface ListTransactionsInput {
72
+ /** Look up a single transaction by ID. When set, dateFrom/dateTo are not required. */
73
+ transactionId?: string;
72
74
  dateFrom?: string;
73
75
  dateTo?: string;
74
- transactionType?: string;
76
+ transactionType?: TransactionType;
75
77
  page?: number;
76
78
  limit?: number;
77
79
  fields?: string;
@@ -79,7 +81,7 @@ export interface ListTransactionsInput {
79
81
  sortOrder?: 'asc' | 'desc';
80
82
  }
81
83
  export interface ListTransactionsResult {
82
- transactions: CardSaleResponseData[];
84
+ transactions: TransactionData[];
83
85
  pagination: TransactionQueryPagination;
84
86
  }
85
87
  export declare class Ozura {
@@ -97,17 +99,6 @@ export declare class Ozura {
97
99
  * Rate limit: 100 requests/minute per merchant.
98
100
  */
99
101
  cardSale(input: CardSaleInput): Promise<CardSaleResponseData>;
100
- /**
101
- * Retrieve a single transaction by ID.
102
- *
103
- * **Known issue:** The Pay API requires the API key as a query parameter
104
- * (`access_token`), which means it can appear in server logs, CDN caches,
105
- * and HTTP Referer headers. This is a Pay API design issue — the SDK will
106
- * switch to header-based auth once the backend supports it.
107
- *
108
- * Rate limit: 100 requests/minute per merchant.
109
- */
110
- getTransaction(transactionId: string): Promise<CardSaleResponseData>;
111
102
  /**
112
103
  * List transactions by date range with pagination.
113
104
  *
@@ -120,14 +111,17 @@ export declare class Ozura {
120
111
  */
121
112
  private fetchWithRetry;
122
113
  private post;
123
- private get;
124
114
  private getRaw;
125
115
  private handleResponse;
126
116
  }
127
117
  /**
128
118
  * Extract the client IP address from a server request object.
129
119
  * Works with Express (`req.ip`), Fastify (`request.ip`), Next.js App Router
130
- * (`req.headers.get('x-forwarded-for')`), and raw Node.js `IncomingMessage`.
120
+ * (`req.headers.get()`), and raw Node.js `IncomingMessage`.
121
+ *
122
+ * Header priority: `req.ip` (framework-resolved) → `cf-connecting-ip`
123
+ * (Cloudflare) → `x-forwarded-for` (reverse proxy) → `x-real-ip` →
124
+ * `socket.remoteAddress` → `"0.0.0.0"`.
131
125
  *
132
126
  * @example
133
127
  * // Express / Fastify
@@ -137,4 +131,4 @@ export declare class Ozura {
137
131
  * clientIpAddress: getClientIp(req)
138
132
  */
139
133
  export declare function getClientIp(req: Record<string, unknown>): string;
140
- export type { BillingDetails, CardSaleResponseData, TransactionQueryPagination, } from '../types';
134
+ export type { BillingDetails, CardSaleResponseData, TransactionQueryPagination, TransactionType, TransactionBase, CardTransactionData, AchTransactionData, CryptoTransactionData, TransactionData, } from '../types';
@@ -150,8 +150,6 @@ export interface Appearance {
150
150
  variables?: AppearanceVariables;
151
151
  }
152
152
  export interface VaultOptions {
153
- /** Base URL of the vault API. Defaults to the Ozura production vault. */
154
- apiUrl?: string;
155
153
  /** System pub key required for tokenization. Obtain from Ozura admin.
156
154
  * Sent as the `X-Pub-Key` header on tokenize requests. */
157
155
  pubKey: string;
@@ -388,6 +386,95 @@ export interface CardSaleApiResponse {
388
386
  success: boolean;
389
387
  data: CardSaleResponseData;
390
388
  }
389
+ /**
390
+ * Transaction types returned by the Pay API transQuery endpoint.
391
+ * Mirrors the `TransactionType` enum in PayAPI-BE.
392
+ */
393
+ export type TransactionType = 'CreditCardSale' | 'CreditCardReversal' | 'CreditCardReturn' | 'CreditCardVoid' | 'AchSale' | 'AchReversal' | 'AchReturn' | 'AchVoid' | 'CryptoSale' | 'CryptoReturn' | 'CryptoWithdrawal';
394
+ export type CardTransactionType = 'CreditCardSale' | 'CreditCardReversal' | 'CreditCardReturn' | 'CreditCardVoid';
395
+ export type AchTransactionType = 'AchSale' | 'AchReversal' | 'AchReturn' | 'AchVoid';
396
+ export type CryptoTransactionType = 'CryptoSale' | 'CryptoReturn' | 'CryptoWithdrawal';
397
+ /**
398
+ * Shared fields returned by transQuery for all transaction types.
399
+ *
400
+ * Note: transQuery returns billing fields as `firstName`, `lastName`, etc.
401
+ * (the MongoDB field names), NOT the `billingFirstName` format used by the
402
+ * cardSale endpoint response. This is a backend inconsistency — these types
403
+ * reflect what the API actually returns.
404
+ */
405
+ export interface TransactionBase {
406
+ transactionId: string;
407
+ originalTransactionId?: string;
408
+ relatedTransactionIds?: string[];
409
+ transactionType: TransactionType;
410
+ amount: string;
411
+ currentAmount?: string;
412
+ surchargeAmount?: string;
413
+ tipAmount?: string;
414
+ currency: string;
415
+ status: string;
416
+ createdAt: string;
417
+ clientIpAddress?: string;
418
+ isVoided?: boolean;
419
+ isPartiallyReturned?: boolean;
420
+ isFullyReturned?: boolean;
421
+ isReversed?: boolean;
422
+ ozuraUserDetails?: {
423
+ ozuraUserId?: string;
424
+ ozuraMerchantId?: string;
425
+ };
426
+ avsResponseCode?: string;
427
+ cvvResponseCode?: string;
428
+ salesTaxData?: Record<string, unknown>;
429
+ firstName?: string;
430
+ lastName?: string;
431
+ email?: string;
432
+ phone?: string;
433
+ address1?: string;
434
+ address2?: string;
435
+ city?: string;
436
+ state?: string;
437
+ zipcode?: string;
438
+ country?: string;
439
+ }
440
+ /** Card transaction returned by transQuery. */
441
+ export interface CardTransactionData extends TransactionBase {
442
+ transactionType: CardTransactionType;
443
+ cardLastFour?: string;
444
+ cardBin?: string;
445
+ cardExpMonth?: string;
446
+ cardExpYear?: string;
447
+ cardBrand?: string;
448
+ isCreditCard?: boolean;
449
+ }
450
+ /** ACH transaction returned by transQuery. */
451
+ export interface AchTransactionData extends TransactionBase {
452
+ transactionType: AchTransactionType;
453
+ ddaAccountType?: string;
454
+ accountNumber?: string;
455
+ routingNumber?: string;
456
+ }
457
+ /** Crypto transaction returned by transQuery. */
458
+ export interface CryptoTransactionData extends TransactionBase {
459
+ transactionType: CryptoTransactionType;
460
+ originalSourceAddress?: string;
461
+ originalDepositAddress?: string;
462
+ network?: string;
463
+ mintDetails?: {
464
+ mintTransactionHash?: string;
465
+ };
466
+ }
467
+ /**
468
+ * Discriminated union of all transaction types returned by transQuery.
469
+ * Narrow via `transactionType` to access type-specific fields:
470
+ *
471
+ * ```ts
472
+ * if (tx.transactionType === 'CreditCardSale') {
473
+ * console.log(tx.cardLastFour); // TS knows this exists
474
+ * }
475
+ * ```
476
+ */
477
+ export type TransactionData = CardTransactionData | AchTransactionData | CryptoTransactionData;
391
478
  /** Query params for GET /api/v1/transQuery. */
392
479
  export interface TransactionQueryParams {
393
480
  merchantId: string;
@@ -397,8 +484,8 @@ export interface TransactionQueryParams {
397
484
  dateFrom?: string;
398
485
  /** Date range end, format "YYYY-MM-DD HH:MM:SS". */
399
486
  dateTo?: string;
400
- /** Filter by type, e.g. "sale", "refund". */
401
- transactionType?: string;
487
+ /** Filter by transaction type, e.g. "CreditCardSale", "AchSale". */
488
+ transactionType?: TransactionType;
402
489
  /** 1-based page number. Default: 1. */
403
490
  page?: number;
404
491
  /** Results per page. Default: 50, max: 100. */
@@ -420,7 +507,7 @@ export interface TransactionQueryPagination {
420
507
  }
421
508
  export interface TransactionQueryResponse {
422
509
  success: boolean;
423
- data: CardSaleResponseData[];
510
+ data: TransactionData[];
424
511
  pagination: TransactionQueryPagination;
425
512
  }
426
513
  export type OzMessageType = 'OZ_FRAME_READY' | 'OZ_INIT' | 'OZ_UPDATE' | 'OZ_CLEAR' | 'OZ_CHANGE' | 'OZ_FOCUS' | 'OZ_BLUR' | 'OZ_RESIZE' | 'OZ_SET_TOKENIZER_NAME' | '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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozura/elements",
3
- "version": "0.1.0-beta.4",
3
+ "version": "0.1.0-beta.6",
4
4
  "description": "PCI-compliant card tokenization SDK for the Ozura Vault — collect card data in iframe-isolated fields and tokenize without PCI scope",
5
5
  "main": "dist/oz-elements.umd.js",
6
6
  "module": "dist/oz-elements.esm.js",
@@ -72,7 +72,7 @@
72
72
  "url": "https://github.com/Ozura-Inc/pci-vault-elements"
73
73
  },
74
74
  "engines": {
75
- "node": ">=18 <24"
75
+ "node": ">=18"
76
76
  },
77
77
  "sideEffects": false,
78
78
  "devDependencies": {