@funnelfox/billing 0.5.0-beta.2 → 0.5.0-beta.4
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 +30 -24
- package/dist/chunk-index.cjs2.js +35 -11
- package/dist/chunk-index.es.js +24 -18
- package/dist/chunk-index.es2.js +35 -11
- package/dist/funnelfox-billing.cjs.js +133 -34
- package/dist/funnelfox-billing.esm.js +133 -34
- package/dist/funnelfox-billing.js +193 -64
- package/dist/funnelfox-billing.min.js +1 -1
- package/package.json +3 -3
- package/src/types.d.ts +36 -17
|
@@ -213,7 +213,7 @@ var PaymentMethod;
|
|
|
213
213
|
/**
|
|
214
214
|
* @fileoverview Constants for Funnefox SDK
|
|
215
215
|
*/
|
|
216
|
-
const SDK_VERSION = '0.5.0-beta.
|
|
216
|
+
const SDK_VERSION = '0.5.0-beta.4';
|
|
217
217
|
const DEFAULTS = {
|
|
218
218
|
BASE_URL: 'https://billing.funnelfox.com',
|
|
219
219
|
REGION: 'default',
|
|
@@ -245,6 +245,7 @@ const EVENTS = {
|
|
|
245
245
|
PURCHASE_FAILURE: 'purchase-failure',
|
|
246
246
|
PURCHASE_COMPLETED: 'purchase-completed',
|
|
247
247
|
PURCHASE_CANCELLED: 'purchase-cancelled',
|
|
248
|
+
METHODS_AVAILABLE: 'methods-available',
|
|
248
249
|
};
|
|
249
250
|
const API_ENDPOINTS = {
|
|
250
251
|
CREATE_CLIENT_SESSION: '/v1/checkout/create_client_session',
|
|
@@ -291,6 +292,12 @@ const inputStyle = {
|
|
|
291
292
|
({
|
|
292
293
|
paddingLeft: inputStyle.input.base.paddingHorizontal + 'px',
|
|
293
294
|
paddingRight: inputStyle.input.base.paddingHorizontal + 'px'});
|
|
295
|
+
const DEFAULT_PAYMENT_METHOD_ORDER = [
|
|
296
|
+
PaymentMethod.APPLE_PAY,
|
|
297
|
+
PaymentMethod.GOOGLE_PAY,
|
|
298
|
+
PaymentMethod.PAYPAL,
|
|
299
|
+
PaymentMethod.PAYMENT_CARD,
|
|
300
|
+
];
|
|
294
301
|
|
|
295
302
|
/**
|
|
296
303
|
* @fileoverview Primer SDK integration wrapper
|
|
@@ -301,6 +308,7 @@ class PrimerWrapper {
|
|
|
301
308
|
this.destroyCallbacks = [];
|
|
302
309
|
this.headless = null;
|
|
303
310
|
this.availableMethods = [];
|
|
311
|
+
this.paymentMethodsInterfaces = [];
|
|
304
312
|
}
|
|
305
313
|
isPrimerAvailable() {
|
|
306
314
|
return (typeof window !== 'undefined' &&
|
|
@@ -333,10 +341,40 @@ class PrimerWrapper {
|
|
|
333
341
|
disableButtons(disabled) {
|
|
334
342
|
if (!this.paymentMethodsInterfaces)
|
|
335
343
|
return;
|
|
336
|
-
for (const
|
|
337
|
-
|
|
344
|
+
for (const paymentMethodInterface of this.paymentMethodsInterfaces) {
|
|
345
|
+
paymentMethodInterface.setDisabled(disabled);
|
|
338
346
|
}
|
|
339
347
|
}
|
|
348
|
+
waitForPayPalReady() {
|
|
349
|
+
return new Promise((resolve, reject) => {
|
|
350
|
+
let counter = 0;
|
|
351
|
+
const checkPayPalEnabler = async () => {
|
|
352
|
+
/**
|
|
353
|
+
* Wait 1000 seconds for PayPal SDK to initialize
|
|
354
|
+
*/
|
|
355
|
+
await new Promise(resolve => {
|
|
356
|
+
setTimeout(() => {
|
|
357
|
+
resolve();
|
|
358
|
+
}, 1000);
|
|
359
|
+
});
|
|
360
|
+
/**
|
|
361
|
+
* @link https://github.com/krakenjs/zoid/issues/334
|
|
362
|
+
*/
|
|
363
|
+
// @ts-expect-error paymentMethod is private property
|
|
364
|
+
const isPayPalReady = !!window?.paypalPrimer?.Buttons?.instances?.[0];
|
|
365
|
+
if (++counter < 20 && !isPayPalReady) {
|
|
366
|
+
setTimeout(checkPayPalEnabler, 0);
|
|
367
|
+
}
|
|
368
|
+
else if (!isPayPalReady) {
|
|
369
|
+
reject(new PrimerError('PayPal paypal_js_sdk_v5_unhandled_exception was detected', PaymentMethod.PAYPAL));
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
resolve();
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
checkPayPalEnabler();
|
|
376
|
+
});
|
|
377
|
+
}
|
|
340
378
|
async renderButton(allowedPaymentMethod, { htmlNode, onMethodRenderError, onMethodRender, }) {
|
|
341
379
|
let button;
|
|
342
380
|
this.ensurePrimerAvailable();
|
|
@@ -350,6 +388,9 @@ class PrimerWrapper {
|
|
|
350
388
|
}
|
|
351
389
|
button = pmManager.createButton();
|
|
352
390
|
await button.render(htmlNode, {});
|
|
391
|
+
if (allowedPaymentMethod === PaymentMethod.PAYPAL) {
|
|
392
|
+
await this.waitForPayPalReady();
|
|
393
|
+
}
|
|
353
394
|
this.destroyCallbacks.push(() => button.clean());
|
|
354
395
|
onMethodRender(allowedPaymentMethod);
|
|
355
396
|
return {
|
|
@@ -371,20 +412,24 @@ class PrimerWrapper {
|
|
|
371
412
|
!options.onInputChange) {
|
|
372
413
|
throw new PrimerError('Card elements, onSubmit, and onInputChange are required for PAYMENT_CARD method');
|
|
373
414
|
}
|
|
374
|
-
|
|
415
|
+
const cardInterface = await this.renderCardCheckoutWithElements(options.cardElements, {
|
|
375
416
|
onSubmit: options.onSubmit,
|
|
376
417
|
onInputChange: options.onInputChange,
|
|
377
418
|
onMethodRenderError: options.onMethodRenderError,
|
|
378
419
|
onMethodRender: options.onMethodRender,
|
|
379
420
|
});
|
|
421
|
+
this.paymentMethodsInterfaces.push(cardInterface);
|
|
422
|
+
return cardInterface;
|
|
380
423
|
}
|
|
381
424
|
else {
|
|
382
425
|
try {
|
|
383
|
-
|
|
426
|
+
const buttonInterface = await this.renderButton(method, {
|
|
384
427
|
htmlNode,
|
|
385
428
|
onMethodRenderError: options.onMethodRenderError,
|
|
386
429
|
onMethodRender: options.onMethodRender,
|
|
387
430
|
});
|
|
431
|
+
this.paymentMethodsInterfaces.push(buttonInterface);
|
|
432
|
+
return buttonInterface;
|
|
388
433
|
}
|
|
389
434
|
catch (error) {
|
|
390
435
|
throw new PrimerError('Failed to initialize Primer checkout', error);
|
|
@@ -459,8 +504,8 @@ class PrimerWrapper {
|
|
|
459
504
|
]);
|
|
460
505
|
const onDestroy = () => {
|
|
461
506
|
pmManager.removeHostedInputs();
|
|
462
|
-
elements.cardholderName
|
|
463
|
-
elements.button
|
|
507
|
+
elements.cardholderName?.removeEventListener('change', cardHolderOnChange);
|
|
508
|
+
elements.button?.removeEventListener('click', onSubmitHandler);
|
|
464
509
|
};
|
|
465
510
|
this.destroyCallbacks.push(onDestroy);
|
|
466
511
|
onMethodRender(PaymentMethod.PAYMENT_CARD);
|
|
@@ -469,7 +514,12 @@ class PrimerWrapper {
|
|
|
469
514
|
cardNumberInput.setDisabled(disabled);
|
|
470
515
|
expiryInput.setDisabled(disabled);
|
|
471
516
|
cvvInput.setDisabled(disabled);
|
|
472
|
-
elements.button
|
|
517
|
+
if (elements.button) {
|
|
518
|
+
elements.button.disabled = disabled;
|
|
519
|
+
}
|
|
520
|
+
if (elements.cardholderName) {
|
|
521
|
+
elements.cardholderName.disabled = disabled;
|
|
522
|
+
}
|
|
473
523
|
},
|
|
474
524
|
submit: () => onSubmitHandler(),
|
|
475
525
|
destroy: () => {
|
|
@@ -508,12 +558,13 @@ class PrimerWrapper {
|
|
|
508
558
|
});
|
|
509
559
|
}
|
|
510
560
|
async renderCheckout(clientToken, checkoutOptions, checkoutRenderOptions) {
|
|
511
|
-
const { cardElements, paymentButtonElements, container, onSubmit, onInputChange, onMethodRender, onMethodRenderError, } = checkoutRenderOptions;
|
|
561
|
+
const { cardElements, paymentButtonElements, container, onSubmit, onInputChange, onMethodRender, onMethodRenderError, onMethodsAvailable, } = checkoutRenderOptions;
|
|
512
562
|
await this.initializeHeadlessCheckout(clientToken, checkoutOptions);
|
|
513
|
-
|
|
563
|
+
onMethodsAvailable?.(this.availableMethods);
|
|
564
|
+
await Promise.all(this.availableMethods.map(method => {
|
|
514
565
|
if (method === PaymentMethod.PAYMENT_CARD) {
|
|
515
566
|
// For card, use the main container
|
|
516
|
-
|
|
567
|
+
return this.initMethod(method, container, {
|
|
517
568
|
cardElements,
|
|
518
569
|
onSubmit,
|
|
519
570
|
onInputChange,
|
|
@@ -529,12 +580,12 @@ class PrimerWrapper {
|
|
|
529
580
|
};
|
|
530
581
|
// For buttons, use the specific button container element
|
|
531
582
|
const buttonElement = buttonElementsMap[method];
|
|
532
|
-
|
|
583
|
+
return this.initMethod(method, buttonElement, {
|
|
533
584
|
onMethodRender,
|
|
534
585
|
onMethodRenderError,
|
|
535
586
|
});
|
|
536
587
|
}
|
|
537
|
-
}
|
|
588
|
+
}));
|
|
538
589
|
this.isInitialized = true;
|
|
539
590
|
}
|
|
540
591
|
wrapTokenizeHandler(handler) {
|
|
@@ -830,12 +881,6 @@ class CheckoutInstance extends EventEmitter {
|
|
|
830
881
|
constructor(config) {
|
|
831
882
|
super();
|
|
832
883
|
this.counter = 0;
|
|
833
|
-
this.paymentMethodOrder = [
|
|
834
|
-
PaymentMethod.APPLE_PAY,
|
|
835
|
-
PaymentMethod.GOOGLE_PAY,
|
|
836
|
-
PaymentMethod.PAYPAL,
|
|
837
|
-
PaymentMethod.PAYMENT_CARD,
|
|
838
|
-
];
|
|
839
884
|
this.handleInputChange = (inputName, error) => {
|
|
840
885
|
this.emit(EVENTS.INPUT_ERROR, { name: inputName, error });
|
|
841
886
|
};
|
|
@@ -892,8 +937,12 @@ class CheckoutInstance extends EventEmitter {
|
|
|
892
937
|
this._setState('ready');
|
|
893
938
|
}
|
|
894
939
|
};
|
|
940
|
+
this.handleMethodsAvailable = (methods) => {
|
|
941
|
+
this.emit(EVENTS.METHODS_AVAILABLE, methods);
|
|
942
|
+
};
|
|
895
943
|
this.onLoaderChangeWithRace = (state) => {
|
|
896
944
|
const isLoading = !!(state ? ++this.counter : --this.counter);
|
|
945
|
+
this.primerWrapper.disableButtons(isLoading);
|
|
897
946
|
this.emit(EVENTS.LOADER_CHANGE, isLoading);
|
|
898
947
|
};
|
|
899
948
|
this.id = generateId('checkout_');
|
|
@@ -961,14 +1010,32 @@ class CheckoutInstance extends EventEmitter {
|
|
|
961
1010
|
timeout: DEFAULTS.REQUEST_TIMEOUT,
|
|
962
1011
|
retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
|
|
963
1012
|
});
|
|
964
|
-
const
|
|
1013
|
+
const sessionParams = {
|
|
965
1014
|
priceId: this.checkoutConfig.priceId,
|
|
966
1015
|
externalId: this.checkoutConfig.customer.externalId,
|
|
967
1016
|
email: this.checkoutConfig.customer.email,
|
|
968
1017
|
region: this.region || DEFAULTS.REGION,
|
|
969
1018
|
clientMetadata: this.checkoutConfig.clientMetadata,
|
|
970
1019
|
countryCode: this.checkoutConfig.customer.countryCode,
|
|
971
|
-
}
|
|
1020
|
+
};
|
|
1021
|
+
const cacheKey = [
|
|
1022
|
+
this.orgId,
|
|
1023
|
+
this.checkoutConfig.priceId,
|
|
1024
|
+
this.checkoutConfig.customer.externalId,
|
|
1025
|
+
this.checkoutConfig.customer.email,
|
|
1026
|
+
].join('-');
|
|
1027
|
+
let sessionResponse;
|
|
1028
|
+
// Return cached response if payload hasn't changed
|
|
1029
|
+
const cachedResponse = await CheckoutInstance.sessionCache.get(cacheKey);
|
|
1030
|
+
if (cachedResponse) {
|
|
1031
|
+
sessionResponse = cachedResponse;
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
const sessionRequest = this.apiClient.createClientSession(sessionParams);
|
|
1035
|
+
// Cache the successful response
|
|
1036
|
+
CheckoutInstance.sessionCache.set(cacheKey, sessionRequest);
|
|
1037
|
+
sessionResponse = await sessionRequest;
|
|
1038
|
+
}
|
|
972
1039
|
const sessionData = this.apiClient.processSessionResponse(sessionResponse);
|
|
973
1040
|
this.orderId = sessionData.orderId;
|
|
974
1041
|
this.clientToken = sessionData.clientToken;
|
|
@@ -1015,9 +1082,8 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1015
1082
|
let checkoutOptions;
|
|
1016
1083
|
if (!this.checkoutConfig.cardSelectors ||
|
|
1017
1084
|
!this.checkoutConfig.paymentButtonSelectors) {
|
|
1018
|
-
|
|
1019
|
-
this.paymentMethodOrder
|
|
1020
|
-
}
|
|
1085
|
+
this.checkoutConfig.paymentMethodOrder =
|
|
1086
|
+
this.checkoutConfig.paymentMethodOrder || DEFAULT_PAYMENT_METHOD_ORDER;
|
|
1021
1087
|
const defaultSkinCheckoutOptions = await this.getDefaultSkinCheckoutOptions();
|
|
1022
1088
|
if (!defaultSkinCheckoutOptions.cardElements ||
|
|
1023
1089
|
!defaultSkinCheckoutOptions.paymentButtonElements) {
|
|
@@ -1029,14 +1095,14 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1029
1095
|
checkoutOptions = this.getCheckoutOptions(defaultSkinCheckoutOptions);
|
|
1030
1096
|
}
|
|
1031
1097
|
else {
|
|
1098
|
+
if (this.checkoutConfig.paymentMethodOrder) {
|
|
1099
|
+
// eslint-disable-next-line no-console
|
|
1100
|
+
console.warn('paymentMethodOrder is using only for default skin and will be ignored if you are using custom checkout');
|
|
1101
|
+
}
|
|
1032
1102
|
cardElements = this.convertCardSelectorsToElements(this.checkoutConfig.cardSelectors, containerElement);
|
|
1033
1103
|
paymentButtonElements = this.convertPaymentButtonSelectorsToElements(this.checkoutConfig.paymentButtonSelectors);
|
|
1034
1104
|
checkoutOptions = this.getCheckoutOptions({});
|
|
1035
1105
|
}
|
|
1036
|
-
if (this.checkoutConfig.paymentMethodOrder) {
|
|
1037
|
-
// eslint-disable-next-line no-console
|
|
1038
|
-
console.warn('paymentMethodOrder is using only for default skin and will be ignored if you are using custom checkout');
|
|
1039
|
-
}
|
|
1040
1106
|
await this.primerWrapper.renderCheckout(this.clientToken, checkoutOptions, {
|
|
1041
1107
|
container: containerElement,
|
|
1042
1108
|
cardElements,
|
|
@@ -1044,6 +1110,8 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1044
1110
|
onSubmit: this.handleSubmit,
|
|
1045
1111
|
onInputChange: this.handleInputChange,
|
|
1046
1112
|
onMethodRender: this.handleMethodRender,
|
|
1113
|
+
onMethodsAvailable: this.handleMethodsAvailable,
|
|
1114
|
+
onMethodRenderError: this.handleMethodRenderError,
|
|
1047
1115
|
});
|
|
1048
1116
|
}
|
|
1049
1117
|
async _processPaymentResult(result, primerHandler) {
|
|
@@ -1124,6 +1192,8 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1124
1192
|
}
|
|
1125
1193
|
try {
|
|
1126
1194
|
this._setState('updating');
|
|
1195
|
+
// Invalidate session cache
|
|
1196
|
+
CheckoutInstance.sessionCache.clear();
|
|
1127
1197
|
await this.apiClient.updateClientSession({
|
|
1128
1198
|
orderId: this.orderId,
|
|
1129
1199
|
clientToken: this.clientToken,
|
|
@@ -1193,7 +1263,7 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1193
1263
|
async getDefaultSkinCheckoutOptions() {
|
|
1194
1264
|
const skinFactory = (await import('./chunk-index.es.js'))
|
|
1195
1265
|
.default;
|
|
1196
|
-
const skin = await skinFactory(this.
|
|
1266
|
+
const skin = await skinFactory(this.checkoutConfig);
|
|
1197
1267
|
this.on(EVENTS.INPUT_ERROR, skin.onInputError);
|
|
1198
1268
|
this.on(EVENTS.STATUS_CHANGE, skin.onStatusChange);
|
|
1199
1269
|
this.on(EVENTS.ERROR, (error) => skin.onError(error));
|
|
@@ -1204,13 +1274,16 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1204
1274
|
this.on(EVENTS.START_PURCHASE, skin.onStartPurchase);
|
|
1205
1275
|
this.on(EVENTS.PURCHASE_FAILURE, skin.onPurchaseFailure);
|
|
1206
1276
|
this.on(EVENTS.PURCHASE_COMPLETED, skin.onPurchaseCompleted);
|
|
1277
|
+
this.on(EVENTS.METHODS_AVAILABLE, skin.onMethodsAvailable);
|
|
1207
1278
|
return skin.getCheckoutOptions();
|
|
1208
1279
|
}
|
|
1209
1280
|
async getCardDefaultSkinCheckoutOptions(node) {
|
|
1210
1281
|
const CardSkin = (await import('./chunk-index.es2.js')).default;
|
|
1211
|
-
const skin = new CardSkin(node);
|
|
1282
|
+
const skin = new CardSkin(node, this.checkoutConfig);
|
|
1212
1283
|
skin.init();
|
|
1213
1284
|
this.on(EVENTS.INPUT_ERROR, skin.onInputError);
|
|
1285
|
+
this.on(EVENTS.METHOD_RENDER, skin.onMethodRender);
|
|
1286
|
+
this.on(EVENTS.SUCCESS, skin.onDestroy);
|
|
1214
1287
|
return skin.getCheckoutOptions();
|
|
1215
1288
|
}
|
|
1216
1289
|
showInitializingLoader() {
|
|
@@ -1220,6 +1293,7 @@ class CheckoutInstance extends EventEmitter {
|
|
|
1220
1293
|
hideLoader();
|
|
1221
1294
|
}
|
|
1222
1295
|
}
|
|
1296
|
+
CheckoutInstance.sessionCache = new Map();
|
|
1223
1297
|
|
|
1224
1298
|
/**
|
|
1225
1299
|
* @fileoverview Public API with configuration and orchestration logic
|
|
@@ -1275,6 +1349,28 @@ async function createClientSession(params) {
|
|
|
1275
1349
|
});
|
|
1276
1350
|
return apiClient.processSessionResponse(sessionResponse);
|
|
1277
1351
|
}
|
|
1352
|
+
async function silentPurchase(options) {
|
|
1353
|
+
const { priceId, externalId, clientMetadata, orgId, baseUrl } = options;
|
|
1354
|
+
const apiClient = new APIClient({
|
|
1355
|
+
baseUrl: baseUrl,
|
|
1356
|
+
orgId: orgId,
|
|
1357
|
+
timeout: DEFAULTS.REQUEST_TIMEOUT,
|
|
1358
|
+
retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
|
|
1359
|
+
});
|
|
1360
|
+
const response = await apiClient.oneClick({
|
|
1361
|
+
pp_ident: priceId,
|
|
1362
|
+
external_id: externalId,
|
|
1363
|
+
client_metadata: clientMetadata,
|
|
1364
|
+
});
|
|
1365
|
+
if (response.status !== 'success' &&
|
|
1366
|
+
response.error.some(({ code }) => code === 'double_purchase')) {
|
|
1367
|
+
throw new APIError('This product was already purchased');
|
|
1368
|
+
}
|
|
1369
|
+
else if (response.status !== 'success') {
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
return true;
|
|
1373
|
+
}
|
|
1278
1374
|
async function initMethod(method, element, options) {
|
|
1279
1375
|
const checkoutInstance = new CheckoutInstance({
|
|
1280
1376
|
orgId: options.orgId,
|
|
@@ -1287,6 +1383,11 @@ async function initMethod(method, element, options) {
|
|
|
1287
1383
|
},
|
|
1288
1384
|
container: '',
|
|
1289
1385
|
clientMetadata: options.meta,
|
|
1386
|
+
card: options.card,
|
|
1387
|
+
style: options.style,
|
|
1388
|
+
applePay: options.applePay,
|
|
1389
|
+
paypal: options.paypal,
|
|
1390
|
+
googlePay: options.googlePay,
|
|
1290
1391
|
},
|
|
1291
1392
|
});
|
|
1292
1393
|
checkoutInstance._ensureNotDestroyed();
|
|
@@ -1303,7 +1404,6 @@ async function initMethod(method, element, options) {
|
|
|
1303
1404
|
if (method === PaymentMethod.PAYMENT_CARD) {
|
|
1304
1405
|
const cardDefaultOptions = await checkoutInstance['getCardDefaultSkinCheckoutOptions'](element);
|
|
1305
1406
|
const checkoutOptions = checkoutInstance['getCheckoutOptions']({
|
|
1306
|
-
style: options.styles,
|
|
1307
1407
|
...cardDefaultOptions,
|
|
1308
1408
|
});
|
|
1309
1409
|
await checkoutInstance.primerWrapper.initializeHeadlessCheckout(checkoutInstance.clientToken, checkoutOptions);
|
|
@@ -1315,9 +1415,7 @@ async function initMethod(method, element, options) {
|
|
|
1315
1415
|
onMethodRenderError: checkoutInstance['handleMethodRenderError'],
|
|
1316
1416
|
});
|
|
1317
1417
|
}
|
|
1318
|
-
await checkoutInstance.primerWrapper.initializeHeadlessCheckout(checkoutInstance.clientToken, checkoutInstance['getCheckoutOptions']({
|
|
1319
|
-
style: options.styles,
|
|
1320
|
-
}));
|
|
1418
|
+
await checkoutInstance.primerWrapper.initializeHeadlessCheckout(checkoutInstance.clientToken, checkoutInstance['getCheckoutOptions']({}));
|
|
1321
1419
|
return checkoutInstance.primerWrapper.initMethod(method, element, {
|
|
1322
1420
|
onMethodRender: checkoutInstance['handleMethodRender'],
|
|
1323
1421
|
onMethodRenderError: checkoutInstance['handleMethodRenderError'],
|
|
@@ -1332,6 +1430,7 @@ const Billing = {
|
|
|
1332
1430
|
createCheckout: createCheckout,
|
|
1333
1431
|
createClientSession: createClientSession,
|
|
1334
1432
|
initMethod: initMethod,
|
|
1433
|
+
silentPurchase: silentPurchase,
|
|
1335
1434
|
};
|
|
1336
1435
|
if (typeof window !== 'undefined') {
|
|
1337
1436
|
window.Billing = Billing;
|