@idonatedev/idonate-sdk 1.2.0-dev0 → 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.
Files changed (36) hide show
  1. package/dist/constants.js +11 -2
  2. package/dist/esm/constants.js +11 -2
  3. package/dist/esm/recaptcha.d.ts +1 -0
  4. package/dist/esm/recaptcha.js +17 -0
  5. package/dist/esm/tokenize/CardConnectTokenizer.d.ts +1 -1
  6. package/dist/esm/tokenize/CardConnectTokenizer.js +71 -28
  7. package/dist/esm/tokenize/PayPalTokenizer.d.ts +5 -1
  8. package/dist/esm/tokenize/PayPalTokenizer.js +24 -20
  9. package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +9 -2
  10. package/dist/esm/tokenize/SpreedlyTokenizer.js +90 -19
  11. package/dist/esm/tokenize/Tokenizer.d.ts +2 -0
  12. package/dist/esm/tokenize/Tokenizer.js +14 -0
  13. package/dist/esm/tokenize/index.d.ts +1 -1
  14. package/dist/esm/tokenize/styles.d.ts +1 -1
  15. package/dist/esm/tokenize/styles.js +6 -0
  16. package/dist/esm/tokenize/tokenizer-constants.d.ts +1 -0
  17. package/dist/esm/tokenize/tokenizer-constants.js +1 -0
  18. package/dist/esm/tokenize/types.d.ts +13 -7
  19. package/dist/recaptcha.d.ts +1 -0
  20. package/dist/recaptcha.js +18 -0
  21. package/dist/tokenize/CardConnectTokenizer.d.ts +1 -1
  22. package/dist/tokenize/CardConnectTokenizer.js +70 -27
  23. package/dist/tokenize/PayPalTokenizer.d.ts +5 -1
  24. package/dist/tokenize/PayPalTokenizer.js +24 -20
  25. package/dist/tokenize/SpreedlyTokenizer.d.ts +9 -2
  26. package/dist/tokenize/SpreedlyTokenizer.js +89 -18
  27. package/dist/tokenize/Tokenizer.d.ts +2 -0
  28. package/dist/tokenize/Tokenizer.js +14 -0
  29. package/dist/tokenize/index.d.ts +1 -1
  30. package/dist/tokenize/styles.d.ts +1 -1
  31. package/dist/tokenize/styles.js +6 -0
  32. package/dist/tokenize/tokenizer-constants.d.ts +1 -0
  33. package/dist/tokenize/tokenizer-constants.js +2 -1
  34. package/dist/tokenize/types.d.ts +13 -7
  35. package/package.json +13 -2
  36. package/umd/idonate-sdk.js +1 -1
@@ -13,22 +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
- this.isReady = false;
27
26
  this.bankCountry = 'US';
28
27
  this.enableTestMode = false;
28
+ this.effectiveLayout = 'single-line';
29
+ this.responsiveBreakpoint = RESPONSIVE_BREAKPOINT;
29
30
  this.mode = mode;
30
31
  this.bankCountry = bankCountry;
31
32
  this.enableTestMode = enableTestMode;
