@idonatedev/idonate-sdk 1.2.0-dev1 → 1.2.0-dev10

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/dist/constants.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CLIENT_HEADERS = exports.CARD_CONNECT_DEFAULT_STYLE = exports.DEFAULT_APP_NAME = exports.DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL = exports.FALLBACK_CF_TURNSTILE_SITE_KEY = exports.FALLBACK_PC_SCRIPT_ID = exports.FALLBACK_PC_SCRIPT_URL = exports.SANDBOX_APPLE_PAY_URL = exports.APPLE_PAY_URL = exports.SPREEDLY_TOKENIZER_URL = exports.SANDBOX_CARD_CONNECT_BASE_URL = exports.PRODUCTION_CARD_CONNECT_BASE_URL = exports.SANDBOX_BASE_URL = exports.PRODUCTION_BASE_URL = exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = '1.2.0-dev1';
4
+ exports.SDK_VERSION = '1.2.0-dev9';
5
5
  exports.PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
6
6
  exports.SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
7
7
  exports.PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
@@ -78,7 +78,16 @@ input#cccvvfield {
78
78
  color: #8b959d;
79
79
  }
80
80
  `.replace(/\s+/gi, ' ');
81
+ function getUserAgent() {
82
+ if (typeof navigator !== 'undefined') {
83
+ return navigator.userAgent;
84
+ }
85
+ if (typeof process !== 'undefined' && process.version) {
86
+ return `Node.js/${process.version} (${process.platform})`;
87
+ }
88
+ return 'unknown-runtime';
89
+ }
81
90
  exports.CLIENT_HEADERS = {
82
- 'User-Agent': navigator.userAgent + ` idonate-sdk@${exports.SDK_VERSION}`,
91
+ 'User-Agent': getUserAgent() + ` idonate-sdk@${exports.SDK_VERSION}`,
83
92
  'Content-Type': 'application/json',
84
93
  };
@@ -1,4 +1,4 @@
1
- export const SDK_VERSION = '1.2.0-dev1';
1
+ export const SDK_VERSION = '1.2.0-dev9';
2
2
  export const PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
3
3
  export const SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
4
4
  export const PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
@@ -75,7 +75,16 @@ input#cccvvfield {
75
75
  color: #8b959d;
76
76
  }
77
77
  `.replace(/\s+/gi, ' ');
78
+ function getUserAgent() {
79
+ if (typeof navigator !== 'undefined') {
80
+ return navigator.userAgent;
81
+ }
82
+ if (typeof process !== 'undefined' && process.version) {
83
+ return `Node.js/${process.version} (${process.platform})`;
84
+ }
85
+ return 'unknown-runtime';
86
+ }
78
87
  export const CLIENT_HEADERS = {
79
- 'User-Agent': navigator.userAgent + ` idonate-sdk@${SDK_VERSION}`,
88
+ 'User-Agent': getUserAgent() + ` idonate-sdk@${SDK_VERSION}`,
80
89
  'Content-Type': 'application/json',
81
90
  };
@@ -10,3 +10,4 @@ export declare class RecaptchaElement {
10
10
  resolveToken(): Promise<string>;
11
11
  }
12
12
  export declare function wrapElement(container: string, sitekey: string, extraParams?: any): RecaptchaElement;
13
+ export declare function wrapElementWithThrow(container: string, sitekey: string, extraParams?: any): Promise<RecaptchaElement>;
@@ -1,3 +1,12 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  function resolveLib() {
2
11
  const startWait = new Date();
3
12
  return new Promise((resolve, reject) => {
@@ -87,3 +96,11 @@ export function wrapElement(container, sitekey, extraParams) {
87
96
  captcha.render();
88
97
  return captcha;
89
98
  }
99
+ export function wrapElementWithThrow(container, sitekey, extraParams) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ const params = Object.assign(Object.assign({}, (extraParams || {})), { sitekey });
102
+ const captcha = new RecaptchaElement(container, params);
103
+ yield captcha.render();
104
+ return captcha;
105
+ });
106
+ }
@@ -11,7 +11,7 @@ import { Tokenizer } from './Tokenizer';
11
11
  import { TokenizationError, } from './types';
12
12
  import ConfigHandler from '../config-handler';
13
13
  import { DEFAULT_UNIFIED_STYLES, mergeStyles, getContainerStylesForLayout, } from './styles';
14
- import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, BANK_FIELD_FLEX, } from './tokenizer-constants';
14
+ import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, BANK_FIELD_FLEX, RESPONSIVE_BREAKPOINT, } from './tokenizer-constants';
15
15
  import { createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, } from './tokenizer-utils';
