@idonatedev/idonate-sdk 1.1.0-dev1 → 1.1.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.
@@ -8,16 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.SpreedlyTokenizer = void 0;
16
13
  const Tokenizer_1 = require("./Tokenizer");
17
14
  const types_1 = require("./types");
18
15
  const constants_1 = require("../constants");
19
16
  const typeAdapters_1 = require("../typeAdapters");
20
- const config_handler_1 = __importDefault(require("../config-handler"));
21
17
  const spreedly_secure_1 = require("./spreedly-secure");
22
18
  const styles_1 = require("./styles");
23
19
  const tokenizer_constants_1 = require("./tokenizer-constants");
@@ -25,10 +21,11 @@ const tokenizer_utils_1 = require("./tokenizer-utils");
25
21
  const SPREEDLY_SCRIPT_URL = 'https://core.spreedly.com/iframe/iframe-v1.min.js';
26
22
  const SPREEDLY_SCRIPT_ID = 'spreedly-iframe-script';
27
23
  class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
28
- constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false) {
24
+ constructor(environmentKey, containerId, styles, mode = 'credit_card', bankCountry = 'US', enableTestMode = false, layout = 'single-line') {
29
25
  super();
30
26
  this.environmentKey = environmentKey;
31
27
  this.containerId = containerId;
28
+ this.layout = layout;
32
29
  this.isReady = false;
33
30
  this.bankCountry = 'US';
34
31
  this.enableTestMode = false;
@@ -59,9 +56,10 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
59
56
  isValid: false,
60
57
  cardNumber: { isValid: false, isEmpty: true },
61
58
  cvv: { isValid: false, isEmpty: true },
59
+ expiry: { isValid: false, isEmpty: true },
62
60
  };
63
61
  }
64
- this.mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, styles);
62
+ this.mergedStyles = (0, styles_1.getContainerStylesForLayout)((0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, styles), this.layout);
65
63
  const fieldIds = this.generateFieldIds(containerId);
66
64
  this.numberEl = fieldIds.numberId;
67
65
  this.cvvEl = fieldIds.cvvId;
@@ -73,24 +71,29 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
73
71
  if (container.mode !== 'bank_account') {
74
72
  yield SpreedlyTokenizer.ensureSpreedlyLoaded();
75
73
  }
76
- const environmentKey = (_a = gateway.config) === null || _a === void 0 ? void 0 : _a.environment_key;
74
+ let environmentKey = (_a = gateway.config) === null || _a === void 0 ? void 0 : _a.environment_key;
75
+ if (!environmentKey && config.clientConfig.spreedlyEnvironmentKey) {
76
+ environmentKey = config.clientConfig.spreedlyEnvironmentKey;
77
+ }
77
78
  if (!environmentKey) {
78
- throw new Error('Spreedly environment key not configured');
79
+ environmentKey = '';
79
80
  }
80
- const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false);
81
- tokenizer.organizationId = config === null || config === void 0 ? void 0 : config.organizationId;
82
- tokenizer.embedId = config === null || config === void 0 ? void 0 : config.embedId;
81
+ const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line');
82
+ tokenizer.organizationId = config.organizationId;
83
+ tokenizer.embedId = config.embedId;
84
+ tokenizer.clientConfig = config.clientConfig;
83
85
  tokenizer.createInternalElements();
84
86
  let securityArgs;
85
87
  if (container.mode === 'credit_card' &&
86
- (config === null || config === void 0 ? void 0 : config.organizationId) &&
87
- (config === null || config === void 0 ? void 0 : config.embedId)) {
88
+ config.clientConfig.enableSpreedlySecureTokenization) {
89
+ if (!config.organizationId || !config.embedId) {
90
+ throw new Error('Secure tokenization is enabled but organizationId and embedId are required');
91
+ }
88
92
  try {
89
- const configHandler = new config_handler_1.default({});
90
- securityArgs = yield (0, spreedly_secure_1.fetchSpreedlySecurityArgs)(configHandler, config.organizationId, config.embedId);
93
+ securityArgs = yield (0, spreedly_secure_1.fetchSpreedlySecurityArgs)(config.clientConfig, config.organizationId, config.embedId);
91
94
  }
92
95
  catch (error) {
93
- console.warn('Failed to fetch security args, using standard tokenization');
96
+ throw new Error(`Secure tokenization is enabled but failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`);
94
97
  }
95
98
  }
