@idonatedev/idonate-sdk 1.2.0-dev17 → 1.2.0-dev19

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.
@@ -14,15 +14,16 @@ import { extractSpreedlyToken, unpackSpreedlyResponse } from '../typeAdapters';
14
14
  import { fetchSpreedlySecurityArgs } from './spreedly-secure';
15
15
  import { DEFAULT_UNIFIED_STYLES, mergeStyles, getContainerStylesForLayout, } from './styles';
16
16
  import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, FIELD_FLEX, BANK_FIELD_FLEX, CANADIAN_BANK_FIELD_FLEX, PLACEHOLDERS, FIELD_CONSTRAINTS, RESPONSIVE_BREAKPOINT, } from './tokenizer-constants';
17
- import { createFieldContainer, createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, validateInstitutionNumber, validateTransitNumber, validateCanadianAccountNumber, formatCanadianRoutingNumber, } from './tokenizer-utils';
17
+ import { createFieldContainer, createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, validateInstitutionNumber, validateTransitNumber, validateCanadianAccountNumber, formatCanadianRoutingNumber, wrapFieldWithLabel, } 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', responsiveBreakpoint = RESPONSIVE_BREAKPOINT) {
21
+ constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line', responsiveBreakpoint = RESPONSIVE_BREAKPOINT, customPlaceholders) {
22
22
  super();
23
23
  this.environmentKey = environmentKey;
24
24
  this.containerId = containerId;
25
25
  this.layout = layout;
26
+ this.customPlaceholders = customPlaceholders;
26
27
  this.bankCountry = 'US';
27
28
  this.enableTestMode = false;
28
29
  this.effectiveLayout = 'single-line';
@@ -77,7 +78,7 @@ export class SpreedlyTokenizer extends Tokenizer {
77
78
  if (!environmentKey) {
78
79
  throw new Error('Spreedly environment key is required. Provide it via gateway.config.environmentKey or client config.');
79
80
  }
80
- const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', (_b = container.responsiveBreakpoint) !== null && _b !== void 0 ? _b : RESPONSIVE_BREAKPOINT);
81
+ const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', (_b = container.responsiveBreakpoint) !== null && _b !== void 0 ? _b : RESPONSIVE_BREAKPOINT, container.placeholders);
81
82
  tokenizer.organizationId = config.organizationId;
82
83
  tokenizer.embedId = config.embedId;
83
84
  tokenizer.clientConfig = config.clientConfig;
@@ -136,11 +137,12 @@ export class SpreedlyTokenizer extends Tokenizer {
136
137
  reject(new Error('Spreedly initialization timeout'));
137
138
  }, INIT_TIMEOUT);
