@idonatedev/idonate-sdk 1.2.0-dev17 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CLIENT_HEADERS = exports.CARD_CONNECT_DEFAULT_STYLE = exports.DEFAULT_APP_NAME = exports.DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL = exports.FALLBACK_CF_TURNSTILE_SITE_KEY = exports.FALLBACK_PC_SCRIPT_ID = exports.FALLBACK_PC_SCRIPT_URL = exports.SANDBOX_APPLE_PAY_URL = exports.APPLE_PAY_URL = exports.SPREEDLY_TOKENIZER_URL = exports.SANDBOX_CARD_CONNECT_BASE_URL = exports.PRODUCTION_CARD_CONNECT_BASE_URL = exports.SANDBOX_BASE_URL = exports.PRODUCTION_BASE_URL = exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = '1.2.0-dev17';
4
+ exports.SDK_VERSION = '1.2.0-dev19';
5
5
  exports.PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
6
6
  exports.SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
7
7
  exports.PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
@@ -1,4 +1,4 @@
1
- export const SDK_VERSION = '1.2.0-dev17';
1
+ export const SDK_VERSION = '1.2.0-dev19';
2
2
  export const PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
3
3
  export const SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
4
4
  export const PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
@@ -111,10 +111,10 @@ export default class iDonateClient {
111
111
  if (!this.allowTransaction) {
112
112
  throw new Error('Wow, that was fast - try again');
113
113
  }
114
- if (!donation.embedId) {
115
- donation.embedId = this.embedId;
116
- }
117
- const payload = buildCashPaymentPayload(this.organizationId, donation);
114
+ const donationWithEmbed = donation.embedId
115
+ ? donation
116
+ : Object.assign(Object.assign({}, donation), { embedId: this.embedId });
117
+ const payload = buildCashPaymentPayload(this.organizationId, donationWithEmbed);
118
118
  const fetchCall = (clearanceToken) => fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment`, {
119
119
  method: 'POST',
120
120
  headers: Object.assign(Object.assign(Object.assign({}, CLIENT_HEADERS), (clearanceToken ? { 'cf-validation-token': clearanceToken } : {})), { 'User-Agent': CLIENT_HEADERS['User-Agent'] + ' source:' + this.config.client }),
@@ -142,10 +142,10 @@ export default class iDonateClient {
142
142
  });
143
143
  }
144
144
  createPaymentMethod(paymentMethod) {
145
- if (!paymentMethod.embedId) {
146
- paymentMethod.embedId = this.embedId;
147
- }
148
- return shared.createPaymentMethod(paymentMethod, this.config);
145
+ const pmWithEmbed = paymentMethod.embedId
146
+ ? paymentMethod
147
+ : Object.assign(Object.assign({}, paymentMethod), { embedId: this.embedId });
148
+ return shared.createPaymentMethod(pmWithEmbed, this.config);
149
149
  }
150
150
  setOrganizationId(organizationId) {
151
151
  this.currentOrganizationId = organizationId;
@@ -157,7 +157,16 @@ export default class iDonateClient {
157
157
  return new Promise((resolve, reject) => {
158
158
  setTimeout(() => {
159
159
  let pollHandle;
160
+ let attempts = 0;
161
+ const maxAttempts = 90;
160
162
  pollHandle = setInterval(() => {
163
+ attempts++;
164
+ if (attempts > maxAttempts) {
165
+ clearInterval(pollHandle);
166
+ pollHandle = null;
167
+ reject(new ClientError('Donation processing timed out. Please check your email for a receipt or contact support.'));
168
+ return;
169
+ }
161
170
  fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment/${donationId}/payment_status`, {
162
171
  method: 'GET',
163
172
  headers: {
@@ -174,6 +183,7 @@ export default class iDonateClient {
174
183
  }
175
184
  if (response.error) {
176
185
  reject(new ClientError(response.error));
186
+ return;
177
187
  }
178
188
  resolve(buildDonationResult({
179
189
  _raw_response: Object.assign({ campaign: null, designation: {}, donor: {}, form_data: {}, id: null, schedule: {}, transaction: {} }, response),
@@ -61,9 +61,16 @@ export class RecaptchaElement {
61
61
  this.widgetId = lib.render(this.container, Object.assign(Object.assign({}, this.params), { callback: (token) => {
62
62
  var _a;
63
63
  this.resolvedToken = token;
64
- (_a = this.executeResolveQueue.pop()) === null || _a === void 0 ? void 0 : _a(token);
64
+ (_a = this.executeResolveQueue.shift()) === null || _a === void 0 ? void 0 : _a.resolve(token);
65
65
  }, 'expired-callback': () => {
66
66
  this.resolvedToken = undefined;
67
+ }, 'error-callback': () => {
68
+ var _a;
69
+ this.resolvedToken = undefined;
70
+ const error = new Error('reCAPTCHA encountered an error. Please try again.');
71
+ while (this.executeResolveQueue.length > 0) {
72
+ (_a = this.executeResolveQueue.shift()) === null || _a === void 0 ? void 0 : _a.reject(error);
73
+ }
67
74
  } }));
68
75
  });
69
76
  }
@@ -77,7 +84,7 @@ export class RecaptchaElement {
77
84
  ? resolve(response)
78
85
  : reject(new Error('checkbox recaptcha is not checked'));
79
86
  }
80
- this.executeResolveQueue.push(resolve);
87
+ this.executeResolveQueue.push({ resolve, reject });
81
88
  if (this.resolvedToken !== undefined) {
82
89
  this.resolvedToken = undefined;
83
90
  lib.reset(this.widgetId);
@@ -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;
@@ -11,13 +11,14 @@ import { Tokenizer } from './Tokenizer';
11
11
  import { TokenizationError, } from './types';
12
12
  import { DEFAULT_UNIFIED_STYLES, mergeStyles, getContainerStylesForLayout, } from './styles';
13
13
  import { INIT_TIMEOUT, TOKENIZE_TIMEOUT, BANK_FIELD_FLEX, RESPONSIVE_BREAKPOINT, } from './tokenizer-constants';
14
- import { createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, } from './tokenizer-utils';
14
+ import { createInputElement, validateRoutingNumber, validateAccountNumber, createAccountTypeSelect, wrapFieldWithLabel, cssLengthToPixels, } from './tokenizer-utils';
15
15
  export class CardConnectTokenizer extends Tokenizer {
16
- 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) {
17
17
  super();
18
18
  this.iframeUrl = iframeUrl;
19
19
  this.containerId = containerId;
20
20
  this.layout = layout;
21
+ this.customPlaceholders = customPlaceholders;
21
22
  this.enableTestMode = false;
22
23
  this.acceptAutoToken = true;
23
24
  this.mode = mode;
@@ -54,7 +55,7 @@ export class CardConnectTokenizer extends Tokenizer {
54
55
  const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
55
56
  const iframeUrl = CardConnectTokenizer.generateIframeUrl(baseUrl, resolvedContainer);
56
57
  const iframe = CardConnectTokenizer.createIframe(iframeUrl, mergedStyles);
57
- const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout);
58
+ const tokenizer = new CardConnectTokenizer(iframe, iframeUrl, container.containerId, container.mode || 'credit_card', container.enableTestMode || false, effectiveLayout, container.placeholders);
58
59
  tokenizer.createInternalElements(resolvedContainer);
59
60
  yield tokenizer.init();
60
61
  return tokenizer;
@@ -77,19 +78,32 @@ export class CardConnectTokenizer extends Tokenizer {
77
78
  }
78
79
  }
79
80
  createCreditCardFields(containerEl, mergedStyles) {
81
+ var _a;
80
82
  this.iframe.style.width = '100%';
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';
81
86
  if (this.layout === 'two-line' || this.layout === 'responsive') {
82
- const inputHeight = mergedStyles.input.height || '40px';
83
- this.iframe.style.height = `calc((${inputHeight}) * 2 + 10px)`;
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
+ }
84
97
  }
85
98
  else {
86
- this.iframe.style.height = mergedStyles.input.height || '40px';
99
+ this.iframe.style.height = inputHeight;
87
100
  }
88
101
  this.iframe.style.border = 'none';
89
102
  this.iframe.style.display = 'block';
90
103
  containerEl.appendChild(this.iframe);
91
104
  }
92
105
  createBankAccountFields(containerEl, mergedStyles) {
106
+ var _a, _b, _c, _d;
93
107
  this.iframe.style.display = 'none';
94
108
  if (this.layout === 'two-line') {
95
109
  this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
@@ -98,45 +112,45 @@ export class CardConnectTokenizer extends Tokenizer {
98
112
  minWidth: BANK_FIELD_FLEX.accountType.minWidth,
99
113
  });
100
114
  this.applyInputStyles(this.accountTypeEl, mergedStyles, 'left');
101
- containerEl.appendChild(this.accountTypeEl);
102
- 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);
103
117
  Object.assign(this.routingNumberEl.style, {
104
118
  flex: '1',
105
119
  minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
106
120
  });
107
121
  this.applyInputStyles(this.routingNumberEl, mergedStyles, 'right');
108
- containerEl.appendChild(this.routingNumberEl);
109
- 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);
110
124
  Object.assign(this.accountNumberEl.style, {
111
125
  flex: '1',
112
126
  flexBasis: '100%',
113
127
  minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
114
128
  });
115
129
  this.applyInputStyles(this.accountNumberEl, mergedStyles);
116
- containerEl.appendChild(this.accountNumberEl);
130
+ containerEl.appendChild(wrapFieldWithLabel(this.accountNumberEl, 'Account Number', mergedStyles));
117
131
  }
118
132
  else {
119
- 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);
120
134
  Object.assign(this.routingNumberEl.style, {
121
135
  flex: BANK_FIELD_FLEX.routingNumber.flex,
122
136
  minWidth: BANK_FIELD_FLEX.routingNumber.minWidth,
123
137
  });
124
138
  this.applyInputStyles(this.routingNumberEl, mergedStyles, 'left');
125
- containerEl.appendChild(this.routingNumberEl);
126
- 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);
127
141
  Object.assign(this.accountNumberEl.style, {
128
142
  flex: BANK_FIELD_FLEX.accountNumber.flex,
129
143
  minWidth: BANK_FIELD_FLEX.accountNumber.minWidth,
130
144
  });
131
145
  this.applyInputStyles(this.accountNumberEl, mergedStyles, 'middle');
132
- containerEl.appendChild(this.accountNumberEl);
146
+ containerEl.appendChild(wrapFieldWithLabel(this.accountNumberEl, 'Account Number', mergedStyles));
133
147
  this.accountTypeEl = createAccountTypeSelect(`${this.containerId}-account-type`);
134
148
  Object.assign(this.accountTypeEl.style, {
135
149
  flex: BANK_FIELD_FLEX.accountType.flex,
136
150
  minWidth: BANK_FIELD_FLEX.accountType.minWidth,
137
151
  });
138
152
  this.applyInputStyles(this.accountTypeEl, mergedStyles, 'right');
139
- containerEl.appendChild(this.accountTypeEl);
153
+ containerEl.appendChild(wrapFieldWithLabel(this.accountTypeEl, 'Account Type', mergedStyles));
140
154
  }
