@idonatedev/idonate-sdk 1.2.0-dev15 → 1.2.0-dev17
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 +1 -0
- package/dist/esm/tokenize/CardConnectTokenizer.js +36 -6
- package/dist/esm/tokenize/PayPalTokenizer.js +2 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +1 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.js +35 -21
- package/dist/esm/tokenize/Tokenizer.d.ts +5 -1
- package/dist/esm/tokenize/Tokenizer.js +13 -2
- package/dist/esm/tokenize/index.d.ts +1 -1
- package/dist/esm/tokenize/spreedly-secure.js +3 -1
- package/dist/esm/tokenize/tokenizer-utils.d.ts +1 -1
- package/dist/esm/tokenize/tokenizer-utils.js +23 -2
- package/dist/esm/tokenize/types.d.ts +2 -1
- package/dist/esm/typeAdapters.js +6 -4
- package/dist/tokenize/CardConnectTokenizer.d.ts +1 -0
- package/dist/tokenize/CardConnectTokenizer.js +36 -6
- package/dist/tokenize/PayPalTokenizer.js +2 -0
- package/dist/tokenize/SpreedlyTokenizer.d.ts +1 -0
- package/dist/tokenize/SpreedlyTokenizer.js +35 -21
- package/dist/tokenize/Tokenizer.d.ts +5 -1
- package/dist/tokenize/Tokenizer.js +13 -2
- package/dist/tokenize/index.d.ts +1 -1
- package/dist/tokenize/spreedly-secure.js +3 -1
- package/dist/tokenize/tokenizer-utils.d.ts +1 -1
- package/dist/tokenize/tokenizer-utils.js +23 -2
- package/dist/tokenize/types.d.ts +2 -1
- package/dist/typeAdapters.js +6 -4
- package/package.json +1 -1
- package/umd/idonate-sdk.js +1 -1
|
@@ -166,6 +166,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
166
166
|
token,
|
|
167
167
|
lastFour: pmData.last_four_digits,
|
|
168
168
|
cardType: this.normalizeCardType(pmData.card_type),
|
|
169
|
+
paymentMethodType: 'credit_card',
|
|
169
170
|
provider: 'spreedly',
|
|
170
171
|
};
|
|
171
172
|
if (this.tokenizationResolve) {
|
|
@@ -176,13 +177,12 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
176
177
|
}
|
|
177
178
|
});
|
|
178
179
|
this.spreedly.on('errors', (errors) => {
|
|
180
|
+
const error = new types_1.TokenizationError(errors);
|
|
181
|
+
this.emit('error', error);
|
|
179
182
|
if (this.tokenizationReject) {
|
|
180
183
|
const rejectTokenization = this.tokenizationReject;
|
|
181
184
|
this.clearTokenizationState();
|
|
182
|
-
rejectTokenization(
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
this.emit('error', new types_1.TokenizationError(errors));
|
|
185
|
+
rejectTokenization(error);
|
|
186
186
|
}
|
|
187
187
|
});
|
|
188
188
|
this.spreedly.on('fieldEvent', (fieldName, eventType, activeEl, inputProperties) => {
|
|
@@ -209,15 +209,21 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
tokenizeCardInternal(cardData) {
|
|
212
|
+
if (this.tokenizationPromise) {
|
|
213
|
+
return this.tokenizationPromise;
|
|
214
|
+
}
|
|
215
|
+
const expiry = this.parseExpiry(this.expiryEl);
|
|
216
|
+
if (!expiry) {
|
|
217
|
+
return Promise.reject(new types_1.TokenizationError('Expiration date is required', 'VALIDATION_ERROR'));
|
|
218
|
+
}
|
|
219
|
+
this.tokenizationPromise = this.executeCardTokenization(cardData, expiry).finally(() => {
|
|
220
|
+
this.tokenizationPromise = undefined;
|
|
221
|
+
});
|
|
222
|
+
return this.tokenizationPromise;
|
|
223
|
+
}
|
|
224
|
+
executeCardTokenization(cardData, expiry) {
|
|
212
225
|
return __awaiter(this, void 0, void 0, function* () {
|
|
213
226
|
var _a;
|
|
214
|
-
if (this.tokenizationPromise) {
|
|
215
|
-
return this.tokenizationPromise;
|
|
216
|
-
}
|
|
217
|
-
const expiry = this.parseExpiry(this.expiryEl);
|
|
218
|
-
if (!expiry) {
|
|
219
|
-
throw new types_1.TokenizationError('Expiration date is required', 'VALIDATION_ERROR');
|
|
220
|
-
}
|
|
221
227
|
let securityFields = {};
|
|
222
228
|
if ((_a = this.clientConfig) === null || _a === void 0 ? void 0 : _a.enableSpreedlySecureTokenization) {
|
|
223
229
|
try {
|
|
@@ -225,7 +231,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
225
231
|
securityFields = {
|
|
226
232
|
nonce: args.nonce,
|
|
227
233
|
timestamp: args.timestamp,
|
|
228
|
-
|
|
234
|
+
certificateToken: args.certificate_token,
|
|
229
235
|
signature: args.signature,
|
|
230
236
|
};
|
|
231
237
|
}
|
|
@@ -233,7 +239,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
233
239
|
throw new types_1.TokenizationError(`Secure tokenization failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'SECURE_TOKENIZATION_ERROR');
|
|
234
240
|
}
|
|
235
241
|
}
|
|
236
|
-
|
|
242
|
+
return new Promise((resolve, reject) => {
|
|
237
243
|
var _a, _b, _c, _d, _e, _f;
|
|
238
244
|
this.tokenizationResolve = resolve;
|
|
239
245
|
this.tokenizationReject = reject;
|
|
@@ -242,10 +248,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
242
248
|
reject(new types_1.TokenizationError('Tokenization timeout', 'TIMEOUT'));
|
|
243
249
|
}, tokenizer_constants_1.TOKENIZE_TIMEOUT);
|
|
244
250
|
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));
|
|
245
|
-
}).finally(() => {
|
|
246
|
-
this.tokenizationPromise = undefined;
|
|
247
251
|
});
|
|
248
|
-
return this.tokenizationPromise;
|
|
249
252
|
});
|
|
250
253
|
}
|
|
251
254
|
createCanadianBankAccountFields(container) {
|
|
@@ -437,13 +440,15 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
437
440
|
accountHolderType: accountHolderType,
|
|
438
441
|
},
|
|
439
442
|
}, this.clientConfig, this.environmentKey);
|
|
440
|
-
|
|
443
|
+
const paymentToken = {
|
|
441
444
|
token: result,
|
|
442
445
|
lastFour: accountNumber.slice(-4),
|
|
443
446
|
accountType: accountType,
|
|
444
447
|
paymentMethodType: 'bank_account',
|
|
445
448
|
provider: 'spreedly',
|
|
446
449
|
};
|
|
450
|
+
this.emit('tokenReady', paymentToken);
|
|
451
|
+
return paymentToken;
|
|
447
452
|
});
|
|
448
453
|
}
|
|
449
454
|
validate() {
|
|
@@ -656,7 +661,14 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
656
661
|
expiry: { isValid: false, isEmpty: true },
|
|
657
662
|
};
|
|
658
663
|
}
|
|
659
|
-
this.
|
|
664
|
+
if (this.tokenizationReject) {
|
|
665
|
+
const reject = this.tokenizationReject;
|
|
666
|
+
this.clearTokenizationState();
|
|
667
|
+
reject(new types_1.TokenizationError('Tokenizer cleared', 'CLEARED'));
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
this.clearTokenizationState();
|
|
671
|
+
}
|
|
660
672
|
this.emit('validation', this.currentValidationState);
|
|
661
673
|
}
|
|
662
674
|
focus(field) {
|
|
@@ -758,6 +770,7 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
758
770
|
}
|
|
759
771
|
destroy() {
|
|
760
772
|
var _a;
|
|
773
|
+
this.markDestroyed();
|
|
761
774
|
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
762
775
|
if (this.tokenizationReject) {
|
|
763
776
|
const reject = this.tokenizationReject;
|
|
@@ -1072,13 +1085,14 @@ class SpreedlyTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
1072
1085
|
}
|
|
1073
1086
|
else {
|
|
1074
1087
|
const now = new Date();
|
|
1075
|
-
const
|
|
1076
|
-
if (
|
|
1088
|
+
const expiryEndDate = new Date(year, month);
|
|
1089
|
+
if (expiryEndDate <= now) {
|
|
1077
1090
|
this.applyErrorStyles(this.expiryEl);
|
|
1078
1091
|
}
|
|
1079
1092
|
else {
|
|
1080
1093
|
isValid = true;
|
|
1081
|
-
|
|
1094
|
+
const expiryPosition = this.effectiveLayout === 'two-line' ? 'left' : 'middle';
|
|
1095
|
+
this.applyInputStyles(this.expiryEl, this.mergedStyles, expiryPosition);
|
|
1082
1096
|
}
|
|
1083
1097
|
}
|
|
1084
1098
|
}
|
|
@@ -3,8 +3,12 @@ import ConfigHandler from '../config-handler';
|
|
|
3
3
|
export declare abstract class Tokenizer {
|
|
4
4
|
protected mode: PaymentMethodMode;
|
|
5
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: TokenizerEvent, 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;
|
|
@@ -49,10 +49,18 @@ class Tokenizer {
|
|
|
49
49
|
constructor() {
|
|
50
50
|
this.mode = 'credit_card';
|
|
51
51
|
this.eventHandlers = new Map();
|
|
52
|
+
this.focusHandlerElements = new WeakSet();
|
|
52
53
|
this._isReady = false;
|
|
54
|
+
this._isDestroyed = false;
|
|
53
55
|
}
|
|
54
56
|
get isReady() {
|
|
55
|
-
return this._isReady;
|
|
57
|
+
return this._isReady && !this._isDestroyed;
|
|
58
|
+
}
|
|
59
|
+
get isDestroyed() {
|
|
60
|
+
return this._isDestroyed;
|
|
61
|
+
}
|
|
62
|
+
markDestroyed() {
|
|
63
|
+
this._isDestroyed = true;
|
|
56
64
|
}
|
|
57
65
|
getMode() {
|
|
58
66
|
return this.mode;
|
|
@@ -168,7 +176,10 @@ class Tokenizer {
|
|
|
168
176
|
element.style.border = inputStyles.border;
|
|
169
177
|
element.style.borderRadius = inputStyles.borderRadius;
|
|
170
178
|
}
|
|
171
|
-
(
|
|
179
|
+
if (!this.focusHandlerElements.has(element)) {
|
|
180
|
+
(0, tokenizer_utils_1.addFocusHandlers)(element, styles, position);
|
|
181
|
+
this.focusHandlerElements.add(element);
|
|
182
|
+
}
|
|
172
183
|
}
|
|
173
184
|
generateFieldIds(containerId) {
|
|
174
185
|
return {
|
package/dist/tokenize/index.d.ts
CHANGED
|
@@ -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, PaymentMethodMode, PaymentGateway, TokenizerContainer, TokenizerStyling, CardData, BankAccountData, PaymentData, PaymentToken, CardType, TokenizerEvent, ValidationState, ValidationResult, ValidationError, TokenizationError, } from './types';
|
|
6
|
+
export { BackendName, 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 };
|
|
@@ -16,6 +16,7 @@ function fetchSpreedlySecurityArgs(config, organizationId, embedId) {
|
|
|
16
16
|
throw new Error('Secure tokenization is not enabled');
|
|
17
17
|
}
|
|
18
18
|
const makeRequest = () => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
var _a;
|
|
19
20
|
const response = yield fetch(`${config.embedApiBaseUrl}/spreedly/security-args`, {
|
|
20
21
|
method: 'POST',
|
|
21
22
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -27,7 +28,8 @@ function fetchSpreedlySecurityArgs(config, organizationId, embedId) {
|
|
|
27
28
|
if (!response.ok) {
|
|
28
29
|
throw new Error(`Security args request failed: ${response.status}`);
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
const data = yield response.json();
|
|
32
|
+
return (_a = data.result) !== null && _a !== void 0 ? _a : data;
|
|
31
33
|
});
|
|
32
34
|
try {
|
|
33
35
|
return yield makeRequest();
|
|
@@ -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;
|
|
@@ -56,7 +56,7 @@ function getConnectedBorderRadius(baseRadius, position, isConnected) {
|
|
|
56
56
|
return baseRadius;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
function addFocusHandlers(element, styles, onFocus, onBlur) {
|
|
59
|
+
function addFocusHandlers(element, styles, position, onFocus, onBlur) {
|
|
60
60
|
element.addEventListener('focus', () => {
|
|
61
61
|
if (styles.focus) {
|
|
62
62
|
Object.assign(element.style, styles.focus);
|
|
@@ -64,7 +64,28 @@ function addFocusHandlers(element, styles, onFocus, onBlur) {
|
|
|
64
64
|
onFocus === null || onFocus === void 0 ? void 0 : onFocus();
|
|
65
65
|
});
|
|
66
66
|
element.addEventListener('blur', () => {
|
|
67
|
-
|
|
67
|
+
const isConnected = styles.container.gap === '0';
|
|
68
|
+
if (isConnected && position) {
|
|
69
|
+
element.style.borderTop = styles.input.border;
|
|
70
|
+
element.style.borderBottom = styles.input.border;
|
|
71
|
+
switch (position) {
|
|
72
|
+
case 'left':
|
|
73
|
+
element.style.borderLeft = styles.input.border;
|
|
74
|
+
element.style.borderRight = 'none';
|
|
75
|
+
break;
|
|
76
|
+
case 'middle':
|
|
77
|
+
element.style.borderLeft = styles.input.border;
|
|
78
|
+
element.style.borderRight = 'none';
|
|
79
|
+
break;
|
|
80
|
+
case 'right':
|
|
81
|
+
element.style.borderLeft = styles.input.border;
|
|
82
|
+
element.style.borderRight = styles.input.border;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
element.style.border = styles.input.border;
|
|
88
|
+
}
|
|
68
89
|
element.style.outline = '';
|
|
69
90
|
element.style.boxShadow = '';
|
|
70
91
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
package/dist/tokenize/types.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export type PaymentMethodType = 'credit_card' | 'bank_account' | 'paypal' | 'apple_pay' | 'google_pay';
|
|
2
2
|
export type PaymentMethodMode = 'credit_card' | 'bank_account' | 'paypal';
|
|
3
|
+
export type BackendName = 'spreedly' | 'card_connect' | 'iats' | 'paypal_checkout';
|
|
3
4
|
export interface PaymentGateway {
|
|
4
5
|
id: string;
|
|
5
|
-
backendName:
|
|
6
|
+
backendName: BackendName;
|
|
6
7
|
gatewayType?: string;
|
|
7
8
|
name: string;
|
|
8
9
|
config?: {
|
package/dist/typeAdapters.js
CHANGED
|
@@ -111,16 +111,18 @@ function buildCashPaymentPayload(organizationId, input) {
|
|
|
111
111
|
utmFields.utm_term = input.utm.term;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
+
let remainingMeta = input.customerMeta
|
|
115
|
+
? Object.assign({}, input.customerMeta) : {};
|
|
114
116
|
if (input.customerMeta) {
|
|
115
117
|
[1, 2, 3, 4, 5].forEach((customNoteIndex) => {
|
|
116
118
|
const key = `custom_note_${customNoteIndex}`;
|
|
117
|
-
if (
|
|
118
|
-
donationOptions[key] =
|
|
119
|
-
delete
|
|
119
|
+
if (remainingMeta[key]) {
|
|
120
|
+
donationOptions[key] = remainingMeta[key];
|
|
121
|
+
delete remainingMeta[key];
|
|
120
122
|
}
|
|
121
123
|
});
|
|
122
124
|
}
|
|
123
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, donationOptions), billingAddress), billingContact), payment), utmFields), { customer_meta:
|
|
125
|
+
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 });
|
|
124
126
|
}
|
|
125
127
|
function buildDonationResult(response) {
|
|
126
128
|
let campaign;
|