138
139
  this.spreedly.on('ready', () => {
140
+ var _a, _b;
139
141
  clearTimeout(timeout);
140
- this.spreedly.setPlaceholder('number', PLACEHOLDERS.cardNumber);
142
+ this.spreedly.setPlaceholder('number', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || PLACEHOLDERS.cardNumber);
141
143
  this.spreedly.setFieldType('number', 'text');
142
144
  this.spreedly.setNumberFormat('prettyFormat');
143
- this.spreedly.setPlaceholder('cvv', PLACEHOLDERS.cvv);
145
+ this.spreedly.setPlaceholder('cvv', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.cvv) || PLACEHOLDERS.cvv);
144
146
  this.spreedly.setFieldType('cvv', 'text');
145
147
  this.applyUnifiedStyles();
146
148
  if (this.enableTestMode &&
@@ -256,7 +258,7 @@ export class SpreedlyTokenizer extends Tokenizer {
256
258
  minWidth: CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
257
259
  });
258
260
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
259
- container.appendChild(this.accountTypeEl);
261
+ this.appendField(container, this.accountTypeEl, 'Account Type');
260
262
  this.institutionNumberEl = createInputElement(`${this.containerId}-institution`, 'text', 'Inst *', 3);
261
263
  Object.assign(this.institutionNumberEl.style, {
262
264
  flex: '1',
@@ -273,7 +275,7 @@ export class SpreedlyTokenizer extends Tokenizer {
273
275
  }
274
276
  this.updateBankAccountValidation();
275
277
  });
276
- container.appendChild(this.institutionNumberEl);
278
+ this.appendField(container, this.institutionNumberEl, 'Institution');
277
279
  this.transitNumberEl = createInputElement(`${this.containerId}-transit`, 'text', 'Transit *', 5);
278
280
  Object.assign(this.transitNumberEl.style, {
279
281
  flex: '2',
@@ -290,7 +292,7 @@ export class SpreedlyTokenizer extends Tokenizer {
290
292
  }
291
293
  this.updateBankAccountValidation();
292
294
  });
293
- container.appendChild(this.transitNumberEl);
295
+ this.appendField(container, this.transitNumberEl, 'Transit');
294
296
  this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *');
295
297
  Object.assign(this.accountNumberEl.style, {
296
298
  flex: '1',
@@ -308,7 +310,7 @@ export class SpreedlyTokenizer extends Tokenizer {
308
310
  }
309
311
  this.updateBankAccountValidation();
310
312
  });
311
- container.appendChild(this.accountNumberEl);
313
+ this.appendField(container, this.accountNumberEl, 'Account Number');
312
314
  }
313
315
  else {
314
316
  this.institutionNumberEl = createInputElement(`${this.containerId}-institution`, 'text', 'Inst *', 3);
@@ -327,7 +329,7 @@ export class SpreedlyTokenizer extends Tokenizer {
327
329
  }
328
330
  this.updateBankAccountValidation();
329
331
  });
330
- container.appendChild(this.institutionNumberEl);
332
+ this.appendField(container, this.institutionNumberEl, 'Institution');
331
333
  this.transitNumberEl = createInputElement(`${this.containerId}-transit`, 'text', 'Transit *', 5);
332
334
  Object.assign(this.transitNumberEl.style, {
333
335
  flex: CANADIAN_BANK_FIELD_FLEX.transitNumber.flex,
@@ -344,7 +346,7 @@ export class SpreedlyTokenizer extends Tokenizer {
344
346
  }
345
347
  this.updateBankAccountValidation();
346
348
  });
347
- container.appendChild(this.transitNumberEl);
349
+ this.appendField(container, this.transitNumberEl, 'Transit');
348
350
  this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *');
349
351
  Object.assign(this.accountNumberEl.style, {
350
352
  flex: CANADIAN_BANK_FIELD_FLEX.accountNumber.flex,
@@ -361,14 +363,14 @@ export class SpreedlyTokenizer extends Tokenizer {
361
363
  }
362
364
  this.updateBankAccountValidation();
363
365
  });
364
- container.appendChild(this.accountNumberEl);
366
+ this.appendField(container, this.accountNumberEl, 'Account Number');
365
367
  this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
366
368
  Object.assign(this.accountTypeEl.style, {
367
369
  flex: CANADIAN_BANK_FIELD_FLEX.accountType.flex,
368
370
  minWidth: CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
369
371
  });
370
372
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
371
- container.appendChild(this.accountTypeEl);
373
+ this.appendField(container, this.accountTypeEl, 'Account Type');
372
374
  }
373
375
  }
374
376
  tokenizeBankAccountInternal(bankData) {
@@ -841,7 +843,11 @@ export class SpreedlyTokenizer extends Tokenizer {
841
843
  this.createCreditCardFields(container);
842
844
  }
843
845
  }
