@funnelfox/billing 0.5.0-beta.3 → 0.5.0
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/chunk-index.cjs.js +4 -5
- package/dist/chunk-index.cjs2.js +10 -3
- package/dist/chunk-index.es.js +4 -5
- package/dist/chunk-index.es2.js +10 -3
- package/dist/funnelfox-billing.cjs.js +175 -17
- package/dist/funnelfox-billing.esm.js +175 -17
- package/dist/funnelfox-billing.js +189 -25
- package/dist/funnelfox-billing.min.js +1 -1
- package/package.json +4 -6
- package/src/types.d.ts +12 -15
package/dist/chunk-index.cjs.js
CHANGED
|
@@ -29,9 +29,8 @@ const paymentMethodTemplates = {
|
|
|
29
29
|
[index.PaymentMethod.APPLE_PAY]: applePayTemplate,
|
|
30
30
|
};
|
|
31
31
|
class DefaultSkin {
|
|
32
|
-
constructor(
|
|
32
|
+
constructor(checkoutConfig) {
|
|
33
33
|
this.onLoaderChange = (isLoading) => {
|
|
34
|
-
this.primerWrapper.disableButtons(isLoading);
|
|
35
34
|
document
|
|
36
35
|
.querySelectorAll(`${this.containerSelector} .loader-container`)
|
|
37
36
|
?.forEach(loaderEl => {
|
|
@@ -95,6 +94,7 @@ class DefaultSkin {
|
|
|
95
94
|
this.onMethodsAvailable = (methods) => {
|
|
96
95
|
this.availableMethods = methods;
|
|
97
96
|
this.initAccordion();
|
|
97
|
+
methods.forEach(this.onMethodRender);
|
|
98
98
|
};
|
|
99
99
|
this.onStartPurchase = (paymentMethod) => {
|
|
100
100
|
this.currentPurchaseMethod = paymentMethod;
|
|
@@ -115,7 +115,6 @@ class DefaultSkin {
|
|
|
115
115
|
throw new Error(`Container element not found for selector: ${this.containerSelector}`);
|
|
116
116
|
}
|
|
117
117
|
this.containerEl = containerEl;
|
|
118
|
-
this.primerWrapper = primerWrapper;
|
|
119
118
|
this.checkoutConfig = checkoutConfig;
|
|
120
119
|
}
|
|
121
120
|
initAccordion() {
|
|
@@ -214,8 +213,8 @@ class DefaultSkin {
|
|
|
214
213
|
};
|
|
215
214
|
}
|
|
216
215
|
}
|
|
217
|
-
const createDefaultSkin = async (
|
|
218
|
-
const skin = new DefaultSkin(
|
|
216
|
+
const createDefaultSkin = async (checkoutConfig) => {
|
|
217
|
+
const skin = new DefaultSkin(checkoutConfig);
|
|
219
218
|
await skin['init']();
|
|
220
219
|
return skin;
|
|
221
220
|
};
|
package/dist/chunk-index.cjs2.js
CHANGED
|
@@ -38,6 +38,9 @@ class CardSkin {
|
|
|
38
38
|
this.onMethodRender = () => {
|
|
39
39
|
this.containerEl.style.display = 'block';
|
|
40
40
|
};
|
|
41
|
+
this.onDestroy = () => {
|
|
42
|
+
this.containerEl.remove();
|
|
43
|
+
};
|
|
41
44
|
if (!containerEl) {
|
|
42
45
|
throw new Error('Container element not found');
|
|
43
46
|
}
|
|
@@ -49,15 +52,19 @@ class CardSkin {
|
|
|
49
52
|
const cardNumber = this.containerEl.querySelector('#cardNumberInput');
|
|
50
53
|
const expiryDate = this.containerEl.querySelector('#expiryInput');
|
|
51
54
|
const cvv = this.containerEl.querySelector('#cvvInput');
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
const hasCardholderInput = !!this.checkoutConfig?.card?.cardholderName;
|
|
56
|
+
let cardholderName = undefined;
|
|
57
|
+
if (hasCardholderInput) {
|
|
54
58
|
cardholderName =
|
|
55
59
|
this.containerEl.querySelector('#cardHolderInput');
|
|
56
60
|
}
|
|
57
61
|
else {
|
|
58
62
|
this.containerEl.querySelector('#cardHolderInput').parentElement.style.display = 'none';
|
|
59
63
|
}
|
|
60
|
-
if (!cardNumber ||
|
|
64
|
+
if (!cardNumber ||
|
|
65
|
+
!expiryDate ||
|
|
66
|
+
!cvv ||
|
|
67
|
+
(hasCardholderInput && !cardholderName)) {
|
|
61
68
|
throw new Error('One or more card input elements are missing in the default skin');
|
|
62
69
|
}
|
|
63
70
|
this.cardInputElements = {
|
package/dist/chunk-index.es.js
CHANGED
|
@@ -27,9 +27,8 @@ const paymentMethodTemplates = {
|
|
|
27
27
|
[PaymentMethod.APPLE_PAY]: applePayTemplate,
|
|
28
28
|
};
|
|
29
29
|
class DefaultSkin {
|
|
30
|
-
constructor(
|
|
30
|
+
constructor(checkoutConfig) {
|
|
31
31
|
this.onLoaderChange = (isLoading) => {
|
|
32
|
-
this.primerWrapper.disableButtons(isLoading);
|
|
33
32
|
document
|
|
34
33
|
.querySelectorAll(`${this.containerSelector} .loader-container`)
|
|
35
34
|
?.forEach(loaderEl => {
|
|
@@ -93,6 +92,7 @@ class DefaultSkin {
|
|
|
93
92
|
this.onMethodsAvailable = (methods) => {
|
|
94
93
|
this.availableMethods = methods;
|
|
95
94
|
this.initAccordion();
|
|
95
|
+
methods.forEach(this.onMethodRender);
|
|
96
96
|
};
|
|
97
97
|
this.onStartPurchase = (paymentMethod) => {
|
|
98
98
|
this.currentPurchaseMethod = paymentMethod;
|
|
@@ -113,7 +113,6 @@ class DefaultSkin {
|
|
|
113
113
|
throw new Error(`Container element not found for selector: ${this.containerSelector}`);
|
|
114
114
|
}
|
|
115
115
|
this.containerEl = containerEl;
|
|
116
|
-
this.primerWrapper = primerWrapper;
|
|
117
116
|
this.checkoutConfig = checkoutConfig;
|
|
118
117
|
}
|
|
119
118
|
initAccordion() {
|
|
@@ -212,8 +211,8 @@ class DefaultSkin {
|
|
|
212
211
|
};
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
|
-
const createDefaultSkin = async (
|
|
216
|
-
const skin = new DefaultSkin(
|
|
214
|
+
const createDefaultSkin = async (checkoutConfig) => {
|
|
215
|
+
const skin = new DefaultSkin(checkoutConfig);
|
|
217
216
|
await skin['init']();
|
|
218
217
|
return skin;
|
|
219
218
|
};
|
package/dist/chunk-index.es2.js
CHANGED
|
@@ -36,6 +36,9 @@ class CardSkin {
|
|
|
36
36
|
this.onMethodRender = () => {
|
|
37
37
|
this.containerEl.style.display = 'block';
|
|
38
38
|
};
|
|
39
|
+
this.onDestroy = () => {
|
|
40
|
+
this.containerEl.remove();
|
|
41
|
+
};
|
|
39
42
|
if (!containerEl) {
|
|
40
43
|
throw new Error('Container element not found');
|
|
41
44
|
}
|
|
@@ -47,15 +50,19 @@ class CardSkin {
|
|
|
47
50
|
const cardNumber = this.containerEl.querySelector('#cardNumberInput');
|
|
48
51
|
const expiryDate = this.containerEl.querySelector('#expiryInput');
|
|
49
52
|
const cvv = this.containerEl.querySelector('#cvvInput');
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
const hasCardholderInput = !!this.checkoutConfig?.card?.cardholderName;
|
|
54
|
+
let cardholderName = undefined;
|
|
55
|
+
if (hasCardholderInput) {
|
|
52
56
|
cardholderName =
|
|
53
57
|
this.containerEl.querySelector('#cardHolderInput');
|
|
54
58
|
}
|
|
55
59
|
else {
|
|
56
60
|
this.containerEl.querySelector('#cardHolderInput').parentElement.style.display = 'none';
|
|
57
61
|
}
|
|
58
|
-
if (!cardNumber ||
|
|
62
|
+
if (!cardNumber ||
|
|
63
|
+
!expiryDate ||
|
|
64
|
+
!cvv ||
|
|
65
|
+
(hasCardholderInput && !cardholderName)) {
|
|
59
66
|
throw new Error('One or more card input elements are missing in the default skin');
|
|
60
67
|
}
|
|
61
68
|
this.cardInputElements = {
|
|
@@ -206,6 +206,132 @@ function withTimeout(promise, timeoutMs, message = 'Operation timed out') {
|
|
|
206
206
|
return Promise.race([promise, timeoutPromise]);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
/**
|
|
210
|
+
* @fileoverview Dynamic loader for Primer SDK
|
|
211
|
+
* Loads Primer script and CSS from CDN independently of bundler
|
|
212
|
+
*/
|
|
213
|
+
const PRIMER_CDN_BASE = 'https://sdk.primer.io/web';
|
|
214
|
+
const DEFAULT_VERSION = '2.57.3';
|
|
215
|
+
// Integrity hashes for specific versions (for SRI security)
|
|
216
|
+
const INTEGRITY_HASHES = {
|
|
217
|
+
'2.57.3': {
|
|
218
|
+
js: 'sha384-xq2SWkYvTlKOMpuXQUXq1QI3eZN7JiqQ3Sc72U9wY1IE30MW3HkwQWg/1n6BTMz4',
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
let loadingPromise = null;
|
|
222
|
+
let isLoaded = false;
|
|
223
|
+
/**
|
|
224
|
+
* Injects a script tag into the document head
|
|
225
|
+
*/
|
|
226
|
+
function injectScript(src, integrity) {
|
|
227
|
+
return new Promise((resolve, reject) => {
|
|
228
|
+
// Check if script already exists
|
|
229
|
+
const existingScript = document.querySelector(`script[src="${src}"]`);
|
|
230
|
+
if (existingScript) {
|
|
231
|
+
resolve(existingScript);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const script = document.createElement('script');
|
|
235
|
+
script.src = src;
|
|
236
|
+
script.async = true;
|
|
237
|
+
script.crossOrigin = 'anonymous';
|
|
238
|
+
if (integrity) {
|
|
239
|
+
script.integrity = integrity;
|
|
240
|
+
}
|
|
241
|
+
script.onload = () => resolve(script);
|
|
242
|
+
script.onerror = () => reject(new Error(`Failed to load Primer SDK script from ${src}`));
|
|
243
|
+
document.head.appendChild(script);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Injects a CSS link tag into the document head
|
|
248
|
+
*/
|
|
249
|
+
function injectCSS(href, integrity) {
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
// Check if stylesheet already exists
|
|
252
|
+
const existingLink = document.querySelector(`link[href="${href}"]`);
|
|
253
|
+
if (existingLink) {
|
|
254
|
+
resolve(existingLink);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const link = document.createElement('link');
|
|
258
|
+
link.rel = 'stylesheet';
|
|
259
|
+
link.href = href;
|
|
260
|
+
link.crossOrigin = 'anonymous';
|
|
261
|
+
if (integrity) {
|
|
262
|
+
link.integrity = integrity;
|
|
263
|
+
}
|
|
264
|
+
link.onload = () => resolve(link);
|
|
265
|
+
link.onerror = () => reject(new Error(`Failed to load Primer SDK CSS from ${href}`));
|
|
266
|
+
document.head.appendChild(link);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Waits for window.Primer to be available
|
|
271
|
+
*/
|
|
272
|
+
function waitForPrimer(timeout = 10000) {
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
const startTime = Date.now();
|
|
275
|
+
const check = () => {
|
|
276
|
+
if (typeof window !== 'undefined' &&
|
|
277
|
+
window.Primer &&
|
|
278
|
+
typeof window.Primer.createHeadless === 'function') {
|
|
279
|
+
resolve();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (Date.now() - startTime > timeout) {
|
|
283
|
+
reject(new Error('Timeout waiting for Primer SDK to initialize on window'));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
setTimeout(check, 50);
|
|
287
|
+
};
|
|
288
|
+
check();
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Loads the Primer SDK script and CSS from CDN
|
|
293
|
+
* @param version - The version of Primer SDK to load (default: 2.57.3)
|
|
294
|
+
* @returns Promise that resolves when SDK is loaded and ready
|
|
295
|
+
*/
|
|
296
|
+
async function loadPrimerSDK(version) {
|
|
297
|
+
// Already loaded
|
|
298
|
+
if (isLoaded) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
// Already loading - return existing promise
|
|
302
|
+
if (loadingPromise) {
|
|
303
|
+
return loadingPromise;
|
|
304
|
+
}
|
|
305
|
+
// Check if Primer is already available (user may have loaded it manually)
|
|
306
|
+
if (typeof window !== 'undefined' &&
|
|
307
|
+
window.Primer &&
|
|
308
|
+
typeof window.Primer.createHeadless === 'function') {
|
|
309
|
+
isLoaded = true;
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const ver = version || DEFAULT_VERSION;
|
|
313
|
+
const jsUrl = `${PRIMER_CDN_BASE}/v${ver}/Primer.min.js`;
|
|
314
|
+
const cssUrl = `${PRIMER_CDN_BASE}/v${ver}/Checkout.css`;
|
|
315
|
+
const hashes = INTEGRITY_HASHES[ver];
|
|
316
|
+
loadingPromise = (async () => {
|
|
317
|
+
try {
|
|
318
|
+
// Load CSS and JS in parallel
|
|
319
|
+
await Promise.all([
|
|
320
|
+
injectCSS(cssUrl, hashes?.css),
|
|
321
|
+
injectScript(jsUrl, hashes?.js),
|
|
322
|
+
]);
|
|
323
|
+
// Wait for Primer to be available on window
|
|
324
|
+
await waitForPrimer();
|
|
325
|
+
isLoaded = true;
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
loadingPromise = null;
|
|
329
|
+
throw error;
|
|
330
|
+
}
|
|
331
|
+
})();
|
|
332
|
+
return loadingPromise;
|
|
333
|
+
}
|
|
334
|
+
|
|
209
335
|
exports.PaymentMethod = void 0;
|
|
210
336
|
(function (PaymentMethod) {
|
|
211
337
|
PaymentMethod["GOOGLE_PAY"] = "GOOGLE_PAY";
|
|
@@ -217,7 +343,7 @@ exports.PaymentMethod = void 0;
|
|
|
217
343
|
/**
|
|
218
344
|
* @fileoverview Constants for Funnefox SDK
|
|
219
345
|
*/
|
|
220
|
-
const SDK_VERSION = '0.5.0
|
|
346
|
+
const SDK_VERSION = '0.5.0';
|
|
221
347
|
const DEFAULTS = {
|
|
222
348
|
BASE_URL: 'https://billing.funnelfox.com',
|
|
223
349
|
REGION: 'default',
|
|
@@ -312,12 +438,28 @@ class PrimerWrapper {
|
|
|
312
438
|
this.destroyCallbacks = [];
|
|
313
439
|
this.headless = null;
|
|
314
440
|
this.availableMethods = [];
|
|
441
|
+
this.paymentMethodsInterfaces = [];
|
|
315
442
|
}
|
|
316
443
|
isPrimerAvailable() {
|
|
317
444
|
return (typeof window !== 'undefined' &&
|
|
318
445
|
window.Primer &&
|
|
319
446
|
typeof window.Primer?.createHeadless === 'function');
|
|
320
447
|
}
|
|
448
|
+
/**
|
|
449
|
+
* Loads Primer SDK if not already available
|
|
450
|
+
* @param version - Optional version to load (uses default if not specified)
|
|
451
|
+
*/
|
|
452
|
+
async ensurePrimerLoaded(version) {
|
|
453
|
+
if (this.isPrimerAvailable()) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
try {
|
|
457
|
+
await loadPrimerSDK(version);
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
throw new PrimerError('Failed to load Primer SDK', error);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
321
463
|
ensurePrimerAvailable() {
|
|
322
464
|
if (!this.isPrimerAvailable()) {
|
|
323
465
|
throw new PrimerError('Primer SDK not found. Please include the Primer SDK script before initializing FunnefoxSDK.');
|
|
@@ -327,7 +469,8 @@ class PrimerWrapper {
|
|
|
327
469
|
if (this.headless) {
|
|
328
470
|
return this.headless;
|
|
329
471
|
}
|
|
330
|
-
|
|
472
|
+
// Load Primer SDK if not already available
|
|
473
|
+
await this.ensurePrimerLoaded();
|
|
331
474
|
const primerOptions = merge({
|
|
332
475
|
paymentHandling: 'MANUAL',
|
|
333
476
|
apiVersion: '2.4',
|
|
@@ -380,7 +523,8 @@ class PrimerWrapper {
|
|
|
380
523
|
}
|
|
381
524
|
async renderButton(allowedPaymentMethod, { htmlNode, onMethodRenderError, onMethodRender, }) {
|
|
382
525
|
let button;
|
|
383
|
-
|
|
526
|
+
// Ensure Primer SDK is loaded
|
|
527
|
+
await this.ensurePrimerLoaded();
|
|
384
528
|
if (!this.headless) {
|
|
385
529
|
throw new PrimerError('Headless checkout not found');
|
|
386
530
|
}
|
|
@@ -415,20 +559,24 @@ class PrimerWrapper {
|
|
|
415
559
|
!options.onInputChange) {
|
|
416
560
|
throw new PrimerError('Card elements, onSubmit, and onInputChange are required for PAYMENT_CARD method');
|
|
417
561
|
}
|
|
418
|
-
|
|
562
|
+
const cardInterface = await this.renderCardCheckoutWithElements(options.cardElements, {
|
|
419
563
|
onSubmit: options.onSubmit,
|
|
420
564
|
onInputChange: options.onInputChange,
|
|
421
565
|
onMethodRenderError: options.onMethodRenderError,
|
|
422
566
|
onMethodRender: options.onMethodRender,
|
|
423
567
|
});
|
|
568
|
+
this.paymentMethodsInterfaces.push(cardInterface);
|
|
569
|
+
return cardInterface;
|
|
424
570
|
}
|
|
425
571
|
else {
|
|
426
572
|
try {
|
|
427
|
-
|
|
573
|
+
const buttonInterface = await this.renderButton(method, {
|
|
428
574
|
htmlNode,
|
|
429
575
|
onMethodRenderError: options.onMethodRenderError,
|
|
430
576
|
onMethodRender: options.onMethodRender,
|
|
431
577
|
});
|
|
578
|
+
this.paymentMethodsInterfaces.push(buttonInterface);
|
|
579
|
+
return buttonInterface;
|
|
432
580
|
}
|
|
433
581
|
catch (error) {
|
|
434
582
|
throw new PrimerError('Failed to initialize Primer checkout', error);
|
|
@@ -513,7 +661,12 @@ class PrimerWrapper {
|
|
|
513
661
|
cardNumberInput.setDisabled(disabled);
|
|
514
662
|
expiryInput.setDisabled(disabled);
|
|
515
663
|
cvvInput.setDisabled(disabled);
|
|
516
|
-
elements.button
|
|
664
|
+
if (elements.button) {
|
|
665
|
+
elements.button.disabled = disabled;
|
|
666
|
+
}
|
|
667
|
+
if (elements.cardholderName) {
|
|
668
|
+
elements.cardholderName.disabled = disabled;
|
|
669
|
+
}
|
|
517
670
|
},
|
|
518
671
|
submit: () => onSubmitHandler(),
|
|
519
672
|
destroy: () => {
|
|
@@ -555,7 +708,7 @@ class PrimerWrapper {
|
|
|
555
708
|
const { cardElements, paymentButtonElements, container, onSubmit, onInputChange, onMethodRender, onMethodRenderError, onMethodsAvailable, } = checkoutRenderOptions;
|
|
556
709
|
await this.initializeHeadlessCheckout(clientToken, checkoutOptions);
|
|
557
710
|
onMethodsAvailable?.(this.availableMethods);
|
|
558
|
-
|
|
711
|
+
await Promise.all(this.availableMethods.map(method => {
|
|
559
712
|
if (method === exports.PaymentMethod.PAYMENT_CARD) {
|
|
560
713
|
// For card, use the main container
|
|
561
714
|
return this.initMethod(method, container, {
|
|
@@ -579,10 +732,8 @@ class PrimerWrapper {
|
|
|
579
732
|
onMethodRenderError,
|
|
580
733
|
});
|
|
581
734
|
}
|
|
582
|
-
}))
|
|
583
|
-
|
|
584
|
-
this.isInitialized = true;
|
|
585
|
-
});
|
|
735
|
+
}));
|
|
736
|
+
this.isInitialized = true;
|
|
586
737
|
}
|
|
587
738
|
wrapTokenizeHandler(handler) {
|
|
588
739
|
return async (paymentMethodTokenData, primerHandler) => {
|
|
@@ -938,6 +1089,7 @@ class CheckoutInstance extends EventEmitter {
|
|
|
938
1089
|
};
|
|
939
1090
|
this.onLoaderChangeWithRace = (state) => {
|
|
940
1091
|
const isLoading = !!(state ? ++this.counter : --this.counter);
|
|
1092
|
+
this.primerWrapper.disableButtons(isLoading);
|
|
941
1093
|
this.emit(EVENTS.LOADER_CHANGE, isLoading);
|
|
942
1094
|
};
|
|
943
1095
|
this.id = generateId('checkout_');
|
|
@@ -1021,14 +1173,15 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1021
1173
|
].join('-');
|
|
1022
1174
|
let sessionResponse;
|
|
1023
1175
|
// Return cached response if payload hasn't changed
|
|
1024
|
-
const cachedResponse = CheckoutInstance.sessionCache.get(cacheKey);
|
|
1176
|
+
const cachedResponse = await CheckoutInstance.sessionCache.get(cacheKey);
|
|
1025
1177
|
if (cachedResponse) {
|
|
1026
1178
|
sessionResponse = cachedResponse;
|
|
1027
1179
|
}
|
|
1028
1180
|
else {
|
|
1029
|
-
|
|
1181
|
+
const sessionRequest = this.apiClient.createClientSession(sessionParams);
|
|
1030
1182
|
// Cache the successful response
|
|
1031
|
-
CheckoutInstance.sessionCache.set(cacheKey,
|
|
1183
|
+
CheckoutInstance.sessionCache.set(cacheKey, sessionRequest);
|
|
1184
|
+
sessionResponse = await sessionRequest;
|
|
1032
1185
|
}
|
|
1033
1186
|
const sessionData = this.apiClient.processSessionResponse(sessionResponse);
|
|
1034
1187
|
this.orderId = sessionData.orderId;
|
|
@@ -1257,18 +1410,18 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1257
1410
|
async getDefaultSkinCheckoutOptions() {
|
|
1258
1411
|
const skinFactory = (await Promise.resolve().then(function () { return require('./chunk-index.cjs.js'); }))
|
|
1259
1412
|
.default;
|
|
1260
|
-
const skin = await skinFactory(this.
|
|
1413
|
+
const skin = await skinFactory(this.checkoutConfig);
|
|
1261
1414
|
this.on(EVENTS.INPUT_ERROR, skin.onInputError);
|
|
1262
1415
|
this.on(EVENTS.STATUS_CHANGE, skin.onStatusChange);
|
|
1263
1416
|
this.on(EVENTS.ERROR, (error) => skin.onError(error));
|
|
1264
1417
|
this.on(EVENTS.LOADER_CHANGE, skin.onLoaderChange);
|
|
1265
1418
|
this.on(EVENTS.DESTROY, skin.onDestroy);
|
|
1266
|
-
this.on(EVENTS.METHOD_RENDER, skin.onMethodRender);
|
|
1267
1419
|
this.on(EVENTS.SUCCESS, skin.onSuccess);
|
|
1268
1420
|
this.on(EVENTS.START_PURCHASE, skin.onStartPurchase);
|
|
1269
1421
|
this.on(EVENTS.PURCHASE_FAILURE, skin.onPurchaseFailure);
|
|
1270
1422
|
this.on(EVENTS.PURCHASE_COMPLETED, skin.onPurchaseCompleted);
|
|
1271
1423
|
this.on(EVENTS.METHODS_AVAILABLE, skin.onMethodsAvailable);
|
|
1424
|
+
this.on(EVENTS.METHODS_AVAILABLE, this.hideInitializingLoader);
|
|
1272
1425
|
return skin.getCheckoutOptions();
|
|
1273
1426
|
}
|
|
1274
1427
|
async getCardDefaultSkinCheckoutOptions(node) {
|
|
@@ -1277,6 +1430,7 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1277
1430
|
skin.init();
|
|
1278
1431
|
this.on(EVENTS.INPUT_ERROR, skin.onInputError);
|
|
1279
1432
|
this.on(EVENTS.METHOD_RENDER, skin.onMethodRender);
|
|
1433
|
+
this.on(EVENTS.SUCCESS, skin.onDestroy);
|
|
1280
1434
|
return skin.getCheckoutOptions();
|
|
1281
1435
|
}
|
|
1282
1436
|
showInitializingLoader() {
|
|
@@ -1311,8 +1465,9 @@ function resolveConfig(options, functionName) {
|
|
|
1311
1465
|
}
|
|
1312
1466
|
async function createCheckout(options) {
|
|
1313
1467
|
const { ...checkoutConfig } = options;
|
|
1468
|
+
// Ensure Primer SDK is loaded before creating checkout
|
|
1314
1469
|
const primerWrapper = new PrimerWrapper();
|
|
1315
|
-
primerWrapper.
|
|
1470
|
+
await primerWrapper.ensurePrimerLoaded();
|
|
1316
1471
|
const config = resolveConfig(options, 'createCheckout');
|
|
1317
1472
|
const checkout = new CheckoutInstance({
|
|
1318
1473
|
...config,
|
|
@@ -1365,6 +1520,9 @@ async function silentPurchase(options) {
|
|
|
1365
1520
|
return true;
|
|
1366
1521
|
}
|
|
1367
1522
|
async function initMethod(method, element, options) {
|
|
1523
|
+
// Ensure Primer SDK is loaded before initializing payment method
|
|
1524
|
+
const primerWrapper = new PrimerWrapper();
|
|
1525
|
+
await primerWrapper.ensurePrimerLoaded();
|
|
1368
1526
|
const checkoutInstance = new CheckoutInstance({
|
|
1369
1527
|
orgId: options.orgId,
|
|
1370
1528
|
baseUrl: options.baseUrl,
|