@funnelfox/billing 0.8.0-ffb-395.10 → 0.8.1

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.
@@ -489,7 +489,7 @@ var PaymentMethod;
489
489
  /**
490
490
  * @fileoverview Constants for Funnefox SDK
491
491
  */
492
- const SDK_VERSION = '0.9.0-beta.1';
492
+ const SDK_VERSION = '0.8.1';
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: params.integration ?? 'primer',
1129
+ integration_type: 'primer',
1130
1130
  pp_ident: params.priceId,
1131
1131
  external_id: params.externalId,
1132
1132
  email_address: params.email,
@@ -1262,45 +1262,6 @@ 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
-
1304
1265
  var loaderHtml = "<div class=\"ff-sdk-loader-container\">\n <div class=\"ff-sdk-loader\"></div>\n</div>\n";
1305
1266
 
1306
1267
  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 }";
@@ -1895,12 +1856,6 @@ class CheckoutInstance extends EventEmitter {
1895
1856
  this.cardEmailAddress = this.checkoutConfig.customer.email;
1896
1857
  this.shouldApplySessionCardholderNameConfig =
1897
1858
  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
- });
1904
1859
  this._setupCallbackBridges();
1905
1860
  }
1906
1861
  _setupCallbackBridges() {
@@ -1942,35 +1897,64 @@ class CheckoutInstance extends EventEmitter {
1942
1897
  }
1943
1898
  }
1944
1899
  async createSession() {
1945
- const response = await sessionService.createSession({
1900
+ this.apiClient = new APIClient({
1901
+ baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1946
1902
  orgId: this.orgId,
1947
- baseUrl: this.baseUrl,
1903
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1904
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1905
+ });
1906
+ const sessionParams = {
1948
1907
  priceId: this.checkoutConfig.priceId,
1949
1908
  externalId: this.checkoutConfig.customer.externalId,
1950
1909
  email: this.checkoutConfig.customer.email,
1951
- region: this.region,
1910
+ region: this.region || DEFAULTS.REGION,
1952
1911
  clientMetadata: this.checkoutConfig.clientMetadata,
1953
1912
  countryCode: this.checkoutConfig.customer.countryCode,
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);
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;
1974
1958
  }
1975
1959
  this.cachedSessionResponse = sessionResponse;
1976
1960
  this.isTelemetryEnabled = !!sessionResponse.data?.sdk_telemetry_enabled;
@@ -2229,7 +2213,8 @@ class CheckoutInstance extends EventEmitter {
2229
2213
  try {
2230
2214
  this.onLoaderChangeWithRace(true);
2231
2215
  this._setState('updating');
2232
- sessionService.clearCache();
2216
+ // Invalidate session cache
2217
+ CheckoutInstance.sessionCache.clear();
2233
2218
  await this.apiClient.updateClientSession({
2234
2219
  orderId: this.orderId,
2235
2220
  clientToken: this.clientToken,
@@ -2262,7 +2247,7 @@ class CheckoutInstance extends EventEmitter {
2262
2247
  return;
2263
2248
  try {
2264
2249
  this.stopUnhandledTelemetry();
2265
- sessionService.clearCache();
2250
+ CheckoutInstance.sessionCache.clear();
2266
2251
  await this.primerWrapper.destroy();
2267
2252
  this._setState('destroyed');
2268
2253
  this.orderId = null;
@@ -2473,6 +2458,7 @@ class CheckoutInstance extends EventEmitter {
2473
2458
  this.telemetryPaymentMethod = undefined;
2474
2459
  }
2475
2460
  }
2461
+ CheckoutInstance.sessionCache = new Map();
2476
2462
 
2477
2463
  /**
2478
2464
  * @fileoverview Public API with configuration and orchestration logic
@@ -2663,79 +2649,6 @@ async function getAvailablePaymentMethods(params) {
2663
2649
  throw error;
2664
2650
  }
2665
2651
  }
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
- const apiClient = new APIClient({
2683
- orgId: config.orgId,
2684
- baseUrl: config.baseUrl || DEFAULTS.BASE_URL,
2685
- });
2686
- return mountStripeCardForm(element, session, { ...params, apiClient });
2687
- }
2688
- async function purchaseStripeWallet(params) {
2689
- const config = resolveConfig(params, 'purchaseStripeWallet');
2690
- const [session, { purchaseWallet }] = await Promise.all([
2691
- sessionService.createSession({
2692
- orgId: config.orgId,
2693
- baseUrl: config.baseUrl,
2694
- region: config.region,
2695
- priceId: params.priceId,
2696
- externalId: params.externalId,
2697
- email: params.email,
2698
- clientMetadata: params.clientMetadata,
2699
- countryCode: params.countryCode,
2700
- integration: 'stripe',
2701
- }),
2702
- import('./chunk-stripe-wallet.es.js'),
2703
- ]);
2704
- const apiClient = new APIClient({
2705
- orgId: config.orgId,
2706
- baseUrl: config.baseUrl || DEFAULTS.BASE_URL,
2707
- });
2708
- return purchaseWallet(session, { ...params, apiClient });
2709
- }
2710
- async function getAvailableStripeWallet(params) {
2711
- const config = resolveConfig(params, 'getAvailableStripeWallet');
2712
- const [session, { getAvailableWallet }] = await Promise.all([
2713
- sessionService.createSession({
2714
- orgId: config.orgId,
2715
- baseUrl: config.baseUrl,
2716
- region: config.region,
2717
- priceId: params.priceId,
2718
- externalId: params.externalId,
2719
- email: params.email,
2720
- clientMetadata: params.clientMetadata,
2721
- countryCode: params.countryCode,
2722
- integration: 'stripe',
2723
- }),
2724
- import('./chunk-stripe-wallet.es.js'),
2725
- ]);
2726
- const result = await getAvailableWallet(session);
2727
- if (result === 'APPLE_PAY')
2728
- return PaymentMethod.APPLE_PAY;
2729
- if (result === 'GOOGLE_PAY')
2730
- return PaymentMethod.GOOGLE_PAY;
2731
- return null;
2732
- }
2733
- async function getAvailableStripePaymentMethods(params) {
2734
- const wallet = await getAvailableStripeWallet(params);
2735
- return wallet
2736
- ? [PaymentMethod.PAYMENT_CARD, wallet]
2737
- : [PaymentMethod.PAYMENT_CARD];
2738
- }
2739
2652
 
2740
2653
  /**
2741
2654
  * @fileoverview Main entry point for @funnelfox/billing
@@ -2747,15 +2660,10 @@ const Billing = {
2747
2660
  initMethod: initMethod,
2748
2661
  silentPurchase: silentPurchase,
2749
2662
  getAvailablePaymentMethods: getAvailablePaymentMethods,
2750
- stripe: {
2751
- createCardForm: createStripeCardForm,
2752
- purchaseWallet: purchaseStripeWallet,
2753
- getAvailableWallet: getAvailableStripeWallet,
2754
- getAvailablePaymentMethods: getAvailableStripePaymentMethods,
2755
- },
2756
2663
  };
2757
2664
  if (typeof window !== 'undefined') {
2758
2665
  window.Billing = Billing;
2759
2666
  }
2667
+ console.debug('Billing SDK inited');
2760
2668
 
2761
- 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 };
2669
+ 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 };