846
+ appendField(container, field, labelText) {
847
+ container.appendChild(wrapFieldWithLabel(field, labelText, this.mergedStyles));
848
+ }
844
849
  createCreditCardFields(container) {
850
+ var _a, _b;
845
851
  if (this.layout === 'responsive') {
846
852
  this.effectiveLayout = this.determineLayout(container.offsetWidth);
847
853
  }
@@ -854,8 +860,8 @@ export class SpreedlyTokenizer extends Tokenizer {
854
860
  cardNumberDiv.style.height = this.mergedStyles.input.height;
855
861
  cardNumberDiv.style.flexBasis = '100%';
856
862
  this.cardNumberDiv = cardNumberDiv;
857
- container.appendChild(cardNumberDiv);
858
- this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
863
+ this.appendField(container, cardNumberDiv, 'Card Number');
864
+ this.expiryEl = createInputElement(this.expiryId, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.expiry) || PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
859
865
  Object.assign(this.expiryEl.style, {
860
866
  flex: '1',
861
867
  minWidth: FIELD_FLEX.expiry.minWidth,
@@ -875,18 +881,18 @@ export class SpreedlyTokenizer extends Tokenizer {
875
881
  this.validateExpiry();
876
882
  this.updateOverallValidation();
877
883
  });
878
- container.appendChild(this.expiryEl);
884
+ this.appendField(container, this.expiryEl, 'Expiration');
879
885
  const cvvDiv = createFieldContainer(this.cvvEl, '1', FIELD_FLEX.cvv.minWidth);
880
886
  cvvDiv.style.height = this.mergedStyles.input.height;
881
887
  this.cvvDiv = cvvDiv;
882
- container.appendChild(cvvDiv);
888
+ this.appendField(container, cvvDiv, 'CVV');
883
889
  }
884
890
  else {
885
891
  const cardNumberDiv = createFieldContainer(this.numberEl, FIELD_FLEX.cardNumber.flex, FIELD_FLEX.cardNumber.minWidth);
886
892
  cardNumberDiv.style.height = this.mergedStyles.input.height;
887
893
  this.cardNumberDiv = cardNumberDiv;
888
- container.appendChild(cardNumberDiv);
889
- this.expiryEl = createInputElement(this.expiryId, 'text', PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
894
+ this.appendField(container, cardNumberDiv, 'Card Number');
895
+ this.expiryEl = createInputElement(this.expiryId, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.expiry) || PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
890
896
  Object.assign(this.expiryEl.style, {
891
897
  flex: FIELD_FLEX.expiry.flex,
892
898
  minWidth: FIELD_FLEX.expiry.minWidth,
@@ -906,11 +912,11 @@ export class SpreedlyTokenizer extends Tokenizer {
906
912
  this.validateExpiry();
907
913
  this.updateOverallValidation();
908
914
  });
909
- container.appendChild(this.expiryEl);
915
+ this.appendField(container, this.expiryEl, 'Expiration');
910
916
  const cvvDiv = createFieldContainer(this.cvvEl, FIELD_FLEX.cvv.flex, FIELD_FLEX.cvv.minWidth);
911
917
  cvvDiv.style.height = this.mergedStyles.input.height;
912
918
  this.cvvDiv = cvvDiv;
913
- container.appendChild(cvvDiv);
919
+ this.appendField(container, cvvDiv, 'CVV');
914
920
  if (this.layout === 'responsive') {
915
921
  this.applyLayoutStyles(this.effectiveLayout);
916
922
  this.setupResizeObserver();
@@ -926,6 +932,7 @@ export class SpreedlyTokenizer extends Tokenizer {
926
932
  }
927
933
  }
928
934
  createUSBankAccountFields(container) {
935
+ var _a, _b, _c, _d;
929
936
  if (this.layout === 'two-line') {
930
937
  this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
931
938
  Object.assign(this.accountTypeEl.style, {
@@ -933,8 +940,8 @@ export class SpreedlyTokenizer extends Tokenizer {
933
940
  minWidth: BANK_FIELD_FLEX.accountType.minWidth,
934
941
  });
935
942
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
936
- container.appendChild(this.accountTypeEl);
937
- this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
943
+ this.appendField(container, this.accountTypeEl, 'Account Type');
944
+ this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.routingNumber) || 'Routing *', 9);
938
945
  Object.assign(this.routingNumberEl.style, {
939
946
  flex: '1',
940
947
  minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
@@ -950,8 +957,8 @@ export class SpreedlyTokenizer extends Tokenizer {
950
957
  }
951
958
  this.updateBankAccountValidation();
952
959
  });
953
- container.appendChild(this.routingNumberEl);
954
- this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
960
+ this.appendField(container, this.routingNumberEl, 'Routing Number');
961
+ this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.accountNumber) || 'Account Number *', 17);
955
962
  Object.assign(this.accountNumberEl.style, {
956
963
  flex: '1',
957
964
  flexBasis: '100%',
@@ -968,10 +975,10 @@ export class SpreedlyTokenizer extends Tokenizer {
968
975
  }
969
976
  this.updateBankAccountValidation();
970
977
  });
971
- container.appendChild(this.accountNumberEl);
978
+ this.appendField(container, this.accountNumberEl, 'Account Number');
972
979
  }
973
980
  else {
974
- this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
981
+ this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_c = this.customPlaceholders) === null || _c === void 0 ? void 0 : _c.routingNumber) || 'Routing *', 9);
975
982
  Object.assign(this.routingNumberEl.style, {
976
983
  flex: BANK_FIELD_FLEX.routingNumber.flex,
977
984
  minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
@@ -987,8 +994,8 @@ export class SpreedlyTokenizer extends Tokenizer {
987
994
  }
988
995
  this.updateBankAccountValidation();
989
996
  });
990
- container.appendChild(this.routingNumberEl);
991
- this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
997
+ this.appendField(container, this.routingNumberEl, 'Routing Number');
998
+ this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_d = this.customPlaceholders) === null || _d === void 0 ? void 0 : _d.accountNumber) || 'Account Number *', 17);
992
999
  Object.assign(this.accountNumberEl.style, {
993
1000
  flex: BANK_FIELD_FLEX.accountNumber.flex,
994
1001
  minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
@@ -1004,14 +1011,14 @@ export class SpreedlyTokenizer extends Tokenizer {
1004
1011
  }
1005
1012
  this.updateBankAccountValidation();
1006
1013
  });