16
16
  export class CardConnectTokenizer extends Tokenizer {
17
17
  constructor(iframe, iframeUrl, containerId, mode = 'credit_card', enableTestMode = false, layout = 'single-line') {
@@ -38,13 +38,25 @@ export class CardConnectTokenizer extends Tokenizer {
38
38
  if (container.mode === 'bank_account' && container.bankCountry === 'CA') {
39
39
  throw new Error('CardConnect does not support Canadian bank accounts');
40
40
  }
41
+ let effectiveLayout = 'single-line';
42
+ if (container.layout === 'responsive') {
43
+ const containerEl = document.getElementById(container.containerId);
44
+ const containerWidth = (containerEl === null || containerEl === void 0 ? void 0 : containerEl.offsetWidth) || 0;
45
+ const breakpoint = container.responsiveBreakpoint || RESPONSIVE_BREAKPOINT;
46
+ effectiveLayout =
47
+ containerWidth < breakpoint ? 'two-line' : 'single-line';
48
+ }
49
+ else if (container.layout === 'two-line') {
50
+ effectiveLayout = 'two-line';
51
+ }
52
+ const resolvedContainer = Object.assign(Object.assign({}, container), { layout: effectiveLayout });
41
53
  let baseUrl = ((_a = gateway.config) === null || _a === void 0 ? void 0 : _a.base_url) || config.clientConfig.cardConnectBaseUrl;
42
54
  config.cardConnectBaseUrl = baseUrl;
43
55
  const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
44
- const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, container);
56
+ const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, resolvedContainer);
45
57
  const iframe = CardConnectTokenizer.createIframe(iframeUrl, mergedStyles);
46
- const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, container.layout || 'single-line');
47
- tokenizer.createInternalElements(container);
58
+ const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout);
59
+ tokenizer.createInternalElements(resolvedContainer);
48
60
  yield tokenizer.init();
49
61
  return tokenizer;
50
62
  });
@@ -67,7 +79,7 @@ export class CardConnectTokenizer extends Tokenizer {
67
79
  }
68
80
  createCreditCardFields(containerEl, mergedStyles) {
69
81
  this.iframe.style.width = '100%';
70
- if (this.layout === 'two-line') {
82
+ if (this.layout === 'two-line' || this.layout === 'responsive') {
71
83
  const inputHeight = mergedStyles.input.height || '40px';
72
84
  this.iframe.style.height = `calc((${inputHeight}) * 2 + 10px)`;
73
85
  }
@@ -447,7 +459,8 @@ export class CardConnectTokenizer extends Tokenizer {
447
459
  : this.normalizeCardType('unknown');
448
460
  return {
449
461
  token: this.cachedTokenResult.token,
450
- lastFour: this.cachedTokenResult.last4 || this.cachedTokenResult.token.slice(-4),
462
+ lastFour: this.cachedTokenResult.last4 ||
463
+ this.cachedTokenResult.token.slice(-4),
451
464
  cardType,
452
465
  provider: 'cardconnect',
453
466
  };
@@ -540,12 +553,15 @@ export class CardConnectTokenizer extends Tokenizer {
540
553
  errorLower.includes('year')) {
541
554
  this.currentValidationState.expiry = { isValid: false, isEmpty: false };
542
555
  }
543
- this.emit('error', new TokenizationError(data.validationError));
556
+ this.currentValidationState.isValid = false;
557
+ this.emit('validation', this.currentValidationState);
558
+ }
559
+ else {
560
+ this.currentValidationState.isValid =
561
+ ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
562
+ ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false) &&
563
+ ((_f = (_e = this.currentValidationState.expiry) === null || _e === void 0 ? void 0 : _e.isValid) !== null && _f !== void 0 ? _f : false);
544
564
  }
545
- this.currentValidationState.isValid =
546
- ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
547
- ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false) &&
548
- ((_f = (_e = this.currentValidationState.expiry) === null || _e === void 0 ? void 0 : _e.isValid) !== null && _f !== void 0 ? _f : false);
549
565
  }
