@idonatedev/idonate-sdk 1.2.0-dev2 → 1.2.0-dev20
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 +17 -1
- package/dist/esm/tokenize/SpreedlyTokenizer.js +270 -138
- 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 +17 -1
- package/dist/tokenize/SpreedlyTokenizer.js +267 -135
- 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
|
@@ -9,17 +9,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { Tokenizer } from './Tokenizer';
|
|
11
11
|
import { TokenizationError, } from './types';
|
|
12
|
-
import ConfigHandler from '../config-handler';
|
|
13
12
|
import { DEFAULT_UNIFIED_STYLES, mergeStyles, getContainerStylesForLayout, } from './styles';
|
|
14
|
-
import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, BANK_FIELD_FLEX, } from './tokenizer-constants';
|
|
15
|
-
import { createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, } from './tokenizer-utils';
|
|
13
|
+
import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, BANK_FIELD_FLEX, RESPONSIVE_BREAKPOINT, } from './tokenizer-constants';
|
|
14
|
+
import { createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, wrapFieldWithLabel, cssLengthToPixels, } from './tokenizer-utils';
|
|
16
15
|
export class CardConnectTokenizer extends Tokenizer {
|
|
17
|
-
constructor(iframe, iframeUrl, containerId, mode = 'credit_card', enableTestMode = false, layout = 'single-line') {
|
|
16
|
+
constructor(iframe, iframeUrl, containerId, mode = 'credit_card', enableTestMode = false, layout = 'single-line', customPlaceholders) {
|
|
18
17
|
super();
|
|
19
18
|
this.iframeUrl = iframeUrl;
|
|
20
19
|
this.containerId = containerId;
|
|
21
20
|
this.layout = layout;
|
|
21
|
+
this.customPlaceholders = customPlaceholders;
|
|
22
22
|
this.enableTestMode = false;
|
|
23
|
+
this.acceptAutoToken = true;
|
|
23
24
|
this.mode = mode;
|
|
24
25
|
this.enableTestMode = enableTestMode;
|
|
25
26
|
this.iframe = iframe;
|
|
@@ -34,17 +35,28 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
34
35
|
}
|
|
35
36
|
static create(gateway, container, config) {
|
|
36
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
var _a;
|
|
38
|
+
var _a, _b;
|
|
38
39
|
if (container.mode === 'bank_account' && container.bankCountry === 'CA') {
|
|
39
40
|
throw new Error('CardConnect does not support Canadian bank accounts');
|
|
40
41
|
}
|
|
41
|
-
let
|
|
42
|
-
|
|
42
|
+
let effectiveLayout = 'single-line';
|
|
43
|
+
if (container.layout === 'responsive') {
|
|
44
|
+
const containerEl = document.getElementById(container.containerId);
|
|
45
|
+
const containerWidth = (containerEl === null || containerEl === void 0 ? void 0 : containerEl.offsetWidth) || 0;
|
|
46
|
+
const breakpoint = (_a = container.responsiveBreakpoint) !== null && _a !== void 0 ? _a : RESPONSIVE_BREAKPOINT;
|
|
47
|
+
effectiveLayout =
|
|
48
|
+
containerWidth < breakpoint ? 'two-line' : 'single-line';
|
|
49
|
+
}
|
|
50
|
+
else if (container.layout === 'two-line') {
|
|
51
|
+
effectiveLayout = 'two-line';
|
|
52
|
+
}
|
|
53
|
+
const resolvedContainer = Object.assign(Object.assign({}, container), { layout: effectiveLayout });
|
|
54
|
+
const baseUrl = ((_b = gateway.config) === null || _b === void 0 ? void 0 : _b.baseUrl) || config.clientConfig.cardConnectBaseUrl;
|
|
43
55
|
const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
|
|
44
|
-
const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl,
|
|
56
|
+
const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, resolvedContainer);
|
|
45
57
|
const iframe = CardConnectTokenizer.createIframe(iframeUrl, mergedStyles);
|
|
46
|
-
const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, container.
|
|
47
|
-
tokenizer.createInternalElements(
|
|
58
|
+
const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout, container.placeholders);
|
|
59
|
+
tokenizer.createInternalElements(resolvedContainer);
|
|
48
60
|
yield tokenizer.init();
|
|
49
61
|
return tokenizer;
|
|
50
62
|
});
|
|
@@ -66,19 +78,32 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
80
|
createCreditCardFields(containerEl, mergedStyles) {
|
|
81
|
+
var _a;
|
|
69
82
|
this.iframe.style.width = '100%';
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
83
|
+
const hasLabels = ((_a = mergedStyles.label) === null || _a === void 0 ? void 0 : _a.show) &&
|
|
84
|
+
(this.layout === 'two-line' || this.layout === 'responsive');
|
|
85
|
+
const inputHeight = mergedStyles.input.height || '40px';
|
|
86
|
+
if (this.layout === 'two-line' || this.layout === 'responsive') {
|
|
87
|
+
if (hasLabels) {
|
|
88
|
+
const labelFontPx = cssLengthToPixels(mergedStyles.label.fontSize);
|
|
89
|
+
const labelMarginPx = parseFloat(mergedStyles.label.marginBottom) || 0;
|
|
90
|
+
const labelRowHeight = Math.ceil(labelFontPx * 1.2) + labelMarginPx;
|
|
91
|
+
const extraHeight = Math.ceil(labelRowHeight * 2) + 34;
|
|
92
|
+
this.iframe.style.height = `calc(${inputHeight} * 2 + ${extraHeight}px)`;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.iframe.style.height = `calc((${inputHeight}) * 2 + 10px)`;
|
|
96
|
+
}
|
|
73
97
|
}
|
|
74
98
|
else {
|
|
75
|
-
this.iframe.style.height =
|
|
99
|
+
this.iframe.style.height = inputHeight;
|
|
76
100
|
}
|
|
77
101
|
this.iframe.style.border = 'none';
|
|
78
102
|
this.iframe.style.display = 'block';
|
|
79
103
|
containerEl.appendChild(this.iframe);
|
|
80
104
|
}
|
|
81
105
|
createBankAccountFields(containerEl, mergedStyles) {
|
|
106
|
+
var _a, _b, _c, _d;
|
|
82
107
|
this.iframe.style.display = 'none';
|
|
83
108
|
if (this.layout === 'two-line') {
|
|
84
109
|
this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
|
|
@@ -87,47 +112,115 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
87
112
|
minWidth: BANK_FIELD_FLEX.accountType.minWidth,
|
|
88
113
|
});
|
|
89
114
|
this.applyInputStyles(this.accountTypeEl, mergedStyles, 'left');
|
|
90
|
-
containerEl.appendChild(this.accountTypeEl);
|
|
91
|
-
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
115
|
+
containerEl.appendChild(wrapFieldWithLabel(this.accountTypeEl, 'Account Type', mergedStyles));
|
|
116
|
+
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.routingNumber) || 'Routing *', 9);
|
|
92
117
|
Object.assign(this.routingNumberEl.style, {
|
|
93
118
|
flex: '1',
|
|
94
119
|
minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
95
120
|
});
|
|
96
121
|
this.applyInputStyles(this.routingNumberEl, mergedStyles, 'right');
|
|
97
|
-
containerEl.appendChild(this.routingNumberEl);
|
|
98
|
-
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
122
|
+
containerEl.appendChild(wrapFieldWithLabel(this.routingNumberEl, 'Routing Number', mergedStyles));
|
|
123
|
+
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.accountNumber) || 'Account Number *', 17);
|
|
99
124
|
Object.assign(this.accountNumberEl.style, {
|
|
100
125
|
flex: '1',
|
|
101
126
|
flexBasis: '100%',
|
|
102
127
|
minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
|
|
103
128
|
});
|
|
104
129
|
this.applyInputStyles(this.accountNumberEl, mergedStyles);
|
|
105
|
-
containerEl.appendChild(this.accountNumberEl);
|
|
130
|
+
containerEl.appendChild(wrapFieldWithLabel(this.accountNumberEl, 'Account Number', mergedStyles));
|
|
106
131
|
}
|
|
107
132
|
else {
|
|
108
|
-
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
133
|
+
this.routingNumberEl = createInputElement(`${this.containerId}-routing`, 'text', ((_c = this.customPlaceholders) === null || _c === void 0 ? void 0 : _c.routingNumber) || 'Routing *', 9);
|
|
109
134
|
Object.assign(this.routingNumberEl.style, {
|
|
110
135
|
flex: BANK_FIELD_FLEX.routingNumber.flex,
|
|
111
136
|
minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
112
137
|
});
|
|
113
138
|
this.applyInputStyles(this.routingNumberEl, mergedStyles, 'left');
|
|
114
|
-
containerEl.appendChild(this.routingNumberEl);
|
|
115
|
-
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
139
|
+
containerEl.appendChild(wrapFieldWithLabel(this.routingNumberEl, 'Routing Number', mergedStyles));
|
|
140
|
+
this.accountNumberEl = createInputElement(`${this.containerId}-account`, 'text', ((_d = this.customPlaceholders) === null || _d === void 0 ? void 0 : _d.accountNumber) || 'Account Number *', 17);
|
|
116
141
|
Object.assign(this.accountNumberEl.style, {
|
|
117
142
|
flex: BANK_FIELD_FLEX.accountNumber.flex,
|
|
118
143
|
minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
|
|
119
144
|
});
|
|
120
145
|
this.applyInputStyles(this.accountNumberEl, mergedStyles, 'middle');
|
|
121
|
-
containerEl.appendChild(this.accountNumberEl);
|
|
146
|
+
containerEl.appendChild(wrapFieldWithLabel(this.accountNumberEl, 'Account Number', mergedStyles));
|
|
122
147
|
this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
|
|
123
148
|
Object.assign(this.accountTypeEl.style, {
|
|
124
149
|
flex: BANK_FIELD_FLEX.accountType.flex,
|
|
125
150
|
minWidth: BANK_FIELD_FLEX.accountType.minWidth,
|
|
126
151
|
});
|
|
127
152
|
this.applyInputStyles(this.accountTypeEl, mergedStyles, 'right');
|
|
128
|
-
containerEl.appendChild(this.accountTypeEl);
|
|
153
|
+
containerEl.appendChild(wrapFieldWithLabel(this.accountTypeEl, 'Account Type', mergedStyles));
|
|
154
|
+
}
|
|
155
|
+
this.mergedStyles = mergedStyles;
|
|
156
|
+
this.currentValidationState = {
|
|
157
|
+
isValid: false,
|
|
158
|
+
routingNumber: { isValid: false, isEmpty: true },
|
|
159
|
+
accountNumber: { isValid: false, isEmpty: true },
|
|
160
|
+
};
|
|
161
|
+
this.addBankAccountValidationListeners(mergedStyles);
|
|
162
|
+
}
|
|
163
|
+
addBankAccountValidationListeners(styles) {
|
|
164
|
+
if (this.routingNumberEl) {
|
|
165
|
+
this.routingNumberEl.addEventListener('blur', () => {
|
|
166
|
+
this.updateBankAccountValidation(styles);
|
|
167
|
+
});
|
|
168
|
+
this.routingNumberEl.addEventListener('input', () => {
|
|
169
|
+
this.updateBankAccountValidation(styles);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (this.accountNumberEl) {
|
|
173
|
+
this.accountNumberEl.addEventListener('blur', () => {
|
|
174
|
+
this.updateBankAccountValidation(styles);
|
|
175
|
+
});
|
|
176
|
+
this.accountNumberEl.addEventListener('input', () => {
|
|
177
|
+
this.updateBankAccountValidation(styles);
|
|
178
|
+
});
|
|
129
179
|
}
|
|
130
180
|
}
|
|
181
|
+
updateBankAccountValidation(styles) {
|
|
182
|
+
var _a, _b;
|
|
183
|
+
const routingValue = ((_a = this.routingNumberEl) === null || _a === void 0 ? void 0 : _a.value) || '';
|
|
184
|
+
const accountValue = ((_b = this.accountNumberEl) === null || _b === void 0 ? void 0 : _b.value) || '';
|
|
185
|
+
const routingValid = routingValue.length > 0 && validateRoutingNumber(routingValue);
|
|
186
|
+
const accountValid = accountValue.length > 0 && validateAccountNumber(accountValue);
|
|
187
|
+
if (this.routingNumberEl) {
|
|
188
|
+
if (routingValue.length > 0 && !routingValid) {
|
|
189
|
+
this.routingNumberEl.style.border = `1px solid ${styles.error.borderColor}`;
|
|
190
|
+
if (styles.error.backgroundColor) {
|
|
191
|
+
this.routingNumberEl.style.backgroundColor =
|
|
192
|
+
styles.error.backgroundColor;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
this.applyInputStyles(this.routingNumberEl, this.mergedStyles, 'left');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (this.accountNumberEl) {
|
|
200
|
+
if (accountValue.length > 0 && !accountValid) {
|
|
201
|
+
this.accountNumberEl.style.border = `1px solid ${styles.error.borderColor}`;
|
|
202
|
+
if (styles.error.backgroundColor) {
|
|
203
|
+
this.accountNumberEl.style.backgroundColor =
|
|
204
|
+
styles.error.backgroundColor;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.applyInputStyles(this.accountNumberEl, this.mergedStyles, 'right');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
this.currentValidationState = {
|
|
212
|
+
isValid: routingValid && accountValid,
|
|
213
|
+
routingNumber: {
|
|
214
|
+
isValid: routingValid,
|
|
215
|
+
isEmpty: routingValue.length === 0,
|
|
216
|
+
},
|
|
217
|
+
accountNumber: {
|
|
218
|
+
isValid: accountValid,
|
|
219
|
+
isEmpty: accountValue.length === 0,
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
this.emit('validation', this.currentValidationState);
|
|
223
|
+
}
|
|
131
224
|
init() {
|
|
132
225
|
return __awaiter(this, void 0, void 0, function* () {
|
|
133
226
|
if (this.mode === 'bank_account') {
|
|
@@ -163,8 +256,6 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
163
256
|
window.addEventListener('message', this.messageHandler);
|
|
164
257
|
this.iframe.onload = () => {
|
|
165
258
|
clearTimeout(timeout);
|
|
166
|
-
if (this.enableTestMode && this.mode === 'credit_card') {
|
|
167
|
-
}
|
|
168
259
|
this.emit('ready');
|
|
169
260
|
resolve();
|
|
170
261
|
};
|
|
@@ -196,31 +287,39 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
196
287
|
}
|
|
197
288
|
tokenizeCardInternal(cardData) {
|
|
198
289
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
|
+
var _a, _b, _c;
|
|
199
291
|
if (this.cachedTokenResult && this.cachedTokenResult.errorCode === '0') {
|
|
292
|
+
const cardType = this.cachedTokenResult.cardType
|
|
293
|
+
? this.normalizeCardType(this.cachedTokenResult.cardType)
|
|
294
|
+
: this.normalizeCardType('unknown');
|
|
200
295
|
return {
|
|
201
296
|
token: this.cachedTokenResult.token,
|
|
202
|
-
lastFour: this.cachedTokenResult.
|
|
203
|
-
|
|
297
|
+
lastFour: this.cachedTokenResult.last4 ||
|
|
298
|
+
this.cachedTokenResult.token.slice(-4),
|
|
299
|
+
cardType,
|
|
300
|
+
paymentMethodType: 'credit_card',
|
|
204
301
|
provider: 'cardconnect',
|
|
205
302
|
};
|
|
206
303
|
}
|
|
207
304
|
if (this.tokenizationPromise) {
|
|
208
305
|
return this.tokenizationPromise;
|
|
209
306
|
}
|
|
307
|
+
if (!this.currentValidationState.isValid &&
|
|
308
|
+
(((_a = this.currentValidationState.cardNumber) === null || _a === void 0 ? void 0 : _a.isEmpty) ||
|
|
309
|
+
((_b = this.currentValidationState.cvv) === null || _b === void 0 ? void 0 : _b.isEmpty) ||
|
|
310
|
+
((_c = this.currentValidationState.expiry) === null || _c === void 0 ? void 0 : _c.isEmpty))) {
|
|
311
|
+
throw new TokenizationError('Card fields are incomplete', 'VALIDATION_ERROR');
|
|
312
|
+
}
|
|
210
313
|
this.tokenizationPromise = new Promise((resolve, reject) => {
|
|
211
314
|
this.tokenizationResolve = resolve;
|
|
212
315
|
this.tokenizationReject = reject;
|
|
213
|
-
|
|
316
|
+
this.tokenizationTimeout = setTimeout(() => {
|
|
317
|
+
this.tokenizationTimeout = undefined;
|
|
214
318
|
this.tokenizationPromise = undefined;
|
|
215
319
|
this.tokenizationResolve = undefined;
|
|
216
320
|
this.tokenizationReject = undefined;
|
|
217
321
|
reject(new TokenizationError('Tokenization timeout - ensure all card fields are filled in iframe', 'TIMEOUT'));
|
|
218
322
|
}, TOKENIZE_TIMEOUT);
|
|
219
|
-
const tokenizationHandler = (data) => {
|
|
220
|
-
clearTimeout(timeout);
|
|
221
|
-
this.off('tokenization', tokenizationHandler);
|
|
222
|
-
};
|
|
223
|
-
this.on('tokenization', tokenizationHandler);
|
|
224
323
|
});
|
|
225
324
|
return this.tokenizationPromise;
|
|
226
325
|
});
|
|
@@ -242,16 +341,16 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
242
341
|
throw new TokenizationError('Invalid account number', 'VALIDATION_ERROR');
|
|
243
342
|
}
|
|
244
343
|
const baseUrl = new URL(this.iframeUrl).origin;
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
const result = yield CardConnectTokenizer.tokenizeBankAccount(routingNumber, accountNumber, config);
|
|
248
|
-
return {
|
|
344
|
+
const result = yield CardConnectTokenizer.tokenizeBankAccount(routingNumber, accountNumber, baseUrl);
|
|
345
|
+
const paymentToken = {
|
|
249
346
|
token: result.token,
|
|
250
347
|
lastFour: accountNumber.slice(-4),
|
|
251
348
|
accountType: accountType,
|
|
252
349
|
paymentMethodType: 'bank_account',
|
|
253
350
|
provider: 'cardconnect',
|
|
254
351
|
};
|
|
352
|
+
this.emit('tokenReady', paymentToken);
|
|
353
|
+
return paymentToken;
|
|
255
354
|
});
|
|
256
355
|
}
|
|
257
356
|
validate() {
|
|
@@ -388,12 +487,39 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
388
487
|
action: 'clear',
|
|
389
488
|
}, this.expectedOrigin);
|
|
390
489
|
}
|
|
391
|
-
this.
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
490
|
+
this.cachedTokenResult = undefined;
|
|
491
|
+
this.acceptAutoToken = false;
|
|
492
|
+
if (this.tokenizationTimeout) {
|
|
493
|
+
clearTimeout(this.tokenizationTimeout);
|
|
494
|
+
this.tokenizationTimeout = undefined;
|
|
495
|
+
}
|
|
496
|
+
if (this.tokenizationReject) {
|
|
497
|
+
const reject = this.tokenizationReject;
|
|
498
|
+
this.tokenizationPromise = undefined;
|
|
499
|
+
this.tokenizationResolve = undefined;
|
|
500
|
+
this.tokenizationReject = undefined;
|
|
501
|
+
reject(new TokenizationError('Tokenizer cleared', 'CLEARED'));
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
this.tokenizationPromise = undefined;
|
|
505
|
+
this.tokenizationResolve = undefined;
|
|
506
|
+
this.tokenizationReject = undefined;
|
|
507
|
+
}
|
|
508
|
+
if (this.mode === 'bank_account') {
|
|
509
|
+
this.currentValidationState = {
|
|
510
|
+
isValid: false,
|
|
511
|
+
routingNumber: { isValid: false, isEmpty: true },
|
|
512
|
+
accountNumber: { isValid: false, isEmpty: true },
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
this.currentValidationState = {
|
|
517
|
+
isValid: false,
|
|
518
|
+
cardNumber: { isValid: false, isEmpty: true },
|
|
519
|
+
cvv: { isValid: false, isEmpty: true },
|
|
520
|
+
expiry: { isValid: false, isEmpty: true },
|
|
521
|
+
};
|
|
522
|
+
}
|
|
397
523
|
this.emit('validation', this.currentValidationState);
|
|
398
524
|
}
|
|
399
525
|
focus(field) {
|
|
@@ -422,8 +548,22 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
422
548
|
}
|
|
423
549
|
}
|
|
424
550
|
destroy() {
|
|
551
|
+
this.markDestroyed();
|
|
552
|
+
if (this.tokenizationTimeout) {
|
|
553
|
+
clearTimeout(this.tokenizationTimeout);
|
|
554
|
+
this.tokenizationTimeout = undefined;
|
|
555
|
+
}
|
|
556
|
+
if (this.tokenizationReject) {
|
|
557
|
+
const reject = this.tokenizationReject;
|
|
558
|
+
this.tokenizationPromise = undefined;
|
|
559
|
+
this.tokenizationResolve = undefined;
|
|
560
|
+
this.tokenizationReject = undefined;
|
|
561
|
+
reject(new TokenizationError('Tokenizer destroyed', 'DESTROYED'));
|
|
562
|
+
}
|
|
563
|
+
this.cachedTokenResult = undefined;
|
|
425
564
|
if (this.messageHandler) {
|
|
426
565
|
window.removeEventListener('message', this.messageHandler);
|
|
566
|
+
this.messageHandler = undefined;
|
|
427
567
|
}
|
|
428
568
|
if (this.containerEl) {
|
|
429
569
|
this.containerEl.innerHTML = '';
|
|
@@ -450,6 +590,7 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
450
590
|
lastFour: this.cachedTokenResult.last4 ||
|
|
451
591
|
this.cachedTokenResult.token.slice(-4),
|
|
452
592
|
cardType,
|
|
593
|
+
paymentMethodType: 'credit_card',
|
|
453
594
|
provider: 'cardconnect',
|
|
454
595
|
};
|
|
455
596
|
}
|
|
@@ -462,8 +603,14 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
462
603
|
try {
|
|
463
604
|
const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
|
|
464
605
|
if (data.token && data.errorCode !== undefined) {
|
|
606
|
+
if (!this.acceptAutoToken && !this.tokenizationResolve) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
465
609
|
this.cachedTokenResult = data;
|
|
466
|
-
this.
|
|
610
|
+
if (this.tokenizationTimeout) {
|
|
611
|
+
clearTimeout(this.tokenizationTimeout);
|
|
612
|
+
this.tokenizationTimeout = undefined;
|
|
613
|
+
}
|
|
467
614
|
if (data.errorCode === '0') {
|
|
468
615
|
const cardType = data.cardType
|
|
469
616
|
? this.normalizeCardType(data.cardType)
|
|
@@ -476,6 +623,7 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
476
623
|
token: data.token,
|
|
477
624
|
lastFour: data.last4 || data.token.slice(-4),
|
|
478
625
|
cardType,
|
|
626
|
+
paymentMethodType: 'credit_card',
|
|
479
627
|
provider: 'cardconnect',
|
|
480
628
|
};
|
|
481
629
|
if (this.tokenizationResolve) {
|
|
@@ -490,12 +638,14 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
490
638
|
cvv: { isValid: true, isEmpty: false },
|
|
491
639
|
expiry: { isValid: true, isEmpty: false },
|
|
492
640
|
};
|
|
493
|
-
this.emit('validation',
|
|
641
|
+
this.emit('validation', this.currentValidationState);
|
|
494
642
|
this.emit('tokenReady', token);
|
|
495
643
|
}
|
|
496
644
|
else {
|
|
645
|
+
const error = new TokenizationError(data.errorMessage || 'Tokenization failed', data.errorCode || 'UNKNOWN');
|
|
646
|
+
this.emit('error', error);
|
|
497
647
|
if (this.tokenizationReject) {
|
|
498
|
-
this.tokenizationReject(
|
|
648
|
+
this.tokenizationReject(error);
|
|
499
649
|
this.tokenizationPromise = undefined;
|
|
500
650
|
this.tokenizationResolve = undefined;
|
|
501
651
|
this.tokenizationReject = undefined;
|
|
@@ -503,19 +653,16 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
503
653
|
}
|
|
504
654
|
}
|
|
505
655
|
if (data.event === 'validation' || data.validationError !== undefined) {
|
|
656
|
+
this.acceptAutoToken = true;
|
|
506
657
|
this.handleValidationMessage(data);
|
|
507
658
|
}
|
|
508
|
-
if (data.event === '
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (cardType !== this.currentCardType) {
|
|
516
|
-
this.currentCardType = cardType;
|
|
517
|
-
this.emit('cardTypeChange', { cardType });
|
|
518
|
-
}
|
|
659
|
+
if ((data.event === 'input' || data.event === 'change') &&
|
|
660
|
+
data.cardType) {
|
|
661
|
+
this.acceptAutoToken = true;
|
|
662
|
+
const cardType = this.normalizeCardType(data.cardType);
|
|
663
|
+
if (cardType !== this.currentCardType) {
|
|
664
|
+
this.currentCardType = cardType;
|
|
665
|
+
this.emit('cardTypeChange', { cardType });
|
|
519
666
|
}
|
|
520
667
|
}
|
|
521
668
|
}
|
|
@@ -523,7 +670,6 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
523
670
|
}
|
|
524
671
|
}
|
|
525
672
|
handleValidationMessage(data) {
|
|
526
|
-
var _a, _b, _c, _d, _e, _f;
|
|
527
673
|
if (data.validationError) {
|
|
528
674
|
const errorLower = data.validationError.toLowerCase();
|
|
529
675
|
if (errorLower.includes('card') || errorLower.includes('number')) {
|
|
@@ -541,14 +687,48 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
541
687
|
errorLower.includes('year')) {
|
|
542
688
|
this.currentValidationState.expiry = { isValid: false, isEmpty: false };
|
|
543
689
|
}
|
|
544
|
-
this.
|
|
690
|
+
this.currentValidationState.isValid = false;
|
|
691
|
+
this.emit('validation', this.currentValidationState);
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
this.currentValidationState.cardNumber = {
|
|
695
|
+
isValid: true,
|
|
696
|
+
isEmpty: false,
|
|
697
|
+
};
|
|
698
|
+
this.currentValidationState.cvv = { isValid: true, isEmpty: false };
|
|
699
|
+
this.currentValidationState.expiry = { isValid: true, isEmpty: false };
|
|
700
|
+
this.currentValidationState.isValid = true;
|
|
701
|
+
this.emit('validation', this.currentValidationState);
|
|
545
702
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
703
|
+
}
|
|
704
|
+
static measureCvvLabelMarginLeft(monthWidth, yearWidth, cvvMarginLeft) {
|
|
705
|
+
var _a;
|
|
706
|
+
const targetCvvX = monthWidth + 4 + 4 + yearWidth + 12 + cvvMarginLeft;
|
|
707
|
+
const host = document.createElement('div');
|
|
708
|
+
host.style.cssText =
|
|
709
|
+
'position:absolute;visibility:hidden;left:0;top:0;width:9999px;height:0;overflow:hidden;';
|
|
710
|
+
document.body.appendChild(host);
|
|
711
|
+
const shadow = host.attachShadow({ mode: 'open' });
|
|
712
|
+
shadow.innerHTML = [
|
|
713
|
+
'<input type="text" size="2" style="margin-right:4px">',
|
|
714
|
+
'<label>/</label>',
|
|
715
|
+
'<input type="text" size="4" style="margin-left:4px;margin-right:12px">',
|
|
716
|
+
'<input type="tel" size="5">',
|
|
717
|
+
].join('');
|
|
718
|
+
const inputs = shadow.querySelectorAll('input');
|
|
719
|
+
const hostX = host.getBoundingClientRect().x;
|
|
720
|
+
const cvvRect = (_a = inputs[2]) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
721
|
+
const defaultCvvX = cvvRect ? cvvRect.x - hostX : -1;
|
|
722
|
+
document.body.removeChild(host);
|
|
723
|
+
if (defaultCvvX <= 0 || defaultCvvX > 500) {
|
|
724
|
+
console.warn('[CardConnect] CVV measurement out of range, using fallback margin-left:100px');
|
|
725
|
+
return 100;
|
|
726
|
+
}
|
|
727
|
+
const predictedLabelLeft = defaultCvvX + 8;
|
|
728
|
+
return Math.round(targetCvvX - predictedLabelLeft);
|
|
550
729
|
}
|
|
551
730
|
static generateIframeUrl(baseUrl, container) {
|
|
731
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
552
732
|
const params = new URLSearchParams({
|
|
553
733
|
invalidinputevent: 'true',
|
|
554
734
|
enhancedresponse: 'true',
|
|
@@ -557,25 +737,46 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
557
737
|
formatinput: 'true',
|
|
558
738
|
unique: 'true',
|
|
559
739
|
norsa: 'true',
|
|
560
|
-
placeholder: 'Card Number *',
|
|
561
|
-
placeholdercvv: 'CVV',
|
|
740
|
+
placeholder: ((_a = container.placeholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || 'Card Number *',
|
|
741
|
+
placeholdercvv: ((_b = container.placeholders) === null || _b === void 0 ? void 0 : _b.cvv) || 'CVV',
|
|
562
742
|
invalidcreditcardevent: 'true',
|
|
563
743
|
invalidexpiry: 'true',
|
|
564
744
|
invalidcvv: 'true',
|
|
565
745
|
});
|
|
746
|
+
const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
|
|
747
|
+
const showLabelsInUrl = ((_c = mergedStyles.label) === null || _c === void 0 ? void 0 : _c.show) && container.layout === 'two-line';
|
|
748
|
+
if (showLabelsInUrl) {
|
|
749
|
+
params.set('cardlabel', 'Card Number');
|
|
750
|
+
params.set('expirylabel', 'Expiration');
|
|
751
|
+
params.set('cvvlabel', 'CVV');
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
params.set('cardlabel', '');
|
|
755
|
+
params.set('expirylabel', '');
|
|
756
|
+
params.set('cvvlabel', '');
|
|
757
|
+
}
|
|
566
758
|
if (container.layout === 'two-line') {
|
|
567
759
|
params.set('useexpiryfield', 'true');
|
|
568
760
|
params.set('orientation', 'horizontal');
|
|
569
|
-
params.set('placeholdermonth', 'MM');
|
|
570
|
-
params.set('placeholderyear', 'YYYY');
|
|
761
|
+
params.set('placeholdermonth', ((_d = container.placeholders) === null || _d === void 0 ? void 0 : _d.expiryMonth) || 'MM');
|
|
762
|
+
params.set('placeholderyear', ((_e = container.placeholders) === null || _e === void 0 ? void 0 : _e.expiryYear) || 'YYYY');
|
|
571
763
|
}
|
|
572
764
|
else {
|
|
573
765
|
params.set('orientation', 'horizontal');
|
|
574
|
-
params.set('placeholdermonth', 'MM');
|
|
575
|
-
params.set('placeholderyear', 'YYYY');
|
|
766
|
+
params.set('placeholdermonth', ((_f = container.placeholders) === null || _f === void 0 ? void 0 : _f.expiryMonth) || 'MM');
|
|
767
|
+
params.set('placeholderyear', ((_g = container.placeholders) === null || _g === void 0 ? void 0 : _g.expiryYear) || 'YYYY');
|
|
576
768
|
}
|
|
577
|
-
const
|
|
578
|
-
|
|
769
|
+
const isDesktopSafari = typeof navigator !== 'undefined' &&
|
|
770
|
+
/Safari/.test(navigator.userAgent) &&
|
|
771
|
+
/Apple Computer/.test(navigator.vendor) &&
|
|
772
|
+
!/Chrome/.test(navigator.userAgent) &&
|
|
773
|
+
!/Mobile/.test(navigator.userAgent);
|
|
774
|
+
const showLabels = ((_h = mergedStyles.label) === null || _h === void 0 ? void 0 : _h.show) && container.layout === 'two-line';
|
|
775
|
+
let cvvLabelMarginLeft;
|
|
776
|
+
if (showLabels && typeof document !== 'undefined') {
|
|
777
|
+
cvvLabelMarginLeft = CardConnectTokenizer.measureCvvLabelMarginLeft(60, 80, 40);
|
|
778
|
+
}
|
|
779
|
+
const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari, cvvLabelMarginLeft);
|
|
579
780
|
const queryPairs = [];
|
|
580
781
|
params.forEach((value, key) => {
|
|
581
782
|
queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
@@ -590,7 +791,7 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
590
791
|
iframe.style.width = '100%';
|
|
591
792
|
iframe.style.height = styles.input.height;
|
|
592
793
|
iframe.style.border = 'none';
|
|
593
|
-
iframe.style.overflow = '
|
|
794
|
+
iframe.style.overflow = '';
|
|
594
795
|
iframe.style.display = 'block';
|
|
595
796
|
iframe.style.minWidth = '0';
|
|
596
797
|
if (styles.container) {
|
|
@@ -608,18 +809,30 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
608
809
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
|
|
609
810
|
return iframe;
|
|
610
811
|
}
|
|
611
|
-
static generateCardConnectCss(styles, layout = 'single-line') {
|
|
612
|
-
var _a, _b, _c, _d;
|
|
812
|
+
static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false, cvvLabelMarginLeft) {
|
|
813
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
613
814
|
const css = [];
|
|
614
|
-
|
|
615
|
-
|
|
815
|
+
const showLabelsInIframe = ((_a = styles.label) === null || _a === void 0 ? void 0 : _a.show) && layout === 'two-line';
|
|
816
|
+
if (showLabelsInIframe) {
|
|
817
|
+
const labelCss = `font-size:${styles.label.fontSize};font-weight:${styles.label.fontWeight};font-family:${styles.label.fontFamily};color:${styles.label.color};margin-bottom:${styles.label.marginBottom}`;
|
|
818
|
+
css.push(`label{${labelCss};}`);
|
|
819
|
+
css.push(`label[for="ccexpiryfieldyear"]{display:none;}`);
|
|
820
|
+
css.push(`br{line-height:0;font-size:0;margin:0;}`);
|
|
821
|
+
css.push(`input,select{margin-top:0;margin-bottom:0;}`);
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
616
824
|
css.push('label{display:none;}');
|
|
617
|
-
|
|
825
|
+
}
|
|
826
|
+
if (layout === 'two-line') {
|
|
827
|
+
css.push('html,body{margin:0;padding:0;overflow:hidden;}');
|
|
828
|
+
css.push('form{margin:0;padding:0;width:100%;box-sizing:border-box;}');
|
|
829
|
+
if (!showLabelsInIframe) {
|
|
830
|
+
css.push('br{display:none;}');
|
|
831
|
+
}
|
|
618
832
|
}
|
|
619
833
|
else {
|
|
620
834
|
css.push('body{margin:0;padding:0;display:flex;align-items:center;}');
|
|
621
835
|
css.push('form{margin:0;padding:0;display:flex;width:100%;align-items:center;}');
|
|
622
|
-
css.push('label{display:none;}');
|
|
623
836
|
css.push('br{display:none;}');
|
|
624
837
|
}
|
|
625
838
|
const isConnected = styles.container.gap === '0';
|
|
@@ -643,14 +856,31 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
643
856
|
commonStyles.push('box-sizing:border-box');
|
|
644
857
|
const baseStyles = commonStyles.join(';');
|
|
645
858
|
css.push(`input{${baseStyles};}`);
|
|
646
|
-
|
|
859
|
+
if (isDesktopSafari) {
|
|
860
|
+
css.push(`select{${baseStyles};-webkit-appearance:none;appearance:none;}`);
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
css.push(`select{${baseStyles};}`);
|
|
864
|
+
}
|
|
647
865
|
}
|
|
648
866
|
if (layout === 'two-line') {
|
|
649
867
|
css.push('input#ccnumfield{width:100%;display:block;margin-bottom:8px;}');
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (
|
|
868
|
+
const twoLinePadding = ((_b = styles.twoLine) === null || _b === void 0 ? void 0 : _b.padding) || ((_c = styles.input) === null || _c === void 0 ? void 0 : _c.padding) || '10px';
|
|
869
|
+
const twoLineFontSize = ((_d = styles.twoLine) === null || _d === void 0 ? void 0 : _d.fontSize) || ((_e = styles.input) === null || _e === void 0 ? void 0 : _e.fontSize) || '14px';
|
|
870
|
+
const twoLineTextAlign = ((_f = styles.twoLine) === null || _f === void 0 ? void 0 : _f.textAlign) || 'left';
|
|
871
|
+
if (showLabelsInIframe) {
|
|
872
|
+
css.push(`input#ccexpiryfieldmonth{width:60px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
873
|
+
css.push(`input#ccexpiryfieldyear{width:80px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
874
|
+
css.push(`input#cccvvfield{width:80px;margin-left:40px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
875
|
+
const labelMargin = cvvLabelMarginLeft !== null && cvvLabelMarginLeft !== void 0 ? cvvLabelMarginLeft : 100;
|
|
876
|
+
css.push(`label#cccvvlabel{margin-left:${labelMargin}px;}`);
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
css.push(`input#ccexpiryfieldmonth{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
880
|
+
css.push(`input#ccexpiryfieldyear{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
881
|
+
css.push(`input#cccvvfield{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
882
|
+
}
|
|
883
|
+
if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
|
|
654
884
|
css.push(`input{border-radius:${styles.input.borderRadius};}`);
|
|
655
885
|
}
|
|
656
886
|
}
|
|
@@ -659,16 +889,16 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
659
889
|
css.push('select#ccexpirymonth{width:16%;margin:0;margin-right:-12px;}');
|
|
660
890
|
css.push('select#ccexpiryyear{width:20%;}');
|
|
661
891
|
css.push('input#cccvvfield{width:20%;margin:0;margin-left:-12px;}');
|
|
662
|
-
if ((
|
|
663
|
-
css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right:
|
|
664
|
-
css.push('select#ccexpirymonth{border-radius:0;border-right:
|
|
665
|
-
css.push('select#ccexpiryyear{border-radius:0;border-right:
|
|
892
|
+
if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
|
|
893
|
+
css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right-color:transparent;}`);
|
|
894
|
+
css.push('select#ccexpirymonth{border-radius:0;border-right-color:transparent;}');
|
|
895
|
+
css.push('select#ccexpiryyear{border-radius:0;border-right-color:transparent;}');
|
|
666
896
|
css.push(`input#cccvvfield{border-radius:0 ${styles.input.borderRadius} ${styles.input.borderRadius} 0;}`);
|
|
667
897
|
}
|
|
668
898
|
else {
|
|
669
|
-
css.push('input#ccnumfield{border-right:
|
|
670
|
-
css.push('select#ccexpirymonth{border-right:
|
|
671
|
-
css.push('select#ccexpiryyear{border-right:
|
|
899
|
+
css.push('input#ccnumfield{border-right-color:transparent;}');
|
|
900
|
+
css.push('select#ccexpirymonth{border-right-color:transparent;}');
|
|
901
|
+
css.push('select#ccexpiryyear{border-right-color:transparent;}');
|
|
672
902
|
}
|
|
673
903
|
}
|
|
674
904
|
else {
|
|
@@ -677,7 +907,7 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
677
907
|
css.push(`select#ccexpirymonth{width:15%;margin-right:${marginRight};}`);
|
|
678
908
|
css.push(`select#ccexpiryyear{width:20%;margin-right:${marginRight};}`);
|
|
679
909
|
css.push('input#cccvvfield{width:15%;}');
|
|
680
|
-
if ((
|
|
910
|
+
if ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.borderRadius) {
|
|
681
911
|
css.push(`input,select{border-radius:${styles.input.borderRadius};}`);
|
|
682
912
|
}
|
|
683
913
|
}
|
|
@@ -693,7 +923,7 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
693
923
|
if (focusStyles.length > 0) {
|
|
694
924
|
css.push(`input:focus{${focusStyles.join(';')};}`);
|
|
695
925
|
css.push(`select:focus{${focusStyles.join(';')};}`);
|
|
696
|
-
if (isConnected && ((
|
|
926
|
+
if (isConnected && ((_k = styles.input) === null || _k === void 0 ? void 0 : _k.border)) {
|
|
697
927
|
css.push(`input#ccnumfield:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
698
928
|
css.push(`select#ccexpirymonth:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
699
929
|
css.push(`select#ccexpiryyear:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
@@ -708,20 +938,39 @@ export class CardConnectTokenizer extends Tokenizer {
|
|
|
708
938
|
errorStyles.push(`background-color:${styles.error.backgroundColor}`);
|
|
709
939
|
if (errorStyles.length > 0) {
|
|
710
940
|
css.push(`.error{${errorStyles.join(';')};}`);
|
|
941
|
+
if (isConnected && styles.error.borderColor) {
|
|
942
|
+
const ec = styles.error.borderColor;
|
|
943
|
+
css.push(`#ccnumfield.error{border-right-color:${ec};}`);
|
|
944
|
+
css.push(`#ccexpirymonth.error{border-right-color:${ec};}`);
|
|
945
|
+
css.push(`#ccexpiryyear.error{border-right-color:${ec};}`);
|
|
946
|
+
}
|
|
711
947
|
}
|
|
712
948
|
}
|
|
713
949
|
return encodeURIComponent(css.join(''));
|
|
714
950
|
}
|
|
715
|
-
static tokenizeBankAccount(routingNumber, accountNumber,
|
|
716
|
-
return
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
951
|
+
static tokenizeBankAccount(routingNumber, accountNumber, configOrBaseUrl) {
|
|
952
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
953
|
+
const baseUrl = typeof configOrBaseUrl === 'string'
|
|
954
|
+
? configOrBaseUrl
|
|
955
|
+
: configOrBaseUrl.cardConnectBaseUrl;
|
|
956
|
+
const response = yield fetch(`${baseUrl}/cardsecure/api/v1/ccn/tokenize`, {
|
|
957
|
+
method: 'POST',
|
|
958
|
+
headers: {
|
|
959
|
+
'Content-Type': 'application/json',
|
|
960
|
+
},
|
|
961
|
+
body: JSON.stringify({
|
|
962
|
+
account: `${routingNumber}/${accountNumber}`,
|
|
963
|
+
unique: true,
|
|
964
|
+
}),
|
|
965
|
+
});
|
|
966
|
+
if (!response.ok) {
|
|
967
|
+
throw new TokenizationError(`Bank account tokenization failed: HTTP ${response.status}`, 'API_ERROR');
|
|
968
|
+
}
|
|
969
|
+
const result = yield response.json();
|
|
970
|
+
if (!result.token) {
|
|
971
|
+
throw new TokenizationError(result.message || 'Bank account tokenization failed: no token returned', 'API_ERROR');
|
|
972
|
+
}
|
|
973
|
+
return result;
|
|
974
|
+
});
|
|
726
975
|
}
|
|
727
976
|
}
|