@funnelfox/billing 0.4.3 → 0.5.0-beta.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.
@@ -213,7 +213,7 @@ var PaymentMethod;
213
213
  /**
214
214
  * @fileoverview Constants for Funnefox SDK
215
215
  */
216
- const SDK_VERSION = '0.4.3';
216
+ const SDK_VERSION = '0.5.0-beta.0';
217
217
  const DEFAULTS = {
218
218
  BASE_URL: 'https://billing.funnelfox.com',
219
219
  REGION: 'default',
@@ -240,9 +240,11 @@ const EVENTS = {
240
240
  INPUT_ERROR: 'input-error',
241
241
  LOADER_CHANGE: 'loader-change',
242
242
  METHOD_RENDER: 'method-render',
243
+ METHOD_RENDER_ERROR: 'method-render-error',
243
244
  START_PURCHASE: 'start-purchase',
244
245
  PURCHASE_FAILURE: 'purchase-failure',
245
246
  PURCHASE_COMPLETED: 'purchase-completed',
247
+ PURCHASE_CANCELLED: 'purchase-cancelled',
246
248
  };
247
249
  const API_ENDPOINTS = {
248
250
  CREATE_CLIENT_SESSION: '/v1/checkout/create_client_session',
@@ -318,10 +320,6 @@ class PrimerWrapper {
318
320
  const primerOptions = merge({
319
321
  paymentHandling: 'MANUAL',
320
322
  apiVersion: '2.4',
321
- paypal: {
322
- buttonColor: 'blue',
323
- paymentFlow: 'PREFER_VAULT',
324
- },
325
323
  }, options);
326
324
  try {
327
325
  const headless = await window.Primer.createHeadless(clientToken, primerOptions);
@@ -349,9 +347,64 @@ class PrimerWrapper {
349
347
  this.paymentMethodsInterfaces[method].setDisabled(disabled);
350
348
  }
351
349
  }
352
- async renderCardCheckout({ onSubmit, cardSelectors, onInputChange, }) {
350
+ async renderButton(allowedPaymentMethod, { container, }) {
351
+ const containerEl = this.validateContainer(container);
352
+ let button;
353
+ this.ensurePrimerAvailable();
354
+ if (!this.headless) {
355
+ throw new PrimerError('Headless checkout not found');
356
+ }
357
+ try {
358
+ const pmManager = await this.headless.createPaymentMethodManager(allowedPaymentMethod);
359
+ if (!pmManager) {
360
+ throw new Error('Payment method manager is not available');
361
+ }
362
+ button = pmManager.createButton();
363
+ await button.render(containerEl, {});
364
+ this.destroyCallbacks.push(() => button.clean());
365
+ }
366
+ catch (error) {
367
+ throw new PrimerError('Failed to initialize Primer checkout', error);
368
+ }
369
+ }
370
+ async initMethod(method, htmlNode, options) {
371
+ if (method === PaymentMethod.PAYMENT_CARD) {
372
+ if (!options.cardElements ||
373
+ !options.onSubmit ||
374
+ !options.onInputChange) {
375
+ throw new PrimerError('Card elements, onSubmit, and onInputChange are required for PAYMENT_CARD method');
376
+ }
377
+ return this.renderCardCheckoutWithElements(options.cardElements, {
378
+ onSubmit: options.onSubmit,
379
+ onInputChange: options.onInputChange,
380
+ onMethodRenderError: options.onMethodRenderError,
381
+ onMethodRender: options.onMethodRender,
382
+ });
383
+ }
384
+ else {
385
+ // For button methods, render directly into htmlNode
386
+ this.ensurePrimerAvailable();
387
+ if (!this.headless) {
388
+ throw new PrimerError('Headless checkout not found');
389
+ }
390
+ try {
391
+ const pmManager = await this.headless.createPaymentMethodManager(method);
392
+ if (!pmManager) {
393
+ throw new Error('Payment method manager is not available');
394
+ }
395
+ const button = pmManager.createButton();
396
+ await button.render(htmlNode, {});
397
+ this.destroyCallbacks.push(() => button.clean());
398
+ options.onMethodRender(method);
399
+ }
400
+ catch (error) {
401
+ options.onMethodRenderError(method);
402
+ throw new PrimerError('Failed to initialize Primer checkout', error);
403
+ }
404
+ }
405
+ }
406
+ async renderCardCheckoutWithElements(elements, { onSubmit, onInputChange, onMethodRenderError, onMethodRender, }) {
353
407
  try {
354
- const elements = this.initializeCardElements(cardSelectors);
355
408
  const pmManager = await this.headless.createPaymentMethodManager('PAYMENT_CARD');
356
409
  if (!pmManager) {
357
410
  throw new Error('Payment method manager is not available');
@@ -398,7 +451,7 @@ class PrimerWrapper {
398
451
  onSubmit(false);
399
452
  }
400
453
  };
401
- elements.button.addEventListener('click', onSubmitHandler);
454
+ elements.button?.addEventListener('click', onSubmitHandler);
402
455
  await Promise.all([
403
456
  cardNumberInput.render(elements.cardNumber, {
404
457
  placeholder: '1234 1234 1234 1234',
@@ -416,10 +469,13 @@ class PrimerWrapper {
416
469
  style: inputStyle,
417
470
  }),
418
471
  ]);
419
- this.destroyCallbacks.push(() => {
472
+ const onDestroy = () => {
420
473
  pmManager.removeHostedInputs();
421
474
  elements.cardholderName.removeEventListener('change', cardHolderOnChange);
422
- });
475
+ elements.button.removeEventListener('click', onSubmitHandler);
476
+ };
477
+ this.destroyCallbacks.push(onDestroy);
478
+ onMethodRender(PaymentMethod.PAYMENT_CARD);
423
479
  return {
424
480
  setDisabled: (disabled) => {
425
481
  cardNumberInput.setDisabled(disabled);
@@ -427,38 +483,22 @@ class PrimerWrapper {
427
483
  cvvInput.setDisabled(disabled);
428
484
  elements.button.disabled = disabled;
429
485
  },
486
+ submit: () => onSubmitHandler(),
487
+ destroy: () => {
488
+ this.destroyCallbacks = this.destroyCallbacks.filter(callback => callback !== onDestroy);
489
+ onDestroy();
490
+ },
430
491
  };
431
492
  }
432
493
  catch (error) {
433
494
  throw new PrimerError('Failed to initialize Primer checkout', error);
434
495
  }
435
496
  }
436
- async renderButton(allowedPaymentMethod, { container, }) {
437
- const containerEl = this.validateContainer(container);
438
- let button;
439
- this.ensurePrimerAvailable();
440
- if (!this.headless) {
441
- throw new PrimerError('Headless checkout not found');
442
- }
443
- try {
444
- const pmManager = await this.headless.createPaymentMethodManager(allowedPaymentMethod);
445
- if (!pmManager) {
446
- throw new Error('Payment method manager is not available');
447
- }
448
- button = pmManager.createButton();
449
- await button.render(containerEl, {});
450
- this.destroyCallbacks.push(() => button.clean());
451
- }
452
- catch (error) {
453
- throw new PrimerError('Failed to initialize Primer checkout', error);
454
- }
455
- }
456
- async renderCheckout(clientToken, options) {
457
- const { cardSelectors, paymentButtonSelectors, container, onTokenizeSuccess, onResumeSuccess, onSubmit, onInputChange, onMethodRender, ...restPrimerOptions } = options;
497
+ async initializeHeadlessCheckout(clientToken, primerOptions) {
458
498
  await this.createHeadlessCheckout(clientToken, {
459
- ...restPrimerOptions,
460
- onTokenizeSuccess: this.wrapTokenizeHandler(onTokenizeSuccess),
461
- onResumeSuccess: this.wrapResumeHandler(onResumeSuccess),
499
+ ...primerOptions,
500
+ onTokenizeSuccess: this.wrapTokenizeHandler(primerOptions.onTokenizeSuccess),
501
+ onResumeSuccess: this.wrapResumeHandler(primerOptions.onResumeSuccess),
462
502
  onAvailablePaymentMethodsLoad: (items) => {
463
503
  let isApplePayAvailable = false;
464
504
  this.availableMethods = ALLOWED_PAYMENT_METHODS.filter(method => {
@@ -477,25 +517,33 @@ class PrimerWrapper {
477
517
  }
478
518
  },
479
519
  });
480
- const methodOptions = {
481
- cardSelectors,
482
- container,
483
- onSubmit,
484
- onInputChange,
485
- };
520
+ }
521
+ async renderCheckout(clientToken, checkoutOptions, checkoutRenderOptions) {
522
+ const { cardElements, paymentButtonElements, container, onSubmit, onInputChange, onMethodRender, onMethodRenderError, } = checkoutRenderOptions;
523
+ await this.initializeHeadlessCheckout(clientToken, checkoutOptions);
486
524
  for (const method of this.availableMethods) {
487
525
  if (method === PaymentMethod.PAYMENT_CARD) {
488
- await this.renderCardCheckout(methodOptions);
489
- onMethodRender(PaymentMethod.PAYMENT_CARD);
526
+ // For card, use the main container
527
+ await this.initMethod(method, container, {
528
+ cardElements,
529
+ onSubmit,
530
+ onInputChange,
531
+ onMethodRender,
532
+ onMethodRenderError,
533
+ });
490
534
  }
491
535
  else {
492
- const container = method === PaymentMethod.PAYPAL
493
- ? paymentButtonSelectors.paypal
494
- : method === PaymentMethod.GOOGLE_PAY
495
- ? paymentButtonSelectors.googlePay
496
- : paymentButtonSelectors.applePay;
497
- await this.renderButton(method, { container });
498
- onMethodRender(method);
536
+ const buttonElementsMap = {
537
+ [PaymentMethod.PAYPAL]: paymentButtonElements.paypal,
538
+ [PaymentMethod.GOOGLE_PAY]: paymentButtonElements.googlePay,
539
+ [PaymentMethod.APPLE_PAY]: paymentButtonElements.applePay,
540
+ };
541
+ // For buttons, use the specific button container element
542
+ const buttonElement = buttonElementsMap[method];
543
+ await this.initMethod(method, buttonElement, {
544
+ onMethodRender,
545
+ onMethodRenderError,
546
+ });
499
547
  }
500
548
  }
501
549
  this.isInitialized = true;
@@ -756,6 +804,12 @@ class APIClient {
756
804
  }
757
805
  throw new APIError('Invalid payment response format', null, { response });
758
806
  }
807
+ async oneClick(payload) {
808
+ return (await this.request(`/billing/${this.orgId}/v1/checkout/one_click`, {
809
+ method: 'POST',
810
+ body: JSON.stringify(payload),
811
+ }));
812
+ }
759
813
  }
760
814
 
761
815
  var loaderHtml = "<div class=\"ff-sdk-loader-container\">\n <div class=\"ff-sdk-loader\"></div>\n</div>\n";
@@ -793,6 +847,9 @@ class CheckoutInstance extends EventEmitter {
793
847
  this.handleMethodRender = (method) => {
794
848
  this.emit(EVENTS.METHOD_RENDER, method);
795
849
  };
850
+ this.handleMethodRenderError = (method) => {
851
+ this.emit(EVENTS.METHOD_RENDER_ERROR, method);
852
+ };
796
853
  this.handleSubmit = (isSubmitting) => {
797
854
  this.onLoaderChangeWithRace(isSubmitting);
798
855
  this._setState(isSubmitting ? 'processing' : 'ready');
@@ -865,9 +922,6 @@ class CheckoutInstance extends EventEmitter {
865
922
  this.primerWrapper = new PrimerWrapper();
866
923
  this.isDestroyed = false;
867
924
  this._setupCallbackBridges();
868
- this.initialize().then(() => {
869
- this.checkoutConfig?.onInitialized?.();
870
- });
871
925
  }
872
926
  _setupCallbackBridges() {
873
927
  if (this.callbacks.onSuccess) {
@@ -890,25 +944,10 @@ class CheckoutInstance extends EventEmitter {
890
944
  try {
891
945
  this.showInitializingLoader();
892
946
  this._setState('initializing');
893
- this.apiClient = new APIClient({
894
- baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
895
- orgId: this.orgId,
896
- timeout: DEFAULTS.REQUEST_TIMEOUT,
897
- retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
898
- });
899
- const sessionResponse = await this.apiClient.createClientSession({
900
- priceId: this.checkoutConfig.priceId,
901
- externalId: this.checkoutConfig.customer.externalId,
902
- email: this.checkoutConfig.customer.email,
903
- region: this.region || DEFAULTS.REGION,
904
- clientMetadata: this.checkoutConfig.clientMetadata,
905
- countryCode: this.checkoutConfig.customer.countryCode,
906
- });
907
- const sessionData = this.apiClient.processSessionResponse(sessionResponse);
908
- this.orderId = sessionData.orderId;
909
- this.clientToken = sessionData.clientToken;
947
+ await this.createSession();
910
948
  await this._initializePrimerCheckout();
911
949
  this._setState('ready');
950
+ this.checkoutConfig?.onInitialized?.();
912
951
  return this;
913
952
  }
914
953
  catch (error) {
@@ -920,41 +959,90 @@ class CheckoutInstance extends EventEmitter {
920
959
  this.hideInitializingLoader();
921
960
  }
922
961
  }
923
- async _initializePrimerCheckout() {
924
- const checkoutOptions = {
925
- ...this.checkoutConfig,
926
- onTokenizeSuccess: this.handleTokenizeSuccess,
927
- onResumeSuccess: this.handleResumeSuccess,
928
- onSubmit: this.handleSubmit,
929
- onInputChange: this.handleInputChange,
930
- onMethodRender: this.handleMethodRender,
931
- onResumeError: error => {
932
- if (error.stack?.includes('PROCESSOR_3DS') &&
933
- error.code === 'RESUME_ERROR' &&
934
- error.message?.includes('fetch resume key')) {
935
- // Ignore 3DS close error, because it is not understandable by user
936
- return;
937
- }
938
- this.emit(EVENTS.PURCHASE_FAILURE, error);
939
- },
940
- onCheckoutFail: error => {
941
- this.emit(EVENTS.PURCHASE_FAILURE, error);
942
- },
943
- onTokenizeError: error => {
944
- this.emit(EVENTS.PURCHASE_FAILURE, error);
945
- },
946
- onTokenizeShouldStart: data => {
947
- this.emit(EVENTS.ERROR, undefined);
948
- this.emit(EVENTS.START_PURCHASE, data.paymentMethodType);
949
- return true;
950
- },
962
+ async createSession() {
963
+ this.apiClient = new APIClient({
964
+ baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
965
+ orgId: this.orgId,
966
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
967
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
968
+ });
969
+ const sessionResponse = await this.apiClient.createClientSession({
970
+ priceId: this.checkoutConfig.priceId,
971
+ externalId: this.checkoutConfig.customer.externalId,
972
+ email: this.checkoutConfig.customer.email,
973
+ region: this.region || DEFAULTS.REGION,
974
+ clientMetadata: this.checkoutConfig.clientMetadata,
975
+ countryCode: this.checkoutConfig.customer.countryCode,
976
+ });
977
+ const sessionData = this.apiClient.processSessionResponse(sessionResponse);
978
+ this.orderId = sessionData.orderId;
979
+ this.clientToken = sessionData.clientToken;
980
+ }
981
+ convertCardSelectorsToElements(selectors, container) {
982
+ const cardNumber = container.querySelector(selectors.cardNumber);
983
+ const expiryDate = container.querySelector(selectors.expiryDate);
984
+ const cvv = container.querySelector(selectors.cvv);
985
+ const cardholderName = container.querySelector(selectors.cardholderName);
986
+ const button = container.querySelector(selectors.button);
987
+ if (!cardNumber || !expiryDate || !cvv || !button) {
988
+ throw new CheckoutError('Required card input elements not found in container');
989
+ }
990
+ return {
991
+ cardNumber,
992
+ expiryDate,
993
+ cvv,
994
+ cardholderName,
995
+ button,
996
+ };
997
+ }
998
+ convertPaymentButtonSelectorsToElements(selectors) {
999
+ const paypal = document.querySelector(selectors.paypal);
1000
+ const googlePay = document.querySelector(selectors.googlePay);
1001
+ const applePay = document.querySelector(selectors.applePay);
1002
+ if (!paypal || !googlePay || !applePay) {
1003
+ throw new CheckoutError('Required payment button elements not found in container');
1004
+ }
1005
+ return {
1006
+ paypal,
1007
+ googlePay,
1008
+ applePay,
951
1009
  };
1010
+ }
1011
+ async _initializePrimerCheckout() {
1012
+ // Get container element
1013
+ const containerElement = this.getContainer();
1014
+ if (!containerElement) {
1015
+ throw new CheckoutError(`Checkout container not found: ${this.checkoutConfig.container}`);
1016
+ }
1017
+ // Get selectors (either from config or default skin)
1018
+ let cardElements;
1019
+ let paymentButtonElements;
1020
+ let checkoutOptions;
952
1021
  if (!this.checkoutConfig.cardSelectors ||
953
1022
  !this.checkoutConfig.paymentButtonSelectors) {
954
1023
  const defaultSkinCheckoutOptions = await this.getDefaultSkinCheckoutOptions();
955
- Object.assign(checkoutOptions, defaultSkinCheckoutOptions);
1024
+ if (!defaultSkinCheckoutOptions.cardElements ||
1025
+ !defaultSkinCheckoutOptions.paymentButtonElements) {
1026
+ throw new CheckoutError('Default skin must provide cardSelectors and paymentButtonSelectors');
1027
+ }
1028
+ cardElements =
1029
+ defaultSkinCheckoutOptions.cardElements;
1030
+ paymentButtonElements = defaultSkinCheckoutOptions.paymentButtonElements;
1031
+ checkoutOptions = this.getCheckoutOptions(defaultSkinCheckoutOptions);
1032
+ }
1033
+ else {
1034
+ cardElements = this.convertCardSelectorsToElements(this.checkoutConfig.cardSelectors, containerElement);
1035
+ paymentButtonElements = this.convertPaymentButtonSelectorsToElements(this.checkoutConfig.paymentButtonSelectors);
1036
+ checkoutOptions = this.getCheckoutOptions({});
956
1037
  }
957
- await this.primerWrapper.renderCheckout(this.clientToken, checkoutOptions);
1038
+ await this.primerWrapper.renderCheckout(this.clientToken, checkoutOptions, {
1039
+ container: containerElement,
1040
+ cardElements,
1041
+ paymentButtonElements,
1042
+ onSubmit: this.handleSubmit,
1043
+ onInputChange: this.handleInputChange,
1044
+ onMethodRender: this.handleMethodRender,
1045
+ });
958
1046
  }
959
1047
  async _processPaymentResult(result, primerHandler) {
960
1048
  if (result.orderId) {
@@ -984,6 +1072,48 @@ class CheckoutInstance extends EventEmitter {
984
1072
  throw new CheckoutError(`Unknown payment result type: ${result.type}`);
985
1073
  }
986
1074
  }
1075
+ getCheckoutOptions(options) {
1076
+ let wasPaymentProcessedStarted = false;
1077
+ return {
1078
+ ...this.checkoutConfig,
1079
+ ...options,
1080
+ onTokenizeSuccess: this.handleTokenizeSuccess,
1081
+ onResumeSuccess: this.handleResumeSuccess,
1082
+ onResumeError: error => {
1083
+ if (error.stack?.includes('PROCESSOR_3DS') &&
1084
+ error.code === 'RESUME_ERROR' &&
1085
+ error.message?.includes('fetch resume key')) {
1086
+ // Ignore 3DS close error, because it is not understandable by user
1087
+ return;
1088
+ }
1089
+ this.emit(EVENTS.PURCHASE_FAILURE, error);
1090
+ },
1091
+ onCheckoutFail: error => {
1092
+ this.emit(EVENTS.PURCHASE_FAILURE, error);
1093
+ },
1094
+ onTokenizeError: error => {
1095
+ this.emit(EVENTS.PURCHASE_FAILURE, error);
1096
+ },
1097
+ onTokenizeShouldStart: data => {
1098
+ this.emit(EVENTS.ERROR, undefined);
1099
+ this.emit(EVENTS.START_PURCHASE, data.paymentMethodType);
1100
+ return true;
1101
+ },
1102
+ onPaymentMethodAction: action => {
1103
+ switch (action) {
1104
+ case 'PAYMENT_METHOD_SELECTED':
1105
+ this.emit(EVENTS.ERROR, undefined);
1106
+ break;
1107
+ case 'PAYMENT_METHOD_UNSELECTED':
1108
+ if (!wasPaymentProcessedStarted) {
1109
+ this.emit(EVENTS.PURCHASE_CANCELLED);
1110
+ }
1111
+ wasPaymentProcessedStarted = false;
1112
+ break;
1113
+ }
1114
+ },
1115
+ };
1116
+ }
987
1117
  async updatePrice(newPriceId) {
988
1118
  this._ensureNotDestroyed();
989
1119
  requireString(newPriceId, 'priceId');
@@ -1074,6 +1204,13 @@ class CheckoutInstance extends EventEmitter {
1074
1204
  this.on(EVENTS.PURCHASE_COMPLETED, skin.onPurchaseCompleted);
1075
1205
  return skin.getCheckoutOptions();
1076
1206
  }
1207
+ async getCardDefaultSkinCheckoutOptions(node) {
1208
+ const CardSkin = (await import('./chunk-index.es2.js')).default;
1209
+ const skin = new CardSkin(node);
1210
+ skin.init();
1211
+ this.on(EVENTS.INPUT_ERROR, skin.onInputError);
1212
+ return skin.getCheckoutOptions();
1213
+ }
1077
1214
  showInitializingLoader() {
1078
1215
  renderLoader(this.checkoutConfig.container);
1079
1216
  }
@@ -1108,19 +1245,14 @@ async function createCheckout(options) {
1108
1245
  const primerWrapper = new PrimerWrapper();
1109
1246
  primerWrapper.ensurePrimerAvailable();
1110
1247
  const config = resolveConfig(options, 'createCheckout');
1111
- return new Promise(resolve => {
1112
- const onInitialized = () => {
1113
- resolve(checkout);
1114
- checkoutConfig.onInitialized?.();
1115
- };
1116
- const checkout = new CheckoutInstance({
1117
- ...config,
1118
- checkoutConfig: {
1119
- ...checkoutConfig,
1120
- onInitialized,
1121
- },
1122
- });
1248
+ const checkout = new CheckoutInstance({
1249
+ ...config,
1250
+ checkoutConfig: {
1251
+ ...checkoutConfig,
1252
+ },
1123
1253
  });
1254
+ await checkout.initialize();
1255
+ return checkout;
1124
1256
  }
1125
1257
  async function createClientSession(params) {
1126
1258
  const { priceId, externalId, email, clientMetadata, countryCode } = params;
@@ -1141,6 +1273,54 @@ async function createClientSession(params) {
1141
1273
  });
1142
1274
  return apiClient.processSessionResponse(sessionResponse);
1143
1275
  }
1276
+ async function initMethod(method, element, options) {
1277
+ const checkoutInstance = new CheckoutInstance({
1278
+ orgId: options.orgId,
1279
+ baseUrl: options.baseUrl,
1280
+ checkoutConfig: {
1281
+ priceId: options.priceId,
1282
+ customer: {
1283
+ externalId: options.externalId,
1284
+ email: options.email,
1285
+ },
1286
+ container: '',
1287
+ clientMetadata: options.meta,
1288
+ },
1289
+ });
1290
+ checkoutInstance._ensureNotDestroyed();
1291
+ if (!checkoutInstance.isReady()) {
1292
+ await checkoutInstance['createSession']();
1293
+ }
1294
+ checkoutInstance.on(EVENTS.METHOD_RENDER, options.onRenderSuccess);
1295
+ checkoutInstance.on(EVENTS.METHOD_RENDER_ERROR, options.onRenderError);
1296
+ checkoutInstance.on(EVENTS.LOADER_CHANGE, options.onLoaderChange);
1297
+ checkoutInstance.on(EVENTS.SUCCESS, options.onPaymentSuccess);
1298
+ checkoutInstance.on(EVENTS.PURCHASE_FAILURE, options.onPaymentFail);
1299
+ checkoutInstance.on(EVENTS.PURCHASE_CANCELLED, options.onPaymentCancel);
1300
+ checkoutInstance.on(EVENTS.ERROR, options.onErrorMessageChange);
1301
+ if (method === PaymentMethod.PAYMENT_CARD) {
1302
+ const cardDefaultOptions = await checkoutInstance['getCardDefaultSkinCheckoutOptions'](element);
1303
+ const checkoutOptions = checkoutInstance['getCheckoutOptions']({
1304
+ style: options.styles,
1305
+ ...cardDefaultOptions,
1306
+ });
1307
+ await checkoutInstance.primerWrapper.initializeHeadlessCheckout(checkoutInstance.clientToken, checkoutOptions);
1308
+ return checkoutInstance.primerWrapper.initMethod(method, element, {
1309
+ cardElements: cardDefaultOptions.cardElements,
1310
+ onSubmit: checkoutInstance['handleSubmit'],
1311
+ onInputChange: checkoutInstance['handleInputChange'],
1312
+ onMethodRender: checkoutInstance['handleMethodRender'],
1313
+ onMethodRenderError: checkoutInstance['handleMethodRenderError'],
1314
+ });
1315
+ }
1316
+ await checkoutInstance.primerWrapper.initializeHeadlessCheckout(checkoutInstance.clientToken, checkoutInstance['getCheckoutOptions']({
1317
+ style: options.styles,
1318
+ }));
1319
+ return checkoutInstance.primerWrapper.initMethod(method, element, {
1320
+ onMethodRender: checkoutInstance['handleMethodRender'],
1321
+ onMethodRenderError: checkoutInstance['handleMethodRenderError'],
1322
+ });
1323
+ }
1144
1324
 
1145
1325
  /**
1146
1326
  * @fileoverview Main entry point for @funnelfox/billing
@@ -1149,9 +1329,10 @@ const Billing = {
1149
1329
  configure: configure,
1150
1330
  createCheckout: createCheckout,
1151
1331
  createClientSession: createClientSession,
1332
+ initMethod: initMethod,
1152
1333
  };
1153
1334
  if (typeof window !== 'undefined') {
1154
1335
  window.Billing = Billing;
1155
1336
  }
1156
1337
 
1157
- export { APIError, Billing, CHECKOUT_STATES, CheckoutError, ConfigurationError, DEFAULTS, ERROR_CODES, EVENTS, FunnefoxSDKError, NetworkError, PrimerError, SDK_VERSION, ValidationError, configure, createCheckout, createClientSession, Billing as default };
1338
+ export { APIError, Billing, CHECKOUT_STATES, CheckoutError, ConfigurationError, DEFAULTS, ERROR_CODES, EVENTS, FunnefoxSDKError, NetworkError, PaymentMethod, PrimerError, SDK_VERSION, ValidationError, configure, createCheckout, createClientSession, Billing as default };