33
+ this.responsiveBreakpoint = responsiveBreakpoint;
32
34
  if (mode === 'credit_card') {
33
35
  const SpreedlyFrame = window.SpreedlyPaymentFrame;
34
36
  if (SpreedlyFrame) {
@@ -75,7 +77,7 @@ export class SpreedlyTokenizer extends Tokenizer {
75
77
  if (!environmentKey) {
76
78
  environmentKey = '';
77
79
  }
78
- 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);
79
81
  tokenizer.organizationId = config.organizationId;
80
82
  tokenizer.embedId = config.embedId;
81
83
  tokenizer.clientConfig = config.clientConfig;
@@ -101,7 +103,6 @@ export class SpreedlyTokenizer extends Tokenizer {
101
103
  return __awaiter(this, void 0, void 0, function* () {
102
104
  this.containerEl = document.getElementById(this.containerId);
103
105
  if (this.mode === 'bank_account') {
104
- this.isReady = true;
105
106
  if (this.enableTestMode) {
106
107
  setTimeout(() => {
107
108
  if (this.bankCountry === 'CA') {
@@ -143,7 +144,6 @@ export class SpreedlyTokenizer extends Tokenizer {
143
144
  }, INIT_TIMEOUT);
144
145
  this.spreedly.on('ready', () => {
145
146
  clearTimeout(timeout);
146
- this.isReady = true;
147
147
  this.spreedly.setPlaceholder('number', PLACEHOLDERS.cardNumber);
148
148
  this.spreedly.setFieldType('number', 'text');
149
149
  this.spreedly.setNumberFormat('prettyFormat');
@@ -244,11 +244,11 @@ export class SpreedlyTokenizer extends Tokenizer {
244
244
  year: expiryYear,
245
245
  email: cardData.email,
246
246
  phone_number: cardData.phone,
247
- address1: (_a = cardData.address) === null || _a === void 0 ? void 0 : _a.line1,
248
- 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,
249
249
  city: (_c = cardData.address) === null || _c === void 0 ? void 0 : _c.city,
250
250
  state: (_d = cardData.address) === null || _d === void 0 ? void 0 : _d.state,
251
- 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,
252
252
  country: (_f = cardData.address) === null || _f === void 0 ? void 0 : _f.country,
253
253
  });
254
254
  });
@@ -429,11 +429,11 @@ export class SpreedlyTokenizer extends Tokenizer {
429
429
  primaryPhone: bankData.phone,
430
430
  },
431
431
  address: {
432
- address1: (_g = bankData.address) === null || _g === void 0 ? void 0 : _g.line1,
433
- 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,
434
434
  city: (_j = bankData.address) === null || _j === void 0 ? void 0 : _j.city,
435
435
  state: (_k = bankData.address) === null || _k === void 0 ? void 0 : _k.state,
436
- 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,
437
437
  country: (_m = bankData.address) === null || _m === void 0 ? void 0 : _m.country,
438
438
  },
439
439
  account: {
@@ -442,7 +442,7 @@ export class SpreedlyTokenizer extends Tokenizer {
442
442
  accountType: accountType,
443
443
  accountHolderType: accountHolderType,
444
444
  },
445
- }, this.clientConfig);
445
+ }, this.clientConfig, this.environmentKey);
446
446
  return {
447
447
  token: result,
448
448
  lastFour: accountNumber.slice(-4),
@@ -585,8 +585,6 @@ export class SpreedlyTokenizer extends Tokenizer {
585
585
  }
586
586
  applyUnifiedStyles() {
587
587
  var _a;
588
- if (!this.isReady)
589
- return;
590
588
  const isConnected = ((_a = this.mergedStyles.container) === null || _a === void 0 ? void 0 : _a.gap) === '0';
591
589
  if (this.mergedStyles.input) {
592
590
  if (isConnected) {
@@ -685,7 +683,64 @@ export class SpreedlyTokenizer extends Tokenizer {
685
683
  element === null || element === void 0 ? void 0 : element.focus();
686
684
  }
687
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
+ }
688
741
  destroy() {
742
+ var _a;
743
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
689
744
  if (this.spreedly && this.spreedly.removeHandlers) {
690
745
  this.spreedly.removeHandlers();
691
746
  }
@@ -762,10 +817,18 @@ export class SpreedlyTokenizer extends Tokenizer {
762
817
  }
763
818
  }
764
819
  createCreditCardFields(container) {
765
- 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') {
766
828
  const cardNumberDiv = createFieldContainer(this.numberEl, '1', FIELD_FLEX.cardNumber.minWidth);
767
829
  cardNumberDiv.style.height = this.mergedStyles.input.height;
768
830
  cardNumberDiv.style.flexBasis = '100%';
831
+ this.cardNumberDiv = cardNumberDiv;
769
832
  container.appendChild(cardNumberDiv);
770
833
  this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
771
834
  Object.assign(this.expiryEl.style, {
@@ -786,11 +849,13 @@ export class SpreedlyTokenizer extends Tokenizer {
786
849
  container.appendChild(this.expiryEl);
787
850
  const cvvDiv = createFieldContainer(this.cvvEl, '1', FIELD_FLEX.cvv.minWidth);
788
851
  cvvDiv.style.height = this.mergedStyles.input.height;
852
+ this.cvvDiv = cvvDiv;
789
853
  container.appendChild(cvvDiv);
790
854
  }
791
855
  else {
792
856
  const cardNumberDiv = createFieldContainer(this.numberEl, FIELD_FLEX.cardNumber.flex, FIELD_FLEX.cardNumber.minWidth);
793
857
  cardNumberDiv.style.height = this.mergedStyles.input.height;
858
+ this.cardNumberDiv = cardNumberDiv;
794
859
  container.appendChild(cardNumberDiv);
795
860
  this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
796
861
  Object.assign(this.expiryEl.style, {
@@ -811,7 +876,12 @@ export class SpreedlyTokenizer extends Tokenizer {
811
876
  container.appendChild(this.expiryEl);
812
877
  const cvvDiv = createFieldContainer(this.cvvEl, FIELD_FLEX.cvv.flex, FIELD_FLEX.cvv.minWidth);
813
878
  cvvDiv.style.height = this.mergedStyles.input.height;
879
+ this.cvvDiv = cvvDiv;
814
880
  container.appendChild(cvvDiv);
881
+ if (this.layout === 'responsive') {
882
+ this.applyLayoutStyles(this.effectiveLayout);
883
+ this.setupResizeObserver();
884
+ }
815
885
  }
816
886
  }
817
887
  createBankAccountFields(container) {
@@ -1035,13 +1105,14 @@ export class SpreedlyTokenizer extends Tokenizer {
1035
1105
  throw new Error(`Timeout waiting for global: ${globalName}`);
1036
1106
  });
1037
1107
  }
1038
- static tokenizeBankAccount(data, config) {
1039
- if (config.spreedlyEnvironmentKey === undefined) {
1108
+ static tokenizeBankAccount(data, config, environmentKeyOverride) {
1109
+ const environmentKey = environmentKeyOverride || config.spreedlyEnvironmentKey;
1110
+ if (!environmentKey) {
1040
1111
  return Promise.reject(new Error('Spreedly is not configured.'));
1041
1112
  }
1042
1113
  return fetch(SPREEDLY_TOKENIZER_URL +
1043
1114
  '?' +
1044
- new URLSearchParams({ environment_key: config.spreedlyEnvironmentKey }), {
1115
+ new URLSearchParams({ environment_key: environmentKey }), {
1045
1116
  method: 'POST',
1046
1117
  headers: {
1047
1118
  'Content-Type': 'application/json',
@@ -3,6 +3,8 @@ import ConfigHandler from '../config-handler';
3
3
  export declare abstract class Tokenizer {
4
4
  protected mode: PaymentMethodMode;
5
5
  protected eventHandlers: Map<TokenizerEvent, Set<(data?: any) => void>>;
6
+ private _isReady;
7
+ get isReady(): boolean;
6
8
  abstract tokenize(paymentData: PaymentData): Promise<PaymentToken>;
7
9
  abstract validate(): Promise<ValidationResult>;
8
10
  abstract clear(): void;
@@ -12,6 +12,10 @@ export class Tokenizer {
12
12
  constructor() {
13
13
  this.mode = 'credit_card';
14
14
  this.eventHandlers = new Map();
15
+ this._isReady = false;
16
+ }
17
+ get isReady() {
18
+ return this._isReady;
15
19
  }
16
20
  getMode() {
17
21
  return this.mode;
@@ -21,6 +25,13 @@ export class Tokenizer {
21
25
  this.eventHandlers.set(event, new Set());
22
26
  }
23
27
  this.eventHandlers.get(event).add(handler);
28
+ if (event === 'ready' && this._isReady) {
29
+ try {
30
+ handler();
31
+ }
32
+ catch (error) {
33
+ }
34
+ }
24
35
  }
25
36
  off(event, handler) {
26
37
  const handlers = this.eventHandlers.get(event);
@@ -29,6 +40,9 @@ export class Tokenizer {
29
40
  }
30
41
  }
31
42
  emit(event, data) {
43
+ if (event === 'ready') {
44
+ this._isReady = true;
45
+ }
32
46
  const handlers = this.eventHandlers.get(event);
33
47
  if (handlers) {
34
48
  handlers.forEach((handler) => {
@@ -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>;
package/dist/recaptcha.js CHANGED
@@ -1,8 +1,18 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.RecaptchaElement = void 0;
4
13
  exports.injectScript = injectScript;
5
14
  exports.wrapElement = wrapElement;
15
+ exports.wrapElementWithThrow = wrapElementWithThrow;
6
16
  function resolveLib() {
7
17
  const startWait = new Date();
8
18
  return new Promise((resolve, reject) => {
@@ -93,3 +103,11 @@ function wrapElement(container, sitekey, extraParams) {
93
103
  captcha.render();
94
104
  return captcha;
95
105
  }
106
+ function wrapElementWithThrow(container, sitekey, extraParams) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ const params = Object.assign(Object.assign({}, (extraParams || {})), { sitekey });
109
+ const captcha = new RecaptchaElement(container, params);
110
+ yield captcha.render();
111
+ return captcha;
112
+ });
113
+ }
@@ -9,7 +9,6 @@ export declare class CardConnectTokenizer extends Tokenizer {
9
9
  private iframe;
10
10
  private messageHandler?;
11
11
  private expectedOrigin;
12
- private isReady;
13
12
  private currentValidationState;
14
13
  private containerEl?;
15
14
  private routingNumberEl?;
@@ -20,6 +19,7 @@ export declare class CardConnectTokenizer extends Tokenizer {
20
19
  private tokenizationPromise?;
21
20
  private tokenizationResolve?;
22
21
  private tokenizationReject?;
22
+ private currentCardType?;
23
23
  private constructor();
24
24
  static create(gateway: PaymentGateway, container: TokenizerContainer, config: {
25
25
  organizationId: string;
@@ -25,7 +25,6 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
25
25
  this.iframeUrl = iframeUrl;
26
26
  this.containerId = containerId;
27
27
  this.layout = layout;
28
- this.isReady = false;
29
28
  this.enableTestMode = false;
30
29
  this.mode = mode;
31
30
  this.enableTestMode = enableTestMode;
@@ -45,13 +44,25 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
45
44
  if (container.mode === 'bank_account' && container.bankCountry === 'CA') {
46
45
  throw new Error('CardConnect does not support Canadian bank accounts');
47
46
  }
47
+ let effectiveLayout = 'single-line';
48
+ if (container.layout === 'responsive') {
49
+ const containerEl = document.getElementById(container.containerId);
50
+ const containerWidth = (containerEl === null || containerEl === void 0 ? void 0 : containerEl.offsetWidth) || 0;
51
+ const breakpoint = container.responsiveBreakpoint || tokenizer_constants_1.RESPONSIVE_BREAKPOINT;
52
+ effectiveLayout =
53
+ containerWidth < breakpoint ? 'two-line' : 'single-line';
54
+ }
55
+ else if (container.layout === 'two-line') {
56
+ effectiveLayout = 'two-line';
57
+ }
58
+ const resolvedContainer = Object.assign(Object.assign({}, container), { layout: effectiveLayout });
48
59
  let baseUrl = ((_a = gateway.config) === null || _a === void 0 ? void 0 : _a.base_url) || config.clientConfig.cardConnectBaseUrl;
49
60
  config.cardConnectBaseUrl = baseUrl;
50
61
  const mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, container.styling);
51
- const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, container);
62
+ const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, resolvedContainer);
52
63
  const iframe = CardConnectTokenizer.createIframe(iframeUrl, mergedStyles);
53
- const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, container.layout || 'single-line');
54
- tokenizer.createInternalElements(container);
64
+ const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout);
65
+ tokenizer.createInternalElements(resolvedContainer);
55
66
  yield tokenizer.init();
56
67
  return tokenizer;
57
68
  });
@@ -74,7 +85,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
74
85
  }
75
86
  createCreditCardFields(containerEl, mergedStyles) {
76
87
  this.iframe.style.width = '100%';
77
- if (this.layout === 'two-line') {
88
+ if (this.layout === 'two-line' || this.layout === 'responsive') {
78
89
  const inputHeight = mergedStyles.input.height || '40px';
79
90
  this.iframe.style.height = `calc((${inputHeight}) * 2 + 10px)`;
80
91
  }
@@ -138,7 +149,6 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
138
149
  init() {
139
150
  return __awaiter(this, void 0, void 0, function* () {
140
151
  if (this.mode === 'bank_account') {
141
- this.isReady = true;
142
152
  if (this.enableTestMode) {
143
153
  setTimeout(() => {
144
154
  if (this.routingNumberEl) {
@@ -171,7 +181,6 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
171
181
  window.addEventListener('message', this.messageHandler);
172
182
  this.iframe.onload = () => {
173
183
  clearTimeout(timeout);
174
- this.isReady = true;
175
184
  if (this.enableTestMode && this.mode === 'credit_card') {
176
185
  }
177
186
  this.emit('ready');
@@ -451,10 +460,14 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
451
460
  var _a;
452
461
  if (this.mode === 'credit_card' &&
453
462
  ((_a = this.cachedTokenResult) === null || _a === void 0 ? void 0 : _a.errorCode) === '0') {
463
+ const cardType = this.cachedTokenResult.cardType
464
+ ? this.normalizeCardType(this.cachedTokenResult.cardType)
465
+ : this.normalizeCardType('unknown');
454
466
  return {
455
467
  token: this.cachedTokenResult.token,
456
- lastFour: this.cachedTokenResult.token.slice(-4),
457
- cardType: this.normalizeCardType('unknown'),
468
+ lastFour: this.cachedTokenResult.last4 ||
469
+ this.cachedTokenResult.token.slice(-4),
470
+ cardType,
458
471
  provider: 'cardconnect',
459
472
  };
460
473
  }
@@ -470,10 +483,17 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
470
483
  this.cachedTokenResult = data;
471
484
  this.emit('tokenization', data);
472
485
  if (data.errorCode === '0') {
486
+ const cardType = data.cardType
487
+ ? this.normalizeCardType(data.cardType)
488
+ : this.normalizeCardType('unknown');
489
+ if (data.cardType && cardType !== this.currentCardType) {
490
+ this.currentCardType = cardType;
491
+ this.emit('cardTypeChange', { cardType });
492
+ }
473
493
  const token = {
474
494
  token: data.token,
475
- lastFour: data.token.slice(-4),
476
- cardType: this.normalizeCardType('unknown'),
495
+ lastFour: data.last4 || data.token.slice(-4),
496
+ cardType,
477
497
  provider: 'cardconnect',
478
498
  };
479
499
  if (this.tokenizationResolve) {
@@ -508,6 +528,13 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
508
528
  }
509
529
  if (data.event === 'input' || data.event === 'change') {
510
530
  this.emit('change', { field: data.data });
531
+ if (data.cardType) {
532
+ const cardType = this.normalizeCardType(data.cardType);
533
+ if (cardType !== this.currentCardType) {
534
+ this.currentCardType = cardType;
535
+ this.emit('cardTypeChange', { cardType });
536
+ }
537
+ }
511
538
  }
512
539
  }
513
540
  catch (error) {
@@ -532,12 +559,15 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
532
559
  errorLower.includes('year')) {
533
560
  this.currentValidationState.expiry = { isValid: false, isEmpty: false };
534
561
  }
535
- this.emit('error', new types_1.TokenizationError(data.validationError));
562
+ this.currentValidationState.isValid = false;
563
+ this.emit('validation', this.currentValidationState);
564
+ }
565
+ else {
566
+ this.currentValidationState.isValid =
567
+ ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
568
+ ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false) &&
569
+ ((_f = (_e = this.currentValidationState.expiry) === null || _e === void 0 ? void 0 : _e.isValid) !== null && _f !== void 0 ? _f : false);
536
570
  }
537
- this.currentValidationState.isValid =
538
- ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
539
- ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false) &&
540
- ((_f = (_e = this.currentValidationState.expiry) === null || _e === void 0 ? void 0 : _e.isValid) !== null && _f !== void 0 ? _f : false);
541
571
  }
542
572
  static generateIframeUrl(baseUrl, container) {
543
573
  const params = new URLSearchParams({
@@ -566,7 +596,12 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
566
596
  params.set('placeholderyear', 'YYYY');
567
597
  }
568
598
  const mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, container.styling);
569
- const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, container.layout || 'single-line');
599
+ const isDesktopSafari = typeof navigator !== 'undefined' &&
600
+ /Safari/.test(navigator.userAgent) &&
601
+ /Apple Computer/.test(navigator.vendor) &&
602
+ !/Chrome/.test(navigator.userAgent) &&
603
+ !/Mobile/.test(navigator.userAgent);
604
+ const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari);
570
605
  const queryPairs = [];
571
606
  params.forEach((value, key) => {
572
607
  queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
@@ -599,8 +634,8 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
599
634
  iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
600
635
  return iframe;
601
636
  }
602
- static generateCardConnectCss(styles, layout = 'single-line') {
603
- var _a, _b, _c, _d;
637
+ static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false) {
638
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
604
639
  const css = [];
605
640
  if (layout === 'two-line') {
606
641
  css.push('html,form,body{margin:0;padding:0;}');
@@ -634,14 +669,22 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
634
669
  commonStyles.push('box-sizing:border-box');
635
670
  const baseStyles = commonStyles.join(';');
636
671
  css.push(`input{${baseStyles};}`);
637
- css.push(`select{${baseStyles};}`);
672
+ if (isDesktopSafari) {
673
+ css.push(`select{${baseStyles};-webkit-appearance:none;appearance:none;}`);
674
+ }
675
+ else {
676
+ css.push(`select{${baseStyles};}`);
677
+ }
638
678
  }
639
679
  if (layout === 'two-line') {
640
680
  css.push('input#ccnumfield{width:100%;display:block;margin-bottom:8px;}');
641
- css.push('input#ccexpiryfieldmonth{width:20%;}');
642
- css.push('input#ccexpiryfieldyear{width:24%;}');
643
- css.push('input#cccvvfield{width:calc(56% - 20px);}');
644
- if ((_a = styles.input) === null || _a === void 0 ? void 0 : _a.borderRadius) {
681
+ 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';
682
+ 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';
683
+ const twoLineTextAlign = ((_e = styles.twoLine) === null || _e === void 0 ? void 0 : _e.textAlign) || 'left';
684
+ css.push(`input#ccexpiryfieldmonth{width:25%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
685
+ css.push(`input#ccexpiryfieldyear{width:35%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
686
+ css.push(`input#cccvvfield{width:calc(40% - 16px);padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};margin-left:-4px;}`);
687
+ if ((_f = styles.input) === null || _f === void 0 ? void 0 : _f.borderRadius) {
645
688
  css.push(`input{border-radius:${styles.input.borderRadius};}`);
646
689
  }
647
690
  }
@@ -650,7 +693,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
650
693
  css.push('select#ccexpirymonth{width:16%;margin:0;margin-right:-12px;}');
651
694
  css.push('select#ccexpiryyear{width:20%;}');
652
695
  css.push('input#cccvvfield{width:20%;margin:0;margin-left:-12px;}');
653
- if ((_b = styles.input) === null || _b === void 0 ? void 0 : _b.borderRadius) {
696
+ if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
654
697
  css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right:none;}`);
655
698
  css.push('select#ccexpirymonth{border-radius:0;border-right:none;}');
656
699
  css.push('select#ccexpiryyear{border-radius:0;border-right:none;}');
@@ -668,7 +711,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
668
711
  css.push(`select#ccexpirymonth{width:15%;margin-right:${marginRight};}`);
669
712
  css.push(`select#ccexpiryyear{width:20%;margin-right:${marginRight};}`);
670
713
  css.push('input#cccvvfield{width:15%;}');
671
- if ((_c = styles.input) === null || _c === void 0 ? void 0 : _c.borderRadius) {
714
+ if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
672
715
  css.push(`input,select{border-radius:${styles.input.borderRadius};}`);
673
716
  }
674
717
  }
@@ -684,7 +727,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
684
727
  if (focusStyles.length > 0) {
685
728
  css.push(`input:focus{${focusStyles.join(';')};}`);
686
729
  css.push(`select:focus{${focusStyles.join(';')};}`);
687
- if (isConnected && ((_d = styles.input) === null || _d === void 0 ? void 0 : _d.border)) {
730
+ if (isConnected && ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.border)) {
688
731
  css.push(`input#ccnumfield:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
689
732
  css.push(`select#ccexpirymonth:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
690
733
  css.push(`select#ccexpiryyear:focus{border:${styles.input.border};${focusStyles.join(';')};}`);