@idonatedev/idonate-sdk 1.2.0-dev2 → 1.2.0-dev21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +11 -2
- package/dist/esm/constants.js +11 -2
- package/dist/esm/idonate-client.js +18 -8
- package/dist/esm/recaptcha.d.ts +1 -0
- package/dist/esm/recaptcha.js +26 -2
- package/dist/esm/shared.js +9 -1
- package/dist/esm/tokenize/CardConnectTokenizer.d.ts +8 -1
- package/dist/esm/tokenize/CardConnectTokenizer.js +353 -104
- package/dist/esm/tokenize/PayPalTokenizer.d.ts +6 -0
- package/dist/esm/tokenize/PayPalTokenizer.js +66 -16
- package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +23 -1
- package/dist/esm/tokenize/SpreedlyTokenizer.js +330 -151
- package/dist/esm/tokenize/Tokenizer.d.ts +6 -2
- package/dist/esm/tokenize/Tokenizer.js +24 -8
- package/dist/esm/tokenize/gateway-utils.d.ts +2 -0
- package/dist/esm/tokenize/gateway-utils.js +27 -0
- package/dist/esm/tokenize/index.d.ts +3 -2
- package/dist/esm/tokenize/index.js +1 -0
- package/dist/esm/tokenize/spreedly-secure.js +6 -2
- package/dist/esm/tokenize/styles.d.ts +1 -1
- package/dist/esm/tokenize/styles.js +20 -1
- package/dist/esm/tokenize/tokenizer-constants.d.ts +1 -0
- package/dist/esm/tokenize/tokenizer-constants.js +1 -0
- package/dist/esm/tokenize/tokenizer-utils.d.ts +4 -1
- package/dist/esm/tokenize/tokenizer-utils.js +77 -4
- package/dist/esm/tokenize/types.d.ts +33 -8
- package/dist/esm/typeAdapters.js +6 -4
- package/dist/esm/types.d.ts +4 -10
- package/dist/idonate-client.js +18 -8
- package/dist/recaptcha.d.ts +1 -0
- package/dist/recaptcha.js +27 -2
- package/dist/shared.js +9 -1
- package/dist/tokenize/CardConnectTokenizer.d.ts +8 -1
- package/dist/tokenize/CardConnectTokenizer.js +351 -105
- package/dist/tokenize/PayPalTokenizer.d.ts +6 -0
- package/dist/tokenize/PayPalTokenizer.js +66 -16
- package/dist/tokenize/SpreedlyTokenizer.d.ts +23 -1
- package/dist/tokenize/SpreedlyTokenizer.js +327 -148
- package/dist/tokenize/Tokenizer.d.ts +6 -2
- package/dist/tokenize/Tokenizer.js +24 -8
- package/dist/tokenize/gateway-utils.d.ts +2 -0
- package/dist/tokenize/gateway-utils.js +30 -0
- package/dist/tokenize/index.d.ts +3 -2
- package/dist/tokenize/index.js +3 -1
- package/dist/tokenize/spreedly-secure.js +6 -2
- package/dist/tokenize/styles.d.ts +1 -1
- package/dist/tokenize/styles.js +20 -1
- package/dist/tokenize/tokenizer-constants.d.ts +1 -0
- package/dist/tokenize/tokenizer-constants.js +2 -1
- package/dist/tokenize/tokenizer-utils.d.ts +4 -1
- package/dist/tokenize/tokenizer-utils.js +80 -4
- package/dist/tokenize/types.d.ts +33 -8
- package/dist/typeAdapters.js +6 -4
- package/dist/types.d.ts +4 -10
- package/package.json +33 -2
- package/umd/idonate-sdk.js +1 -1
|
@@ -11,23 +11,33 @@ import { Tokenizer } from './Tokenizer';
|
|
|
11
11
|
import { TokenizationError, } from './types';
|
|
12
12
|
import { SPREEDLY_TOKENIZER_URL } from '../constants';
|
|
13
13
|
import { extractSpreedlyToken, unpackSpreedlyResponse } from '../typeAdapters';
|
|
14
|
-
import { fetchSpreedlySecurityArgs
|
|
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';
|
|
17
|
-
import { createFieldContainer, createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, validateInstitutionNumber, validateTransitNumber, validateCanadianAccountNumber, formatCanadianRoutingNumber, } from './tokenizer-utils';
|
|
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, 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') {
|
|
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;
|
|
29
|
+
this.numberBaseCss = '';
|
|
30
|
+
this.cvvBaseCss = '';
|
|
31
|
+
this.numberErrorCss = '';
|
|
32
|
+
this.cvvErrorCss = '';
|
|
33
|
+
this.numberHasError = false;
|
|
34
|
+
this.cvvHasError = false;
|
|
35
|
+
this.effectiveLayout = 'single-line';
|
|
36
|
+
this.responsiveBreakpoint = RESPONSIVE_BREAKPOINT;
|
|
28
37
|
this.mode = mode;
|
|
29
38
|
this.bankCountry = bankCountry;
|
|
30
39
|
this.enableTestMode = enableTestMode;
|
|
40
|
+
this.responsiveBreakpoint = responsiveBreakpoint;
|
|
31
41
|
if (mode === 'credit_card') {
|
|
32
42
|
const SpreedlyFrame = window.SpreedlyPaymentFrame;
|
|
33
43
|
if (SpreedlyFrame) {
|
|
@@ -63,40 +73,33 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
63
73
|
}
|
|
64
74
|
static create(gateway, container, config) {
|
|
65
75
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
var _a;
|
|
76
|
+
var _a, _b;
|
|
67
77
|
if (container.mode !== 'bank_account') {
|
|
68
78
|
yield SpreedlyTokenizer.ensureSpreedlyLoaded();
|
|
69
79
|
}
|
|
70
|
-
let environmentKey = (_a = gateway.config) === null || _a === void 0 ? void 0 : _a.
|
|
80
|
+
let environmentKey = (_a = gateway.config) === null || _a === void 0 ? void 0 : _a.environmentKey;
|
|
71
81
|
if (!environmentKey && config.clientConfig.spreedlyEnvironmentKey) {
|
|
72
82
|
environmentKey = config.clientConfig.spreedlyEnvironmentKey;
|
|
73
83
|
}
|
|
74
84
|
if (!environmentKey) {
|
|
75
|
-
environmentKey
|
|
85
|
+
throw new Error('Spreedly environment key is required. Provide it via gateway.config.environmentKey or client config.');
|
|
76
86
|
}
|
|
77
|
-
const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line');
|
|
87
|
+
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);
|
|
78
88
|
tokenizer.organizationId = config.organizationId;
|
|
79
89
|
tokenizer.embedId = config.embedId;
|
|
80
90
|
tokenizer.clientConfig = config.clientConfig;
|
|
81
91
|
tokenizer.createInternalElements();
|
|
82
|
-
let securityArgs;
|
|
83
92
|
if (container.mode === 'credit_card' &&
|
|
84
93
|
config.clientConfig.enableSpreedlySecureTokenization) {
|
|
85
94
|
if (!config.organizationId || !config.embedId) {
|
|
86
95
|
throw new Error('Secure tokenization is enabled but organizationId and embedId are required');
|
|
87
96
|
}
|
|
88
|
-
try {
|
|
89
|
-
securityArgs = yield fetchSpreedlySecurityArgs(config.clientConfig, config.organizationId, config.embedId);
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
throw new Error(`Secure tokenization is enabled but failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
93
|
-
}
|
|
94
97
|
}
|
|
95
|
-
yield tokenizer.init(
|
|
98
|
+
yield tokenizer.init();
|
|
96
99
|
return tokenizer;
|
|
97
100
|
});
|
|
98
101
|
}
|
|
99
|
-
init(
|
|
102
|
+
init() {
|
|
100
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
101
104
|
this.containerEl = document.getElementById(this.containerId);
|
|
102
105
|
if (this.mode === 'bank_account') {
|
|
@@ -140,11 +143,12 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
140
143
|
reject(new Error('Spreedly initialization timeout'));
|
|
141
144
|
}, INIT_TIMEOUT);
|
|
142
145
|
this.spreedly.on('ready', () => {
|
|
146
|
+
var _a, _b;
|
|
143
147
|
clearTimeout(timeout);
|
|
144
|
-
this.spreedly.setPlaceholder('number', PLACEHOLDERS.cardNumber);
|
|
148
|
+
this.spreedly.setPlaceholder('number', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || PLACEHOLDERS.cardNumber);
|
|
145
149
|
this.spreedly.setFieldType('number', 'text');
|
|
146
150
|
this.spreedly.setNumberFormat('prettyFormat');
|
|
147
|
-
this.spreedly.setPlaceholder('cvv', PLACEHOLDERS.cvv);
|
|
151
|
+
this.spreedly.setPlaceholder('cvv', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.cvv) || PLACEHOLDERS.cvv);
|
|
148
152
|
this.spreedly.setFieldType('cvv', 'text');
|
|
149
153
|
this.applyUnifiedStyles();
|
|
150
154
|
if (this.enableTestMode &&
|
|
@@ -162,23 +166,37 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
162
166
|
this.emit('ready');
|
|
163
167
|
resolve();
|
|
164
168
|
});
|
|
169
|
+
this.spreedly.on('paymentMethod', (token, pmData) => {
|
|
170
|
+
const paymentToken = {
|
|
171
|
+
token,
|
|
172
|
+
lastFour: pmData.last_four_digits,
|
|
173
|
+
cardType: this.normalizeCardType(pmData.card_type),
|
|
174
|
+
paymentMethodType: 'credit_card',
|
|
175
|
+
provider: 'spreedly',
|
|
176
|
+
};
|
|
177
|
+
if (this.tokenizationResolve) {
|
|
178
|
+
const resolveTokenization = this.tokenizationResolve;
|
|
179
|
+
this.clearTokenizationState();
|
|
180
|
+
this.emit('tokenReady', paymentToken);
|
|
181
|
+
resolveTokenization(paymentToken);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
165
184
|
this.spreedly.on('errors', (errors) => {
|
|
166
|
-
|
|
185
|
+
const error = new TokenizationError(errors);
|
|
186
|
+
this.emit('error', error);
|
|
187
|
+
if (this.tokenizationReject) {
|
|
188
|
+
const rejectTokenization = this.tokenizationReject;
|
|
189
|
+
this.clearTokenizationState();
|
|
190
|
+
rejectTokenization(error);
|
|
191
|
+
}
|
|
167
192
|
});
|
|
168
193
|
this.spreedly.on('fieldEvent', (fieldName, eventType, activeEl, inputProperties) => {
|
|
169
194
|
this.handleFieldEvent(fieldName, eventType, inputProperties);
|
|
170
195
|
});
|
|
171
|
-
|
|
196
|
+
this.spreedly.init(this.environmentKey, {
|
|
172
197
|
numberEl: this.numberEl,
|
|
173
198
|
cvvEl: this.cvvEl,
|
|
174
|
-
};
|
|
175
|
-
if (securityArgs) {
|
|
176
|
-
initOptions.certificateToken = securityArgs.certificate_token;
|
|
177
|
-
initOptions.signature = securityArgs.signature;
|
|
178
|
-
initOptions.timestamp = securityArgs.timestamp;
|
|
179
|
-
initOptions.nonce = securityArgs.nonce;
|
|
180
|
-
}
|
|
181
|
-
this.spreedly.init(this.environmentKey, initOptions);
|
|
199
|
+
});
|
|
182
200
|
});
|
|
183
201
|
});
|
|
184
202
|
}
|
|
@@ -196,58 +214,45 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
196
214
|
});
|
|
197
215
|
}
|
|
198
216
|
tokenizeCardInternal(cardData) {
|
|
217
|
+
if (this.tokenizationPromise) {
|
|
218
|
+
return this.tokenizationPromise;
|
|
219
|
+
}
|
|
220
|
+
const expiry = this.parseExpiry(this.expiryEl);
|
|
221
|
+
if (!expiry) {
|
|
222
|
+
return Promise.reject(new TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
|
|
223
|
+
}
|
|
224
|
+
this.tokenizationPromise = this.executeCardTokenization(cardData, expiry).finally(() => {
|
|
225
|
+
this.tokenizationPromise = undefined;
|
|
226
|
+
});
|
|
227
|
+
return this.tokenizationPromise;
|
|
228
|
+
}
|
|
229
|
+
executeCardTokenization(cardData, expiry) {
|
|
199
230
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
var _a;
|
|
232
|
+
let securityFields = {};
|
|
233
|
+
if ((_a = this.clientConfig) === null || _a === void 0 ? void 0 : _a.enableSpreedlySecureTokenization) {
|
|
234
|
+
try {
|
|
235
|
+
const args = yield fetchSpreedlySecurityArgs(this.clientConfig, this.organizationId, this.embedId);
|
|
236
|
+
securityFields = {
|
|
237
|
+
nonce: args.nonce,
|
|
238
|
+
timestamp: args.timestamp,
|
|
239
|
+
certificateToken: args.certificate_token,
|
|
240
|
+
signature: args.signature,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
throw new TokenizationError(`Secure tokenization failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'SECURE_TOKENIZATION_ERROR');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
200
247
|
return new Promise((resolve, reject) => {
|
|
201
248
|
var _a, _b, _c, _d, _e, _f;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
249
|
+
this.tokenizationResolve = resolve;
|
|
250
|
+
this.tokenizationReject = reject;
|
|
251
|
+
this.tokenizationTimeout = setTimeout(() => {
|
|
252
|
+
this.clearTokenizationState();
|
|
206
253
|
reject(new TokenizationError('Tokenization timeout', 'TIMEOUT'));
|
|
207
254
|
}, TOKENIZE_TIMEOUT);
|
|
208
|
-
|
|
209
|
-
clearTimeout(timeout);
|
|
210
|
-
if (this.spreedly && this.spreedly.removeHandlers) {
|
|
211
|
-
this.spreedly.removeHandlers();
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
this.spreedly.on('paymentMethod', (token, pmData) => {
|
|
215
|
-
cleanup();
|
|
216
|
-
const paymentToken = {
|
|
217
|
-
token,
|
|
218
|
-
lastFour: pmData.last_four_digits,
|
|
219
|
-
cardType: this.normalizeCardType(pmData.card_type),
|
|
220
|
-
provider: 'spreedly',
|
|
221
|
-
};
|
|
222
|
-
this.emit('tokenReady', paymentToken);
|
|
223
|
-
resolve(paymentToken);
|
|
224
|
-
});
|
|
225
|
-
this.spreedly.on('errors', (errors) => {
|
|
226
|
-
cleanup();
|
|
227
|
-
reject(new TokenizationError(errors));
|
|
228
|
-
});
|
|
229
|
-
const expiry = this.parseExpiry(this.expiryEl);
|
|
230
|
-
if (!expiry) {
|
|
231
|
-
cleanup();
|
|
232
|
-
reject(new TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const expiryMonth = expiry.month;
|
|
236
|
-
const expiryYear = expiry.year;
|
|
237
|
-
this.spreedly.tokenizeCreditCard({
|
|
238
|
-
first_name: cardData.firstName,
|
|
239
|
-
last_name: cardData.lastName,
|
|
240
|
-
month: expiryMonth,
|
|
241
|
-
year: expiryYear,
|
|
242
|
-
email: cardData.email,
|
|
243
|
-
phone_number: cardData.phone,
|
|
244
|
-
address1: (_a = cardData.address) === null || _a === void 0 ? void 0 : _a.address1,
|
|
245
|
-
address2: (_b = cardData.address) === null || _b === void 0 ? void 0 : _b.address2,
|
|
246
|
-
city: (_c = cardData.address) === null || _c === void 0 ? void 0 : _c.city,
|
|
247
|
-
state: (_d = cardData.address) === null || _d === void 0 ? void 0 : _d.state,
|
|
248
|
-
zip: (_e = cardData.address) === null || _e === void 0 ? void 0 : _e.zip,
|
|
249
|
-
country: (_f = cardData.address) === null || _f === void 0 ? void 0 : _f.country,
|
|
250
|
-
});
|
|
255
|
+
this.spreedly.tokenizeCreditCard(Object.assign({ first_name: cardData.firstName, last_name: cardData.lastName, month: expiry.month, year: expiry.year, email: cardData.email, phone_number: cardData.phone, address1: (_a = cardData.address) === null || _a === void 0 ? void 0 : _a.address1, address2: (_b = cardData.address) === null || _b === void 0 ? void 0 : _b.address2, city: (_c = cardData.address) === null || _c === void 0 ? void 0 : _c.city, state: (_d = cardData.address) === null || _d === void 0 ? void 0 : _d.state, zip: (_e = cardData.address) === null || _e === void 0 ? void 0 : _e.zip, country: (_f = cardData.address) === null || _f === void 0 ? void 0 : _f.country }, securityFields));
|
|
251
256
|
});
|
|
252
257
|
});
|
|
253
258
|
}
|
|
@@ -259,7 +264,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
259
264
|
minWidth: CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
|
|
260
265
|
});
|
|
261
266
|
this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
|
|
262
|
-
|
|
267
|
+
this.appendField(container, this.accountTypeEl, 'Account Type');
|
|
263
268
|
this.institutionNumberEl = createInputElement(`${this.containerId}-institution`, 'text', 'Inst *', 3);
|
|
264
269
|
Object.assign(this.institutionNumberEl.style, {
|
|
265
270
|
flex: '1',
|
|
@@ -276,7 +281,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
276
281
|
}
|
|
277
282
|
this.updateBankAccountValidation();
|
|
278
283
|
});
|
|
279
|
-
|
|
284
|
+
this.appendField(container, this.institutionNumberEl, 'Institution');
|
|
280
285
|
this.transitNumberEl = createInputElement(`${this.containerId}-transit`, 'text', 'Transit *', 5);
|
|
281
286
|
Object.assign(this.transitNumberEl.style, {
|
|
282
287
|
flex: '2',
|
|
@@ -293,7 +298,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
293
298
|
}
|
|
294
299
|
this.updateBankAccountValidation();
|
|
295
300
|
});
|
|
296
|
-
|
|
301
|
+
this.appendField(container, this.transitNumberEl, 'Transit');
|
|
297
302
|
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *');
|
|
298
303
|
Object.assign(this.accountNumberEl.style, {
|
|
299
304
|
flex: '1',
|
|
@@ -311,7 +316,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
311
316
|
}
|
|
312
317
|
this.updateBankAccountValidation();
|
|
313
318
|
});
|
|
314
|
-
|
|
319
|
+
this.appendField(container, this.accountNumberEl, 'Account Number');
|
|
315
320
|
}
|
|
316
321
|
else {
|
|
317
322
|
this.institutionNumberEl = createInputElement(`${this.containerId}-institution`, 'text', 'Inst *', 3);
|
|
@@ -330,7 +335,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
330
335
|
}
|
|
331
336
|
this.updateBankAccountValidation();
|
|
332
337
|
});
|
|
333
|
-
|
|
338
|
+
this.appendField(container, this.institutionNumberEl, 'Institution');
|
|
334
339
|
this.transitNumberEl = createInputElement(`${this.containerId}-transit`, 'text', 'Transit *', 5);
|
|
335
340
|
Object.assign(this.transitNumberEl.style, {
|
|
336
341
|
flex: CANADIAN_BANK_FIELD_FLEX.transitNumber.flex,
|
|
@@ -347,7 +352,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
347
352
|
}
|
|
348
353
|
this.updateBankAccountValidation();
|
|
349
354
|
});
|
|
350
|
-
|
|
355
|
+
this.appendField(container, this.transitNumberEl, 'Transit');
|
|
351
356
|
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *');
|
|
352
357
|
Object.assign(this.accountNumberEl.style, {
|
|
353
358
|
flex: CANADIAN_BANK_FIELD_FLEX.accountNumber.flex,
|
|
@@ -364,14 +369,14 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
364
369
|
}
|
|
365
370
|
this.updateBankAccountValidation();
|
|
366
371
|
});
|
|
367
|
-
|
|
372
|
+
this.appendField(container, this.accountNumberEl, 'Account Number');
|
|
368
373
|
this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
|
|
369
374
|
Object.assign(this.accountTypeEl.style, {
|
|
370
375
|
flex: CANADIAN_BANK_FIELD_FLEX.accountType.flex,
|
|
371
376
|
minWidth: CANADIAN_BANK_FIELD_FLEX.accountType.minWidth,
|
|
372
377
|
});
|
|
373
378
|
this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
|
|
374
|
-
|
|
379
|
+
this.appendField(container, this.accountTypeEl, 'Account Type');
|
|
375
380
|
}
|
|
376
381
|
}
|
|
377
382
|
tokenizeBankAccountInternal(bankData) {
|
|
@@ -439,18 +444,23 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
439
444
|
accountType: accountType,
|
|
440
445
|
accountHolderType: accountHolderType,
|
|
441
446
|
},
|
|
442
|
-
}, this.clientConfig);
|
|
443
|
-
|
|
447
|
+
}, this.clientConfig, this.environmentKey);
|
|
448
|
+
const paymentToken = {
|
|
444
449
|
token: result,
|
|
445
450
|
lastFour: accountNumber.slice(-4),
|
|
446
451
|
accountType: accountType,
|
|
447
452
|
paymentMethodType: 'bank_account',
|
|
448
453
|
provider: 'spreedly',
|
|
449
454
|
};
|
|
455
|
+
this.emit('tokenReady', paymentToken);
|
|
456
|
+
return paymentToken;
|
|
450
457
|
});
|
|
451
458
|
}
|
|
452
459
|
validate() {
|
|
453
460
|
return __awaiter(this, void 0, void 0, function* () {
|
|
461
|
+
if (!this.isReady) {
|
|
462
|
+
throw new Error('Tokenizer not initialized');
|
|
463
|
+
}
|
|
454
464
|
if (this.mode === 'bank_account') {
|
|
455
465
|
return this.validateBankAccountInternal();
|
|
456
466
|
}
|
|
@@ -585,19 +595,21 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
585
595
|
const isConnected = ((_a = this.mergedStyles.container) === null || _a === void 0 ? void 0 : _a.gap) === '0';
|
|
586
596
|
if (this.mergedStyles.input) {
|
|
587
597
|
if (isConnected) {
|
|
588
|
-
const numberStyles = Object.assign(Object.assign({}, this.mergedStyles.input), { borderRight: '
|
|
598
|
+
const numberStyles = Object.assign(Object.assign({}, this.mergedStyles.input), { borderRight: '1px solid transparent', borderRadius: this.mergedStyles.input.borderRadius
|
|
589
599
|
? `${this.mergedStyles.input.borderRadius} 0 0 ${this.mergedStyles.input.borderRadius}`
|
|
590
600
|
: '0' });
|
|
591
|
-
|
|
592
|
-
this.spreedly.setStyle('number',
|
|
601
|
+
this.numberBaseCss = this.stylesToCssString(numberStyles);
|
|
602
|
+
this.spreedly.setStyle('number', this.numberBaseCss);
|
|
593
603
|
const cvvStyles = Object.assign(Object.assign({}, this.mergedStyles.input), { borderRadius: this.mergedStyles.input.borderRadius
|
|
594
604
|
? `0 ${this.mergedStyles.input.borderRadius} ${this.mergedStyles.input.borderRadius} 0`
|
|
595
605
|
: '0' });
|
|
596
|
-
|
|
597
|
-
this.spreedly.setStyle('cvv',
|
|
606
|
+
this.cvvBaseCss = this.stylesToCssString(cvvStyles);
|
|
607
|
+
this.spreedly.setStyle('cvv', this.cvvBaseCss);
|
|
598
608
|
}
|
|
599
609
|
else {
|
|
600
610
|
const baseCss = this.stylesToCssString(this.mergedStyles.input);
|
|
611
|
+
this.numberBaseCss = baseCss;
|
|
612
|
+
this.cvvBaseCss = baseCss;
|
|
601
613
|
this.spreedly.setStyle('number', baseCss);
|
|
602
614
|
this.spreedly.setStyle('cvv', baseCss);
|
|
603
615
|
}
|
|
@@ -608,9 +620,20 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
608
620
|
this.spreedly.setStyle('cvv:focus', focusCss);
|
|
609
621
|
}
|
|
610
622
|
if (this.mergedStyles.error) {
|
|
611
|
-
const
|
|
612
|
-
this.
|
|
613
|
-
|
|
623
|
+
const errorOverrides = {};
|
|
624
|
+
if (this.mergedStyles.error.borderColor) {
|
|
625
|
+
errorOverrides.border = `1px solid ${this.mergedStyles.error.borderColor}`;
|
|
626
|
+
}
|
|
627
|
+
if (this.mergedStyles.error.backgroundColor) {
|
|
628
|
+
errorOverrides.backgroundColor =
|
|
629
|
+
this.mergedStyles.error.backgroundColor;
|
|
630
|
+
}
|
|
631
|
+
if (this.mergedStyles.error.color) {
|
|
632
|
+
errorOverrides.color = this.mergedStyles.error.color;
|
|
633
|
+
}
|
|
634
|
+
const errorCss = this.stylesToCssString(errorOverrides);
|
|
635
|
+
this.numberErrorCss = this.numberBaseCss + '; ' + errorCss;
|
|
636
|
+
this.cvvErrorCss = this.cvvBaseCss + '; ' + errorCss;
|
|
614
637
|
}
|
|
615
638
|
}
|
|
616
639
|
stylesToCssString(styles) {
|
|
@@ -638,13 +661,41 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
638
661
|
this.accountNumberEl.value = '';
|
|
639
662
|
if (this.accountTypeEl)
|
|
640
663
|
this.accountTypeEl.selectedIndex = 0;
|
|
664
|
+
this.currentValidationState = {
|
|
665
|
+
isValid: false,
|
|
666
|
+
routingNumber: { isValid: false, isEmpty: true },
|
|
667
|
+
accountNumber: { isValid: false, isEmpty: true },
|
|
668
|
+
};
|
|
641
669
|
}
|
|
642
670
|
else {
|
|
643
671
|
this.spreedly.reload();
|
|
644
672
|
if (this.expiryEl) {
|
|
645
673
|
this.expiryEl.value = '';
|
|
646
674
|
}
|
|
675
|
+
if (this.numberHasError && this.numberBaseCss) {
|
|
676
|
+
this.spreedly.setStyle('number', this.numberBaseCss);
|
|
677
|
+
this.numberHasError = false;
|
|
678
|
+
}
|
|
679
|
+
if (this.cvvHasError && this.cvvBaseCss) {
|
|
680
|
+
this.spreedly.setStyle('cvv', this.cvvBaseCss);
|
|
681
|
+
this.cvvHasError = false;
|
|
682
|
+
}
|
|
683
|
+
this.currentValidationState = {
|
|
684
|
+
isValid: false,
|
|
685
|
+
cardNumber: { isValid: false, isEmpty: true },
|
|
686
|
+
cvv: { isValid: false, isEmpty: true },
|
|
687
|
+
expiry: { isValid: false, isEmpty: true },
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
if (this.tokenizationReject) {
|
|
691
|
+
const reject = this.tokenizationReject;
|
|
692
|
+
this.clearTokenizationState();
|
|
693
|
+
reject(new TokenizationError('Tokenizer cleared', 'CLEARED'));
|
|
647
694
|
}
|
|
695
|
+
else {
|
|
696
|
+
this.clearTokenizationState();
|
|
697
|
+
}
|
|
698
|
+
this.emit('validation', this.currentValidationState);
|
|
648
699
|
}
|
|
649
700
|
focus(field) {
|
|
650
701
|
if (this.mode === 'bank_account') {
|
|
@@ -680,12 +731,84 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
680
731
|
element === null || element === void 0 ? void 0 : element.focus();
|
|
681
732
|
}
|
|
682
733
|
}
|
|
734
|
+
determineLayout(width) {
|
|
735
|
+
return width < this.responsiveBreakpoint ? 'two-line' : 'single-line';
|
|
736
|
+
}
|
|
737
|
+
setupResizeObserver() {
|
|
738
|
+
if (this.layout !== 'responsive')
|
|
739
|
+
return;
|
|
740
|
+
const container = document.getElementById(this.containerId);
|
|
741
|
+
if (!container)
|
|
742
|
+
return;
|
|
743
|
+
let debounceTimer;
|
|
744
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
745
|
+
clearTimeout(debounceTimer);
|
|
746
|
+
debounceTimer = setTimeout(() => {
|
|
747
|
+
const newWidth = entries[0].contentRect.width;
|
|
748
|
+
const newLayout = this.determineLayout(newWidth);
|
|
749
|
+
if (newLayout !== this.effectiveLayout) {
|
|
750
|
+
this.applyLayoutStyles(newLayout);
|
|
751
|
+
}
|
|
752
|
+
}, 100);
|
|
753
|
+
});
|
|
754
|
+
this.resizeObserver.observe(container);
|
|
755
|
+
}
|
|
756
|
+
applyLayoutStyles(newLayout) {
|
|
757
|
+
this.effectiveLayout = newLayout;
|
|
758
|
+
const container = document.getElementById(this.containerId);
|
|
759
|
+
if (!container)
|
|
760
|
+
return;
|
|
761
|
+
if (newLayout === 'two-line') {
|
|
762
|
+
container.style.flexWrap = 'wrap';
|
|
763
|
+
if (this.cardNumberDiv) {
|
|
764
|
+
this.cardNumberDiv.style.flex = '1';
|
|
765
|
+
this.cardNumberDiv.style.flexBasis = '100%';
|
|
766
|
+
}
|
|
767
|
+
if (this.expiryEl) {
|
|
768
|
+
this.expiryEl.style.flex = '1';
|
|
769
|
+
this.expiryEl.style.flexBasis = 'auto';
|
|
770
|
+
}
|
|
771
|
+
if (this.cvvDiv) {
|
|
772
|
+
this.cvvDiv.style.flex = '1';
|
|
773
|
+
this.cvvDiv.style.flexBasis = 'auto';
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
container.style.flexWrap = 'nowrap';
|
|
778
|
+
if (this.cardNumberDiv) {
|
|
779
|
+
this.cardNumberDiv.style.flex = FIELD_FLEX.cardNumber.flex;
|
|
780
|
+
}
|
|
781
|
+
if (this.expiryEl) {
|
|
782
|
+
this.expiryEl.style.flex = FIELD_FLEX.expiry.flex;
|
|
783
|
+
}
|
|
784
|
+
if (this.cvvDiv) {
|
|
785
|
+
this.cvvDiv.style.flex = FIELD_FLEX.cvv.flex;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
clearTokenizationState() {
|
|
790
|
+
if (this.tokenizationTimeout) {
|
|
791
|
+
clearTimeout(this.tokenizationTimeout);
|
|
792
|
+
this.tokenizationTimeout = undefined;
|
|
793
|
+
}
|
|
794
|
+
this.tokenizationResolve = undefined;
|
|
795
|
+
this.tokenizationReject = undefined;
|
|
796
|
+
}
|
|
683
797
|
destroy() {
|
|
798
|
+
var _a;
|
|
799
|
+
this.markDestroyed();
|
|
800
|
+
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
801
|
+
if (this.tokenizationReject) {
|
|
802
|
+
const reject = this.tokenizationReject;
|
|
803
|
+
this.clearTokenizationState();
|
|
804
|
+
reject(new TokenizationError('Tokenizer destroyed', 'DESTROYED'));
|
|
805
|
+
}
|
|
684
806
|
if (this.spreedly && this.spreedly.removeHandlers) {
|
|
685
807
|
this.spreedly.removeHandlers();
|
|
686
808
|
}
|
|
687
809
|
this.eventHandlers.clear();
|
|
688
|
-
if (this.
|
|
810
|
+
if (this.containerEl) {
|
|
811
|
+
this.containerEl.innerHTML = '';
|
|
689
812
|
}
|
|
690
813
|
}
|
|
691
814
|
hasToken() {
|
|
@@ -713,10 +836,9 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
713
836
|
handleFieldEvent(fieldName, eventType, inputProperties) {
|
|
714
837
|
if (eventType === 'input') {
|
|
715
838
|
if (fieldName === 'number') {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
};
|
|
839
|
+
const isEmpty = inputProperties.numberLength === 0;
|
|
840
|
+
const isValid = inputProperties.validNumber || false;
|
|
841
|
+
this.currentValidationState.cardNumber = { isValid, isEmpty };
|
|
720
842
|
if (inputProperties.cardType &&
|
|
721
843
|
inputProperties.cardType !== 'unknown') {
|
|
722
844
|
this.emit('cardTypeChange', {
|
|
@@ -725,21 +847,37 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
725
847
|
}
|
|
726
848
|
}
|
|
727
849
|
else if (fieldName === 'cvv') {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
};
|
|
850
|
+
const isEmpty = inputProperties.cvvLength === 0;
|
|
851
|
+
const isValid = inputProperties.validCvv || false;
|
|
852
|
+
this.currentValidationState.cvv = { isValid, isEmpty };
|
|
732
853
|
}
|
|
733
854
|
this.updateOverallValidation();
|
|
734
855
|
}
|
|
735
|
-
if (eventType === '
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
856
|
+
if (eventType === 'blur') {
|
|
857
|
+
if (fieldName === 'number') {
|
|
858
|
+
const state = this.currentValidationState.cardNumber;
|
|
859
|
+
const shouldShowError = state
|
|
860
|
+
? !state.isEmpty && !state.isValid
|
|
861
|
+
: false;
|
|
862
|
+
if (shouldShowError !== this.numberHasError) {
|
|
863
|
+
this.numberHasError = shouldShowError;
|
|
864
|
+
if (this.numberErrorCss) {
|
|
865
|
+
this.spreedly.setStyle('number', shouldShowError ? this.numberErrorCss : this.numberBaseCss);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
else if (fieldName === 'cvv') {
|
|
870
|
+
const state = this.currentValidationState.cvv;
|
|
871
|
+
const shouldShowError = state
|
|
872
|
+
? !state.isEmpty && !state.isValid
|
|
873
|
+
: false;
|
|
874
|
+
if (shouldShowError !== this.cvvHasError) {
|
|
875
|
+
this.cvvHasError = shouldShowError;
|
|
876
|
+
if (this.cvvErrorCss) {
|
|
877
|
+
this.spreedly.setStyle('cvv', shouldShowError ? this.cvvErrorCss : this.cvvBaseCss);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
743
881
|
}
|
|
744
882
|
}
|
|
745
883
|
createInternalElements() {
|
|
@@ -756,13 +894,25 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
756
894
|
this.createCreditCardFields(container);
|
|
757
895
|
}
|
|
758
896
|
}
|
|
897
|
+
appendField(container, field, labelText) {
|
|
898
|
+
container.appendChild(wrapFieldWithLabel(field, labelText, this.mergedStyles));
|
|
899
|
+
}
|
|
759
900
|
createCreditCardFields(container) {
|
|
760
|
-
|
|
901
|
+
var _a, _b;
|
|
902
|
+
if (this.layout === 'responsive') {
|
|
903
|
+
this.effectiveLayout = this.determineLayout(container.offsetWidth);
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
this.effectiveLayout =
|
|
907
|
+
this.layout === 'two-line' ? 'two-line' : 'single-line';
|
|
908
|
+
}
|
|
909
|
+
if (this.effectiveLayout === 'two-line' && this.layout !== 'responsive') {
|
|
761
910
|
const cardNumberDiv = createFieldContainer(this.numberEl, '1', FIELD_FLEX.cardNumber.minWidth);
|
|
762
911
|
cardNumberDiv.style.height = this.mergedStyles.input.height;
|
|
763
912
|
cardNumberDiv.style.flexBasis = '100%';
|
|
764
|
-
|
|
765
|
-
this.
|
|
913
|
+
this.cardNumberDiv = cardNumberDiv;
|
|
914
|
+
this.appendField(container, cardNumberDiv, 'Card Number');
|
|
915
|
+
this.expiryEl = createInputElement(this.expiryId, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.expiry) || PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
|
|
766
916
|
Object.assign(this.expiryEl.style, {
|
|
767
917
|
flex: '1',
|
|
768
918
|
minWidth: FIELD_FLEX.expiry.minWidth,
|
|
@@ -778,16 +928,22 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
778
928
|
};
|
|
779
929
|
this.updateOverallValidation();
|
|
780
930
|
});
|
|
781
|
-
|
|
931
|
+
this.expiryEl.addEventListener('blur', () => {
|
|
932
|
+
this.validateExpiry();
|
|
933
|
+
this.updateOverallValidation();
|
|
934
|
+
});
|
|
935
|
+
this.appendField(container, this.expiryEl, 'Expiration');
|
|
782
936
|
const cvvDiv = createFieldContainer(this.cvvEl, '1', FIELD_FLEX.cvv.minWidth);
|
|
783
937
|
cvvDiv.style.height = this.mergedStyles.input.height;
|
|
784
|
-
|
|
938
|
+
this.cvvDiv = cvvDiv;
|
|
939
|
+
this.appendField(container, cvvDiv, 'CVV');
|
|
785
940
|
}
|
|
786
941
|
else {
|
|
787
942
|
const cardNumberDiv = createFieldContainer(this.numberEl, FIELD_FLEX.cardNumber.flex, FIELD_FLEX.cardNumber.minWidth);
|
|
788
943
|
cardNumberDiv.style.height = this.mergedStyles.input.height;
|
|
789
|
-
|
|
790
|
-
this.
|
|
944
|
+
this.cardNumberDiv = cardNumberDiv;
|
|
945
|
+
this.appendField(container, cardNumberDiv, 'Card Number');
|
|
946
|
+
this.expiryEl = createInputElement(this.expiryId, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.expiry) || PLACEHOLDERS.expiry, FIELD_CONSTRAINTS.expiry.maxLength);
|
|
791
947
|
Object.assign(this.expiryEl.style, {
|
|
792
948
|
flex: FIELD_FLEX.expiry.flex,
|
|
793
949
|
minWidth: FIELD_FLEX.expiry.minWidth,
|
|
@@ -803,10 +959,19 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
803
959
|
};
|
|
804
960
|
this.updateOverallValidation();
|
|
805
961
|
});
|
|
806
|
-
|
|
962
|
+
this.expiryEl.addEventListener('blur', () => {
|
|
963
|
+
this.validateExpiry();
|
|
964
|
+
this.updateOverallValidation();
|
|
965
|
+
});
|
|
966
|
+
this.appendField(container, this.expiryEl, 'Expiration');
|
|
807
967
|
const cvvDiv = createFieldContainer(this.cvvEl, FIELD_FLEX.cvv.flex, FIELD_FLEX.cvv.minWidth);
|
|
808
968
|
cvvDiv.style.height = this.mergedStyles.input.height;
|
|
809
|
-
|
|
969
|
+
this.cvvDiv = cvvDiv;
|
|
970
|
+
this.appendField(container, cvvDiv, 'CVV');
|
|
971
|
+
if (this.layout === 'responsive') {
|
|
972
|
+
this.applyLayoutStyles(this.effectiveLayout);
|
|
973
|
+
this.setupResizeObserver();
|
|
974
|
+
}
|
|
810
975
|
}
|
|
811
976
|
}
|
|
812
977
|
createBankAccountFields(container) {
|
|
@@ -818,6 +983,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
818
983
|
}
|
|
819
984
|
}
|
|
820
985
|
createUSBankAccountFields(container) {
|
|
986
|
+
var _a, _b, _c, _d;
|
|
821
987
|
if (this.layout === 'two-line') {
|
|
822
988
|
this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
|
|
823
989
|
Object.assign(this.accountTypeEl.style, {
|
|
@@ -825,8 +991,8 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
825
991
|
minWidth: BANK_FIELD_FLEX.accountType.minWidth,
|
|
826
992
|
});
|
|
827
993
|
this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'left');
|
|
828
|
-
|
|
829
|
-
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
994
|
+
this.appendField(container, this.accountTypeEl, 'Account Type');
|
|
995
|
+
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.routingNumber) || 'Routing *', 9);
|
|
830
996
|
Object.assign(this.routingNumberEl.style, {
|
|
831
997
|
flex: '1',
|
|
832
998
|
minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
@@ -842,8 +1008,8 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
842
1008
|
}
|
|
843
1009
|
this.updateBankAccountValidation();
|
|
844
1010
|
});
|
|
845
|
-
|
|
846
|
-
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
1011
|
+
this.appendField(container, this.routingNumberEl, 'Routing Number');
|
|
1012
|
+
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.accountNumber) || 'Account Number *', 17);
|
|
847
1013
|
Object.assign(this.accountNumberEl.style, {
|
|
848
1014
|
flex: '1',
|
|
849
1015
|
flexBasis: '100%',
|
|
@@ -860,10 +1026,10 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
860
1026
|
}
|
|
861
1027
|
this.updateBankAccountValidation();
|
|
862
1028
|
});
|
|
863
|
-
|
|
1029
|
+
this.appendField(container, this.accountNumberEl, 'Account Number');
|
|
864
1030
|
}
|
|
865
1031
|
else {
|
|
866
|
-
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
1032
|
+
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_c = this.customPlaceholders) === null || _c === void 0 ? void 0 : _c.routingNumber) || 'Routing *', 9);
|
|
867
1033
|
Object.assign(this.routingNumberEl.style, {
|
|
868
1034
|
flex: BANK_FIELD_FLEX.routingNumber.flex,
|
|
869
1035
|
minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
@@ -879,8 +1045,8 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
879
1045
|
}
|
|
880
1046
|
this.updateBankAccountValidation();
|
|
881
1047
|
});
|
|
882
|
-
|
|
883
|
-
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
1048
|
+
this.appendField(container, this.routingNumberEl, 'Routing Number');
|
|
1049
|
+
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_d = this.customPlaceholders) === null || _d === void 0 ? void 0 : _d.accountNumber) || 'Account Number *', 17);
|
|
884
1050
|
Object.assign(this.accountNumberEl.style, {
|
|
885
1051
|
flex: BANK_FIELD_FLEX.accountNumber.flex,
|
|
886
1052
|
minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
|
|
@@ -896,14 +1062,14 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
896
1062
|
}
|
|
897
1063
|
this.updateBankAccountValidation();
|
|
898
1064
|
});
|
|
899
|
-
|
|
1065
|
+
this.appendField(container, this.accountNumberEl, 'Account Number');
|
|
900
1066
|
this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
|
|
901
1067
|
Object.assign(this.accountTypeEl.style, {
|
|
902
1068
|
flex: BANK_FIELD_FLEX.accountType.flex,
|
|
903
1069
|
minWidth: BANK_FIELD_FLEX.accountType.minWidth,
|
|
904
1070
|
});
|
|
905
1071
|
this.applyInputStyles(this.accountTypeEl, this.mergedStyles, 'right');
|
|
906
|
-
|
|
1072
|
+
this.appendField(container, this.accountTypeEl, 'Account Type');
|
|
907
1073
|
}
|
|
908
1074
|
}
|
|
909
1075
|
updateBankAccountValidation() {
|
|
@@ -960,30 +1126,42 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
960
1126
|
if (!this.expiryEl)
|
|
961
1127
|
return;
|
|
962
1128
|
const expiry = this.parseExpiry(this.expiryEl);
|
|
1129
|
+
const isEmpty = !this.expiryEl.value;
|
|
1130
|
+
let isValid = false;
|
|
963
1131
|
if (!expiry) {
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
}
|
|
967
|
-
const month = parseInt(expiry.month, 10);
|
|
968
|
-
const year = parseInt(expiry.year, 10);
|
|
969
|
-
if (month < 1 || month > 12) {
|
|
970
|
-
this.applyErrorStyles(this.expiryEl);
|
|
971
|
-
return;
|
|
1132
|
+
if (!isEmpty)
|
|
1133
|
+
this.applyErrorStyles(this.expiryEl);
|
|
972
1134
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1135
|
+
else {
|
|
1136
|
+
const month = parseInt(expiry.month, 10);
|
|
1137
|
+
const year = parseInt(expiry.year, 10);
|
|
1138
|
+
if (month < 1 || month > 12) {
|
|
1139
|
+
this.applyErrorStyles(this.expiryEl);
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
const now = new Date();
|
|
1143
|
+
const expiryEndDate = new Date(year, month);
|
|
1144
|
+
if (expiryEndDate <= now) {
|
|
1145
|
+
this.applyErrorStyles(this.expiryEl);
|
|
1146
|
+
}
|
|
1147
|
+
else {
|
|
1148
|
+
isValid = true;
|
|
1149
|
+
const expiryPosition = this.effectiveLayout === 'two-line' ? 'left' : 'middle';
|
|
1150
|
+
this.applyInputStyles(this.expiryEl, this.mergedStyles, expiryPosition);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
978
1153
|
}
|
|
979
|
-
this.
|
|
1154
|
+
this.currentValidationState.expiry = { isValid, isEmpty };
|
|
980
1155
|
}
|
|
981
1156
|
applyErrorStyles(element) {
|
|
982
|
-
|
|
983
|
-
|
|
1157
|
+
var _a, _b, _c;
|
|
1158
|
+
const errorColor = ((_a = this.mergedStyles.error) === null || _a === void 0 ? void 0 : _a.borderColor) || '#dc3545';
|
|
1159
|
+
element.style.border = `1px solid ${errorColor}`;
|
|
1160
|
+
if ((_b = this.mergedStyles.error) === null || _b === void 0 ? void 0 : _b.backgroundColor) {
|
|
1161
|
+
element.style.backgroundColor = this.mergedStyles.error.backgroundColor;
|
|
984
1162
|
}
|
|
985
|
-
|
|
986
|
-
element.style.
|
|
1163
|
+
if ((_c = this.mergedStyles.error) === null || _c === void 0 ? void 0 : _c.color) {
|
|
1164
|
+
element.style.color = this.mergedStyles.error.color;
|
|
987
1165
|
}
|
|
988
1166
|
}
|
|
989
1167
|
static ensureSpreedlyLoaded() {
|
|
@@ -1030,13 +1208,14 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
1030
1208
|
throw new Error(`Timeout waiting for global: ${globalName}`);
|
|
1031
1209
|
});
|
|
1032
1210
|
}
|
|
1033
|
-
static tokenizeBankAccount(data, config) {
|
|
1034
|
-
|
|
1211
|
+
static tokenizeBankAccount(data, config, environmentKeyOverride) {
|
|
1212
|
+
const environmentKey = environmentKeyOverride || config.spreedlyEnvironmentKey;
|
|
1213
|
+
if (!environmentKey) {
|
|
1035
1214
|
return Promise.reject(new Error('Spreedly is not configured.'));
|
|
1036
1215
|
}
|
|
1037
1216
|
return fetch(SPREEDLY_TOKENIZER_URL +
|
|
1038
1217
|
'?' +
|
|
1039
|
-
new URLSearchParams({ environment_key:
|
|
1218
|
+
new URLSearchParams({ environment_key: environmentKey }), {
|
|
1040
1219
|
method: 'POST',
|
|
1041
1220
|
headers: {
|
|
1042
1221
|
'Content-Type': 'application/json',
|