1007
- container.appendChild(this.accountNumberEl);
1014
+ this.appendField(container, this.accountNumberEl, 'Account Number');
1008
1015
  this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
1009
1016
  Object.assign(this.accountTypeEl.style, {
1010
1017
  flex: BANK_FIELD_FLEX.accountType.flex,
1011
1018
  minWidth: BANK_FIELD_FLEX.accountType.minWidth,
1012
1019
  });
1013
1020
  this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
1014
- container.appendChild(this.accountTypeEl);
1021
+ this.appendField(container, this.accountTypeEl, 'Account Type');
1015
1022
  }
1016
1023
  }
1017
1024
  updateBankAccountValidation() {
@@ -32,17 +32,30 @@ export const DEFAULT_UNIFIED_STYLES = {
32
32
  fontSize: '',
33
33
  textAlign: '',
34
34
  },
35
+ label: {
36
+ show: false,
37
+ fontSize: '0.875rem',
38
+ fontWeight: 'bold',
39
+ fontFamily: '',
40
+ color: '#333',
41
+ marginBottom: '0.25rem',
42
+ },
35
43
  };
36
44
  export function mergeStyles(defaults, userStyles) {
37
45
  if (!userStyles)
38
46
  return defaults;
39
- return {
47
+ const merged = {
40
48
  input: Object.assign(Object.assign({}, defaults.input), userStyles.input),
41
49
  focus: Object.assign(Object.assign({}, defaults.focus), userStyles.focus),
42
50
  error: Object.assign(Object.assign({}, defaults.error), userStyles.error),
43
51
  container: Object.assign(Object.assign({}, defaults.container), userStyles.container),
44
52
  twoLine: Object.assign(Object.assign({}, defaults.twoLine), userStyles.twoLine),
53
+ label: Object.assign(Object.assign({}, defaults.label), userStyles.label),
45
54
  };
55
+ if (!merged.label.fontFamily) {
56
+ merged.label.fontFamily = merged.input.fontFamily;
57
+ }
58
+ return merged;
46
59
  }
47
60
  export function getContainerStylesForLayout(baseStyles, layout = 'single-line') {
48
61
  if (layout === 'two-line') {
@@ -7,6 +7,8 @@ export declare function formatExpiryInput(value: string): string;
7
7
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T>;
8
8
  export declare function getConnectedBorderRadius(baseRadius: string, position: 'left' | 'middle' | 'right', isConnected: boolean): string;
9
9
  export declare function addFocusHandlers(element: HTMLElement, styles: TokenizerStylingComplete, position?: 'left' | 'middle' | 'right', onFocus?: () => void, onBlur?: () => void): void;
10
+ export declare function createFieldLabel(text: string, forId: string, styles: TokenizerStylingComplete): HTMLLabelElement;
11
+ export declare function wrapFieldWithLabel(field: HTMLElement, labelText: string, styles: TokenizerStylingComplete): HTMLElement;
10
12
  export declare function createFieldContainer(id: string, flex: string, minWidth?: string, maxWidth?: string): HTMLDivElement;
11
13
  export declare function createInputElement(id: string, type: string, placeholder: string, maxLength?: number): HTMLInputElement;
12
14
  export declare function validateRoutingNumber(routingNumber: string): boolean;
@@ -17,3 +19,4 @@ export declare function validateInstitutionNumber(institutionNumber: string): bo
17
19
  export declare function validateTransitNumber(transitNumber: string): boolean;
18
20
  export declare function validateCanadianAccountNumber(accountNumber: string): boolean;
19
21
  export declare function formatCanadianRoutingNumber(institutionNumber: string, transitNumber: string): string;
22
+ export declare function cssLengthToPixels(value: string): number;
@@ -74,6 +74,43 @@ export function addFocusHandlers(element, styles, position, onFocus, onBlur) {
74
74
  onBlur === null || onBlur === void 0 ? void 0 : onBlur();
75
75
  });
76
76
  }
77
+ export function createFieldLabel(text, forId, styles) {
78
+ const label = document.createElement('label');
79
+ label.htmlFor = forId;
80
+ label.textContent = text;
81
+ label.style.display = styles.label.show ? 'block' : 'none';
82
+ label.style.fontSize = styles.label.fontSize;
83
+ label.style.fontWeight = styles.label.fontWeight;
84
+ label.style.fontFamily = styles.label.fontFamily;
85
+ label.style.color = styles.label.color;
86
+ label.style.marginBottom = styles.label.marginBottom;
87
+ return label;
88
+ }
89
+ export function wrapFieldWithLabel(field, labelText, styles) {
90
+ if (!styles.label.show)
91
+ return field;
92
+ const wrapper = document.createElement('div');
93
+ wrapper.style.display = 'flex';
94
+ wrapper.style.flexDirection = 'column';
95
+ if (field.style.flex) {
96
+ wrapper.style.flex = field.style.flex;
97
+ field.style.flex = '';
98
+ }
99
+ if (field.style.minWidth) {
100
+ wrapper.style.minWidth = field.style.minWidth;
101
+ }
102
+ if (field.style.maxWidth) {
103
+ wrapper.style.maxWidth = field.style.maxWidth;
104
+ }
105
+ if (field.style.flexBasis) {
106
+ wrapper.style.flexBasis = field.style.flexBasis;
107
+ field.style.flexBasis = '';
108
+ }
109
+ const label = createFieldLabel(labelText, field.id, styles);
110
+ wrapper.appendChild(label);
111
+ wrapper.appendChild(field);
112
+ return wrapper;
113
+ }
77
114
  export function createFieldContainer(id, flex, minWidth, maxWidth) {
78
115
  const div = document.createElement('div');
79
116
  div.id = id;
@@ -158,3 +195,19 @@ export function formatCanadianRoutingNumber(institutionNumber, transitNumber) {
158
195
  const transit = transitNumber.replace(/\D/g, '').padStart(5, '0');
159
196
  return '0' + institution + transit;
160
197
  }
198
+ export function cssLengthToPixels(value) {
199
+ const num = parseFloat(value);
200
+ if (isNaN(num)) {
201
+ console.warn(`[cssLengthToPixels] Cannot parse "${value}", defaulting to 14px`);
202
+ return 14;
203
+ }
204
+ if (value.endsWith('rem'))
205
+ return num * 16;
206
+ if (value.endsWith('pt'))
207
+ return num * 1.333;
208
+ if (value.endsWith('px') || !value.match(/[a-z%]/i))
209
+ return num;
210
+ console.warn(`[cssLengthToPixels] Unsupported unit in "${value}". ` +
211
+ `Only px, rem, and pt are supported. Using ${num}px as approximation.`);
212
+ return num;
213
+ }
@@ -21,6 +21,15 @@ export interface TokenizerContainer {
21
21
  enableTestMode?: boolean;
22
22
  layout?: 'single-line' | 'two-line' | 'responsive';
23
23
  responsiveBreakpoint?: number;
24
+ placeholders?: {
25
+ cardNumber?: string;
26
+ expiry?: string;
27
+ expiryMonth?: string;
28
+ expiryYear?: string;
29
+ cvv?: string;
30
+ routingNumber?: string;
31
+ accountNumber?: string;
32
+ };
24
33
  }
25
34
  export interface TokenizerStylingComplete {
26
35
  input: {
@@ -59,6 +68,14 @@ export interface TokenizerStylingComplete {
59
68
  fontSize: string;
60
69
  textAlign: string;
61
70
  };
71
+ label: {
72
+ show: boolean;
73
+ fontSize: string;
74
+ fontWeight: string;
75
+ fontFamily: string;
76
+ color: string;
77
+ marginBottom: string;
78
+ };
62
79
  }
63
80
  type DeepPartial<T> = T extends object ? {
64
81
  [P in keyof T]?: DeepPartial<T[P]>;
@@ -149,10 +149,10 @@ class iDonateClient {
149
149
  if (!this.allowTransaction) {
150
150
  throw new Error('Wow, that was fast - try again');
151
151
  }
152
- if (!donation.embedId) {
153
- donation.embedId = this.embedId;
154
- }
155
- const payload = (0, typeAdapters_1.buildCashPaymentPayload)(this.organizationId, donation);
152
+ const donationWithEmbed = donation.embedId
153
+ ? donation
154
+ : Object.assign(Object.assign({}, donation), { embedId: this.embedId });
155
+ const payload = (0, typeAdapters_1.buildCashPaymentPayload)(this.organizationId, donationWithEmbed);
156
156
  const fetchCall = (clearanceToken) => fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment`, {
157
157
  method: 'POST',
158
158
  headers: Object.assign(Object.assign(Object.assign({}, constants_1.CLIENT_HEADERS), (clearanceToken ? { 'cf-validation-token': clearanceToken } : {})), { 'User-Agent': constants_1.CLIENT_HEADERS['User-Agent'] + ' source:' + this.config.client }),
@@ -180,10 +180,10 @@ class iDonateClient {
180
180
  });
181
181
  }
182
182
  createPaymentMethod(paymentMethod) {
183
- if (!paymentMethod.embedId) {
184
- paymentMethod.embedId = this.embedId;
185
- }
186
- return shared.createPaymentMethod(paymentMethod, this.config);
183
+ const pmWithEmbed = paymentMethod.embedId
184
+ ? paymentMethod
185
+ : Object.assign(Object.assign({}, paymentMethod), { embedId: this.embedId });
186
+ return shared.createPaymentMethod(pmWithEmbed, this.config);
187
187
  }
188
188
  setOrganizationId(organizationId) {
189
189
  this.currentOrganizationId = organizationId;
@@ -195,7 +195,16 @@ class iDonateClient {
195
195
  return new Promise((resolve, reject) => {
196
196
  setTimeout(() => {
197
197
  let pollHandle;
198
+ let attempts = 0;
199
+ const maxAttempts = 90;
198
200
  pollHandle = setInterval(() => {
201
+ attempts++;
202
+ if (attempts > maxAttempts) {
203
+ clearInterval(pollHandle);
204
+ pollHandle = null;
205
+ reject(new types_1.ClientError('Donation processing timed out. Please check your email for a receipt or contact support.'));
206
+ return;
207
+ }
199
208
  fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment/${donationId}/payment_status`, {
200
209
  method: 'GET',
201
210
  headers: {
@@ -212,6 +221,7 @@ class iDonateClient {
212
221
  }
213
222
  if (response.error) {
214
223
  reject(new types_1.ClientError(response.error));
224
+ return;
215
225
  }
216
226
  resolve((0, typeAdapters_1.buildDonationResult)({
217
227
  _raw_response: Object.assign({ campaign: null, designation: {}, donor: {}, form_data: {}, id: null, schedule: {}, transaction: {} }, response),
package/dist/recaptcha.js CHANGED
@@ -67,9 +67,16 @@ class RecaptchaElement {
67
67
  this.widgetId = lib.render(this.container, Object.assign(Object.assign({}, this.params), { callback: (token) => {
68
68
  var _a;
69
69
  this.resolvedToken = token;
70
- (_a = this.executeResolveQueue.pop()) === null || _a === void 0 ? void 0 : _a(token);
70
+ (_a = this.executeResolveQueue.shift()) === null || _a === void 0 ? void 0 : _a.resolve(token);
71
71
  }, 'expired-callback': () => {
72
72
  this.resolvedToken = undefined;
73
+ }, 'error-callback': () => {
74
+ var _a;
75
+ this.resolvedToken = undefined;
76
+ const error = new Error('reCAPTCHA encountered an error. Please try again.');
77
+ while (this.executeResolveQueue.length > 0) {
78
+ (_a = this.executeResolveQueue.shift()) === null || _a === void 0 ? void 0 : _a.reject(error);
79
+ }
73
80
  } }));
74
81
  });
75
82
  }
@@ -83,7 +90,7 @@ class RecaptchaElement {
83
90
  ? resolve(response)
84
91
  : reject(new Error('checkbox recaptcha is not checked'));
85
92
  }
86
- this.executeResolveQueue.push(resolve);
93
+ this.executeResolveQueue.push({ resolve, reject });
87
94
  if (this.resolvedToken !== undefined) {
88
95
  this.resolvedToken = undefined;
89
96
  lib.reset(this.widgetId);
@@ -6,6 +6,7 @@ export declare class CardConnectTokenizer extends Tokenizer {
6
6
  private iframeUrl;
7
7
  private containerId;
8
8
  private layout;
9
+ private customPlaceholders?;
9
10
  private iframe;
10
11
  private messageHandler?;
11
12
  private expectedOrigin;
@@ -49,6 +50,7 @@ export declare class CardConnectTokenizer extends Tokenizer {
49
50
  get tokenizationMode(): 'auto' | 'manual';
50
51
  private handleMessage;
51
52
  private handleValidationMessage;
53
+ private static measureCvvLabelMarginLeft;
52
54
  private static generateIframeUrl;
53
55
  private static createIframe;
54
56
  private static generateCardConnectCss;