@idonatedev/idonate-sdk 1.2.0-dev14 → 1.2.0-dev16
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 +1 -1
- package/dist/esm/constants.js +1 -1
- package/dist/esm/tokenize/CardConnectTokenizer.d.ts +6 -1
- package/dist/esm/tokenize/CardConnectTokenizer.js +184 -53
- package/dist/esm/tokenize/PayPalTokenizer.d.ts +1 -0
- package/dist/esm/tokenize/PayPalTokenizer.js +52 -16
- package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +6 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.js +113 -63
- package/dist/esm/tokenize/Tokenizer.d.ts +6 -2
- package/dist/esm/tokenize/Tokenizer.js +13 -3
- package/dist/esm/tokenize/gateway-utils.js +3 -2
- package/dist/esm/tokenize/index.d.ts +1 -1
- package/dist/esm/tokenize/spreedly-secure.js +6 -2
- package/dist/esm/tokenize/tokenizer-utils.d.ts +1 -1
- package/dist/esm/tokenize/tokenizer-utils.js +25 -4
- package/dist/esm/tokenize/types.d.ts +3 -2
- package/dist/esm/typeAdapters.js +6 -4
- package/dist/tokenize/CardConnectTokenizer.d.ts +6 -1
- package/dist/tokenize/CardConnectTokenizer.js +184 -56
- package/dist/tokenize/PayPalTokenizer.d.ts +1 -0
- package/dist/tokenize/PayPalTokenizer.js +52 -16
- package/dist/tokenize/SpreedlyTokenizer.d.ts +6 -0
- package/dist/tokenize/SpreedlyTokenizer.js +113 -63
- package/dist/tokenize/Tokenizer.d.ts +6 -2
- package/dist/tokenize/Tokenizer.js +13 -3
- package/dist/tokenize/gateway-utils.js +3 -2
- package/dist/tokenize/index.d.ts +1 -1
- package/dist/tokenize/spreedly-secure.js +6 -2
- package/dist/tokenize/tokenizer-utils.d.ts +1 -1
- package/dist/tokenize/tokenizer-utils.js +25 -4
- package/dist/tokenize/types.d.ts +3 -2
- package/dist/typeAdapters.js +6 -4
- package/package.json +1 -1
- package/umd/idonate-sdk.js +1 -1
|
@@ -66,7 +66,7 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
66
66
|
}
|
|
67
67
|
static create(gateway, container, config) {
|
|
68
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
-
var _a;
|
|
69
|
+
var _a, _b;
|
|
70
70
|
if (container.mode !== 'bank_account') {
|
|
71
71
|
yield SpreedlyTokenizer.ensureSpreedlyLoaded();
|
|
72
72
|
}
|
|
@@ -75,9 +75,9 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
75
75
|
environmentKey = config.clientConfig.spreedlyEnvironmentKey;
|
|
76
76
|
}
|
|
77
77
|
if (!environmentKey) {
|
|
78
|
-
environmentKey
|
|
78
|
+
throw new Error('Spreedly environment key is required. Provide it via gateway.config.environmentKey or client config.');
|
|
79
79
|
}
|
|
80
|
-
const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', container.responsiveBreakpoint
|
|
80
|
+
const tokenizer = new SpreedlyTokenizer(environmentKey, container.containerId, container.styling, container.mode || 'credit_card', container.bankCountry || 'US', container.enableTestMode || false, container.layout || 'single-line', (_b = container.responsiveBreakpoint) !== null && _b !== void 0 ? _b : RESPONSIVE_BREAKPOINT);
|
|
81
81
|
tokenizer.organizationId = config.organizationId;
|
|
82
82
|
tokenizer.embedId = config.embedId;
|
|
83
83
|
tokenizer.clientConfig = config.clientConfig;
|
|
@@ -158,8 +158,29 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
158
158
|
this.emit('ready');
|
|
159
159
|
resolve();
|
|
160
160
|
});
|
|
161
|
+
this.spreedly.on('paymentMethod', (token, pmData) => {
|
|
162
|
+
const paymentToken = {
|
|
163
|
+
token,
|
|
164
|
+
lastFour: pmData.last_four_digits,
|
|
165
|
+
cardType: this.normalizeCardType(pmData.card_type),
|
|
166
|
+
paymentMethodType: 'credit_card',
|
|
167
|
+
provider: 'spreedly',
|
|
168
|
+
};
|
|
169
|
+
if (this.tokenizationResolve) {
|
|
170
|
+
const resolveTokenization = this.tokenizationResolve;
|
|
171
|
+
this.clearTokenizationState();
|
|
172
|
+
this.emit('tokenReady', paymentToken);
|
|
173
|
+
resolveTokenization(paymentToken);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
161
176
|
this.spreedly.on('errors', (errors) => {
|
|
162
|
-
|
|
177
|
+
const error = new TokenizationError(errors);
|
|
178
|
+
this.emit('error', error);
|
|
179
|
+
if (this.tokenizationReject) {
|
|
180
|
+
const rejectTokenization = this.tokenizationReject;
|
|
181
|
+
this.clearTokenizationState();
|
|
182
|
+
rejectTokenization(error);
|
|
183
|
+
}
|
|
163
184
|
});
|
|
164
185
|
this.spreedly.on('fieldEvent', (fieldName, eventType, activeEl, inputProperties) => {
|
|
165
186
|
this.handleFieldEvent(fieldName, eventType, inputProperties);
|
|
@@ -185,6 +206,19 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
185
206
|
});
|
|
186
207
|
}
|
|
187
208
|
tokenizeCardInternal(cardData) {
|
|
209
|
+
if (this.tokenizationPromise) {
|
|
210
|
+
return this.tokenizationPromise;
|
|
211
|
+
}
|
|
212
|
+
const expiry = this.parseExpiry(this.expiryEl);
|
|
213
|
+
if (!expiry) {
|
|
214
|
+
return Promise.reject(new TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
|
|
215
|
+
}
|
|
216
|
+
this.tokenizationPromise = this.executeCardTokenization(cardData, expiry).finally(() => {
|
|
217
|
+
this.tokenizationPromise = undefined;
|
|
218
|
+
});
|
|
219
|
+
return this.tokenizationPromise;
|
|
220
|
+
}
|
|
221
|
+
executeCardTokenization(cardData, expiry) {
|
|
188
222
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
223
|
var _a;
|
|
190
224
|
let securityFields = {};
|
|
@@ -204,42 +238,13 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
204
238
|
}
|
|
205
239
|
return new Promise((resolve, reject) => {
|
|
206
240
|
var _a, _b, _c, _d, _e, _f;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
241
|
+
this.tokenizationResolve = resolve;
|
|
242
|
+
this.tokenizationReject = reject;
|
|
243
|
+
this.tokenizationTimeout = setTimeout(() => {
|
|
244
|
+
this.clearTokenizationState();
|
|
211
245
|
reject(new TokenizationError('Tokenization timeout', 'TIMEOUT'));
|
|
212
246
|
}, TOKENIZE_TIMEOUT);
|
|
213
|
-
|
|
214
|
-
clearTimeout(timeout);
|
|
215
|
-
if (this.spreedly && this.spreedly.removeHandlers) {
|
|
216
|
-
this.spreedly.removeHandlers();
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
this.spreedly.on('paymentMethod', (token, pmData) => {
|
|
220
|
-
cleanup();
|
|
221
|
-
const paymentToken = {
|
|
222
|
-
token,
|
|
223
|
-
lastFour: pmData.last_four_digits,
|
|
224
|
-
cardType: this.normalizeCardType(pmData.card_type),
|
|
225
|
-
provider: 'spreedly',
|
|
226
|
-
};
|
|
227
|
-
this.emit('tokenReady', paymentToken);
|
|
228
|
-
resolve(paymentToken);
|
|
229
|
-
});
|
|
230
|
-
this.spreedly.on('errors', (errors) => {
|
|
231
|
-
cleanup();
|
|
232
|
-
reject(new TokenizationError(errors));
|
|
233
|
-
});
|
|
234
|
-
const expiry = this.parseExpiry(this.expiryEl);
|
|
235
|
-
if (!expiry) {
|
|
236
|
-
cleanup();
|
|
237
|
-
reject(new TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
const expiryMonth = expiry.month;
|
|
241
|
-
const expiryYear = expiry.year;
|
|
242
|
-
this.spreedly.tokenizeCreditCard(Object.assign({ first_name: cardData.firstName, last_name: cardData.lastName, month: expiryMonth, year: expiryYear, 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));
|
|
247
|
+
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));
|
|
243
248
|
});
|
|
244
249
|
});
|
|
245
250
|
}
|
|
@@ -432,17 +437,22 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
432
437
|
accountHolderType: accountHolderType,
|
|
433
438
|
},
|
|
434
439
|
}, this.clientConfig, this.environmentKey);
|
|
435
|
-
|
|
440
|
+
const paymentToken = {
|
|
436
441
|
token: result,
|
|
437
442
|
lastFour: accountNumber.slice(-4),
|
|
438
443
|
accountType: accountType,
|
|
439
444
|
paymentMethodType: 'bank_account',
|
|
440
445
|
provider: 'spreedly',
|
|
441
446
|
};
|
|
447
|
+
this.emit('tokenReady', paymentToken);
|
|
448
|
+
return paymentToken;
|
|
442
449
|
});
|
|
443
450
|
}
|
|
444
451
|
validate() {
|
|
445
452
|
return __awaiter(this, void 0, void 0, function* () {
|
|
453
|
+
if (!this.isReady) {
|
|
454
|
+
throw new Error('Tokenizer not initialized');
|
|
455
|
+
}
|
|
446
456
|
if (this.mode === 'bank_account') {
|
|
447
457
|
return this.validateBankAccountInternal();
|
|
448
458
|
}
|
|
@@ -630,13 +640,31 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
630
640
|
this.accountNumberEl.value = '';
|
|
631
641
|
if (this.accountTypeEl)
|
|
632
642
|
this.accountTypeEl.selectedIndex = 0;
|
|
643
|
+
this.currentValidationState = {
|
|
644
|
+
isValid: false,
|
|
645
|
+
routingNumber: { isValid: false, isEmpty: true },
|
|
646
|
+
accountNumber: { isValid: false, isEmpty: true },
|
|
647
|
+
};
|
|
633
648
|
}
|
|
634
649
|
else {
|
|
635
650
|
this.spreedly.reload();
|
|
636
651
|
if (this.expiryEl) {
|
|
637
652
|
this.expiryEl.value = '';
|
|
638
653
|
}
|
|
654
|
+
this.currentValidationState = {
|
|
655
|
+
isValid: false,
|
|
656
|
+
cardNumber: { isValid: false, isEmpty: true },
|
|
657
|
+
cvv: { isValid: false, isEmpty: true },
|
|
658
|
+
expiry: { isValid: false, isEmpty: true },
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
if (this.tokenizationReject) {
|
|
662
|
+
const reject = this.tokenizationReject;
|
|
663
|
+
this.clearTokenizationState();
|
|
664
|
+
reject(new TokenizationError('Tokenizer cleared', 'CLEARED'));
|
|
639
665
|
}
|
|
666
|
+
this.clearTokenizationState();
|
|
667
|
+
this.emit('validation', this.currentValidationState);
|
|
640
668
|
}
|
|
641
669
|
focus(field) {
|
|
642
670
|
if (this.mode === 'bank_account') {
|
|
@@ -727,14 +755,29 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
727
755
|
}
|
|
728
756
|
}
|
|
729
757
|
}
|
|
758
|
+
clearTokenizationState() {
|
|
759
|
+
if (this.tokenizationTimeout) {
|
|
760
|
+
clearTimeout(this.tokenizationTimeout);
|
|
761
|
+
this.tokenizationTimeout = undefined;
|
|
762
|
+
}
|
|
763
|
+
this.tokenizationResolve = undefined;
|
|
764
|
+
this.tokenizationReject = undefined;
|
|
765
|
+
}
|
|
730
766
|
destroy() {
|
|
731
767
|
var _a;
|
|
768
|
+
this.markDestroyed();
|
|
732
769
|
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
770
|
+
if (this.tokenizationReject) {
|
|
771
|
+
const reject = this.tokenizationReject;
|
|
772
|
+
this.clearTokenizationState();
|
|
773
|
+
reject(new TokenizationError('Tokenizer destroyed', 'DESTROYED'));
|
|
774
|
+
}
|
|
733
775
|
if (this.spreedly && this.spreedly.removeHandlers) {
|
|
734
776
|
this.spreedly.removeHandlers();
|
|
735
777
|
}
|
|
736
778
|
this.eventHandlers.clear();
|
|
737
|
-
if (this.
|
|
779
|
+
if (this.containerEl) {
|
|
780
|
+
this.containerEl.innerHTML = '';
|
|
738
781
|
}
|
|
739
782
|
}
|
|
740
783
|
hasToken() {
|
|
@@ -781,15 +824,6 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
781
824
|
}
|
|
782
825
|
this.updateOverallValidation();
|
|
783
826
|
}
|
|
784
|
-
if (eventType === 'focus') {
|
|
785
|
-
this.emit('focus', { field: fieldName });
|
|
786
|
-
}
|
|
787
|
-
else if (eventType === 'blur') {
|
|
788
|
-
this.emit('blur', { field: fieldName });
|
|
789
|
-
}
|
|
790
|
-
else if (eventType === 'input') {
|
|
791
|
-
this.emit('change', { field: fieldName });
|
|
792
|
-
}
|
|
793
827
|
}
|
|
794
828
|
createInternalElements() {
|
|
795
829
|
const container = document.getElementById(this.containerId);
|
|
@@ -835,6 +869,10 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
835
869
|
};
|
|
836
870
|
this.updateOverallValidation();
|
|
837
871
|
});
|
|
872
|
+
this.expiryEl.addEventListener('blur', () => {
|
|
873
|
+
this.validateExpiry();
|
|
874
|
+
this.updateOverallValidation();
|
|
875
|
+
});
|
|
838
876
|
container.appendChild(this.expiryEl);
|
|
839
877
|
const cvvDiv = createFieldContainer(this.cvvEl, '1', FIELD_FLEX.cvv.minWidth);
|
|
840
878
|
cvvDiv.style.height = this.mergedStyles.input.height;
|
|
@@ -862,6 +900,10 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
862
900
|
};
|
|
863
901
|
this.updateOverallValidation();
|
|
864
902
|
});
|
|
903
|
+
this.expiryEl.addEventListener('blur', () => {
|
|
904
|
+
this.validateExpiry();
|
|
905
|
+
this.updateOverallValidation();
|
|
906
|
+
});
|
|
865
907
|
container.appendChild(this.expiryEl);
|
|
866
908
|
const cvvDiv = createFieldContainer(this.cvvEl, FIELD_FLEX.cvv.flex, FIELD_FLEX.cvv.minWidth);
|
|
867
909
|
cvvDiv.style.height = this.mergedStyles.input.height;
|
|
@@ -1024,23 +1066,31 @@ export class SpreedlyTokenizer extends Tokenizer {
|
|
|
1024
1066
|
if (!this.expiryEl)
|
|
1025
1067
|
return;
|
|
1026
1068
|
const expiry = this.parseExpiry(this.expiryEl);
|
|
1069
|
+
const isEmpty = !this.expiryEl.value;
|
|
1070
|
+
let isValid = false;
|
|
1027
1071
|
if (!expiry) {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
}
|
|
1031
|
-
const month = parseInt(expiry.month, 10);
|
|
1032
|
-
const year = parseInt(expiry.year, 10);
|
|
1033
|
-
if (month < 1 || month > 12) {
|
|
1034
|
-
this.applyErrorStyles(this.expiryEl);
|
|
1035
|
-
return;
|
|
1072
|
+
if (!isEmpty)
|
|
1073
|
+
this.applyErrorStyles(this.expiryEl);
|
|
1036
1074
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1075
|
+
else {
|
|
1076
|
+
const month = parseInt(expiry.month, 10);
|
|
1077
|
+
const year = parseInt(expiry.year, 10);
|
|
1078
|
+
if (month < 1 || month > 12) {
|
|
1079
|
+
this.applyErrorStyles(this.expiryEl);
|
|
1080
|
+
}
|
|
1081
|
+
else {
|
|
1082
|
+
const now = new Date();
|
|
1083
|
+
const expiryEndDate = new Date(year, month);
|
|
1084
|
+
if (expiryEndDate <= now) {
|
|
1085
|
+
this.applyErrorStyles(this.expiryEl);
|
|
1086
|
+
}
|
|
1087
|
+
else {
|
|
1088
|
+
isValid = true;
|
|
1089
|
+
this.applyInputStyles(this.expiryEl, this.mergedStyles, 'middle');
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1042
1092
|
}
|
|
1043
|
-
this.
|
|
1093
|
+
this.currentValidationState.expiry = { isValid, isEmpty };
|
|
1044
1094
|
}
|
|
1045
1095
|
applyErrorStyles(element) {
|
|
1046
1096
|
if (this.mergedStyles.error) {
|
|
@@ -2,9 +2,13 @@ import { CardData, BankAccountData, PaymentData, PaymentToken, ValidationResult,
|
|
|
2
2
|
import ConfigHandler from '../config-handler';
|
|
3
3
|
export declare abstract class Tokenizer {
|
|
4
4
|
protected mode: PaymentMethodMode;
|
|
5
|
-
protected eventHandlers: Map<
|
|
5
|
+
protected eventHandlers: Map<string, Set<(data?: any) => void>>;
|
|
6
|
+
private focusHandlerElements;
|
|
6
7
|
private _isReady;
|
|
8
|
+
private _isDestroyed;
|
|
7
9
|
get isReady(): boolean;
|
|
10
|
+
get isDestroyed(): boolean;
|
|
11
|
+
protected markDestroyed(): void;
|
|
8
12
|
abstract tokenize(paymentData: PaymentData): Promise<PaymentToken>;
|
|
9
13
|
abstract validate(): Promise<ValidationResult>;
|
|
10
14
|
abstract clear(): void;
|
|
@@ -16,7 +20,7 @@ export declare abstract class Tokenizer {
|
|
|
16
20
|
getMode(): PaymentMethodMode;
|
|
17
21
|
on(event: TokenizerEvent, handler: (data?: any) => void): void;
|
|
18
22
|
off(event: TokenizerEvent, handler: (data?: any) => void): void;
|
|
19
|
-
protected emit(event:
|
|
23
|
+
protected emit(event: string, data?: any): void;
|
|
20
24
|
protected isCardData(data: PaymentData): data is CardData;
|
|
21
25
|
protected isBankAccountData(data: PaymentData): data is BankAccountData;
|
|
22
26
|
protected normalizeCardType(providerCardType: string): CardType;
|
|
@@ -13,10 +13,18 @@ export class Tokenizer {
|
|
|
13
13
|
constructor() {
|
|
14
14
|
this.mode = 'credit_card';
|
|
15
15
|
this.eventHandlers = new Map();
|
|
16
|
+
this.focusHandlerElements = new WeakSet();
|
|
16
17
|
this._isReady = false;
|
|
18
|
+
this._isDestroyed = false;
|
|
17
19
|
}
|
|
18
20
|
get isReady() {
|
|
19
|
-
return this._isReady;
|
|
21
|
+
return this._isReady && !this._isDestroyed;
|
|
22
|
+
}
|
|
23
|
+
get isDestroyed() {
|
|
24
|
+
return this._isDestroyed;
|
|
25
|
+
}
|
|
26
|
+
markDestroyed() {
|
|
27
|
+
this._isDestroyed = true;
|
|
20
28
|
}
|
|
21
29
|
getMode() {
|
|
22
30
|
return this.mode;
|
|
@@ -82,7 +90,6 @@ export class Tokenizer {
|
|
|
82
90
|
expiryEl.addEventListener('input', (e) => {
|
|
83
91
|
const target = e.target;
|
|
84
92
|
target.value = formatExpiryInput(target.value);
|
|
85
|
-
this.emit('change', { field: 'expiry' });
|
|
86
93
|
});
|
|
87
94
|
expiryEl.addEventListener('keypress', (e) => {
|
|
88
95
|
const char = String.fromCharCode(e.which);
|
|
@@ -133,7 +140,10 @@ export class Tokenizer {
|
|
|
133
140
|
element.style.border = inputStyles.border;
|
|
134
141
|
element.style.borderRadius = inputStyles.borderRadius;
|
|
135
142
|
}
|
|
136
|
-
|
|
143
|
+
if (!this.focusHandlerElements.has(element)) {
|
|
144
|
+
addFocusHandlers(element, styles, position);
|
|
145
|
+
this.focusHandlerElements.add(element);
|
|
146
|
+
}
|
|
137
147
|
}
|
|
138
148
|
generateFieldIds(containerId) {
|
|
139
149
|
return {
|
|
@@ -10,8 +10,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
export function normalizeGateway(input) {
|
|
13
|
-
if (!input)
|
|
14
|
-
|
|
13
|
+
if (!input) {
|
|
14
|
+
throw new Error('Gateway is required but received ' + String(input));
|
|
15
|
+
}
|
|
15
16
|
if (input.backendName !== undefined)
|
|
16
17
|
return input;
|
|
17
18
|
const _a = input.config || {}, { environment_key, base_url, merchant_id } = _a, extraConfigKeys = __rest(_a, ["environment_key", "base_url", "merchant_id"]);
|
|
@@ -3,6 +3,6 @@ export { Tokenizer } from './Tokenizer';
|
|
|
3
3
|
export { SpreedlyTokenizer } from './SpreedlyTokenizer';
|
|
4
4
|
export { CardConnectTokenizer } from './CardConnectTokenizer';
|
|
5
5
|
export { PayPalTokenizer, PayPalCreateOrderData } from './PayPalTokenizer';
|
|
6
|
-
export { PaymentMethodType, PaymentGateway, TokenizerContainer, TokenizerStyling, CardData, PaymentData, PaymentToken, CardType, TokenizerEvent, ValidationState, ValidationResult, ValidationError, TokenizationError, } from './types';
|
|
6
|
+
export { PaymentMethodType, PaymentMethodMode, PaymentGateway, TokenizerContainer, TokenizerStyling, CardData, BankAccountData, PaymentData, PaymentToken, CardType, TokenizerEvent, ValidationState, ValidationResult, ValidationError, TokenizationError, } from './types';
|
|
7
7
|
export { normalizeGateway } from './gateway-utils';
|
|
8
8
|
export { iats };
|
|
@@ -13,6 +13,7 @@ export function fetchSpreedlySecurityArgs(config, organizationId, embedId) {
|
|
|
13
13
|
throw new Error('Secure tokenization is not enabled');
|
|
14
14
|
}
|
|
15
15
|
const makeRequest = () => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
var _a;
|
|
16
17
|
const response = yield fetch(`${config.embedApiBaseUrl}/spreedly/security-args`, {
|
|
17
18
|
method: 'POST',
|
|
18
19
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -24,13 +25,16 @@ export function fetchSpreedlySecurityArgs(config, organizationId, embedId) {
|
|
|
24
25
|
if (!response.ok) {
|
|
25
26
|
throw new Error(`Security args request failed: ${response.status}`);
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
const data = yield response.json();
|
|
29
|
+
return (_a = data.result) !== null && _a !== void 0 ? _a : data;
|
|
28
30
|
});
|
|
29
31
|
try {
|
|
30
32
|
return yield makeRequest();
|
|
31
33
|
}
|
|
32
34
|
catch (error) {
|
|
33
|
-
|
|
35
|
+
const isNetworkError = error instanceof TypeError && error.message.includes('fetch');
|
|
36
|
+
const isServerError = error instanceof Error && error.message.includes('failed: 5');
|
|
37
|
+
if (isNetworkError || isServerError) {
|
|
34
38
|
yield new Promise((resolve) => setTimeout(resolve, 1000));
|
|
35
39
|
return makeRequest();
|
|
36
40
|
}
|
|
@@ -6,7 +6,7 @@ export declare function parseExpiryDate(value: string): {
|
|
|
6
6
|
export declare function formatExpiryInput(value: string): string;
|
|
7
7
|
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string): Promise<T>;
|
|
8
8
|
export declare function getConnectedBorderRadius(baseRadius: string, position: 'left' | 'middle' | 'right', isConnected: boolean): string;
|
|
9
|
-
export declare function addFocusHandlers(element: HTMLElement, styles: TokenizerStylingComplete, onFocus?: () => void, onBlur?: () => void): void;
|
|
9
|
+
export declare function addFocusHandlers(element: HTMLElement, styles: TokenizerStylingComplete, position?: 'left' | 'middle' | 'right', onFocus?: () => void, onBlur?: () => void): void;
|
|
10
10
|
export declare function createFieldContainer(id: string, flex: string, minWidth?: string, maxWidth?: string): HTMLDivElement;
|
|
11
11
|
export declare function createInputElement(id: string, type: string, placeholder: string, maxLength?: number): HTMLInputElement;
|
|
12
12
|
export declare function validateRoutingNumber(routingNumber: string): boolean;
|
|
@@ -39,7 +39,7 @@ export function getConnectedBorderRadius(baseRadius, position, isConnected) {
|
|
|
39
39
|
return baseRadius;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
export function addFocusHandlers(element, styles, onFocus, onBlur) {
|
|
42
|
+
export function addFocusHandlers(element, styles, position, onFocus, onBlur) {
|
|
43
43
|
element.addEventListener('focus', () => {
|
|
44
44
|
if (styles.focus) {
|
|
45
45
|
Object.assign(element.style, styles.focus);
|
|
@@ -47,9 +47,30 @@ export function addFocusHandlers(element, styles, onFocus, onBlur) {
|
|
|
47
47
|
onFocus === null || onFocus === void 0 ? void 0 : onFocus();
|
|
48
48
|
});
|
|
49
49
|
element.addEventListener('blur', () => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const isConnected = styles.container.gap === '0';
|
|
51
|
+
if (isConnected && position) {
|
|
52
|
+
element.style.borderTop = styles.input.border;
|
|
53
|
+
element.style.borderBottom = styles.input.border;
|
|
54
|
+
switch (position) {
|
|
55
|
+
case 'left':
|
|
56
|
+
element.style.borderLeft = styles.input.border;
|
|
57
|
+
element.style.borderRight = 'none';
|
|
58
|
+
break;
|
|
59
|
+
case 'middle':
|
|
60
|
+
element.style.borderLeft = styles.input.border;
|
|
61
|
+
element.style.borderRight = 'none';
|
|
62
|
+
break;
|
|
63
|
+
case 'right':
|
|
64
|
+
element.style.borderLeft = styles.input.border;
|
|
65
|
+
element.style.borderRight = styles.input.border;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
element.style.border = styles.input.border;
|
|
71
|
+
}
|
|
72
|
+
element.style.outline = '';
|
|
73
|
+
element.style.boxShadow = '';
|
|
53
74
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
|
54
75
|
});
|
|
55
76
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type PaymentMethodType = 'credit_card' | 'bank_account' | 'paypal' | 'apple_pay' | 'google_pay';
|
|
2
|
-
export type PaymentMethodMode = 'credit_card' | 'bank_account';
|
|
2
|
+
export type PaymentMethodMode = 'credit_card' | 'bank_account' | 'paypal';
|
|
3
3
|
export interface PaymentGateway {
|
|
4
4
|
id: string;
|
|
5
5
|
backendName: string;
|
|
@@ -106,9 +106,10 @@ export interface PaymentToken {
|
|
|
106
106
|
paymentTransactionId?: string;
|
|
107
107
|
}
|
|
108
108
|
export type CardType = 'visa' | 'mastercard' | 'amex' | 'discover' | 'diners' | 'jcb' | 'unknown';
|
|
109
|
-
export type TokenizerEvent = 'ready' | '
|
|
109
|
+
export type TokenizerEvent = 'ready' | 'validation' | 'cardTypeChange' | 'error' | 'tokenReady';
|
|
110
110
|
export interface ValidationState {
|
|
111
111
|
isValid: boolean;
|
|
112
|
+
hasToken?: boolean;
|
|
112
113
|
cardNumber?: {
|
|
113
114
|
isValid: boolean;
|
|
114
115
|
isEmpty: boolean;
|
package/dist/esm/typeAdapters.js
CHANGED
|
@@ -102,16 +102,18 @@ export function buildCashPaymentPayload(organizationId, input) {
|
|
|
102
102
|
utmFields.utm_term = input.utm.term;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
let remainingMeta = input.customerMeta
|
|
106
|
+
? Object.assign({}, input.customerMeta) : {};
|
|
105
107
|
if (input.customerMeta) {
|
|
106
108
|
[1, 2, 3, 4, 5].forEach((customNoteIndex) => {
|
|
107
109
|
const key = `custom_note_${customNoteIndex}`;
|
|
108
|
-
if (
|
|
109
|
-
donationOptions[key] =
|
|
110
|
-
delete
|
|
110
|
+
if (remainingMeta[key]) {
|
|
111
|
+
donationOptions[key] = remainingMeta[key];
|
|
112
|
+
delete remainingMeta[key];
|
|
111
113
|
}
|
|
112
114
|
});
|
|
113
115
|
}
|
|
114
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, donationOptions), billingAddress), billingContact), payment), utmFields), { customer_meta:
|
|
116
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, donationOptions), billingAddress), billingContact), payment), utmFields), { customer_meta: remainingMeta, recaptcha_token: input.recaptchaToken, recaptcha_type: input.recaptchaType });
|
|
115
117
|
}
|
|
116
118
|
export function buildDonationResult(response) {
|
|
117
119
|
let campaign;
|
|
@@ -16,10 +16,13 @@ export declare class CardConnectTokenizer extends Tokenizer {
|
|
|
16
16
|
private accountTypeEl?;
|
|
17
17
|
private enableTestMode;
|
|
18
18
|
private cachedTokenResult?;
|
|
19
|
+
private acceptAutoToken;
|
|
19
20
|
private tokenizationPromise?;
|
|
20
21
|
private tokenizationResolve?;
|
|
21
22
|
private tokenizationReject?;
|
|
22
23
|
private currentCardType?;
|
|
24
|
+
private tokenizationTimeout?;
|
|
25
|
+
private mergedStyles?;
|
|
23
26
|
private constructor();
|
|
24
27
|
static create(gateway: PaymentGateway, container: TokenizerContainer, config: {
|
|
25
28
|
organizationId: string;
|
|
@@ -29,6 +32,8 @@ export declare class CardConnectTokenizer extends Tokenizer {
|
|
|
29
32
|
private createInternalElements;
|
|
30
33
|
private createCreditCardFields;
|
|
31
34
|
private createBankAccountFields;
|
|
35
|
+
private addBankAccountValidationListeners;
|
|
36
|
+
private updateBankAccountValidation;
|
|
32
37
|
private init;
|
|
33
38
|
tokenize(paymentData: PaymentData): Promise<PaymentToken>;
|
|
34
39
|
private tokenizeCardInternal;
|
|
@@ -47,5 +52,5 @@ export declare class CardConnectTokenizer extends Tokenizer {
|
|
|
47
52
|
private static generateIframeUrl;
|
|
48
53
|
private static createIframe;
|
|
49
54
|
private static generateCardConnectCss;
|
|
50
|
-
static tokenizeBankAccount(routingNumber: string, accountNumber: string,
|
|
55
|
+
static tokenizeBankAccount(routingNumber: string, accountNumber: string, configOrBaseUrl: ConfigHandler | string): Promise<TokenizeCardConnectBankAccountResult>;
|
|
51
56
|
}
|