@funnelfox/billing 0.8.0 → 0.9.0-beta.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.
@@ -0,0 +1,62 @@
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
+ import { g as getStripe } from './chunk-stripe-loader.es.js';
9
+ import './chunk-index.es.js';
10
+
11
+ async function mountStripeCardForm(element, session, params) {
12
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
13
+ const { intent_client_secret, customer_session_client_secret } = stripe_intent;
14
+ const stripe = await getStripe(stripe_public_key);
15
+ if (!stripe)
16
+ throw new Error('Failed to load Stripe');
17
+ const stripeElements = stripe.elements({
18
+ clientSecret: intent_client_secret,
19
+ customerSessionClientSecret: customer_session_client_secret,
20
+ appearance: params.appearance,
21
+ });
22
+ const paymentElement = stripeElements.create('payment', {
23
+ layout: 'tabs',
24
+ wallets: {
25
+ applePay: params.showWallets ? 'auto' : 'never',
26
+ googlePay: params.showWallets ? 'auto' : 'never',
27
+ },
28
+ terms: { card: 'never' },
29
+ });
30
+ paymentElement.mount(element);
31
+ await new Promise((resolve, reject) => {
32
+ paymentElement.once('ready', () => resolve());
33
+ // 'loaderror' is a valid Stripe event but not yet in the @stripe/stripe-js types
34
+ paymentElement.once('loaderror', e => reject(e.error));
35
+ });
36
+ params.onRenderSuccess?.();
37
+ return {
38
+ submit: async () => {
39
+ params.onLoaderChange?.(true);
40
+ try {
41
+ const { error: submitError } = await stripeElements.submit();
42
+ if (submitError)
43
+ throw submitError;
44
+ const { error, paymentMethod } = await stripe.createPaymentMethod({
45
+ elements: stripeElements,
46
+ });
47
+ if (error)
48
+ throw error;
49
+ params.onPaymentSuccess?.(paymentMethod, order_id);
50
+ }
51
+ catch (err) {
52
+ params.onPaymentFail?.(err);
53
+ throw err;
54
+ }
55
+ finally {
56
+ params.onLoaderChange?.(false);
57
+ }
58
+ },
59
+ };
60
+ }
61
+
62
+ export { mountStripeCardForm };
@@ -0,0 +1,20 @@
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 index = require('./chunk-index.cjs.js');
11
+
12
+ const cache = new Map();
13
+ function getStripe(publicKey) {
14
+ if (!cache.has(publicKey)) {
15
+ cache.set(publicKey, index.loadStripe(publicKey));
16
+ }
17
+ return cache.get(publicKey);
18
+ }
19
+
20
+ exports.getStripe = getStripe;
@@ -0,0 +1,18 @@
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
+ import { l as loadStripe } from './chunk-index.es.js';
9
+
10
+ const cache = new Map();
11
+ function getStripe(publicKey) {
12
+ if (!cache.has(publicKey)) {
13
+ cache.set(publicKey, loadStripe(publicKey));
14
+ }
15
+ return cache.get(publicKey);
16
+ }
17
+
18
+ export { getStripe as g };
@@ -0,0 +1,80 @@
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
+ function buildPaymentRequest(stripe, stripe_intent, totalLabel) {
14
+ return stripe.paymentRequest({
15
+ country: stripe_intent.country || 'US',
16
+ currency: stripe_intent.currency || 'usd',
17
+ total: {
18
+ label: totalLabel ?? 'Test Total',
19
+ amount: stripe_intent.amount || 1,
20
+ },
21
+ requestPayerName: false,
22
+ requestPayerEmail: false,
23
+ });
24
+ }
25
+ async function getAvailableWallet(session) {
26
+ const { stripe_public_key, stripe_intent } = session.data;
27
+ const stripe = await stripeLoader.getStripe(stripe_public_key);
28
+ if (!stripe)
29
+ throw new Error('Failed to load Stripe');
30
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent);
31
+ const result = await paymentRequest.canMakePayment();
32
+ if (!result)
33
+ return null;
34
+ if (result.applePay)
35
+ return 'APPLE_PAY';
36
+ if (result.googlePay)
37
+ return 'GOOGLE_PAY';
38
+ return null;
39
+ }
40
+ async function purchaseWallet(session, params) {
41
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
42
+ const { intent_client_secret } = stripe_intent;
43
+ const stripe = await stripeLoader.getStripe(stripe_public_key);
44
+ if (!stripe)
45
+ throw new Error('Failed to load Stripe');
46
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent, params.totalLabel);
47
+ const canPay = await paymentRequest.canMakePayment();
48
+ if (!canPay)
49
+ throw new Error('No wallet payment method available');
50
+ return new Promise((resolve, reject) => {
51
+ paymentRequest.on('paymentmethod', async (event) => {
52
+ params.onLoaderChange?.(true);
53
+ try {
54
+ const { error } = await stripe.confirmCardPayment(intent_client_secret, { payment_method: event.paymentMethod.id }, { handleActions: false });
55
+ if (error) {
56
+ event.complete('fail');
57
+ throw error;
58
+ }
59
+ event.complete('success');
60
+ params.onPaymentSuccess?.(event.paymentMethod, order_id);
61
+ resolve();
62
+ }
63
+ catch (err) {
64
+ params.onPaymentFail?.(err);
65
+ reject(err);
66
+ }
67
+ finally {
68
+ params.onLoaderChange?.(false);
69
+ }
70
+ });
71
+ paymentRequest.on('cancel', () => {
72
+ params.onPaymentCancel?.();
73
+ resolve();
74
+ });
75
+ paymentRequest.show();
76
+ });
77
+ }
78
+
79
+ exports.getAvailableWallet = getAvailableWallet;
80
+ exports.purchaseWallet = purchaseWallet;
@@ -0,0 +1,77 @@
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
+ import { g as getStripe } from './chunk-stripe-loader.es.js';
9
+ import './chunk-index.es.js';
10
+
11
+ function buildPaymentRequest(stripe, stripe_intent, totalLabel) {
12
+ return stripe.paymentRequest({
13
+ country: stripe_intent.country || 'US',
14
+ currency: stripe_intent.currency || 'usd',
15
+ total: {
16
+ label: totalLabel ?? 'Test Total',
17
+ amount: stripe_intent.amount || 1,
18
+ },
19
+ requestPayerName: false,
20
+ requestPayerEmail: false,
21
+ });
22
+ }
23
+ async function getAvailableWallet(session) {
24
+ const { stripe_public_key, stripe_intent } = session.data;
25
+ const stripe = await getStripe(stripe_public_key);
26
+ if (!stripe)
27
+ throw new Error('Failed to load Stripe');
28
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent);
29
+ const result = await paymentRequest.canMakePayment();
30
+ if (!result)
31
+ return null;
32
+ if (result.applePay)
33
+ return 'APPLE_PAY';
34
+ if (result.googlePay)
35
+ return 'GOOGLE_PAY';
36
+ return null;
37
+ }
38
+ async function purchaseWallet(session, params) {
39
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
40
+ const { intent_client_secret } = stripe_intent;
41
+ const stripe = await getStripe(stripe_public_key);
42
+ if (!stripe)
43
+ throw new Error('Failed to load Stripe');
44
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent, params.totalLabel);
45
+ const canPay = await paymentRequest.canMakePayment();
46
+ if (!canPay)
47
+ throw new Error('No wallet payment method available');
48
+ return new Promise((resolve, reject) => {
49
+ paymentRequest.on('paymentmethod', async (event) => {
50
+ params.onLoaderChange?.(true);
51
+ try {
52
+ const { error } = await stripe.confirmCardPayment(intent_client_secret, { payment_method: event.paymentMethod.id }, { handleActions: false });
53
+ if (error) {
54
+ event.complete('fail');
55
+ throw error;
56
+ }
57
+ event.complete('success');
58
+ params.onPaymentSuccess?.(event.paymentMethod, order_id);
59
+ resolve();
60
+ }
61
+ catch (err) {
62
+ params.onPaymentFail?.(err);
63
+ reject(err);
64
+ }
65
+ finally {
66
+ params.onLoaderChange?.(false);
67
+ }
68
+ });
69
+ paymentRequest.on('cancel', () => {
70
+ params.onPaymentCancel?.();
71
+ resolve();
72
+ });
73
+ paymentRequest.show();
74
+ });
75
+ }
76
+
77
+ export { getAvailableWallet, purchaseWallet };
@@ -495,7 +495,7 @@
495
495
  /**
496
496
  * @fileoverview Constants for Funnefox SDK
497
497
  */