96
99
  yield tokenizer.init(securityArgs);
@@ -203,40 +206,40 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
203
206
  return new Promise((resolve, reject) => {
204
207
  var _a, _b, _c, _d, _e, _f;
205
208
  const timeout = setTimeout(() => {
206
- this.spreedly.removeHandlers();
209
+ if (this.spreedly && this.spreedly.removeHandlers) {
210
+ this.spreedly.removeHandlers();
211
+ }
207
212
  reject(new types_1.TokenizationError('Tokenization timeout', 'TIMEOUT'));
208
213
  }, tokenizer_constants_1.TOKENIZE_TIMEOUT);
209
214
  const cleanup = () => {
210
215
  clearTimeout(timeout);
211
- this.spreedly.removeHandlers();
216
+ if (this.spreedly && this.spreedly.removeHandlers) {
217
+ this.spreedly.removeHandlers();
218
+ }
212
219
  };
213
220
  this.spreedly.on('paymentMethod', (token, pmData) => {
214
221
  cleanup();
215
- resolve({
222
+ const paymentToken = {
216
223
  token,
217
224
  lastFour: pmData.last_four_digits,
218
225
  cardType: this.normalizeCardType(pmData.card_type),
219
226
  provider: 'spreedly',
220
- });
227
+ };
228
+ this.emit('tokenReady', paymentToken);
229
+ resolve(paymentToken);
221
230
  });
222
231
  this.spreedly.on('errors', (errors) => {
223
232
  cleanup();
224
233
  reject(new types_1.TokenizationError(errors));
225
234
  });
226
- let expiryMonth = cardData.expiryMonth || '';
227
- let expiryYear = cardData.expiryYear || '';
228
- if (!expiryMonth || !expiryYear) {
229
- const expiry = this.parseExpiry(this.expiryEl);
230
- if (expiry) {
231
- expiryMonth = expiry.month;
232
- expiryYear = expiry.year;
233
- }
234
- else {
235
- cleanup();
236
- reject(new types_1.TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
237
- return;
238
- }
235
+ const expiry = this.parseExpiry(this.expiryEl);
236
+ if (!expiry) {
237
+ cleanup();
238
+ reject(new types_1.TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
239
+ return;
239
240
  }
241
+ const expiryMonth = expiry.month;
242
+ const expiryYear = expiry.year;
240
243
  this.spreedly.tokenizeCreditCard({
241
244
  first_name: cardData.firstName,
242
245
  last_name: cardData.lastName,
@@ -255,64 +258,127 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
255
258
  });
256
259
  }
257
260
  createCanadianBankAccountFields(container) {
258
- this.institutionNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-institution`, 'text', 'Inst *', 3);
259
- Object.assign(this.institutionNumberEl.style, {
260
- flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.institutionNumber.flex,
261
- minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.institutionNumber.minWidth,
262
- });
263
- this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'left');
264
- this.institutionNumberEl.addEventListener('blur', () => {
265
- const isValid = (0, tokenizer_utils_1.validateInstitutionNumber)(this.institutionNumberEl.value);
266
- if (!isValid && this.institutionNumberEl.value) {
267
- this.applyErrorStyles(this.institutionNumberEl);
268
- }
269
- else {
270
- this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'left');
271
- }
272
- this.updateBankAccountValidation();
273
- });
274
- container.appendChild(this.institutionNumberEl);
275
- this.transitNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-transit`, 'text', 'Transit *', 5);
276
- Object.assign(this.transitNumberEl.style, {
277
- flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.flex,
278
- minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.minWidth,
279
- });
280
- this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'middle');
281
- this.transitNumberEl.addEventListener('blur', () => {
282
- const isValid = (0, tokenizer_utils_1.validateTransitNumber)(this.transitNumberEl.value);
283
- if (!isValid && this.transitNumberEl.value) {
284
- this.applyErrorStyles(this.transitNumberEl);
285
- }
286
- else {
287
- this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'middle');
288
- }
289
- this.updateBankAccountValidation();
290
- });
291
- container.appendChild(this.transitNumberEl);
292
- this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *');
293
- Object.assign(this.accountNumberEl.style, {
294
- flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.flex,
295
- minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.minWidth,
296
- });
297
- this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
298
- this.accountNumberEl.addEventListener('blur', () => {
299
- const isValid = (0, tokenizer_utils_1.validateCanadianAccountNumber)(this.accountNumberEl.value);
300
- if (!isValid && this.accountNumberEl.value) {
301
- this.applyErrorStyles(this.accountNumberEl);
302
- }
303
- else {
304
- this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
305
- }
306
- this.updateBankAccountValidation();
307
- });
308
- container.appendChild(this.accountNumberEl);
309
- this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
310
- Object.assign(this.accountTypeEl.style, {
311
- flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.flex,
312
- minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
313
- });
314
- this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
315
- container.appendChild(this.accountTypeEl);
261
+ if (this.layout === 'two-line') {
262
+ this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
263
+ Object.assign(this.accountTypeEl.style, {
264
+ flex: '2',
265
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
266
+ });
267
+ this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
268
+ container.appendChild(this.accountTypeEl);
269
+ this.institutionNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-institution`, 'text', 'Inst *', 3);
270
+ Object.assign(this.institutionNumberEl.style, {
271
+ flex: '1',
272
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.institutionNumber.minWidth,
273
+ });
274
+ this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'middle');
275
+ this.institutionNumberEl.addEventListener('blur', () => {
276
+ const isValid = (0, tokenizer_utils_1.validateInstitutionNumber)(this.institutionNumberEl.value);
277
+ if (!isValid && this.institutionNumberEl.value) {
278
+ this.applyErrorStyles(this.institutionNumberEl);
279
+ }
280
+ else {
281
+ this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'middle');
282
+ }
283
+ this.updateBankAccountValidation();
284
+ });
285
+ container.appendChild(this.institutionNumberEl);
286
+ this.transitNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-transit`, 'text', 'Transit *', 5);
287
+ Object.assign(this.transitNumberEl.style, {
288
+ flex: '2',
289
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.minWidth,
290
+ });
291
+ this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'right');
292
+ this.transitNumberEl.addEventListener('blur', () => {
293
+ const isValid = (0, tokenizer_utils_1.validateTransitNumber)(this.transitNumberEl.value);
294
+ if (!isValid && this.transitNumberEl.value) {
295
+ this.applyErrorStyles(this.transitNumberEl);
296
+ }
297
+ else {
298
+ this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'right');
299
+ }
300
+ this.updateBankAccountValidation();
301
+ });
302
+ container.appendChild(this.transitNumberEl);
303
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *');
304
+ Object.assign(this.accountNumberEl.style, {
305
+ flex: '1',
306
+ flexBasis: '100%',
307
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.minWidth,
308
+ });
309
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles);
310
+ this.accountNumberEl.addEventListener('blur', () => {
311
+ const isValid = (0, tokenizer_utils_1.validateCanadianAccountNumber)(this.accountNumberEl.value);
312
+ if (!isValid && this.accountNumberEl.value) {
313
+ this.applyErrorStyles(this.accountNumberEl);
314
+ }
315
+ else {
316
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles);
317
+ }
318
+ this.updateBankAccountValidation();
319
+ });
320
+ container.appendChild(this.accountNumberEl);
321
+ }
322
+ else {
323
+ this.institutionNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-institution`, 'text', 'Inst *', 3);
324
+ Object.assign(this.institutionNumberEl.style, {
325
+ flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.institutionNumber.flex,
326
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.institutionNumber.minWidth,
327
+ });
328
+ this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'left');
329
+ this.institutionNumberEl.addEventListener('blur', () => {
330
+ const isValid = (0, tokenizer_utils_1.validateInstitutionNumber)(this.institutionNumberEl.value);
331
+ if (!isValid && this.institutionNumberEl.value) {
332
+ this.applyErrorStyles(this.institutionNumberEl);
333
+ }
334
+ else {
335
+ this.applyInputStyles(this.institutionNumberEl, this.mergedStyles, 'left');
336
+ }
337
+ this.updateBankAccountValidation();
338
+ });
339
+ container.appendChild(this.institutionNumberEl);
340
+ this.transitNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-transit`, 'text', 'Transit *', 5);
341
+ Object.assign(this.transitNumberEl.style, {
342
+ flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.flex,
343
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.transitNumber.minWidth,
344
+ });
345
+ this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'middle');
346
+ this.transitNumberEl.addEventListener('blur', () => {
347
+ const isValid = (0, tokenizer_utils_1.validateTransitNumber)(this.transitNumberEl.value);
348
+ if (!isValid && this.transitNumberEl.value) {
349
+ this.applyErrorStyles(this.transitNumberEl);
350
+ }
351
+ else {
352
+ this.applyInputStyles(this.transitNumberEl, this.mergedStyles, 'middle');
353
+ }
354
+ this.updateBankAccountValidation();
355
+ });
356
+ container.appendChild(this.transitNumberEl);
357
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *');
358
+ Object.assign(this.accountNumberEl.style, {
359
+ flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.flex,
360
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountNumber.minWidth,
361
+ });
362
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
363
+ this.accountNumberEl.addEventListener('blur', () => {
364
+ const isValid = (0, tokenizer_utils_1.validateCanadianAccountNumber)(this.accountNumberEl.value);
365
+ if (!isValid && this.accountNumberEl.value) {
366
+ this.applyErrorStyles(this.accountNumberEl);
367
+ }
368
+ else {
369
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
370
+ }
371
+ this.updateBankAccountValidation();
372
+ });
373
+ container.appendChild(this.accountNumberEl);
374
+ this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
375
+ Object.assign(this.accountTypeEl.style, {
376
+ flex: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.flex,
377
+ minWidth: tokenizer_constants_1.CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
378
+ });
379
+ this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
380
+ container.appendChild(this.accountTypeEl);
381
+ }
316
382
  }