550
566
  static generateIframeUrl(baseUrl, container) {
551
567
  const params = new URLSearchParams({
@@ -574,7 +590,12 @@ export class CardConnectTokenizer extends Tokenizer {
574
590
  params.set('placeholderyear', 'YYYY');
575
591
  }
576
592
  const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
577
- const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, container.layout || 'single-line');
593
+ const isDesktopSafari = typeof navigator !== 'undefined' &&
594
+ /Safari/.test(navigator.userAgent) &&
595
+ /Apple Computer/.test(navigator.vendor) &&
596
+ !/Chrome/.test(navigator.userAgent) &&
597
+ !/Mobile/.test(navigator.userAgent);
598
+ const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari);
578
599
  const queryPairs = [];
579
600
  params.forEach((value, key) => {
580
601
  queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
@@ -607,8 +628,8 @@ export class CardConnectTokenizer extends Tokenizer {
607
628
  iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
608
629
  return iframe;
609
630
  }
610
- static generateCardConnectCss(styles, layout = 'single-line') {
611
- var _a, _b, _c, _d;
631
+ static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false) {
632
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
612
633
  const css = [];
613
634
  if (layout === 'two-line') {
614
635
  css.push('html,form,body{margin:0;padding:0;}');
@@ -642,14 +663,22 @@ export class CardConnectTokenizer extends Tokenizer {
642
663
  commonStyles.push('box-sizing:border-box');
643
664
  const baseStyles = commonStyles.join(';');
644
665
  css.push(`input{${baseStyles};}`);
645
- css.push(`select{${baseStyles};}`);
666
+ if (isDesktopSafari) {
667
+ css.push(`select{${baseStyles};-webkit-appearance:none;appearance:none;}`);
668
+ }
669
+ else {
670
+ css.push(`select{${baseStyles};}`);
671
+ }
646
672
  }
647
673
  if (layout === 'two-line') {
648
674
  css.push('input#ccnumfield{width:100%;display:block;margin-bottom:8px;}');
649
- css.push('input#ccexpiryfieldmonth{width:20%;}');
650
- css.push('input#ccexpiryfieldyear{width:24%;}');
651
- css.push('input#cccvvfield{width:calc(56% - 20px);}');
652
- if ((_a = styles.input) === null || _a === void 0 ? void 0 : _a.borderRadius) {
675
+ const twoLinePadding = ((_a = styles.twoLine) === null || _a === void 0 ? void 0 : _a.padding) || ((_b = styles.input) === null || _b === void 0 ? void 0 : _b.padding) || '10px';
676
+ const twoLineFontSize = ((_c = styles.twoLine) === null || _c === void 0 ? void 0 : _c.fontSize) || ((_d = styles.input) === null || _d === void 0 ? void 0 : _d.fontSize) || '14px';
677
+ const twoLineTextAlign = ((_e = styles.twoLine) === null || _e === void 0 ? void 0 : _e.textAlign) || 'left';
678
+ css.push(`input#ccexpiryfieldmonth{width:25%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
679
+ css.push(`input#ccexpiryfieldyear{width:35%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
680
+ css.push(`input#cccvvfield{width:calc(40% - 16px);padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};margin-left:-4px;}`);
681
+ if ((_f = styles.input) === null || _f === void 0 ? void 0 : _f.borderRadius) {
653
682
  css.push(`input{border-radius:${styles.input.borderRadius};}`);
654
683
  }
655
684
  }
@@ -658,7 +687,7 @@ export class CardConnectTokenizer extends Tokenizer {
658
687
  css.push('select#ccexpirymonth{width:16%;margin:0;margin-right:-12px;}');
659
688
  css.push('select#ccexpiryyear{width:20%;}');
660
689
  css.push('input#cccvvfield{width:20%;margin:0;margin-left:-12px;}');
661
- if ((_b = styles.input) === null || _b === void 0 ? void 0 : _b.borderRadius) {
690
+ if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
662
691
  css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right:none;}`);
663
692
  css.push('select#ccexpirymonth{border-radius:0;border-right:none;}');
664
693
  css.push('select#ccexpiryyear{border-radius:0;border-right:none;}');
@@ -676,7 +705,7 @@ export class CardConnectTokenizer extends Tokenizer {
676
705
  css.push(`select#ccexpirymonth{width:15%;margin-right:${marginRight};}`);
677
706
  css.push(`select#ccexpiryyear{width:20%;margin-right:${marginRight};}`);
678
707
  css.push('input#cccvvfield{width:15%;}');
679
- if ((_c = styles.input) === null || _c === void 0 ? void 0 : _c.borderRadius) {
708
+ if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
680
709
  css.push(`input,select{border-radius:${styles.input.borderRadius};}`);
681
710
  }
682
711
  }
@@ -692,7 +721,7 @@ export class CardConnectTokenizer extends Tokenizer {
692
721
  if (focusStyles.length > 0) {
693
722
  css.push(`input:focus{${focusStyles.join(';')};}`);
694
723
  css.push(`select:focus{${focusStyles.join(';')};}`);
695
- if (isConnected && ((_d = styles.input) === null || _d === void 0 ? void 0 : _d.border)) {
724
+ if (isConnected && ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.border)) {
696
725
  css.push(`input#ccnumfield:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
697
726
  css.push(`select#ccexpirymonth:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
698
727
  css.push(`select#ccexpiryyear:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
@@ -31,6 +31,10 @@ interface PayPalApproveData {
31
31
  payerID?: string;
32
32
  facilitatorAccessToken?: string;
33
33
  }
34
+ export interface PayPalCreateOrderData {
35
+ amount: number;
36
+ currency?: string;
37
+ }
34
38
  export declare class PayPalTokenizer extends Tokenizer {
35
39
  private gateway;
36
40
  private containerId;
@@ -49,6 +53,7 @@ export declare class PayPalTokenizer extends Tokenizer {
49
53
  private clientConfig;
50
54
  private paymentTransactionId?;
51
55
  private paymentMethodId?;
56
+ private onCreateOrder?;
52
57
  private constructor();
53
58
  static create(gateway: PaymentGateway, container: TokenizerContainer, config: {
54
59
  organizationId: string;
@@ -30,6 +30,7 @@ export class PayPalTokenizer extends Tokenizer {
30
30
  this.amount = config.amount;
31
31
  this.enableVenmo = (_b = config.enableVenmo) !== null && _b !== void 0 ? _b : true;
32
32
  this.locale = config.locale || 'en_US';
33
+ this.onCreateOrder = config.onCreateOrder;
33
34
  this.organizationId = configContext.organizationId;
34
35
  this.embedId = configContext.embedId;
35
36
  this.clientConfig = configContext.clientConfig;
@@ -160,13 +161,26 @@ export class PayPalTokenizer extends Tokenizer {
160
161
  }
161
162
  createOrder() {
162
163
  const endpoint = `${this.clientConfig.embedApiBaseUrl}/payment/paypal/create-order`;
164
+ let orderAmount;
165
+ let orderCurrency = this.currency;
166
+ if (this.onCreateOrder) {
167
+ const orderData = this.onCreateOrder();
168
+ orderAmount = orderData.amount;
169
+ orderCurrency = orderData.currency || this.currency;
170
+ }
171
+ else {
172
+ orderAmount = this.amount;
173
+ }
174
+ if (orderAmount === undefined || orderAmount <= 0) {
175
+ const error = new Error('Amount is required to create PayPal order');
176
+ this.handleError(error, 'Order creation failed');
177
+ return Promise.reject(error);
178
+ }
163
179
  const requestBody = {
164
180
  payment_gateway_id: this.gateway.id,
165
- currency: this.currency,
181
+ currency: orderCurrency,
182
+ amount: orderAmount,
166
183
  };
167
- if (this.amount !== undefined) {
168
- requestBody.amount = this.amount;
169
- }
170
184
  return fetch(endpoint, {
171
185
  method: 'POST',
172
186
  headers: {
@@ -24,6 +24,11 @@ export declare class SpreedlyTokenizer extends Tokenizer {
24
24
  private institutionNumberEl?;
25
25
  private transitNumberEl?;
26
26
  private enableTestMode;
27
+ private resizeObserver?;
28
+ private effectiveLayout;
29
+ private cardNumberDiv?;
30
+ private cvvDiv?;
31
+ private responsiveBreakpoint;
27
32
  private constructor();
28
33
  static create(gateway: PaymentGateway, container: TokenizerContainer, config: {
29
34
  organizationId: string;
@@ -42,6 +47,9 @@ export declare class SpreedlyTokenizer extends Tokenizer {
42
47
  private stylesToCssString;
43
48
  clear(): void;
44
49
  focus(field: 'cardNumber' | 'cvv' | 'expiry' | 'routingNumber' | 'accountNumber'): void;
50
+ private determineLayout;
51
+ private setupResizeObserver;
52
+ private applyLayoutStyles;
45
53
  destroy(): void;
46
54
  hasToken(): boolean;
47
55
  getToken(): PaymentToken | null;
@@ -67,7 +75,7 @@ export declare class SpreedlyTokenizer extends Tokenizer {
67
75
  });
68
76
  address: Partial<Address>;
69
77
  account: Partial<ACHAccount> & Pick<ACHAccount, 'accountNumber' | 'routingNumber'>;
70
- }, config: ConfigHandler): Promise<string>;
78
+ }, config: ConfigHandler, environmentKeyOverride?: string): Promise<string>;
71
79
  static tokenizeCreditCard(data: {
72
80
  contact: Partial<Contact> & ({
73
81
  firstName: string;
@@ -13,21 +13,24 @@ import { SPREEDLY_TOKENIZER_URL } from '../constants';
13
13
  import { extractSpreedlyToken, unpackSpreedlyResponse } from '../typeAdapters';
14
14
  import { fetchSpreedlySecurityArgs, } from './spreedly-secure';
15
15
  import { DEFAULT_UNIFIED_STYLES, mergeStyles, getContainerStylesForLayout, } from './styles';
16
- import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, FIELD_FLEX, BANK_FIELD_FLEX, CANADIAN_BANK_FIELD_FLEX, PLACEHOLDERS, FIELD_CONSTRAINTS, } from './tokenizer-constants';
16
+ import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, FIELD_FLEX, BANK_FIELD_FLEX, CANADIAN_BANK_FIELD_FLEX, PLACEHOLDERS, FIELD_CONSTRAINTS, RESPONSIVE_BREAKPOINT, } from './tokenizer-constants';
17
17
  import { createFieldContainer, createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, validateInstitutionNumber, validateTransitNumber, validateCanadianAccountNumber, formatCanadianRoutingNumber, } from './tokenizer-utils';
18
18
  const SPREEDLY_SCRIPT_URL = 'https://core.spreedly.com/iframe/iframe-v1.min.js';
19
19
  const SPREEDLY_SCRIPT_ID = 'spreedly-iframe-script';
20
20
  export class SpreedlyTokenizer extends Tokenizer {
21
- constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line') {
21
+ constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line', responsiveBreakpoint = RESPONSIVE_BREAKPOINT) {
22
22
  super();
23
23
  this.environmentKey = environmentKey;
24
24
  this.containerId = containerId;
25
25
  this.layout = layout;
26
26
  this.bankCountry = 'US';
27
27
  this.enableTestMode = false;
28
+ this.effectiveLayout = 'single-line';
29
+ this.responsiveBreakpoint = RESPONSIVE_BREAKPOINT;
28
30
  this.mode = mode;
29
31
  this.bankCountry = bankCountry;
30
32
  this.enableTestMode = enableTestMode;
33
+ this.responsiveBreakpoint = responsiveBreakpoint;
31
34
  if (mode === 'credit_card') {
32
35
  const SpreedlyFrame = window.SpreedlyPaymentFrame;
33
36
  if (SpreedlyFrame) {
@@ -74,7 +77,7 @@ export class SpreedlyTokenizer extends Tokenizer {
74
77
  if (!environmentKey) {
75
78
  environmentKey = '';
76
79
  }
77
- const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line');
80
+ const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', container.responsiveBreakpoint || RESPONSIVE_BREAKPOINT);
78
81
  tokenizer.organizationId = config.organizationId;
79
82
  tokenizer.embedId = config.embedId;
80
83
  tokenizer.clientConfig = config.clientConfig;
@@ -241,11 +244,11 @@ export class SpreedlyTokenizer extends Tokenizer {
241
244
  year: expiryYear,
242
245
  email: cardData.email,
243
246
  phone_number: cardData.phone,
244
- address1: (_a = cardData.address) === null || _a === void 0 ? void 0 : _a.line1,
245
- address2: (_b = cardData.address) === null || _b === void 0 ? void 0 : _b.line2,
247
+ address1: (_a = cardData.address) === null || _a === void 0 ? void 0 : _a.address1,
248
+ address2: (_b = cardData.address) === null || _b === void 0 ? void 0 : _b.address2,
246
249
  city: (_c = cardData.address) === null || _c === void 0 ? void 0 : _c.city,
247
250
  state: (_d = cardData.address) === null || _d === void 0 ? void 0 : _d.state,
248
- zip: (_e = cardData.address) === null || _e === void 0 ? void 0 : _e.postalCode,
251
+ zip: (_e = cardData.address) === null || _e === void 0 ? void 0 : _e.zip,
249
252
  country: (_f = cardData.address) === null || _f === void 0 ? void 0 : _f.country,
250
253
  });
251
254
  });
@@ -426,11 +429,11 @@ export class SpreedlyTokenizer extends Tokenizer {
426
429
  primaryPhone: bankData.phone,
427
430
  },
428
431
  address: {
429
- address1: (_g = bankData.address) === null || _g === void 0 ? void 0 : _g.line1,
430
- address2: (_h = bankData.address) === null || _h === void 0 ? void 0 : _h.line2,
432
+ address1: (_g = bankData.address) === null || _g === void 0 ? void 0 : _g.address1,
433
+ address2: (_h = bankData.address) === null || _h === void 0 ? void 0 : _h.address2,
431
434
  city: (_j = bankData.address) === null || _j === void 0 ? void 0 : _j.city,
432
435
  state: (_k = bankData.address) === null || _k === void 0 ? void 0 : _k.state,
433
- zip: (_l = bankData.address) === null || _l === void 0 ? void 0 : _l.postalCode,
436
+ zip: (_l = bankData.address) === null || _l === void 0 ? void 0 : _l.zip,
434
437
  country: (_m = bankData.address) === null || _m === void 0 ? void 0 : _m.country,
435
438
  },
436
439
  account: {
@@ -439,7 +442,7 @@ export class SpreedlyTokenizer extends Tokenizer {
439
442
  accountType: accountType,
440
443
  accountHolderType: accountHolderType,
441
444
  },
442
- }, this.clientConfig);
445
+ }, this.clientConfig, this.environmentKey);
443
446
  return {
444
447
  token: result,
445
448
  lastFour: accountNumber.slice(-4),
@@ -582,8 +585,6 @@ export class SpreedlyTokenizer extends Tokenizer {
582
585
  }
583
586
  applyUnifiedStyles() {
584
587
  var _a;
585
- if (!this.isReady)
586
- return;
587
588
  const isConnected = ((_a = this.mergedStyles.container) === null || _a === void 0 ? void 0 : _a.gap) === '0';
588
589
  if (this.mergedStyles.input) {
589
590
  if (isConnected) {
@@ -682,7 +683,64 @@ export class SpreedlyTokenizer extends Tokenizer {
682
683
  element === null || element === void 0 ? void 0 : element.focus();
683
684
  }
684
685
  }
686
+ determineLayout(width) {
687
+ return width < this.responsiveBreakpoint ? 'two-line' : 'single-line';
688
+ }
689
+ setupResizeObserver() {
690
+ if (this.layout !== 'responsive')
691
+ return;
692
+ const container = document.getElementById(this.containerId);
693
+ if (!container)
694
+ return;
695
+ let debounceTimer;
696
+ this.resizeObserver = new ResizeObserver((entries) => {
697
+ clearTimeout(debounceTimer);
698
+ debounceTimer = setTimeout(() => {
699
+ const newWidth = entries[0].contentRect.width;
700
+ const newLayout = this.determineLayout(newWidth);
701
+ if (newLayout !== this.effectiveLayout) {
702
+ this.applyLayoutStyles(newLayout);
703
+ }
704
+ }, 100);
705
+ });
706
+ this.resizeObserver.observe(container);
707
+ }
708
+ applyLayoutStyles(newLayout) {
709
+ this.effectiveLayout = newLayout;
710
+ const container = document.getElementById(this.containerId);
711
+ if (!container)
712
+ return;
713
+ if (newLayout === 'two-line') {
714
+ container.style.flexWrap = 'wrap';
715
+ if (this.cardNumberDiv) {
716
+ this.cardNumberDiv.style.flex = '1';
717
+ this.cardNumberDiv.style.flexBasis = '100%';
718
+ }
719
+ if (this.expiryEl) {
720
+ this.expiryEl.style.flex = '1';
721
+ this.expiryEl.style.flexBasis = 'auto';
722
+ }
723
+ if (this.cvvDiv) {
724
+ this.cvvDiv.style.flex = '1';
725
+ this.cvvDiv.style.flexBasis = 'auto';
726
+ }
727
+ }
728
+ else {
729
+ container.style.flexWrap = 'nowrap';
730
+ if (this.cardNumberDiv) {
731
+ this.cardNumberDiv.style.flex = FIELD_FLEX.cardNumber.flex;
732
+ }
733
+ if (this.expiryEl) {
734
+ this.expiryEl.style.flex = FIELD_FLEX.expiry.flex;
735
+ }
736
+ if (this.cvvDiv) {
737
+ this.cvvDiv.style.flex = FIELD_FLEX.cvv.flex;
738
+ }
739
+ }
740
+ }
685
741
  destroy() {
742
+ var _a;
743
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
686
744
  if (this.spreedly && this.spreedly.removeHandlers) {
687
745
  this.spreedly.removeHandlers();
688
746
  }
@@ -759,10 +817,18 @@ export class SpreedlyTokenizer extends Tokenizer {
759
817
  }
760
818
  }
761
819
  createCreditCardFields(container) {
762
- if (this.layout === 'two-line') {
820
+ if (this.layout === 'responsive') {
821
+ this.effectiveLayout = this.determineLayout(container.offsetWidth);
822
+ }
823
+ else {
824
+ this.effectiveLayout =
825
+ this.layout === 'two-line' ? 'two-line' : 'single-line';
826
+ }
827
+ if (this.effectiveLayout === 'two-line' && this.layout !== 'responsive') {
763
828
  const cardNumberDiv = createFieldContainer(this.numberEl, '1', FIELD_FLEX.cardNumber.minWidth);
764
829
  cardNumberDiv.style.height = this.mergedStyles.input.height;
765
830
  cardNumberDiv.style.flexBasis = '100%';
831
+ this.cardNumberDiv = cardNumberDiv;
766
832
  container.appendChild(cardNumberDiv);
767
833
  this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
768
834
  Object.assign(this.expiryEl.style, {
@@ -783,11 +849,13 @@ export class SpreedlyTokenizer extends Tokenizer {
783
849
  container.appendChild(this.expiryEl);
784
850
  const cvvDiv = createFieldContainer(this.cvvEl, '1', FIELD_FLEX.cvv.minWidth);
785
851
  cvvDiv.style.height = this.mergedStyles.input.height;
852
+ this.cvvDiv = cvvDiv;
786
853
  container.appendChild(cvvDiv);
787
854
  }
788
855
  else {
789
856
  const cardNumberDiv = createFieldContainer(this.numberEl, FIELD_FLEX.cardNumber.flex, FIELD_FLEX.cardNumber.minWidth);
790
857
  cardNumberDiv.style.height = this.mergedStyles.input.height;
858
+ this.cardNumberDiv = cardNumberDiv;
791
859
  container.appendChild(cardNumberDiv);
792
860
  this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
793
861
  Object.assign(this.expiryEl.style, {
@@ -808,7 +876,12 @@ export class SpreedlyTokenizer extends Tokenizer {
808
876
  container.appendChild(this.expiryEl);
809
877
  const cvvDiv = createFieldContainer(this.cvvEl, FIELD_FLEX.cvv.flex, FIELD_FLEX.cvv.minWidth);
810
878
  cvvDiv.style.height = this.mergedStyles.input.height;
879
+ this.cvvDiv = cvvDiv;
811
880
  container.appendChild(cvvDiv);
881
+ if (this.layout === 'responsive') {
882
+ this.applyLayoutStyles(this.effectiveLayout);
883
+ this.setupResizeObserver();
884
+ }
812
885
  }
813
886
  }
814
887
  createBankAccountFields(container) {
@@ -1032,13 +1105,14 @@ export class SpreedlyTokenizer extends Tokenizer {
1032
1105
  throw new Error(`Timeout waiting for global: ${globalName}`);
1033
1106
  });
1034
1107
  }
1035
- static tokenizeBankAccount(data, config) {
1036
- if (config.spreedlyEnvironmentKey === undefined) {
1108
+ static tokenizeBankAccount(data, config, environmentKeyOverride) {
1109
+ const environmentKey = environmentKeyOverride || config.spreedlyEnvironmentKey;
1110
+ if (!environmentKey) {
1037
1111
  return Promise.reject(new Error('Spreedly is not configured.'));
1038
1112
  }
1039
1113
  return fetch(SPREEDLY_TOKENIZER_URL +
1040
1114
  '?' +
1041
- new URLSearchParams({ environment_key: config.spreedlyEnvironmentKey }), {
1115
+ new URLSearchParams({ environment_key: environmentKey }), {
1042
1116
  method: 'POST',
1043
1117
  headers: {
1044
1118
  'Content-Type': 'application/json',
@@ -2,6 +2,6 @@ import * as iats from './iats';
2
2
  export { Tokenizer } from './Tokenizer';
3
3
  export { SpreedlyTokenizer } from './SpreedlyTokenizer';
4
4
  export { CardConnectTokenizer } from './CardConnectTokenizer';
5
- export { PayPalTokenizer } from './PayPalTokenizer';
5
+ export { PayPalTokenizer, PayPalCreateOrderData } from './PayPalTokenizer';
6
6
  export { PaymentMethodType, PaymentGateway, TokenizerContainer, TokenizerStyling, CardData, PaymentData, PaymentToken, CardType, TokenizerEvent, ValidationState, ValidationResult, ValidationError, TokenizationError, } from './types';
7
7
  export { iats };
@@ -1,4 +1,4 @@
1
1
  import { TokenizerStyling, TokenizerStylingComplete } from './types';
2
2
  export declare const DEFAULT_UNIFIED_STYLES: TokenizerStylingComplete;
3
3
  export declare function mergeStyles(defaults: TokenizerStylingComplete, userStyles?: TokenizerStyling): TokenizerStylingComplete;
4
- export declare function getContainerStylesForLayout(baseStyles: TokenizerStylingComplete, layout?: 'single-line' | 'two-line'): TokenizerStylingComplete;
4
+ export declare function getContainerStylesForLayout(baseStyles: TokenizerStylingComplete, layout?: 'single-line' | 'two-line' | 'responsive'): TokenizerStylingComplete;
@@ -27,6 +27,11 @@ export const DEFAULT_UNIFIED_STYLES = {
27
27
  flexWrap: 'nowrap',
28
28
  rowGap: '1rem',
29
29
  },
30
+ twoLine: {
31
+ padding: '',
32
+ fontSize: '',
33
+ textAlign: '',
34
+ },
30
35
  };
31
36
  export function mergeStyles(defaults, userStyles) {
32
37
  if (!userStyles)
@@ -36,6 +41,7 @@ export function mergeStyles(defaults, userStyles) {
36
41
  focus: Object.assign(Object.assign({}, defaults.focus), userStyles.focus),
37
42
  error: Object.assign(Object.assign({}, defaults.error), userStyles.error),
38
43
  container: Object.assign(Object.assign({}, defaults.container), userStyles.container),
44
+ twoLine: Object.assign(Object.assign({}, defaults.twoLine), userStyles.twoLine),
39
45
  };
40
46
  }
41
47
  export function getContainerStylesForLayout(baseStyles, layout = 'single-line') {
@@ -60,3 +60,4 @@ export declare const FIELD_CONSTRAINTS: {
60
60
  readonly maxLength: 4;
61
61
  };
62
62
  };
63
+ export declare const RESPONSIVE_BREAKPOINT = 400;
@@ -60,3 +60,4 @@ export const FIELD_CONSTRAINTS = {
60
60
  maxLength: 4,
61
61
  },
62
62
  };
63
+ export const RESPONSIVE_BREAKPOINT = 400;
@@ -18,7 +18,8 @@ export interface TokenizerContainer {
18
18
  mode?: PaymentMethodMode;
19
19
  bankCountry?: 'US' | 'CA';
20
20
  enableTestMode?: boolean;
21
- layout?: 'single-line' | 'two-line';
21
+ layout?: 'single-line' | 'two-line' | 'responsive';
22
+ responsiveBreakpoint?: number;
22
23
  }
23
24
  export interface TokenizerStylingComplete {
24
25
  input: {
@@ -52,6 +53,11 @@ export interface TokenizerStylingComplete {
52
53
  flexWrap?: string;
53
54
  rowGap?: string;
54
55
  };
56
+ twoLine: {
57
+ padding: string;
58
+ fontSize: string;
59
+ textAlign: string;
60
+ };
55
61
  }
56
62
  type DeepPartial<T> = T extends object ? {
57
63
  [P in keyof T]?: DeepPartial<T[P]>;
@@ -63,11 +69,11 @@ export interface CardData {
63
69
  email?: string;
64
70
  phone?: string;
65
71
  address?: {
66
- line1?: string;
67
- line2?: string;
72
+ address1?: string;
73
+ address2?: string;
68
74
  city?: string;
69
75
  state?: string;
70
- postalCode?: string;
76
+ zip?: string;
71
77
  country?: string;
72
78
  };
73
79
  }
@@ -77,11 +83,11 @@ export interface BankAccountData {
77
83
  email?: string;
78
84
  phone?: string;
79
85
  address?: {
80
- line1?: string;
81
- line2?: string;
86
+ address1?: string;
87
+ address2?: string;
82
88
  city?: string;
83
89
  state?: string;
84
- postalCode?: string;
90
+ zip?: string;
85
91
  country?: string;
86
92
  };
87
93
  }
@@ -10,3 +10,4 @@ export declare class RecaptchaElement {
10
10
  resolveToken(): Promise<string>;
11
11
  }
12
12
  export declare function wrapElement(container: string, sitekey: string, extraParams?: any): RecaptchaElement;
13
+ export declare function wrapElementWithThrow(container: string, sitekey: string, extraParams?: any): Promise<RecaptchaElement>;