@idonatedev/idonate-sdk 1.2.0-dev18 → 1.2.0-dev19
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 +2 -0
- package/dist/esm/tokenize/CardConnectTokenizer.js +119 -43
- package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +2 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.js +38 -31
- package/dist/esm/tokenize/styles.js +14 -1
- package/dist/esm/tokenize/tokenizer-utils.d.ts +3 -0
- package/dist/esm/tokenize/tokenizer-utils.js +53 -0
- package/dist/esm/tokenize/types.d.ts +17 -0
- package/dist/tokenize/CardConnectTokenizer.d.ts +2 -0
- package/dist/tokenize/CardConnectTokenizer.js +118 -42
- package/dist/tokenize/SpreedlyTokenizer.d.ts +2 -0
- package/dist/tokenize/SpreedlyTokenizer.js +37 -30
- package/dist/tokenize/styles.js +14 -1
- package/dist/tokenize/tokenizer-utils.d.ts +3 -0
- package/dist/tokenize/tokenizer-utils.js +56 -0
- package/dist/tokenize/types.d.ts +17 -0
- package/package.json +1 -1
- package/umd/idonate-sdk.js +1 -1
|
@@ -32,17 +32,30 @@ export const DEFAULT_UNIFIED_STYLES = {
|
|
|
32
32
|
fontSize: '',
|
|
33
33
|
textAlign: '',
|
|
34
34
|
},
|
|
35
|
+
label: {
|
|
36
|
+
show: false,
|
|
37
|
+
fontSize: '0.875rem',
|
|
38
|
+
fontWeight: 'bold',
|
|
39
|
+
fontFamily: '',
|
|
40
|
+
color: '#333',
|
|
41
|
+
marginBottom: '0.25rem',
|
|
42
|
+
},
|
|
35
43
|
};
|
|
36
44
|
export function mergeStyles(defaults, userStyles) {
|
|
37
45
|
if (!userStyles)
|
|
38
46
|
return defaults;
|
|
39
|
-
|
|
47
|
+
const merged = {
|
|
40
48
|
input: Object.assign(Object.assign({}, defaults.input), userStyles.input),
|
|
41
49
|
focus: Object.assign(Object.assign({}, defaults.focus), userStyles.focus),
|
|
42
50
|
error: Object.assign(Object.assign({}, defaults.error), userStyles.error),
|
|
43
51
|
container: Object.assign(Object.assign({}, defaults.container), userStyles.container),
|
|
44
52
|
twoLine: Object.assign(Object.assign({}, defaults.twoLine), userStyles.twoLine),
|
|
53
|
+
label: Object.assign(Object.assign({}, defaults.label), userStyles.label),
|
|
45
54
|
};
|
|
55
|
+
if (!merged.label.fontFamily) {
|
|
56
|
+
merged.label.fontFamily = merged.input.fontFamily;
|
|
57
|
+
}
|
|
58
|
+
return merged;
|
|
46
59
|
}
|
|
47
60
|
export function getContainerStylesForLayout(baseStyles, layout = 'single-line') {
|
|
48
61
|
if (layout === 'two-line') {
|
|
@@ -7,6 +7,8 @@ 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
9
|
export declare function addFocusHandlers(element: HTMLElement, styles: TokenizerStylingComplete, position?: 'left' | 'middle' | 'right', onFocus?: () => void, onBlur?: () => void): void;
|
|
10
|
+
export declare function createFieldLabel(text: string, forId: string, styles: TokenizerStylingComplete): HTMLLabelElement;
|
|
11
|
+
export declare function wrapFieldWithLabel(field: HTMLElement, labelText: string, styles: TokenizerStylingComplete): HTMLElement;
|
|
10
12
|
export declare function createFieldContainer(id: string, flex: string, minWidth?: string, maxWidth?: string): HTMLDivElement;
|
|
11
13
|
export declare function createInputElement(id: string, type: string, placeholder: string, maxLength?: number): HTMLInputElement;
|
|
12
14
|
export declare function validateRoutingNumber(routingNumber: string): boolean;
|
|
@@ -17,3 +19,4 @@ export declare function validateInstitutionNumber(institutionNumber: string): bo
|
|
|
17
19
|
export declare function validateTransitNumber(transitNumber: string): boolean;
|
|
18
20
|
export declare function validateCanadianAccountNumber(accountNumber: string): boolean;
|
|
19
21
|
export declare function formatCanadianRoutingNumber(institutionNumber: string, transitNumber: string): string;
|
|
22
|
+
export declare function cssLengthToPixels(value: string): number;
|
|
@@ -74,6 +74,43 @@ export function addFocusHandlers(element, styles, position, onFocus, onBlur) {
|
|
|
74
74
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
+
export function createFieldLabel(text, forId, styles) {
|
|
78
|
+
const label = document.createElement('label');
|
|
79
|
+
label.htmlFor = forId;
|
|
80
|
+
label.textContent = text;
|
|
81
|
+
label.style.display = styles.label.show ? 'block' : 'none';
|
|
82
|
+
label.style.fontSize = styles.label.fontSize;
|
|
83
|
+
label.style.fontWeight = styles.label.fontWeight;
|
|
84
|
+
label.style.fontFamily = styles.label.fontFamily;
|
|
85
|
+
label.style.color = styles.label.color;
|
|
86
|
+
label.style.marginBottom = styles.label.marginBottom;
|
|
87
|
+
return label;
|
|
88
|
+
}
|
|
89
|
+
export function wrapFieldWithLabel(field, labelText, styles) {
|
|
90
|
+
if (!styles.label.show)
|
|
91
|
+
return field;
|
|
92
|
+
const wrapper = document.createElement('div');
|
|
93
|
+
wrapper.style.display = 'flex';
|
|
94
|
+
wrapper.style.flexDirection = 'column';
|
|
95
|
+
if (field.style.flex) {
|
|
96
|
+
wrapper.style.flex = field.style.flex;
|
|
97
|
+
field.style.flex = '';
|
|
98
|
+
}
|
|
99
|
+
if (field.style.minWidth) {
|
|
100
|
+
wrapper.style.minWidth = field.style.minWidth;
|
|
101
|
+
}
|
|
102
|
+
if (field.style.maxWidth) {
|
|
103
|
+
wrapper.style.maxWidth = field.style.maxWidth;
|
|
104
|
+
}
|
|
105
|
+
if (field.style.flexBasis) {
|
|
106
|
+
wrapper.style.flexBasis = field.style.flexBasis;
|
|
107
|
+
field.style.flexBasis = '';
|
|
108
|
+
}
|
|
109
|
+
const label = createFieldLabel(labelText, field.id, styles);
|
|
110
|
+
wrapper.appendChild(label);
|
|
111
|
+
wrapper.appendChild(field);
|
|
112
|
+
return wrapper;
|
|
113
|
+
}
|
|
77
114
|
export function createFieldContainer(id, flex, minWidth, maxWidth) {
|
|
78
115
|
const div = document.createElement('div');
|
|
79
116
|
div.id = id;
|
|
@@ -158,3 +195,19 @@ export function formatCanadianRoutingNumber(institutionNumber, transitNumber) {
|
|
|
158
195
|
const transit = transitNumber.replace(/\D/g, '').padStart(5, '0');
|
|
159
196
|
return '0' + institution + transit;
|
|
160
197
|
}
|
|
198
|
+
export function cssLengthToPixels(value) {
|
|
199
|
+
const num = parseFloat(value);
|
|
200
|
+
if (isNaN(num)) {
|
|
201
|
+
console.warn(`[cssLengthToPixels] Cannot parse "${value}", defaulting to 14px`);
|
|
202
|
+
return 14;
|
|
203
|
+
}
|
|
204
|
+
if (value.endsWith('rem'))
|
|
205
|
+
return num * 16;
|
|
206
|
+
if (value.endsWith('pt'))
|
|
207
|
+
return num * 1.333;
|
|
208
|
+
if (value.endsWith('px') || !value.match(/[a-z%]/i))
|
|
209
|
+
return num;
|
|
210
|
+
console.warn(`[cssLengthToPixels] Unsupported unit in "${value}". ` +
|
|
211
|
+
`Only px, rem, and pt are supported. Using ${num}px as approximation.`);
|
|
212
|
+
return num;
|
|
213
|
+
}
|
|
@@ -21,6 +21,15 @@ export interface TokenizerContainer {
|
|
|
21
21
|
enableTestMode?: boolean;
|
|
22
22
|
layout?: 'single-line' | 'two-line' | 'responsive';
|
|
23
23
|
responsiveBreakpoint?: number;
|
|
24
|
+
placeholders?: {
|
|
25
|
+
cardNumber?: string;
|
|
26
|
+
expiry?: string;
|
|
27
|
+
expiryMonth?: string;
|
|
28
|
+
expiryYear?: string;
|
|
29
|
+
cvv?: string;
|
|
30
|
+
routingNumber?: string;
|
|
31
|
+
accountNumber?: string;
|
|
32
|
+
};
|
|
24
33
|
}
|
|
25
34
|
export interface TokenizerStylingComplete {
|
|
26
35
|
input: {
|
|
@@ -59,6 +68,14 @@ export interface TokenizerStylingComplete {
|
|
|
59
68
|
fontSize: string;
|
|
60
69
|
textAlign: string;
|
|
61
70
|
};
|
|
71
|
+
label: {
|
|
72
|
+
show: boolean;
|
|
73
|
+
fontSize: string;
|
|
74
|
+
fontWeight: string;
|
|
75
|
+
fontFamily: string;
|
|
76
|
+
color: string;
|
|
77
|
+
marginBottom: string;
|
|
78
|
+
};
|
|
62
79
|
}
|
|
63
80
|
type DeepPartial<T> = T extends object ? {
|
|
64
81
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
@@ -6,6 +6,7 @@ export declare class CardConnectTokenizer extends Tokenizer {
|
|
|
6
6
|
private iframeUrl;
|
|
7
7
|
private containerId;
|
|
8
8
|
private layout;
|
|
9
|
+
private customPlaceholders?;
|
|
9
10
|
private iframe;
|
|
10
11
|
private messageHandler?;
|
|
11
12
|
private expectedOrigin;
|
|
@@ -49,6 +50,7 @@ export declare class CardConnectTokenizer extends Tokenizer {
|
|
|
49
50
|
get tokenizationMode(): 'auto' | 'manual';
|
|
50
51
|
private handleMessage;
|
|
51
52
|
private handleValidationMessage;
|
|
53
|
+
private static measureCvvLabelMarginLeft;
|
|
52
54
|
private static generateIframeUrl;
|
|
53
55
|
private static createIframe;
|
|
54
56
|
private static generateCardConnectCss;
|
|
@@ -16,11 +16,12 @@ const styles_1 = require("./styles");
|
|
|
16
16
|
const tokenizer_constants_1 = require("./tokenizer-constants");
|
|
17
17
|
const tokenizer_utils_1 = require("./tokenizer-utils");
|
|
18
18
|
class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
19
|
-
constructor(iframe, iframeUrl, containerId, mode = 'credit_card', enableTestMode = false, layout = 'single-line') {
|
|
19
|
+
constructor(iframe, iframeUrl, containerId, mode = 'credit_card', enableTestMode = false, layout = 'single-line', customPlaceholders) {
|
|
20
20
|
super();
|
|
21
21
|
this.iframeUrl = iframeUrl;
|
|
22
22
|
this.containerId = containerId;
|
|
23
23
|
this.layout = layout;
|
|
24
|
+
this.customPlaceholders = customPlaceholders;
|
|
24
25
|
this.enableTestMode = false;
|
|
25
26
|
this.acceptAutoToken = true;
|
|
26
27
|
this.mode = mode;
|
|
@@ -57,7 +58,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
57
58
|
const mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, container.styling);
|
|
58
59
|
const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, resolvedContainer);
|
|
59
60
|
const iframe = CardConnectTokenizer.createIframe(iframeUrl, mergedStyles);
|
|
60
|
-
const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout);
|
|
61
|
+
const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout, container.placeholders);
|
|
61
62
|
tokenizer.createInternalElements(resolvedContainer);
|
|
62
63
|
yield tokenizer.init();
|
|
63
64
|
return tokenizer;
|
|
@@ -80,19 +81,32 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
createCreditCardFields(containerEl, mergedStyles) {
|
|
84
|
+
var _a;
|
|
83
85
|
this.iframe.style.width = '100%';
|
|
86
|
+
const hasLabels = ((_a = mergedStyles.label) === null || _a === void 0 ? void 0 : _a.show) &&
|
|
87
|
+
(this.layout === 'two-line' || this.layout === 'responsive');
|
|
88
|
+
const inputHeight = mergedStyles.input.height || '40px';
|
|
84
89
|
if (this.layout === 'two-line' || this.layout === 'responsive') {
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
if (hasLabels) {
|
|
91
|
+
const labelFontPx = (0, tokenizer_utils_1.cssLengthToPixels)(mergedStyles.label.fontSize);
|
|
92
|
+
const labelMarginPx = parseFloat(mergedStyles.label.marginBottom) || 0;
|
|
93
|
+
const labelRowHeight = Math.ceil(labelFontPx * 1.2) + labelMarginPx;
|
|
94
|
+
const extraHeight = Math.ceil(labelRowHeight * 2) + 34;
|
|
95
|
+
this.iframe.style.height = `calc(${inputHeight} * 2 + ${extraHeight}px)`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.iframe.style.height = `calc((${inputHeight}) * 2 + 10px)`;
|
|
99
|
+
}
|
|
87
100
|
}
|
|
88
101
|
else {
|
|
89
|
-
this.iframe.style.height =
|
|
102
|
+
this.iframe.style.height = inputHeight;
|
|
90
103
|
}
|
|
91
104
|
this.iframe.style.border = 'none';
|
|
92
105
|
this.iframe.style.display = 'block';
|
|
93
106
|
containerEl.appendChild(this.iframe);
|
|
94
107
|
}
|
|
95
108
|
createBankAccountFields(containerEl, mergedStyles) {
|
|
109
|
+
var _a, _b, _c, _d;
|
|
96
110
|
this.iframe.style.display = 'none';
|
|
97
111
|
if (this.layout === 'two-line') {
|
|
98
112
|
this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
|
|
@@ -101,45 +115,45 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
101
115
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
|
|
102
116
|
});
|
|
103
117
|
this.applyInputStyles(this.accountTypeEl, mergedStyles, 'left');
|
|
104
|
-
containerEl.appendChild(this.accountTypeEl);
|
|
105
|
-
this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
118
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.accountTypeEl, 'Account Type', mergedStyles));
|
|
119
|
+
this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', ((_a = this.customPlaceholders) === null || _a === void 0 ? void 0 : _a.routingNumber) || 'Routing *', 9);
|
|
106
120
|
Object.assign(this.routingNumberEl.style, {
|
|
107
121
|
flex: '1',
|
|
108
122
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
109
123
|
});
|
|
110
124
|
this.applyInputStyles(this.routingNumberEl, mergedStyles, 'right');
|
|
111
|
-
containerEl.appendChild(this.routingNumberEl);
|
|
112
|
-
this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
125
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.routingNumberEl, 'Routing Number', mergedStyles));
|
|
126
|
+
this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', ((_b = this.customPlaceholders) === null || _b === void 0 ? void 0 : _b.accountNumber) || 'Account Number *', 17);
|
|
113
127
|
Object.assign(this.accountNumberEl.style, {
|
|
114
128
|
flex: '1',
|
|
115
129
|
flexBasis: '100%',
|
|
116
130
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
|
|
117
131
|
});
|
|
118
132
|
this.applyInputStyles(this.accountNumberEl, mergedStyles);
|
|
119
|
-
containerEl.appendChild(this.accountNumberEl);
|
|
133
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.accountNumberEl, 'Account Number', mergedStyles));
|
|
120
134
|
}
|
|
121
135
|
else {
|
|
122
|
-
this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', 'Routing *', 9);
|
|
136
|
+
this.routingNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-routing`, 'text', ((_c = this.customPlaceholders) === null || _c === void 0 ? void 0 : _c.routingNumber) || 'Routing *', 9);
|
|
123
137
|
Object.assign(this.routingNumberEl.style, {
|
|
124
138
|
flex: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.flex,
|
|
125
139
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.routingNumber.minWidth,
|
|
126
140
|
});
|
|
127
141
|
this.applyInputStyles(this.routingNumberEl, mergedStyles, 'left');
|
|
128
|
-
containerEl.appendChild(this.routingNumberEl);
|
|
129
|
-
this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', 'Account Number *', 17);
|
|
142
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.routingNumberEl, 'Routing Number', mergedStyles));
|
|
143
|
+
this.accountNumberEl = (0, tokenizer_utils_1.createInputElement)(`${this.containerId}-account`, 'text', ((_d = this.customPlaceholders) === null || _d === void 0 ? void 0 : _d.accountNumber) || 'Account Number *', 17);
|
|
130
144
|
Object.assign(this.accountNumberEl.style, {
|
|
131
145
|
flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.flex,
|
|
132
146
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountNumber.minWidth,
|
|
133
147
|
});
|
|
134
148
|
this.applyInputStyles(this.accountNumberEl, mergedStyles, 'middle');
|
|
135
|
-
containerEl.appendChild(this.accountNumberEl);
|
|
149
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.accountNumberEl, 'Account Number', mergedStyles));
|
|
136
150
|
this.accountTypeEl = (0, tokenizer_utils_1.createAccountTypeSelect)(`${this.containerId}-account-type`);
|
|
137
151
|
Object.assign(this.accountTypeEl.style, {
|
|
138
152
|
flex: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.flex,
|
|
139
153
|
minWidth: tokenizer_constants_1.BANK_FIELD_FLEX.accountType.minWidth,
|
|
140
154
|
});
|
|
141
155
|
this.applyInputStyles(this.accountTypeEl, mergedStyles, 'right');
|
|
142
|
-
containerEl.appendChild(this.accountTypeEl);
|
|
156
|
+
containerEl.appendChild((0, tokenizer_utils_1.wrapFieldWithLabel)(this.accountTypeEl, 'Account Type', mergedStyles));
|
|
143
157
|
}
|
|
144
158
|
this.mergedStyles = mergedStyles;
|
|
145
159
|
this.currentValidationState = {
|
|
@@ -237,8 +251,6 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
237
251
|
window.addEventListener('message', this.messageHandler);
|
|
238
252
|
this.iframe.onload = () => {
|
|
239
253
|
clearTimeout(timeout);
|
|
240
|
-
if (this.enableTestMode && this.mode === 'credit_card') {
|
|
241
|
-
}
|
|
242
254
|
this.emit('ready');
|
|
243
255
|
resolve();
|
|
244
256
|
};
|
|
@@ -684,7 +696,34 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
684
696
|
this.emit('validation', this.currentValidationState);
|
|
685
697
|
}
|
|
686
698
|
}
|
|
699
|
+
static measureCvvLabelMarginLeft(monthWidth, yearWidth, cvvMarginLeft) {
|
|
700
|
+
var _a;
|
|
701
|
+
const targetCvvX = monthWidth + 4 + 4 + yearWidth + 12 + cvvMarginLeft;
|
|
702
|
+
const host = document.createElement('div');
|
|
703
|
+
host.style.cssText =
|
|
704
|
+
'position:absolute;visibility:hidden;left:0;top:0;width:9999px;height:0;overflow:hidden;';
|
|
705
|
+
document.body.appendChild(host);
|
|
706
|
+
const shadow = host.attachShadow({ mode: 'open' });
|
|
707
|
+
shadow.innerHTML = [
|
|
708
|
+
'<input type="text" size="2" style="margin-right:4px">',
|
|
709
|
+
'<label>/</label>',
|
|
710
|
+
'<input type="text" size="4" style="margin-left:4px;margin-right:12px">',
|
|
711
|
+
'<input type="tel" size="5">',
|
|
712
|
+
].join('');
|
|
713
|
+
const inputs = shadow.querySelectorAll('input');
|
|
714
|
+
const hostX = host.getBoundingClientRect().x;
|
|
715
|
+
const cvvRect = (_a = inputs[2]) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
716
|
+
const defaultCvvX = cvvRect ? cvvRect.x - hostX : -1;
|
|
717
|
+
document.body.removeChild(host);
|
|
718
|
+
if (defaultCvvX <= 0 || defaultCvvX > 500) {
|
|
719
|
+
console.warn('[CardConnect] CVV measurement out of range, using fallback margin-left:100px');
|
|
720
|
+
return 100;
|
|
721
|
+
}
|
|
722
|
+
const predictedLabelLeft = defaultCvvX + 8;
|
|
723
|
+
return Math.round(targetCvvX - predictedLabelLeft);
|
|
724
|
+
}
|
|
687
725
|
static generateIframeUrl(baseUrl, container) {
|
|
726
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
688
727
|
const params = new URLSearchParams({
|
|
689
728
|
invalidinputevent: 'true',
|
|
690
729
|
enhancedresponse: 'true',
|
|
@@ -693,30 +732,46 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
693
732
|
formatinput: 'true',
|
|
694
733
|
unique: 'true',
|
|
695
734
|
norsa: 'true',
|
|
696
|
-
placeholder: 'Card Number *',
|
|
697
|
-
placeholdercvv: 'CVV',
|
|
735
|
+
placeholder: ((_a = container.placeholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || 'Card Number *',
|
|
736
|
+
placeholdercvv: ((_b = container.placeholders) === null || _b === void 0 ? void 0 : _b.cvv) || 'CVV',
|
|
698
737
|
invalidcreditcardevent: 'true',
|
|
699
738
|
invalidexpiry: 'true',
|
|
700
739
|
invalidcvv: 'true',
|
|
701
740
|
});
|
|
741
|
+
const mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, container.styling);
|
|
742
|
+
const showLabelsInUrl = ((_c = mergedStyles.label) === null || _c === void 0 ? void 0 : _c.show) && container.layout === 'two-line';
|
|
743
|
+
if (showLabelsInUrl) {
|
|
744
|
+
params.set('cardlabel', 'Card Number');
|
|
745
|
+
params.set('expirylabel', 'Expiration');
|
|
746
|
+
params.set('cvvlabel', 'CVV');
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
params.set('cardlabel', '');
|
|
750
|
+
params.set('expirylabel', '');
|
|
751
|
+
params.set('cvvlabel', '');
|
|
752
|
+
}
|
|
702
753
|
if (container.layout === 'two-line') {
|
|
703
754
|
params.set('useexpiryfield', 'true');
|
|
704
755
|
params.set('orientation', 'horizontal');
|
|
705
|
-
params.set('placeholdermonth', 'MM');
|
|
706
|
-
params.set('placeholderyear', 'YYYY');
|
|
756
|
+
params.set('placeholdermonth', ((_d = container.placeholders) === null || _d === void 0 ? void 0 : _d.expiryMonth) || 'MM');
|
|
757
|
+
params.set('placeholderyear', ((_e = container.placeholders) === null || _e === void 0 ? void 0 : _e.expiryYear) || 'YYYY');
|
|
707
758
|
}
|
|
708
759
|
else {
|
|
709
760
|
params.set('orientation', 'horizontal');
|
|
710
|
-
params.set('placeholdermonth', 'MM');
|
|
711
|
-
params.set('placeholderyear', 'YYYY');
|
|
761
|
+
params.set('placeholdermonth', ((_f = container.placeholders) === null || _f === void 0 ? void 0 : _f.expiryMonth) || 'MM');
|
|
762
|
+
params.set('placeholderyear', ((_g = container.placeholders) === null || _g === void 0 ? void 0 : _g.expiryYear) || 'YYYY');
|
|
712
763
|
}
|
|
713
|
-
const mergedStyles = (0, styles_1.mergeStyles)(styles_1.DEFAULT_UNIFIED_STYLES, container.styling);
|
|
714
764
|
const isDesktopSafari = typeof navigator !== 'undefined' &&
|
|
715
765
|
/Safari/.test(navigator.userAgent) &&
|
|
716
766
|
/Apple Computer/.test(navigator.vendor) &&
|
|
717
767
|
!/Chrome/.test(navigator.userAgent) &&
|
|
718
768
|
!/Mobile/.test(navigator.userAgent);
|
|
719
|
-
const
|
|
769
|
+
const showLabels = ((_h = mergedStyles.label) === null || _h === void 0 ? void 0 : _h.show) && container.layout === 'two-line';
|
|
770
|
+
let cvvLabelMarginLeft;
|
|
771
|
+
if (showLabels && typeof document !== 'undefined') {
|
|
772
|
+
cvvLabelMarginLeft = CardConnectTokenizer.measureCvvLabelMarginLeft(60, 80, 40);
|
|
773
|
+
}
|
|
774
|
+
const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari, cvvLabelMarginLeft);
|
|
720
775
|
const queryPairs = [];
|
|
721
776
|
params.forEach((value, key) => {
|
|
722
777
|
queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
@@ -731,7 +786,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
731
786
|
iframe.style.width = '100%';
|
|
732
787
|
iframe.style.height = styles.input.height;
|
|
733
788
|
iframe.style.border = 'none';
|
|
734
|
-
iframe.style.overflow = '
|
|
789
|
+
iframe.style.overflow = '';
|
|
735
790
|
iframe.style.display = 'block';
|
|
736
791
|
iframe.style.minWidth = '0';
|
|
737
792
|
if (styles.container) {
|
|
@@ -749,18 +804,30 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
749
804
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
|
|
750
805
|
return iframe;
|
|
751
806
|
}
|
|
752
|
-
static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false) {
|
|
753
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
807
|
+
static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false, cvvLabelMarginLeft) {
|
|
808
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
754
809
|
const css = [];
|
|
755
|
-
|
|
756
|
-
|
|
810
|
+
const showLabelsInIframe = ((_a = styles.label) === null || _a === void 0 ? void 0 : _a.show) && layout === 'two-line';
|
|
811
|
+
if (showLabelsInIframe) {
|
|
812
|
+
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}`;
|
|
813
|
+
css.push(`label{${labelCss};}`);
|
|
814
|
+
css.push(`label[for="ccexpiryfieldyear"]{display:none;}`);
|
|
815
|
+
css.push(`br{line-height:0;font-size:0;margin:0;}`);
|
|
816
|
+
css.push(`input,select{margin-top:0;margin-bottom:0;}`);
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
757
819
|
css.push('label{display:none;}');
|
|
758
|
-
|
|
820
|
+
}
|
|
821
|
+
if (layout === 'two-line') {
|
|
822
|
+
css.push('html,body{margin:0;padding:0;overflow:hidden;}');
|
|
823
|
+
css.push('form{margin:0;padding:0;width:100%;box-sizing:border-box;}');
|
|
824
|
+
if (!showLabelsInIframe) {
|
|
825
|
+
css.push('br{display:none;}');
|
|
826
|
+
}
|
|
759
827
|
}
|
|
760
828
|
else {
|
|
761
829
|
css.push('body{margin:0;padding:0;display:flex;align-items:center;}');
|
|
762
830
|
css.push('form{margin:0;padding:0;display:flex;width:100%;align-items:center;}');
|
|
763
|
-
css.push('label{display:none;}');
|
|
764
831
|
css.push('br{display:none;}');
|
|
765
832
|
}
|
|
766
833
|
const isConnected = styles.container.gap === '0';
|
|
@@ -793,13 +860,22 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
793
860
|
}
|
|
794
861
|
if (layout === 'two-line') {
|
|
795
862
|
css.push('input#ccnumfield{width:100%;display:block;margin-bottom:8px;}');
|
|
796
|
-
const twoLinePadding = ((
|
|
797
|
-
const twoLineFontSize = ((
|
|
798
|
-
const twoLineTextAlign = ((
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
863
|
+
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';
|
|
864
|
+
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';
|
|
865
|
+
const twoLineTextAlign = ((_f = styles.twoLine) === null || _f === void 0 ? void 0 : _f.textAlign) || 'left';
|
|
866
|
+
if (showLabelsInIframe) {
|
|
867
|
+
css.push(`input#ccexpiryfieldmonth{width:60px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
868
|
+
css.push(`input#ccexpiryfieldyear{width:80px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
869
|
+
css.push(`input#cccvvfield{width:80px;margin-left:40px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
870
|
+
const labelMargin = cvvLabelMarginLeft !== null && cvvLabelMarginLeft !== void 0 ? cvvLabelMarginLeft : 100;
|
|
871
|
+
css.push(`label#cccvvlabel{margin-left:${labelMargin}px;}`);
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
css.push(`input#ccexpiryfieldmonth{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
875
|
+
css.push(`input#ccexpiryfieldyear{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
876
|
+
css.push(`input#cccvvfield{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
|
|
877
|
+
}
|
|
878
|
+
if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
|
|
803
879
|
css.push(`input{border-radius:${styles.input.borderRadius};}`);
|
|
804
880
|
}
|
|
805
881
|
}
|
|
@@ -808,7 +884,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
808
884
|
css.push('select#ccexpirymonth{width:16%;margin:0;margin-right:-12px;}');
|
|
809
885
|
css.push('select#ccexpiryyear{width:20%;}');
|
|
810
886
|
css.push('input#cccvvfield{width:20%;margin:0;margin-left:-12px;}');
|
|
811
|
-
if ((
|
|
887
|
+
if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
|
|
812
888
|
css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right:none;}`);
|
|
813
889
|
css.push('select#ccexpirymonth{border-radius:0;border-right:none;}');
|
|
814
890
|
css.push('select#ccexpiryyear{border-radius:0;border-right:none;}');
|
|
@@ -826,7 +902,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
826
902
|
css.push(`select#ccexpirymonth{width:15%;margin-right:${marginRight};}`);
|
|
827
903
|
css.push(`select#ccexpiryyear{width:20%;margin-right:${marginRight};}`);
|
|
828
904
|
css.push('input#cccvvfield{width:15%;}');
|
|
829
|
-
if ((
|
|
905
|
+
if ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.borderRadius) {
|
|
830
906
|
css.push(`input,select{border-radius:${styles.input.borderRadius};}`);
|
|
831
907
|
}
|
|
832
908
|
}
|
|
@@ -842,7 +918,7 @@ class CardConnectTokenizer extends Tokenizer_1.Tokenizer {
|
|
|
842
918
|
if (focusStyles.length > 0) {
|
|
843
919
|
css.push(`input:focus{${focusStyles.join(';')};}`);
|
|
844
920
|
css.push(`select:focus{${focusStyles.join(';')};}`);
|
|
845
|
-
if (isConnected && ((
|
|
921
|
+
if (isConnected && ((_k = styles.input) === null || _k === void 0 ? void 0 : _k.border)) {
|
|
846
922
|
css.push(`input#ccnumfield:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
847
923
|
css.push(`select#ccexpirymonth:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
848
924
|
css.push(`select#ccexpiryyear:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
|
|
@@ -6,6 +6,7 @@ export declare class SpreedlyTokenizer extends Tokenizer {
|
|
|
6
6
|
private environmentKey;
|
|
7
7
|
private containerId;
|
|
8
8
|
private layout;
|
|
9
|
+
private customPlaceholders?;
|
|
9
10
|
private spreedly;
|
|
10
11
|
private currentValidationState;
|
|
11
12
|
private mergedStyles;
|
|
@@ -63,6 +64,7 @@ export declare class SpreedlyTokenizer extends Tokenizer {
|
|
|
63
64
|
private updateOverallValidation;
|
|
64
65
|
private handleFieldEvent;
|
|
65
66
|
private createInternalElements;
|
|
67
|
+
private appendField;
|
|
66
68
|
private createCreditCardFields;
|
|
67
69
|
private createBankAccountFields;
|
|
68
70
|
private createUSBankAccountFields;
|