317
383
  tokenizeBankAccountInternal(bankData) {
318
384
  return __awaiter(this, void 0, void 0, function* () {
@@ -379,7 +445,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
379
445
  accountType: accountType,
380
446
  accountHolderType: accountHolderType,
381
447
  },
382
- }, new config_handler_1.default({ spreedlyEnvironmentKey: this.environmentKey }));
448
+ }, this.clientConfig);
383
449
  return {
384
450
  token: result,
385
451
  lastFour: accountNumber.slice(-4),
@@ -401,29 +467,49 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
401
467
  }
402
468
  validateCardInternal() {
403
469
  return __awaiter(this, void 0, void 0, function* () {
404
- return new Promise((resolve) => {
405
- this.spreedly.on('validation', (isValid, validationData) => {
406
- this.spreedly.removeHandlers();
407
- const errors = [];
408
- if (!validationData.validNumber) {
409
- errors.push({
410
- field: 'cardNumber',
411
- message: 'Invalid card number',
412
- });
413
- }
414
- if (!validationData.validCvv) {
415
- errors.push({
416
- field: 'cvv',
417
- message: 'Invalid CVV',
418
- });
419
- }
420
- resolve({
421
- isValid: isValid && errors.length === 0,
422
- errors,
423
- });
470
+ var _a, _b, _c, _d, _e;
471
+ const errors = [];
472
+ if ((_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isEmpty) {
473
+ errors.push({
474
+ field: 'cardNumber',
475
+ message: 'Card number is required',
424
476
  });
425
- this.spreedly.validate();
426
- });
477
+ }
478
+ else if (!((_b = this.currentValidationState.cardNumber) === null || _b === void 0 ? void 0 : _b.isValid)) {
479
+ errors.push({
480
+ field: 'cardNumber',
481
+ message: 'Invalid card number',
482
+ });
483
+ }
484
+ if ((_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isEmpty) {
485
+ errors.push({
486
+ field: 'cvv',
487
+ message: 'CVV is required',
488
+ });
489
+ }
490
+ else if (!((_d = this.currentValidationState.cvv) === null || _d === void 0 ? void 0 : _d.isValid)) {
491
+ errors.push({
492
+ field: 'cvv',
493
+ message: 'Invalid CVV',
494
+ });
495
+ }
496
+ const expiry = this.parseExpiry(this.expiryEl);
497
+ if (!((_e = this.expiryEl) === null || _e === void 0 ? void 0 : _e.value)) {
498
+ errors.push({
499
+ field: 'expiry',
500
+ message: 'Expiration date is required',
501
+ });
502
+ }
503
+ else if (!expiry) {
504
+ errors.push({
505
+ field: 'expiry',
506
+ message: 'Invalid expiration date',
507
+ });
508
+ }
509
+ return {
510
+ isValid: errors.length === 0,
511
+ errors,
512
+ };
427
513
  });
428
514
  }
429
515
  validateBankAccountInternal() {
@@ -603,33 +689,57 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
603
689
  }
604
690
  }
605
691
  destroy() {
606
- this.spreedly.removeHandlers();
692
+ if (this.spreedly && this.spreedly.removeHandlers) {
693
+ this.spreedly.removeHandlers();
694
+ }
607
695
  this.eventHandlers.clear();
608
696
  if (this.expiryEl) {
609
697
  }
610
698
  }
699
+ hasToken() {
700
+ return false;
701
+ }
702
+ getToken() {
703
+ return null;
704
+ }
705
+ get tokenizationMode() {
706
+ return 'manual';
707
+ }
708
+ updateOverallValidation() {
709
+ var _a, _b, _c, _d, _e, _f;
710
+ if (this.mode === 'credit_card') {
711
+ this.currentValidationState.isValid =
712
+ ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
713
+ ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false) &&
714
+ ((_f = (_e = this.currentValidationState.expiry) === null || _e === void 0 ? void 0 : _e.isValid) !== null && _f !== void 0 ? _f : false);
715
+ }
716
+ else {
717
+ this.currentValidationState.isValid = true;
718
+ }
719
+ this.emit('validation', this.currentValidationState);
720
+ }
611
721
  handleFieldEvent(fieldName, eventType, inputProperties) {
612
- var _a, _b, _c, _d;
613
- if (fieldName === 'number') {
614
- this.currentValidationState.cardNumber = {
615
- isValid: inputProperties.validNumber || false,
616
- isEmpty: inputProperties.numberLength === 0,
617
- };
618
- if (inputProperties.cardType && inputProperties.cardType !== 'unknown') {
619
- this.emit('cardTypeChange', {
620
- cardType: this.normalizeCardType(inputProperties.cardType),
621
- });
722
+ if (eventType === 'input') {
723
+ if (fieldName === 'number') {
724
+ this.currentValidationState.cardNumber = {
725
+ isValid: inputProperties.validNumber || false,
726
+ isEmpty: inputProperties.numberLength === 0,
727
+ };
728
+ if (inputProperties.cardType &&
729
+ inputProperties.cardType !== 'unknown') {
730
+ this.emit('cardTypeChange', {
731
+ cardType: this.normalizeCardType(inputProperties.cardType),
732
+ });
733
+ }
622
734
  }
735
+ else if (fieldName === 'cvv') {
736
+ this.currentValidationState.cvv = {
737
+ isValid: inputProperties.validCvv || false,
738
+ isEmpty: inputProperties.cvvLength === 0,
739
+ };
740
+ }
741
+ this.updateOverallValidation();
623
742
  }
624
- else if (fieldName === 'cvv') {
625
- this.currentValidationState.cvv = {
626
- isValid: inputProperties.validCvv || false,
627
- isEmpty: inputProperties.cvvLength === 0,
628
- };
629
- }
630
- this.currentValidationState.isValid =
631
- ((_b = (_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isValid) !== null && _b !== void 0 ? _b : false) &&
632
- ((_d = (_c = this.currentValidationState.cvv) === null || _c === void 0 ? void 0 : _c.isValid) !== null && _d !== void 0 ? _d : false);
633
743
  if (eventType === 'focus') {
634
744
  this.emit('focus', { field: fieldName });
635
745
  }
@@ -638,7 +748,6 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
638
748
  }
639
749
  else if (eventType === 'input') {
640
750
  this.emit('change', { field: fieldName });
641
- this.emit('validation', this.currentValidationState);
642
751
  }
643
752
  }
644
753
  createInternalElements() {
@@ -656,20 +765,57 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
656
765
  }
657
766
  }
658
767
  createCreditCardFields(container) {
659
- const cardNumberDiv = (0, tokenizer_utils_1.createFieldContainer)(this.numberEl, tokenizer_constants_1.FIELD_FLEX.cardNumber.flex, tokenizer_constants_1.FIELD_FLEX.cardNumber.minWidth);
660
- cardNumberDiv.style.height = this.mergedStyles.input.height;
661
- container.appendChild(cardNumberDiv);
662
- this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
663
- Object.assign(this.expiryEl.style, {
664
- flex: tokenizer_constants_1.FIELD_FLEX.expiry.flex,
665
- minWidth: tokenizer_constants_1.FIELD_FLEX.expiry.minWidth,
666
- });
667
- this.applyInputStyles(this.expiryEl, this.mergedStyles, 'middle');
668
- this.addExpiryFormatter(this.expiryEl);
669
- container.appendChild(this.expiryEl);
670
- const cvvDiv = (0, tokenizer_utils_1.createFieldContainer)(this.cvvEl, tokenizer_constants_1.FIELD_FLEX.cvv.flex, tokenizer_constants_1.FIELD_FLEX.cvv.minWidth);
671
- cvvDiv.style.height = this.mergedStyles.input.height;
672
- container.appendChild(cvvDiv);
768
+ if (this.layout === 'two-line') {
769
+ const cardNumberDiv = (0, tokenizer_utils_1.createFieldContainer)(this.numberEl, '1', tokenizer_constants_1.FIELD_FLEX.cardNumber.minWidth);
770
+ cardNumberDiv.style.height = this.mergedStyles.input.height;
771
+ cardNumberDiv.style.flexBasis = '100%';
772
+ container.appendChild(cardNumberDiv);
773
+ this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
774
+ Object.assign(this.expiryEl.style, {
775
+ flex: '1',
776
+ minWidth: tokenizer_constants_1.FIELD_FLEX.expiry.minWidth,
777
+ });
778
+ this.applyInputStyles(this.expiryEl, this.mergedStyles, 'left');
779
+ this.addExpiryFormatter(this.expiryEl);
780
+ this.expiryEl.addEventListener('input', () => {
781
+ var _a;
782
+ const expiry = this.parseExpiry(this.expiryEl);
783
+ this.currentValidationState.expiry = {
784
+ isValid: !!expiry,
785
+ isEmpty: !((_a = this.expiryEl) === null || _a === void 0 ? void 0 : _a.value),
786
+ };
787
+ this.updateOverallValidation();
788
+ });
789
+ container.appendChild(this.expiryEl);
790
+ const cvvDiv = (0, tokenizer_utils_1.createFieldContainer)(this.cvvEl, '1', tokenizer_constants_1.FIELD_FLEX.cvv.minWidth);
791
+ cvvDiv.style.height = this.mergedStyles.input.height;
792
+ container.appendChild(cvvDiv);
793
+ }
794
+ else {
795
+ const cardNumberDiv = (0, tokenizer_utils_1.createFieldContainer)(this.numberEl, tokenizer_constants_1.FIELD_FLEX.cardNumber.flex, tokenizer_constants_1.FIELD_FLEX.cardNumber.minWidth);
796
+ cardNumberDiv.style.height = this.mergedStyles.input.height;
797
+ container.appendChild(cardNumberDiv);
798
+ this.expiryEl = (0, tokenizer_utils_1.createInputElement)(this.expiryId, 'text', tokenizer_constants_1.PLACEHOLDERS.expiry, tokenizer_constants_1.FIELD_CONSTRAINTS.expiry.maxLength);
799
+ Object.assign(this.expiryEl.style, {
800
+ flex: tokenizer_constants_1.FIELD_FLEX.expiry.flex,
801
+ minWidth: tokenizer_constants_1.FIELD_FLEX.expiry.minWidth,
802
+ });
803
+ this.applyInputStyles(this.expiryEl, this.mergedStyles, 'middle');
804
+ this.addExpiryFormatter(this.expiryEl);
805
+ this.expiryEl.addEventListener('input', () => {
806
+ var _a;
807
+ const expiry = this.parseExpiry(this.expiryEl);
808
+ this.currentValidationState.expiry = {
809
+ isValid: !!expiry,
810
+ isEmpty: !((_a = this.expiryEl) === null || _a === void 0 ? void 0 : _a.value),
811
+ };
812
+ this.updateOverallValidation();
813
+ });
814
+ container.appendChild(this.expiryEl);
815
+ const cvvDiv = (0, tokenizer_utils_1.createFieldContainer)(this.cvvEl, tokenizer_constants_1.FIELD_FLEX.cvv.flex, tokenizer_constants_1.FIELD_FLEX.cvv.minWidth);
816
+ cvvDiv.style.height = this.mergedStyles.input.height;
817
+ container.appendChild(cvvDiv);
818
+ }
673
819
  }
674
820
  createBankAccountFields(container) {
675
821
  if (this.bankCountry === 'CA') {
@@ -680,47 +826,93 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
680
826
  }
681
827
  }
682
828
  createUSBankAccountFields(container) {
683
- this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
684
- Object.assign(this.routingNumberEl.style, {
685
- flex: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.flex,
686
- minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
687
- });
688
- this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'left');
689
- this.routingNumberEl.addEventListener('blur', () => {
690
- const isValid = (0, tokenizer_utils_1.validateRoutingNumber)(this.routingNumberEl.value);
691
- if (!isValid && this.routingNumberEl.value) {
692
- this.applyErrorStyles(this.routingNumberEl);
693
- }
694
- else {
695
- this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'left');
696
- }
697
- this.updateBankAccountValidation();
698
- });
699
- container.appendChild(this.routingNumberEl);
700
- this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
701
- Object.assign(this.accountNumberEl.style, {
702
- flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.flex,
703
- minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
704
- });
705
- this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
706
- this.accountNumberEl.addEventListener('blur', () => {
707
- const isValid = (0, tokenizer_utils_1.validateAccountNumber)(this.accountNumberEl.value);
708
- if (!isValid && this.accountNumberEl.value) {
709
- this.applyErrorStyles(this.accountNumberEl);
710
- }
711
- else {
712
- this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
713
- }
714
- this.updateBankAccountValidation();
715
- });
716
- container.appendChild(this.accountNumberEl);
717
- this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
718
- Object.assign(this.accountTypeEl.style, {
719
- flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.flex,
720
- minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
721
- });
722
- this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
723
- container.appendChild(this.accountTypeEl);
829
+ if (this.layout === 'two-line') {
830
+ this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
831
+ Object.assign(this.accountTypeEl.style, {
832
+ flex: '1',
833
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
834
+ });
835
+ this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
836
+ container.appendChild(this.accountTypeEl);
837
+ this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
838
+ Object.assign(this.routingNumberEl.style, {
839
+ flex: '1',
840
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
841
+ });
842
+ this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'right');
843
+ this.routingNumberEl.addEventListener('blur', () => {
844
+ const isValid = (0, tokenizer_utils_1.validateRoutingNumber)(this.routingNumberEl.value);
845
+ if (!isValid && this.routingNumberEl.value) {
846
+ this.applyErrorStyles(this.routingNumberEl);
847
+ }
848
+ else {
849
+ this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'right');
850
+ }
851
+ this.updateBankAccountValidation();
852
+ });
853
+ container.appendChild(this.routingNumberEl);
854
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
855
+ Object.assign(this.accountNumberEl.style, {
856
+ flex: '1',
857
+ flexBasis: '100%',
858
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
859
+ });
860
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles);
861
+ this.accountNumberEl.addEventListener('blur', () => {
862
+ const isValid = (0, tokenizer_utils_1.validateAccountNumber)(this.accountNumberEl.value);
863
+ if (!isValid && this.accountNumberEl.value) {
864
+ this.applyErrorStyles(this.accountNumberEl);
865
+ }
866
+ else {
867
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles);
868
+ }
869
+ this.updateBankAccountValidation();
870
+ });
871
+ container.appendChild(this.accountNumberEl);
872
+ }
873
+ else {
874
+ this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
875
+ Object.assign(this.routingNumberEl.style, {
876
+ flex: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.flex,
877
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
878
+ });
879
+ this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'left');
880
+ this.routingNumberEl.addEventListener('blur', () => {
881
+ const isValid = (0, tokenizer_utils_1.validateRoutingNumber)(this.routingNumberEl.value);
882
+ if (!isValid && this.routingNumberEl.value) {
883
+ this.applyErrorStyles(this.routingNumberEl);
884
+ }
885
+ else {
886
+ this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'left');
887
+ }
888
+ this.updateBankAccountValidation();
889
+ });
890
+ container.appendChild(this.routingNumberEl);
891
+ this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
892
+ Object.assign(this.accountNumberEl.style, {
893
+ flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.flex,
894
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
895
+ });
896
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
897
+ this.accountNumberEl.addEventListener('blur', () => {
898
+ const isValid = (0, tokenizer_utils_1.validateAccountNumber)(this.accountNumberEl.value);
899
+ if (!isValid && this.accountNumberEl.value) {
900
+ this.applyErrorStyles(this.accountNumberEl);
901
+ }
902
+ else {
903
+ this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'middle');
904
+ }
905
+ this.updateBankAccountValidation();
906
+ });
907
+ container.appendChild(this.accountNumberEl);
908
+ this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
909
+ Object.assign(this.accountTypeEl.style, {
910
+ flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.flex,
911
+ minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
912
+ });
913
+ this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
914
+ container.appendChild(this.accountTypeEl);
915
+ }
724
916
  }
725
917
  updateBankAccountValidation() {
726
918
  if (this.bankCountry === 'CA') {