@funnelfox/billing 0.8.0 → 0.9.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.
@@ -491,7 +491,7 @@ exports.PaymentMethod = void 0;
491
491
  /**
492
492
  * @fileoverview Constants for Funnefox SDK
493
493
  */
494
- const SDK_VERSION = '0.8.0';
494
+ const SDK_VERSION = '0.9.0-beta.0';
495
495
  const DEFAULTS = {
496
496
  BASE_URL: 'https://billing.funnelfox.com',
497
497
  REGION: 'default',
@@ -1128,7 +1128,7 @@ class APIClient {
1128
1128
  async createClientSession(params) {
1129
1129
  const payload = {
1130
1130
  region: params.region || 'default',
1131
- integration_type: 'primer',
1131
+ integration_type: params.integration ?? 'primer',
1132
1132
  pp_ident: params.priceId,
1133
1133
  external_id: params.externalId,
1134
1134
  email_address: params.email,
@@ -1264,6 +1264,45 @@ class APIClient {
1264
1264
  }
1265
1265
  }
1266
1266
 
1267
+ class SessionService {
1268
+ constructor() {
1269
+ this.cache = new Map();
1270
+ }
1271
+ buildCacheKey(p) {
1272
+ return [p.orgId, p.priceId, p.externalId, p.email, p.integration].join('-');
1273
+ }
1274
+ makeClient(orgId, baseUrl) {
1275
+ return new APIClient({
1276
+ baseUrl: baseUrl || DEFAULTS.BASE_URL,
1277
+ orgId,
1278
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1279
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1280
+ });
1281
+ }
1282
+ createSession(p) {
1283
+ const key = this.buildCacheKey(p);
1284
+ const cached = this.cache.get(key);
1285
+ if (cached)
1286
+ return cached;
1287
+ const client = this.makeClient(p.orgId, p.baseUrl);
1288
+ const req = client.createClientSession({
1289
+ priceId: p.priceId,
1290
+ externalId: p.externalId,
1291
+ email: p.email,
1292
+ region: p.region || DEFAULTS.REGION,
1293
+ clientMetadata: p.clientMetadata,
1294
+ countryCode: p.countryCode,
1295
+ integration: p.integration,
1296
+ });
1297
+ this.cache.set(key, req);
1298
+ return req;
1299
+ }
1300
+ clearCache() {
1301
+ this.cache.clear();
1302
+ }
1303
+ }
1304
+ var sessionService = new SessionService();
1305
+
1267
1306
  var loaderHtml = "<div class=\"ff-sdk-loader-container\">\n <div class=\"ff-sdk-loader\"></div>\n</div>\n";
1268
1307
 
1269
1308
  if(typeof document!=="undefined")document.head.appendChild(document.createElement("style")).textContent=".ff-sdk-loader-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: rgba(255, 255, 255);\n z-index: 2;\n}\n\n.ff-sdk-loader {\n width: 24px;\n height: 24px;\n border: 4px solid #e32f41;\n border-top: 4px solid transparent;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }";
@@ -1858,6 +1897,12 @@ class CheckoutInstance extends EventEmitter {
1858
1897
  this.cardEmailAddress = this.checkoutConfig.customer.email;
1859
1898
  this.shouldApplySessionCardholderNameConfig =
1860
1899
  this.checkoutConfig.card?.cardholderName?.required === undefined;
1900
+ this.apiClient = new APIClient({
1901
+ baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1902
+ orgId: this.orgId,
1903
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1904
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1905
+ });
1861
1906
  this._setupCallbackBridges();
1862
1907
  }
1863
1908
  _setupCallbackBridges() {
@@ -1899,64 +1944,35 @@ class CheckoutInstance extends EventEmitter {
1899
1944
  }
1900
1945
  }
1901
1946
  async createSession() {
1902
- this.apiClient = new APIClient({
1903
- baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1947
+ const response = await sessionService.createSession({
1904
1948
  orgId: this.orgId,
1905
- timeout: DEFAULTS.REQUEST_TIMEOUT,
1906
- retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1907
- });
1908
- const sessionParams = {
1949
+ baseUrl: this.baseUrl,
1909
1950
  priceId: this.checkoutConfig.priceId,
1910
1951
  externalId: this.checkoutConfig.customer.externalId,
1911
1952
  email: this.checkoutConfig.customer.email,
1912
- region: this.region || DEFAULTS.REGION,
1953
+ region: this.region,
1913
1954
  clientMetadata: this.checkoutConfig.clientMetadata,
1914
1955
  countryCode: this.checkoutConfig.customer.countryCode,
1915
- };
1916
- const cacheKey = [
1917
- this.orgId,
1918
- this.checkoutConfig.priceId,
1919
- this.checkoutConfig.customer.externalId,
1920
- this.checkoutConfig.customer.email,
1921
- ].join('-');
1922
- let sessionResponse;
1923
- // Return cached response if payload hasn't changed
1924
- const cachedResponse = CheckoutInstance.sessionCache.get(cacheKey);
1925
- if (cachedResponse) {
1926
- sessionResponse = await cachedResponse;
1927
- }
1928
- else {
1929
- const sessionRequest = this.apiClient
1930
- .createClientSession(sessionParams)
1931
- .then((response) => {
1932
- const cachedResponse = response;
1933
- if (response.data?.stripe_public_key) {
1934
- const stripePublicKey = response.data.stripe_public_key;
1935
- cachedResponse.radarSessionId = loadStripe(stripePublicKey)
1936
- .then(stripe => stripe
1937
- ? stripe
1938
- .createRadarSession()
1939
- .then(session => session?.radarSession?.id || '')
1940
- .catch(() => '')
1941
- : '')
1942
- .catch(() => '');
1943
- }
1944
- // Initialize Airwallex device fingerprinting if enabled by backend
1945
- if (response.data?.airwallex_risk_enabled) {
1946
- const isLivemode = response.data?.is_livemode;
1947
- const deviceId = generateUUID();
1948
- cachedResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1949
- .then(() => deviceId)
1950
- .catch(() => {
1951
- // Silently fail - return deviceId anyway
1952
- return deviceId;
1953
- });
1954
- }
1955
- return cachedResponse;
1956
- });
1957
- // Cache the successful response
1958
- CheckoutInstance.sessionCache.set(cacheKey, sessionRequest);
1959
- sessionResponse = await sessionRequest;
1956
+ integration: 'primer',
1957
+ });
1958
+ const sessionResponse = response;
1959
+ if (response.data?.stripe_public_key) {
1960
+ const stripePublicKey = response.data.stripe_public_key;
1961
+ sessionResponse.radarSessionId = loadStripe(stripePublicKey)
1962
+ .then(stripe => stripe
1963
+ ? stripe
1964
+ .createRadarSession()
1965
+ .then(session => session?.radarSession?.id || '')
1966
+ .catch(() => '')
1967
+ : '')
1968
+ .catch(() => '');
1969
+ }
1970
+ if (response.data?.airwallex_risk_enabled) {
1971
+ const isLivemode = response.data?.is_livemode;
1972
+ const deviceId = generateUUID();
1973
+ sessionResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1974
+ .then(() => deviceId)
1975
+ .catch(() => deviceId);
1960
1976
  }
1961
1977
  this.cachedSessionResponse = sessionResponse;
1962
1978
  this.isTelemetryEnabled = !!sessionResponse.data?.sdk_telemetry_enabled;
@@ -2215,8 +2231,7 @@ class CheckoutInstance extends EventEmitter {
2215
2231
  try {
2216
2232
  this.onLoaderChangeWithRace(true);
2217
2233
  this._setState('updating');
2218
- // Invalidate session cache
2219
- CheckoutInstance.sessionCache.clear();
2234
+ sessionService.clearCache();
2220
2235
  await this.apiClient.updateClientSession({
2221
2236
  orderId: this.orderId,
2222
2237
  clientToken: this.clientToken,
@@ -2249,7 +2264,7 @@ class CheckoutInstance extends EventEmitter {
2249
2264
  return;
2250
2265
  try {
2251
2266
  this.stopUnhandledTelemetry();
2252
- CheckoutInstance.sessionCache.clear();
2267
+ sessionService.clearCache();
2253
2268
  await this.primerWrapper.destroy();
2254
2269
  this._setState('destroyed');
2255
2270
  this.orderId = null;
@@ -2460,7 +2475,6 @@ class CheckoutInstance extends EventEmitter {
2460
2475
  this.telemetryPaymentMethod = undefined;
2461
2476
  }
2462
2477
  }
2463
- CheckoutInstance.sessionCache = new Map();
2464
2478
 
2465
2479
  /**
2466
2480
  * @fileoverview Public API with configuration and orchestration logic
@@ -2651,6 +2665,71 @@ async function getAvailablePaymentMethods(params) {
2651
2665
  throw error;
2652
2666
  }
2653
2667
  }
2668
+ async function createStripeCardForm(element, params) {
2669
+ const config = resolveConfig(params, 'createStripeCardForm');
2670
+ const [session, { mountStripeCardForm }] = await Promise.all([
2671
+ sessionService.createSession({
2672
+ orgId: config.orgId,
2673
+ baseUrl: config.baseUrl,
2674
+ region: config.region,
2675
+ priceId: params.priceId,
2676
+ externalId: params.externalId,
2677
+ email: params.email,
2678
+ clientMetadata: params.clientMetadata,
2679
+ countryCode: params.countryCode,
2680
+ integration: 'stripe',
2681
+ }),
2682
+ Promise.resolve().then(function () { return require('./chunk-stripe-card-form.cjs.js'); }),
2683
+ ]);
2684
+ return mountStripeCardForm(element, session, params);
2685
+ }
2686
+ async function purchaseStripeWallet(params) {
2687
+ const config = resolveConfig(params, 'purchaseStripeWallet');
2688
+ const [session, { purchaseWallet }] = await Promise.all([
2689
+ sessionService.createSession({
2690
+ orgId: config.orgId,
2691
+ baseUrl: config.baseUrl,
2692
+ region: config.region,
2693
+ priceId: params.priceId,
2694
+ externalId: params.externalId,
2695
+ email: params.email,
2696
+ clientMetadata: params.clientMetadata,
2697
+ countryCode: params.countryCode,
2698
+ integration: 'stripe',
2699
+ }),
2700
+ Promise.resolve().then(function () { return require('./chunk-stripe-wallet.cjs.js'); }),
2701
+ ]);
2702
+ return purchaseWallet(session, params);
2703
+ }
2704
+ async function getAvailableStripeWallet(params) {
2705
+ const config = resolveConfig(params, 'getAvailableStripeWallet');
2706
+ const [session, { getAvailableWallet }] = await Promise.all([
2707
+ sessionService.createSession({
2708
+ orgId: config.orgId,
2709
+ baseUrl: config.baseUrl,
2710
+ region: config.region,
2711
+ priceId: params.priceId,
2712
+ externalId: params.externalId,
2713
+ email: params.email,
2714
+ clientMetadata: params.clientMetadata,
2715
+ countryCode: params.countryCode,
2716
+ integration: 'stripe',
2717
+ }),
2718
+ Promise.resolve().then(function () { return require('./chunk-stripe-wallet.cjs.js'); }),
2719
+ ]);
2720
+ const result = await getAvailableWallet(session);
2721
+ if (result === 'APPLE_PAY')
2722
+ return exports.PaymentMethod.APPLE_PAY;
2723
+ if (result === 'GOOGLE_PAY')
2724
+ return exports.PaymentMethod.GOOGLE_PAY;
2725
+ return null;
2726
+ }
2727
+ async function getAvailableStripePaymentMethods(params) {
2728
+ const wallet = await getAvailableStripeWallet(params);
2729
+ return wallet
2730
+ ? [exports.PaymentMethod.PAYMENT_CARD, wallet]
2731
+ : [exports.PaymentMethod.PAYMENT_CARD];
2732
+ }
2654
2733
 
2655
2734
  /**
2656
2735
  * @fileoverview Main entry point for @funnelfox/billing
@@ -2662,6 +2741,12 @@ const Billing = {
2662
2741
  initMethod: initMethod,
2663
2742
  silentPurchase: silentPurchase,
2664
2743
  getAvailablePaymentMethods: getAvailablePaymentMethods,
2744
+ stripe: {
2745
+ createCardForm: createStripeCardForm,
2746
+ purchaseWallet: purchaseStripeWallet,
2747
+ getAvailableWallet: getAvailableStripeWallet,
2748
+ getAvailablePaymentMethods: getAvailableStripePaymentMethods,
2749
+ },
2665
2750
  };
2666
2751
  if (typeof window !== 'undefined') {
2667
2752
  window.Billing = Billing;
@@ -2685,3 +2770,4 @@ exports.configure = configure;
2685
2770
  exports.createCheckout = createCheckout;
2686
2771
  exports.createClientSession = createClientSession;
2687
2772
  exports.getAvailablePaymentMethods = getAvailablePaymentMethods;
2773
+ exports.loadStripe = loadStripe;
@@ -489,7 +489,7 @@ var PaymentMethod;
489
489
  /**
490
490
  * @fileoverview Constants for Funnefox SDK
491
491
  */
492
- const SDK_VERSION = '0.8.0';
492
+ const SDK_VERSION = '0.9.0-beta.0';
493
493
  const DEFAULTS = {
494
494
  BASE_URL: 'https://billing.funnelfox.com',
495
495
  REGION: 'default',
@@ -1126,7 +1126,7 @@ class APIClient {
1126
1126
  async createClientSession(params) {
1127
1127
  const payload = {
1128
1128
  region: params.region || 'default',
1129
- integration_type: 'primer',
1129
+ integration_type: params.integration ?? 'primer',
1130
1130
  pp_ident: params.priceId,
1131
1131
  external_id: params.externalId,
1132
1132
  email_address: params.email,
@@ -1262,6 +1262,45 @@ class APIClient {
1262
1262
  }
1263
1263
  }
1264
1264
 
1265
+ class SessionService {
1266
+ constructor() {
1267
+ this.cache = new Map();
1268
+ }
1269
+ buildCacheKey(p) {
1270
+ return [p.orgId, p.priceId, p.externalId, p.email, p.integration].join('-');
1271
+ }
1272
+ makeClient(orgId, baseUrl) {
1273
+ return new APIClient({
1274
+ baseUrl: baseUrl || DEFAULTS.BASE_URL,
1275
+ orgId,
1276
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1277
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1278
+ });
1279
+ }
1280
+ createSession(p) {
1281
+ const key = this.buildCacheKey(p);
1282
+ const cached = this.cache.get(key);
1283
+ if (cached)
1284
+ return cached;
1285
+ const client = this.makeClient(p.orgId, p.baseUrl);
1286
+ const req = client.createClientSession({
1287
+ priceId: p.priceId,
1288
+ externalId: p.externalId,
1289
+ email: p.email,
1290
+ region: p.region || DEFAULTS.REGION,
1291
+ clientMetadata: p.clientMetadata,
1292
+ countryCode: p.countryCode,
1293
+ integration: p.integration,
1294
+ });
1295
+ this.cache.set(key, req);
1296
+ return req;
1297
+ }
1298
+ clearCache() {
1299
+ this.cache.clear();
1300
+ }
1301
+ }
1302
+ var sessionService = new SessionService();
1303
+
1265
1304
  var loaderHtml = "<div class=\"ff-sdk-loader-container\">\n <div class=\"ff-sdk-loader\"></div>\n</div>\n";
1266
1305
 
1267
1306
  if(typeof document!=="undefined")document.head.appendChild(document.createElement("style")).textContent=".ff-sdk-loader-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: rgba(255, 255, 255);\n z-index: 2;\n}\n\n.ff-sdk-loader {\n width: 24px;\n height: 24px;\n border: 4px solid #e32f41;\n border-top: 4px solid transparent;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }";
@@ -1856,6 +1895,12 @@ class CheckoutInstance extends EventEmitter {
1856
1895
  this.cardEmailAddress = this.checkoutConfig.customer.email;
1857
1896
  this.shouldApplySessionCardholderNameConfig =
1858
1897
  this.checkoutConfig.card?.cardholderName?.required === undefined;
1898
+ this.apiClient = new APIClient({
1899
+ baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1900
+ orgId: this.orgId,
1901
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1902
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1903
+ });
1859
1904
  this._setupCallbackBridges();
1860
1905
  }
1861
1906
  _setupCallbackBridges() {
@@ -1897,64 +1942,35 @@ class CheckoutInstance extends EventEmitter {
1897
1942
  }
1898
1943
  }
1899
1944
  async createSession() {
1900
- this.apiClient = new APIClient({
1901
- baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1945
+ const response = await sessionService.createSession({
1902
1946
  orgId: this.orgId,
1903
- timeout: DEFAULTS.REQUEST_TIMEOUT,
1904
- retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1905
- });
1906
- const sessionParams = {
1947
+ baseUrl: this.baseUrl,
1907
1948
  priceId: this.checkoutConfig.priceId,
1908
1949
  externalId: this.checkoutConfig.customer.externalId,
1909
1950
  email: this.checkoutConfig.customer.email,
1910
- region: this.region || DEFAULTS.REGION,
1951
+ region: this.region,
1911
1952
  clientMetadata: this.checkoutConfig.clientMetadata,
1912
1953
  countryCode: this.checkoutConfig.customer.countryCode,
1913
- };
1914
- const cacheKey = [
1915
- this.orgId,
1916
- this.checkoutConfig.priceId,
1917
- this.checkoutConfig.customer.externalId,
1918
- this.checkoutConfig.customer.email,
1919
- ].join('-');
1920
- let sessionResponse;
1921
- // Return cached response if payload hasn't changed
1922
- const cachedResponse = CheckoutInstance.sessionCache.get(cacheKey);
1923
- if (cachedResponse) {
1924
- sessionResponse = await cachedResponse;
1925
- }
1926
- else {
1927
- const sessionRequest = this.apiClient
1928
- .createClientSession(sessionParams)
1929
- .then((response) => {
1930
- const cachedResponse = response;
1931
- if (response.data?.stripe_public_key) {
1932
- const stripePublicKey = response.data.stripe_public_key;
1933
- cachedResponse.radarSessionId = loadStripe(stripePublicKey)
1934
- .then(stripe => stripe
1935
- ? stripe
1936
- .createRadarSession()
1937
- .then(session => session?.radarSession?.id || '')
1938
- .catch(() => '')
1939
- : '')
1940
- .catch(() => '');
1941
- }
1942
- // Initialize Airwallex device fingerprinting if enabled by backend
1943
- if (response.data?.airwallex_risk_enabled) {
1944
- const isLivemode = response.data?.is_livemode;
1945
- const deviceId = generateUUID();
1946
- cachedResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1947
- .then(() => deviceId)
1948
- .catch(() => {
1949
- // Silently fail - return deviceId anyway
1950
- return deviceId;
1951
- });
1952
- }
1953
- return cachedResponse;
1954
- });
1955
- // Cache the successful response
1956
- CheckoutInstance.sessionCache.set(cacheKey, sessionRequest);
1957
- sessionResponse = await sessionRequest;
1954
+ integration: 'primer',
1955
+ });
1956
+ const sessionResponse = response;
1957
+ if (response.data?.stripe_public_key) {
1958
+ const stripePublicKey = response.data.stripe_public_key;
1959
+ sessionResponse.radarSessionId = loadStripe(stripePublicKey)
1960
+ .then(stripe => stripe
1961
+ ? stripe
1962
+ .createRadarSession()
1963
+ .then(session => session?.radarSession?.id || '')
1964
+ .catch(() => '')
1965
+ : '')
1966
+ .catch(() => '');
1967
+ }
1968
+ if (response.data?.airwallex_risk_enabled) {
1969
+ const isLivemode = response.data?.is_livemode;
1970
+ const deviceId = generateUUID();
1971
+ sessionResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1972
+ .then(() => deviceId)
1973
+ .catch(() => deviceId);
1958
1974
  }
1959
1975
  this.cachedSessionResponse = sessionResponse;
1960
1976
  this.isTelemetryEnabled = !!sessionResponse.data?.sdk_telemetry_enabled;
@@ -2213,8 +2229,7 @@ class CheckoutInstance extends EventEmitter {
2213
2229
  try {
2214
2230
  this.onLoaderChangeWithRace(true);
2215
2231
  this._setState('updating');
2216
- // Invalidate session cache
2217
- CheckoutInstance.sessionCache.clear();
2232
+ sessionService.clearCache();
2218
2233
  await this.apiClient.updateClientSession({
2219
2234
  orderId: this.orderId,
2220
2235
  clientToken: this.clientToken,
@@ -2247,7 +2262,7 @@ class CheckoutInstance extends EventEmitter {
2247
2262
  return;
2248
2263
  try {
2249
2264
  this.stopUnhandledTelemetry();
2250
- CheckoutInstance.sessionCache.clear();
2265
+ sessionService.clearCache();
2251
2266
  await this.primerWrapper.destroy();
2252
2267
  this._setState('destroyed');
2253
2268
  this.orderId = null;
@@ -2458,7 +2473,6 @@ class CheckoutInstance extends EventEmitter {
2458
2473
  this.telemetryPaymentMethod = undefined;
2459
2474
  }
2460
2475
  }
2461
- CheckoutInstance.sessionCache = new Map();
2462
2476
 
2463
2477
  /**
2464
2478
  * @fileoverview Public API with configuration and orchestration logic
@@ -2649,6 +2663,71 @@ async function getAvailablePaymentMethods(params) {
2649
2663
  throw error;
2650
2664
  }
2651
2665
  }
2666
+ async function createStripeCardForm(element, params) {
2667
+ const config = resolveConfig(params, 'createStripeCardForm');
2668
+ const [session, { mountStripeCardForm }] = await Promise.all([
2669
+ sessionService.createSession({
2670
+ orgId: config.orgId,
2671
+ baseUrl: config.baseUrl,
2672
+ region: config.region,
2673
+ priceId: params.priceId,
2674
+ externalId: params.externalId,
2675
+ email: params.email,
2676
+ clientMetadata: params.clientMetadata,
2677
+ countryCode: params.countryCode,
2678
+ integration: 'stripe',
2679
+ }),
2680
+ import('./chunk-stripe-card-form.es.js'),
2681
+ ]);
2682
+ return mountStripeCardForm(element, session, params);
2683
+ }
2684
+ async function purchaseStripeWallet(params) {
2685
+ const config = resolveConfig(params, 'purchaseStripeWallet');
2686
+ const [session, { purchaseWallet }] = await Promise.all([
2687
+ sessionService.createSession({
2688
+ orgId: config.orgId,
2689
+ baseUrl: config.baseUrl,
2690
+ region: config.region,
2691
+ priceId: params.priceId,
2692
+ externalId: params.externalId,
2693
+ email: params.email,
2694
+ clientMetadata: params.clientMetadata,
2695
+ countryCode: params.countryCode,
2696
+ integration: 'stripe',
2697
+ }),
2698
+ import('./chunk-stripe-wallet.es.js'),
2699
+ ]);
2700
+ return purchaseWallet(session, params);
2701
+ }
2702
+ async function getAvailableStripeWallet(params) {
2703
+ const config = resolveConfig(params, 'getAvailableStripeWallet');
2704
+ const [session, { getAvailableWallet }] = await Promise.all([
2705
+ sessionService.createSession({
2706
+ orgId: config.orgId,
2707
+ baseUrl: config.baseUrl,
2708
+ region: config.region,
2709
+ priceId: params.priceId,
2710
+ externalId: params.externalId,
2711
+ email: params.email,
2712
+ clientMetadata: params.clientMetadata,
2713
+ countryCode: params.countryCode,
2714
+ integration: 'stripe',
2715
+ }),
2716
+ import('./chunk-stripe-wallet.es.js'),
2717
+ ]);
2718
+ const result = await getAvailableWallet(session);
2719
+ if (result === 'APPLE_PAY')
2720
+ return PaymentMethod.APPLE_PAY;
2721
+ if (result === 'GOOGLE_PAY')
2722
+ return PaymentMethod.GOOGLE_PAY;
2723
+ return null;
2724
+ }
2725
+ async function getAvailableStripePaymentMethods(params) {
2726
+ const wallet = await getAvailableStripeWallet(params);
2727
+ return wallet
2728
+ ? [PaymentMethod.PAYMENT_CARD, wallet]
2729
+ : [PaymentMethod.PAYMENT_CARD];
2730
+ }
2652
2731
 
2653
2732
  /**
2654
2733
  * @fileoverview Main entry point for @funnelfox/billing
@@ -2660,9 +2739,15 @@ const Billing = {
2660
2739
  initMethod: initMethod,
2661
2740
  silentPurchase: silentPurchase,
2662
2741
  getAvailablePaymentMethods: getAvailablePaymentMethods,
2742
+ stripe: {
2743
+ createCardForm: createStripeCardForm,
2744
+ purchaseWallet: purchaseStripeWallet,
2745
+ getAvailableWallet: getAvailableStripeWallet,
2746
+ getAvailablePaymentMethods: getAvailableStripePaymentMethods,
2747
+ },
2663
2748
  };
2664
2749
  if (typeof window !== 'undefined') {
2665
2750
  window.Billing = Billing;
2666
2751
  }
2667
2752
 
2668
- export { APIError as A, Billing as B, CheckoutError as C, DEFAULT_BUTTONS_OPTIONS as D, EVENTS as E, FunnefoxSDKError as F, NetworkError as N, PaymentMethod as P, SDK_VERSION as S, ValidationError as V, PrimerError as a, ConfigurationError as b, DEFAULTS as c, CHECKOUT_STATES as d, ERROR_CODES as e, configure as f, createCheckout as g, createClientSession as h, getAvailablePaymentMethods as i };
2753
+ export { APIError as A, Billing as B, CheckoutError as C, DEFAULT_BUTTONS_OPTIONS as D, EVENTS as E, FunnefoxSDKError as F, NetworkError as N, PaymentMethod as P, SDK_VERSION as S, ValidationError as V, PrimerError as a, ConfigurationError as b, DEFAULTS as c, CHECKOUT_STATES as d, ERROR_CODES as e, configure as f, createCheckout as g, createClientSession as h, getAvailablePaymentMethods as i, loadStripe as l };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @funnelfox/billing v0.1.0
3
+ * JavaScript SDK for Funnelfox billing with Primer integration
4
+ *
5
+ * @author Funnelfox
6
+ * @license MIT
7
+ */
8
+ 'use strict';
9
+
10
+ var stripeLoader = require('./chunk-stripe-loader.cjs.js');
11
+ require('./chunk-index.cjs.js');
12
+
13
+ async function mountStripeCardForm(element, session, params) {
14
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
15
+ const { intent_client_secret, customer_session_client_secret } = stripe_intent;
16
+ const stripe = await stripeLoader.getStripe(stripe_public_key);
17
+ if (!stripe)
18
+ throw new Error('Failed to load Stripe');
19
+ const stripeElements = stripe.elements({
20
+ clientSecret: intent_client_secret,
21
+ customerSessionClientSecret: customer_session_client_secret,
22
+ appearance: params.appearance,
23
+ });
24
+ const paymentElement = stripeElements.create('payment', {
25
+ layout: 'tabs',
26
+ wallets: {
27
+ applePay: params.showWallets ? 'auto' : 'never',
28
+ googlePay: params.showWallets ? 'auto' : 'never',
29
+ },
30
+ terms: { card: 'never' },
31
+ });
32
+ paymentElement.mount(element);
33
+ await new Promise((resolve, reject) => {
34
+ paymentElement.once('ready', () => resolve());
35
+ // 'loaderror' is a valid Stripe event but not yet in the @stripe/stripe-js types
36
+ paymentElement.once('loaderror', e => reject(e.error));
37
+ });
38
+ params.onRenderSuccess?.();
39
+ return {
40
+ submit: async () => {
41
+ params.onLoaderChange?.(true);
42
+ try {
43
+ const { error: submitError } = await stripeElements.submit();
44
+ if (submitError)
45
+ throw submitError;
46
+ const { error, paymentMethod } = await stripe.createPaymentMethod({
47
+ elements: stripeElements,
48
+ });
49
+ if (error)
50
+ throw error;
51
+ params.onPaymentSuccess?.(paymentMethod, order_id);
52
+ }
53
+ catch (err) {
54
+ params.onPaymentFail?.(err);
55
+ throw err;
56
+ }
57
+ finally {
58
+ params.onLoaderChange?.(false);
59
+ }
60
+ },
61
+ };
62
+ }
63
+
64
+ exports.mountStripeCardForm = mountStripeCardForm;