498
- const SDK_VERSION = '0.8.0';
498
+ const SDK_VERSION = '0.9.0-beta.1';
499
499
  const DEFAULTS = {
500
500
  BASE_URL: 'https://billing.funnelfox.com',
501
501
  REGION: 'default',
@@ -1132,7 +1132,7 @@
1132
1132
  async createClientSession(params) {
1133
1133
  const payload = {
1134
1134
  region: params.region || 'default',
1135
- integration_type: 'primer',
1135
+ integration_type: params.integration ?? 'primer',
1136
1136
  pp_ident: params.priceId,
1137
1137
  external_id: params.externalId,
1138
1138
  email_address: params.email,
@@ -1268,6 +1268,45 @@
1268
1268
  }
1269
1269
  }
1270
1270
 
1271
+ class SessionService {
1272
+ constructor() {
1273
+ this.cache = new Map();
1274
+ }
1275
+ buildCacheKey(p) {
1276
+ return [p.orgId, p.priceId, p.externalId, p.email, p.integration].join('-');
1277
+ }
1278
+ makeClient(orgId, baseUrl) {
1279
+ return new APIClient({
1280
+ baseUrl: baseUrl || DEFAULTS.BASE_URL,
1281
+ orgId,
1282
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1283
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1284
+ });
1285
+ }
1286
+ createSession(p) {
1287
+ const key = this.buildCacheKey(p);
1288
+ const cached = this.cache.get(key);
1289
+ if (cached)
1290
+ return cached;
1291
+ const client = this.makeClient(p.orgId, p.baseUrl);
1292
+ const req = client.createClientSession({
1293
+ priceId: p.priceId,
1294
+ externalId: p.externalId,
1295
+ email: p.email,
1296
+ region: p.region || DEFAULTS.REGION,
1297
+ clientMetadata: p.clientMetadata,
1298
+ countryCode: p.countryCode,
1299
+ integration: p.integration,
1300
+ });
1301
+ this.cache.set(key, req);
1302
+ return req;
1303
+ }
1304
+ clearCache() {
1305
+ this.cache.clear();
1306
+ }
1307
+ }
1308
+ var sessionService = new SessionService();
1309
+
1271
1310
  var loaderHtml = "<div class=\"ff-sdk-loader-container\">\n <div class=\"ff-sdk-loader\"></div>\n</div>\n";
1272
1311
 
1273
1312
  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 }";