141
155
  this.mergedStyles = mergedStyles;
142
156
  this.currentValidationState = {
@@ -234,8 +248,6 @@ export class CardConnectTokenizer extends Tokenizer {
234
248
  window.addEventListener('message', this.messageHandler);
235
249
  this.iframe.onload = () => {
236
250
  clearTimeout(timeout);
237
- if (this.enableTestMode && this.mode === 'credit_card') {
238
- }
239
251
  this.emit('ready');
240
252
  resolve();
241
253
  };
@@ -681,7 +693,34 @@ export class CardConnectTokenizer extends Tokenizer {
681
693
  this.emit('validation', this.currentValidationState);
682
694
  }
683
695
  }
696
+ static measureCvvLabelMarginLeft(monthWidth, yearWidth, cvvMarginLeft) {
697
+ var _a;
698
+ const targetCvvX = monthWidth + 4 + 4 + yearWidth + 12 + cvvMarginLeft;
699
+ const host = document.createElement('div');
700
+ host.style.cssText =
701
+ 'position:absolute;visibility:hidden;left:0;top:0;width:9999px;height:0;overflow:hidden;';
702
+ document.body.appendChild(host);
703
+ const shadow = host.attachShadow({ mode: 'open' });
704
+ shadow.innerHTML = [
705
+ '<input type="text" size="2" style="margin-right:4px">',
706
+ '<label>/</label>',
707
+ '<input type="text" size="4" style="margin-left:4px;margin-right:12px">',
708
+ '<input type="tel" size="5">',
709
+ ].join('');
710
+ const inputs = shadow.querySelectorAll('input');
711
+ const hostX = host.getBoundingClientRect().x;
712
+ const cvvRect = (_a = inputs[2]) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
713
+ const defaultCvvX = cvvRect ? cvvRect.x - hostX : -1;
714
+ document.body.removeChild(host);
715
+ if (defaultCvvX <= 0 || defaultCvvX > 500) {
716
+ console.warn('[CardConnect] CVV measurement out of range, using fallback margin-left:100px');
717
+ return 100;
718
+ }
719
+ const predictedLabelLeft = defaultCvvX + 8;
720
+ return Math.round(targetCvvX - predictedLabelLeft);
721
+ }
684
722
  static generateIframeUrl(baseUrl, container) {
723
+ var _a, _b, _c, _d, _e, _f, _g, _h;
685
724
  const params = new URLSearchParams({
686
725
  invalidinputevent: 'true',
687
726
  enhancedresponse: 'true',
@@ -690,30 +729,46 @@ export class CardConnectTokenizer extends Tokenizer {
690
729
  formatinput: 'true',
691
730
  unique: 'true',
692
731
  norsa: 'true',
693
- placeholder: 'Card Number *',
694
- placeholdercvv: 'CVV',
732
+ placeholder: ((_a = container.placeholders) === null || _a === void 0 ? void 0 : _a.cardNumber) || 'Card Number *',
733
+ placeholdercvv: ((_b = container.placeholders) === null || _b === void 0 ? void 0 : _b.cvv) || 'CVV',
695
734
  invalidcreditcardevent: 'true',
696
735
  invalidexpiry: 'true',
697
736
  invalidcvv: 'true',
698
737
  });
738
+ const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
739
+ const showLabelsInUrl = ((_c = mergedStyles.label) === null || _c === void 0 ? void 0 : _c.show) && container.layout === 'two-line';
740
+ if (showLabelsInUrl) {
741
+ params.set('cardlabel', 'Card Number');
742
+ params.set('expirylabel', 'Expiration');
743
+ params.set('cvvlabel', 'CVV');
744
+ }
745
+ else {
746
+ params.set('cardlabel', '');
747
+ params.set('expirylabel', '');
748
+ params.set('cvvlabel', '');
749
+ }
699
750
  if (container.layout === 'two-line') {
700
751
  params.set('useexpiryfield', 'true');
701
752
  params.set('orientation', 'horizontal');
702
- params.set('placeholdermonth', 'MM');
703
- params.set('placeholderyear', 'YYYY');
753
+ params.set('placeholdermonth', ((_d = container.placeholders) === null || _d === void 0 ? void 0 : _d.expiryMonth) || 'MM');
754
+ params.set('placeholderyear', ((_e = container.placeholders) === null || _e === void 0 ? void 0 : _e.expiryYear) || 'YYYY');
704
755
  }
705
756
  else {
706
757
  params.set('orientation', 'horizontal');
707
- params.set('placeholdermonth', 'MM');
708
- params.set('placeholderyear', 'YYYY');
758
+ params.set('placeholdermonth', ((_f = container.placeholders) === null || _f === void 0 ? void 0 : _f.expiryMonth) || 'MM');
759
+ params.set('placeholderyear', ((_g = container.placeholders) === null || _g === void 0 ? void 0 : _g.expiryYear) || 'YYYY');
709
760
  }
710
- const mergedStyles = mergeStyles(DEFAULT_UNIFIED_STYLES, container.styling);
711
761
  const isDesktopSafari = typeof navigator !== 'undefined' &&
712
762
  /Safari/.test(navigator.userAgent) &&
713
763
  /Apple Computer/.test(navigator.vendor) &&
714
764
  !/Chrome/.test(navigator.userAgent) &&
715
765
  !/Mobile/.test(navigator.userAgent);
716
- const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari);
766
+ const showLabels = ((_h = mergedStyles.label) === null || _h === void 0 ? void 0 : _h.show) && container.layout === 'two-line';
767
+ let cvvLabelMarginLeft;
768
+ if (showLabels && typeof document !== 'undefined') {
769
+ cvvLabelMarginLeft = CardConnectTokenizer.measureCvvLabelMarginLeft(60, 80, 40);
770
+ }
771
+ const cssString = CardConnectTokenizer.generateCardConnectCss(mergedStyles, (container.layout || 'single-line'), isDesktopSafari, cvvLabelMarginLeft);
717
772
  const queryPairs = [];
718
773
  params.forEach((value, key) => {
719
774
  queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
@@ -728,7 +783,7 @@ export class CardConnectTokenizer extends Tokenizer {
728
783
  iframe.style.width = '100%';
729
784
  iframe.style.height = styles.input.height;
730
785
  iframe.style.border = 'none';
731
- iframe.style.overflow = 'hidden';
786
+ iframe.style.overflow = '';
732
787
  iframe.style.display = 'block';
733
788
  iframe.style.minWidth = '0';
734
789
  if (styles.container) {
@@ -746,18 +801,30 @@ export class CardConnectTokenizer extends Tokenizer {
746
801
  iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
747
802
  return iframe;
748
803
  }
749
- static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false) {
750
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
804
+ static generateCardConnectCss(styles, layout = 'single-line', isDesktopSafari = false, cvvLabelMarginLeft) {
805
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
751
806
  const css = [];
752
- if (layout === 'two-line') {
753
- css.push('html,form,body{margin:0;padding:0;}');
807
+ const showLabelsInIframe = ((_a = styles.label) === null || _a === void 0 ? void 0 : _a.show) && layout === 'two-line';
808
+ if (showLabelsInIframe) {
809
+ 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}`;
810
+ css.push(`label{${labelCss};}`);
811
+ css.push(`label[for="ccexpiryfieldyear"]{display:none;}`);
812
+ css.push(`br{line-height:0;font-size:0;margin:0;}`);
813
+ css.push(`input,select{margin-top:0;margin-bottom:0;}`);
814
+ }
815
+ else {
754
816
  css.push('label{display:none;}');
755
- css.push('br{display:none;}');
817
+ }
818
+ if (layout === 'two-line') {
819
+ css.push('html,body{margin:0;padding:0;overflow:hidden;}');
820
+ css.push('form{margin:0;padding:0;width:100%;box-sizing:border-box;}');
821
+ if (!showLabelsInIframe) {
822
+ css.push('br{display:none;}');
823
+ }
756
824
  }
757
825
  else {
758
826
  css.push('body{margin:0;padding:0;display:flex;align-items:center;}');
759
827
  css.push('form{margin:0;padding:0;display:flex;width:100%;align-items:center;}');
760
- css.push('label{display:none;}');
761
828
  css.push('br{display:none;}');
762
829
  }
763
830
  const isConnected = styles.container.gap === '0';
@@ -790,13 +857,22 @@ export class CardConnectTokenizer extends Tokenizer {
790
857
  }
791
858
  if (layout === 'two-line') {
792
859
  css.push('input#ccnumfield{width:100%;display:block;margin-bottom:8px;}');
793
- const twoLinePadding = ((_a = styles.twoLine) === null || _a === void 0 ? void 0 : _a.padding) || ((_b = styles.input) === null || _b === void 0 ? void 0 : _b.padding) || '10px';
794
- const twoLineFontSize = ((_c = styles.twoLine) === null || _c === void 0 ? void 0 : _c.fontSize) || ((_d = styles.input) === null || _d === void 0 ? void 0 : _d.fontSize) || '14px';
795
- const twoLineTextAlign = ((_e = styles.twoLine) === null || _e === void 0 ? void 0 : _e.textAlign) || 'left';
796
- css.push(`input#ccexpiryfieldmonth{width:25%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
797
- css.push(`input#ccexpiryfieldyear{width:35%;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
798
- css.push(`input#cccvvfield{width:calc(40% - 16px);padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};margin-left:-4px;}`);
799
- if ((_f = styles.input) === null || _f === void 0 ? void 0 : _f.borderRadius) {
860
+ 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';
861
+ 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';
862
+ const twoLineTextAlign = ((_f = styles.twoLine) === null || _f === void 0 ? void 0 : _f.textAlign) || 'left';
863
+ if (showLabelsInIframe) {
864
+ css.push(`input#ccexpiryfieldmonth{width:60px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
865
+ css.push(`input#ccexpiryfieldyear{width:80px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
866
+ css.push(`input#cccvvfield{width:80px;margin-left:40px;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
867
+ const labelMargin = cvvLabelMarginLeft !== null && cvvLabelMarginLeft !== void 0 ? cvvLabelMarginLeft : 100;
868
+ css.push(`label#cccvvlabel{margin-left:${labelMargin}px;}`);
869
+ }
870
+ else {
871
+ css.push(`input#ccexpiryfieldmonth{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
872
+ css.push(`input#ccexpiryfieldyear{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
873
+ css.push(`input#cccvvfield{min-width:4em;padding:${twoLinePadding};font-size:${twoLineFontSize};text-align:${twoLineTextAlign};}`);
874
+ }
875
+ if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
800
876
  css.push(`input{border-radius:${styles.input.borderRadius};}`);
801
877
  }
802
878
  }
@@ -805,7 +881,7 @@ export class CardConnectTokenizer extends Tokenizer {
805
881
  css.push('select#ccexpirymonth{width:16%;margin:0;margin-right:-12px;}');
806
882
  css.push('select#ccexpiryyear{width:20%;}');
807
883
  css.push('input#cccvvfield{width:20%;margin:0;margin-left:-12px;}');
808
- if ((_g = styles.input) === null || _g === void 0 ? void 0 : _g.borderRadius) {
884
+ if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
809
885
  css.push(`input#ccnumfield{border-radius:${styles.input.borderRadius} 0 0 ${styles.input.borderRadius};border-right:none;}`);
810
886
  css.push('select#ccexpirymonth{border-radius:0;border-right:none;}');
811
887
  css.push('select#ccexpiryyear{border-radius:0;border-right:none;}');
@@ -823,7 +899,7 @@ export class CardConnectTokenizer extends Tokenizer {
823
899
  css.push(`select#ccexpirymonth{width:15%;margin-right:${marginRight};}`);
824
900
  css.push(`select#ccexpiryyear{width:20%;margin-right:${marginRight};}`);
825
901
  css.push('input#cccvvfield{width:15%;}');
826
- if ((_h = styles.input) === null || _h === void 0 ? void 0 : _h.borderRadius) {
902
+ if ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.borderRadius) {
827
903
  css.push(`input,select{border-radius:${styles.input.borderRadius};}`);
828
904
  }
829
905
  }
@@ -839,7 +915,7 @@ export class CardConnectTokenizer extends Tokenizer {
839
915
  if (focusStyles.length > 0) {
840
916
  css.push(`input:focus{${focusStyles.join(';')};}`);
841
917
  css.push(`select:focus{${focusStyles.join(';')};}`);
842
- if (isConnected && ((_j = styles.input) === null || _j === void 0 ? void 0 : _j.border)) {
918
+ if (isConnected && ((_k = styles.input) === null || _k === void 0 ? void 0 : _k.border)) {
843
919
  css.push(`input#ccnumfield:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
844
920
  css.push(`select#ccexpirymonth:focus{border:${styles.input.border};${focusStyles.join(';')};}`);
845
921
  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;