@@ -1862,6 +1901,12 @@
1862
1901
  this.cardEmailAddress = this.checkoutConfig.customer.email;
1863
1902
  this.shouldApplySessionCardholderNameConfig =
1864
1903
  this.checkoutConfig.card?.cardholderName?.required === undefined;
1904
+ this.apiClient = new APIClient({
1905
+ baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1906
+ orgId: this.orgId,
1907
+ timeout: DEFAULTS.REQUEST_TIMEOUT,
1908
+ retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1909
+ });
1865
1910
  this._setupCallbackBridges();
1866
1911
  }
1867
1912
  _setupCallbackBridges() {
@@ -1903,64 +1948,35 @@
1903
1948
  }
1904
1949
  }
1905
1950
  async createSession() {
1906
- this.apiClient = new APIClient({
1907
- baseUrl: this.baseUrl || DEFAULTS.BASE_URL,
1951
+ const response = await sessionService.createSession({
1908
1952
  orgId: this.orgId,
1909
- timeout: DEFAULTS.REQUEST_TIMEOUT,
1910
- retryAttempts: DEFAULTS.RETRY_ATTEMPTS,
1911
- });
1912
- const sessionParams = {
1953
+ baseUrl: this.baseUrl,
1913
1954
  priceId: this.checkoutConfig.priceId,
1914
1955
  externalId: this.checkoutConfig.customer.externalId,
1915
1956
  email: this.checkoutConfig.customer.email,
1916
- region: this.region || DEFAULTS.REGION,
1957
+ region: this.region,
1917
1958
  clientMetadata: this.checkoutConfig.clientMetadata,
1918
1959
  countryCode: this.checkoutConfig.customer.countryCode,
1919
- };
1920
- const cacheKey = [
1921
- this.orgId,
1922
- this.checkoutConfig.priceId,
1923
- this.checkoutConfig.customer.externalId,
1924
- this.checkoutConfig.customer.email,
1925
- ].join('-');
1926
- let sessionResponse;
1927
- // Return cached response if payload hasn't changed
1928
- const cachedResponse = CheckoutInstance.sessionCache.get(cacheKey);
1929
- if (cachedResponse) {
1930
- sessionResponse = await cachedResponse;
1931
- }
1932
- else {
1933
- const sessionRequest = this.apiClient
1934
- .createClientSession(sessionParams)
1935
- .then((response) => {
1936
- const cachedResponse = response;
1937
- if (response.data?.stripe_public_key) {
1938
- const stripePublicKey = response.data.stripe_public_key;
1939
- cachedResponse.radarSessionId = loadStripe(stripePublicKey)
1940
- .then(stripe => stripe
1941
- ? stripe
1942
- .createRadarSession()
1943
- .then(session => session?.radarSession?.id || '')
1944
- .catch(() => '')
1945
- : '')
1946
- .catch(() => '');
1947
- }
1948
- // Initialize Airwallex device fingerprinting if enabled by backend
1949
- if (response.data?.airwallex_risk_enabled) {
1950
- const isLivemode = response.data?.is_livemode;
1951
- const deviceId = generateUUID();
1952
- cachedResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1953
- .then(() => deviceId)
1954
- .catch(() => {
1955
- // Silently fail - return deviceId anyway
1956
- return deviceId;
1957
- });
1958
- }
1959
- return cachedResponse;
1960
- });
1961
- // Cache the successful response
1962
- CheckoutInstance.sessionCache.set(cacheKey, sessionRequest);
1963
- sessionResponse = await sessionRequest;
1960
+ integration: 'primer',
1961
+ });
1962
+ const sessionResponse = response;
1963
+ if (response.data?.stripe_public_key) {
1964
+ const stripePublicKey = response.data.stripe_public_key;
1965
+ sessionResponse.radarSessionId = loadStripe(stripePublicKey)
1966
+ .then(stripe => stripe
1967
+ ? stripe
1968
+ .createRadarSession()
1969
+ .then(session => session?.radarSession?.id || '')
1970
+ .catch(() => '')
1971
+ : '')
1972
+ .catch(() => '');
1973
+ }
1974
+ if (response.data?.airwallex_risk_enabled) {
1975
+ const isLivemode = response.data?.is_livemode;
1976
+ const deviceId = generateUUID();
1977
+ sessionResponse.airwallexDeviceId = loadAirwallexDeviceFingerprint(deviceId, isLivemode)
1978
+ .then(() => deviceId)
1979
+ .catch(() => deviceId);
1964
1980
  }
1965
1981
  this.cachedSessionResponse = sessionResponse;
1966
1982
  this.isTelemetryEnabled = !!sessionResponse.data?.sdk_telemetry_enabled;
@@ -2219,8 +2235,7 @@
2219
2235
  try {
2220
2236
  this.onLoaderChangeWithRace(true);
2221
2237
  this._setState('updating');
2222
- // Invalidate session cache
2223
- CheckoutInstance.sessionCache.clear();
2238
+ sessionService.clearCache();
2224
2239
  await this.apiClient.updateClientSession({
2225
2240
  orderId: this.orderId,
2226
2241
  clientToken: this.clientToken,
@@ -2253,7 +2268,7 @@
2253
2268
  return;
2254
2269
  try {
2255
2270
  this.stopUnhandledTelemetry();
2256
- CheckoutInstance.sessionCache.clear();
2271
+ sessionService.clearCache();
2257
2272
  await this.primerWrapper.destroy();
2258
2273
  this._setState('destroyed');
2259
2274
  this.orderId = null;
@@ -2464,7 +2479,6 @@
2464
2479
  this.telemetryPaymentMethod = undefined;
2465
2480
  }
2466
2481
  }
2467
- CheckoutInstance.sessionCache = new Map();
2468
2482
 
2469
2483
  /**
2470
2484
  * @fileoverview Public API with configuration and orchestration logic
@@ -2655,6 +2669,71 @@
2655
2669
  throw error;
2656
2670
  }
2657
2671
  }
2672
+ async function createStripeCardForm(element, params) {
2673
+ const config = resolveConfig(params, 'createStripeCardForm');
2674
+ const [session, { mountStripeCardForm }] = await Promise.all([
2675
+ sessionService.createSession({
2676
+ orgId: config.orgId,
2677
+ baseUrl: config.baseUrl,
2678
+ region: config.region,
2679
+ priceId: params.priceId,
2680
+ externalId: params.externalId,
2681
+ email: params.email,
2682
+ clientMetadata: params.clientMetadata,
2683
+ countryCode: params.countryCode,
2684
+ integration: 'stripe',
2685
+ }),
2686
+ Promise.resolve().then(function () { return stripeCardForm; }),
2687
+ ]);
2688
+ return mountStripeCardForm(element, session, params);
2689
+ }
2690
+ async function purchaseStripeWallet(params) {
2691
+ const config = resolveConfig(params, 'purchaseStripeWallet');
2692
+ const [session, { purchaseWallet }] = await Promise.all([
2693
+ sessionService.createSession({
2694
+ orgId: config.orgId,
2695
+ baseUrl: config.baseUrl,
2696
+ region: config.region,
2697
+ priceId: params.priceId,
2698
+ externalId: params.externalId,
2699
+ email: params.email,
2700
+ clientMetadata: params.clientMetadata,
2701
+ countryCode: params.countryCode,
2702
+ integration: 'stripe',
2703
+ }),
2704
+ Promise.resolve().then(function () { return stripeWallet; }),
2705
+ ]);
2706
+ return purchaseWallet(session, params);
2707
+ }
2708
+ async function getAvailableStripeWallet(params) {
2709
+ const config = resolveConfig(params, 'getAvailableStripeWallet');
2710
+ const [session, { getAvailableWallet }] = await Promise.all([
2711
+ sessionService.createSession({
2712
+ orgId: config.orgId,
2713
+ baseUrl: config.baseUrl,
2714
+ region: config.region,
2715
+ priceId: params.priceId,
2716
+ externalId: params.externalId,
2717
+ email: params.email,
2718
+ clientMetadata: params.clientMetadata,
2719
+ countryCode: params.countryCode,
2720
+ integration: 'stripe',
2721
+ }),
2722
+ Promise.resolve().then(function () { return stripeWallet; }),
2723
+ ]);
2724
+ const result = await getAvailableWallet(session);
2725
+ if (result === 'APPLE_PAY')
2726
+ return exports.PaymentMethod.APPLE_PAY;
2727
+ if (result === 'GOOGLE_PAY')
2728
+ return exports.PaymentMethod.GOOGLE_PAY;
2729
+ return null;
2730
+ }
2731
+ async function getAvailableStripePaymentMethods(params) {
2732
+ const wallet = await getAvailableStripeWallet(params);
2733
+ return wallet
2734
+ ? [exports.PaymentMethod.PAYMENT_CARD, wallet]
2735
+ : [exports.PaymentMethod.PAYMENT_CARD];
2736
+ }
2658
2737
 
2659
2738
  /**
2660
2739
  * @fileoverview Main entry point for @funnelfox/billing
@@ -2666,6 +2745,12 @@
2666
2745
  initMethod: initMethod,
2667
2746
  silentPurchase: silentPurchase,
2668
2747
  getAvailablePaymentMethods: getAvailablePaymentMethods,
2748
+ stripe: {
2749
+ createCardForm: createStripeCardForm,
2750
+ purchaseWallet: purchaseStripeWallet,
2751
+ getAvailableWallet: getAvailableStripeWallet,
2752
+ getAvailablePaymentMethods: getAvailableStripePaymentMethods,
2753
+ },
2669
2754
  };
2670
2755
  if (typeof window !== 'undefined') {
2671
2756
  window.Billing = Billing;
@@ -3069,6 +3154,142 @@
3069
3154
  default: createDefaultSkin
3070
3155
  });
3071
3156
 
3157
+ const cache = new Map();
3158
+ function getStripe(publicKey) {
3159
+ if (!cache.has(publicKey)) {
3160
+ cache.set(publicKey, loadStripe(publicKey));
3161
+ }
3162
+ return cache.get(publicKey);
3163
+ }
3164
+
3165
+ async function mountStripeCardForm(element, session, params) {
3166
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
3167
+ const { intent_client_secret, customer_session_client_secret } = stripe_intent;
3168
+ const stripe = await getStripe(stripe_public_key);
3169
+ if (!stripe)
3170
+ throw new Error('Failed to load Stripe');
3171
+ const stripeElements = stripe.elements({
3172
+ clientSecret: intent_client_secret,
3173
+ customerSessionClientSecret: customer_session_client_secret,
3174
+ appearance: params.appearance,
3175
+ });
3176
+ const paymentElement = stripeElements.create('payment', {
3177
+ layout: 'tabs',
3178
+ wallets: {
3179
+ applePay: params.showWallets ? 'auto' : 'never',
3180
+ googlePay: params.showWallets ? 'auto' : 'never',
3181
+ },
3182
+ terms: { card: 'never' },
3183
+ });
3184
+ paymentElement.mount(element);
3185
+ await new Promise((resolve, reject) => {
3186
+ paymentElement.once('ready', () => resolve());
3187
+ // 'loaderror' is a valid Stripe event but not yet in the @stripe/stripe-js types
3188
+ paymentElement.once('loaderror', e => reject(e.error));
3189
+ });
3190
+ params.onRenderSuccess?.();
3191
+ return {
3192
+ submit: async () => {
3193
+ params.onLoaderChange?.(true);
3194
+ try {
3195
+ const { error: submitError } = await stripeElements.submit();
3196
+ if (submitError)
3197
+ throw submitError;
3198
+ const { error, paymentMethod } = await stripe.createPaymentMethod({
3199
+ elements: stripeElements,
3200
+ });
3201
+ if (error)
3202
+ throw error;
3203
+ params.onPaymentSuccess?.(paymentMethod, order_id);
3204
+ }
3205
+ catch (err) {
3206
+ params.onPaymentFail?.(err);
3207
+ throw err;
3208
+ }
3209
+ finally {
3210
+ params.onLoaderChange?.(false);
3211
+ }
3212
+ },
3213
+ };
3214
+ }
3215
+
3216
+ var stripeCardForm = /*#__PURE__*/Object.freeze({
3217
+ __proto__: null,
3218
+ mountStripeCardForm: mountStripeCardForm
3219
+ });
3220
+
3221
+ function buildPaymentRequest(stripe, stripe_intent, totalLabel) {
3222
+ return stripe.paymentRequest({
3223
+ country: stripe_intent.country || 'US',
3224
+ currency: stripe_intent.currency || 'usd',
3225
+ total: {
3226
+ label: totalLabel ?? 'Test Total',
3227
+ amount: stripe_intent.amount || 1,
3228
+ },
3229
+ requestPayerName: false,
3230
+ requestPayerEmail: false,
3231
+ });
3232
+ }
3233
+ async function getAvailableWallet(session) {
3234
+ const { stripe_public_key, stripe_intent } = session.data;
3235
+ const stripe = await getStripe(stripe_public_key);
3236
+ if (!stripe)
3237
+ throw new Error('Failed to load Stripe');
3238
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent);
3239
+ const result = await paymentRequest.canMakePayment();
3240
+ if (!result)
3241
+ return null;
3242
+ if (result.applePay)
3243
+ return 'APPLE_PAY';
3244
+ if (result.googlePay)
3245
+ return 'GOOGLE_PAY';
3246
+ return null;
3247
+ }
3248
+ async function purchaseWallet(session, params) {
3249
+ const { stripe_public_key, stripe_intent, order_id } = session.data;
3250
+ const { intent_client_secret } = stripe_intent;
3251
+ const stripe = await getStripe(stripe_public_key);
3252
+ if (!stripe)
3253
+ throw new Error('Failed to load Stripe');
3254
+ const paymentRequest = buildPaymentRequest(stripe, stripe_intent, params.totalLabel);
3255
+ const canPay = await paymentRequest.canMakePayment();
3256
+ if (!canPay)
3257
+ throw new Error('No wallet payment method available');
3258
+ return new Promise((resolve, reject) => {
3259
+ paymentRequest.on('paymentmethod', async (event) => {
3260
+ params.onLoaderChange?.(true);
3261
+ try {
3262
+ const { error } = await stripe.confirmCardPayment(intent_client_secret, { payment_method: event.paymentMethod.id }, { handleActions: false });
3263
+ if (error) {
3264
+ event.complete('fail');
3265
+ throw error;
3266
+ }
3267
+ event.complete('success');
3268
+ params.onPaymentSuccess?.(event.paymentMethod, order_id);
3269
+ resolve();
3270
+ }
3271
+ catch (err) {
3272
+ params.onPaymentFail?.(err);
3273
+ reject(err);
3274
+ }
3275
+ finally {
3276
+ params.onLoaderChange?.(false);
3277
+ }
3278
+ });
3279
+ paymentRequest.on('cancel', () => {
3280
+ params.onPaymentCancel?.();
3281
+ resolve();
3282
+ });
3283
+ paymentRequest.show();
3284
+ });
3285
+ }
3286
+
3287
+ var stripeWallet = /*#__PURE__*/Object.freeze({
3288
+ __proto__: null,
3289
+ getAvailableWallet: getAvailableWallet,
3290
+ purchaseWallet: purchaseWallet
3291
+ });
3292
+
3072
3293
  exports.APIError = APIError;
3073
3294
  exports.Billing = Billing;
3074
3295
  exports.CHECKOUT_STATES = CHECKOUT_STATES;