@tagadapay/plugin-sdk 3.0.9 → 3.0.14

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.
Files changed (31) hide show
  1. package/dist/external-tracker.js +3802 -195
  2. package/dist/external-tracker.min.js +25 -2
  3. package/dist/external-tracker.min.js.map +4 -4
  4. package/dist/react/types.d.ts +2 -0
  5. package/dist/v2/core/client.d.ts +4 -0
  6. package/dist/v2/core/client.js +314 -123
  7. package/dist/v2/core/config/environment.js +6 -0
  8. package/dist/v2/core/funnelClient.d.ts +18 -1
  9. package/dist/v2/core/funnelClient.js +90 -17
  10. package/dist/v2/core/resources/checkout.d.ts +44 -1
  11. package/dist/v2/core/resources/checkout.js +48 -1
  12. package/dist/v2/core/resources/funnel.d.ts +44 -4
  13. package/dist/v2/core/resources/offers.d.ts +26 -0
  14. package/dist/v2/core/resources/offers.js +37 -0
  15. package/dist/v2/core/types.d.ts +3 -1
  16. package/dist/v2/core/utils/authHandoff.d.ts +60 -0
  17. package/dist/v2/core/utils/authHandoff.js +154 -0
  18. package/dist/v2/core/utils/deviceInfo.d.ts +20 -3
  19. package/dist/v2/core/utils/deviceInfo.js +62 -94
  20. package/dist/v2/core/utils/previewMode.d.ts +4 -0
  21. package/dist/v2/core/utils/previewMode.js +4 -0
  22. package/dist/v2/react/components/DebugDrawer.js +68 -46
  23. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +0 -1
  24. package/dist/v2/react/hooks/useCheckoutQuery.js +12 -4
  25. package/dist/v2/react/hooks/useFunnelLegacy.js +39 -11
  26. package/dist/v2/react/hooks/usePreviewOffer.d.ts +3 -3
  27. package/dist/v2/react/hooks/usePreviewOffer.js +20 -15
  28. package/dist/v2/react/hooks/useTranslation.js +12 -4
  29. package/dist/v2/standalone/index.d.ts +2 -1
  30. package/dist/v2/standalone/index.js +2 -1
  31. package/package.json +3 -1
@@ -7,12 +7,16 @@
7
7
  * 3. Recalculating totals on-the-fly without backend calls
8
8
  * 4. NO checkout session creation - perfect for browsing/previewing
9
9
  */
10
- import { useCallback, useEffect, useMemo, useState } from 'react';
11
10
  import { useQuery } from '@tanstack/react-query';
11
+ import { useCallback, useEffect, useMemo, useState } from 'react';
12
12
  import { OffersResource } from '../../core/resources/offers';
13
13
  import { getGlobalApiClient } from './useApiQuery';
14
14
  export function usePreviewOffer(options) {
15
15
  const { offerId, currency: requestedCurrency = 'USD', initialSelections = {} } = options;
16
+ const queryParamsCurrency = typeof window !== 'undefined'
17
+ ? new URLSearchParams(window.location.search).get('currency') || undefined
18
+ : undefined;
19
+ const effectiveCurrency = queryParamsCurrency || requestedCurrency;
16
20
  const offersResource = useMemo(() => new OffersResource(getGlobalApiClient()), []);
17
21
  // Track user selections (variant + quantity per product)
18
22
  const [selections, setSelections] = useState(initialSelections);
@@ -35,14 +39,14 @@ export function usePreviewOffer(options) {
35
39
  }, [selections]);
36
40
  // 🎯 ONE API CALL - Fetch offer + preview in one request
37
41
  const { data, isLoading, isFetching, error } = useQuery({
38
- queryKey: ['offer-preview', offerId, requestedCurrency, lineItemsForPreview],
42
+ queryKey: ['offer-preview', offerId, effectiveCurrency, lineItemsForPreview],
39
43
  queryFn: async () => {
40
44
  console.log('🔍 [usePreviewOffer] Fetching preview:', {
41
45
  offerId,
42
- currency: requestedCurrency,
46
+ currency: effectiveCurrency,
43
47
  lineItems: lineItemsForPreview,
44
48
  });
45
- const result = await offersResource.previewOffer(offerId, requestedCurrency, lineItemsForPreview);
49
+ const result = await offersResource.previewOffer(offerId, effectiveCurrency, lineItemsForPreview);
46
50
  console.log('✅ [usePreviewOffer] Preview result:', result);
47
51
  // Extract offer and preview from unified response
48
52
  const offer = result.offer || null;
@@ -66,7 +70,7 @@ export function usePreviewOffer(options) {
66
70
  totalAmount: preview.totalAmount || 0,
67
71
  totalAdjustedAmount: preview.totalAdjustedAmount || 0,
68
72
  totalPromotionAmount: preview.totalPromotionAmount || 0,
69
- currency: preview.currency || requestedCurrency,
73
+ currency: preview.currency || effectiveCurrency,
70
74
  options: preview.options || {},
71
75
  };
72
76
  return { offer, summary };
@@ -200,7 +204,7 @@ export function usePreviewOffer(options) {
200
204
  return [];
201
205
  const currentItem = summary.items.find((i) => i.productId === productId);
202
206
  const activePriceId = currentItem?.priceId;
203
- const currency = summary.currency || requestedCurrency;
207
+ const currency = summary.currency || effectiveCurrency;
204
208
  return summary.options[productId].map((variant) => {
205
209
  // Find matching price or use first
206
210
  let unitAmount = 0;
@@ -222,7 +226,7 @@ export function usePreviewOffer(options) {
222
226
  currency,
223
227
  };
224
228
  });
225
- }, [summary, requestedCurrency]);
229
+ }, [summary, effectiveCurrency]);
226
230
  // Pay for the offer with current selections
227
231
  const pay = useCallback(async (mainOrderId) => {
228
232
  if (isPaying) {
@@ -230,7 +234,7 @@ export function usePreviewOffer(options) {
230
234
  }
231
235
  setIsPaying(true);
232
236
  try {
233
- const result = await offersResource.payPreviewedOffer(offerId, requestedCurrency, lineItemsForPreview, typeof window !== 'undefined' ? window.location.href : undefined, mainOrderId);
237
+ const result = await offersResource.payPreviewedOffer(offerId, effectiveCurrency, lineItemsForPreview, typeof window !== 'undefined' ? window.location.href : undefined, mainOrderId);
234
238
  console.log('[usePreviewOffer] Payment initiated:', result);
235
239
  return {
236
240
  checkoutUrl: result.checkout.checkoutUrl,
@@ -243,20 +247,21 @@ export function usePreviewOffer(options) {
243
247
  finally {
244
248
  setIsPaying(false);
245
249
  }
246
- }, [offerId, requestedCurrency, lineItemsForPreview, offersResource, isPaying]);
247
- // Create checkout session without paying (for landing pages)
250
+ }, [offerId, effectiveCurrency, lineItemsForPreview, offersResource, isPaying]);
251
+ // Create checkout session without paying (for landing pages) - async mode for fast response
248
252
  const toCheckout = useCallback(async (mainOrderId) => {
249
253
  if (isPaying) {
250
254
  throw new Error('Operation already in progress');
251
255
  }
252
256
  setIsPaying(true);
253
257
  try {
254
- const result = await offersResource.toCheckout(offerId, requestedCurrency, lineItemsForPreview, typeof window !== 'undefined' ? window.location.href : undefined, mainOrderId);
255
- console.log('[usePreviewOffer] Checkout session created:', result);
258
+ // Use async mode for fast response (~50ms vs 2-5s)
259
+ const result = await offersResource.toCheckoutAsync(offerId, effectiveCurrency, lineItemsForPreview, typeof window !== 'undefined' ? window.location.href : undefined, mainOrderId);
260
+ console.log('[usePreviewOffer] Checkout session created (async):', result);
256
261
  return {
257
- checkoutSessionId: result.checkoutSessionId,
258
262
  checkoutToken: result.checkoutToken,
259
- checkoutUrl: result.checkoutUrl,
263
+ customerId: result.customerId,
264
+ status: result.status,
260
265
  };
261
266
  }
262
267
  catch (error) {
@@ -266,7 +271,7 @@ export function usePreviewOffer(options) {
266
271
  finally {
267
272
  setIsPaying(false);
268
273
  }
269
- }, [offerId, requestedCurrency, lineItemsForPreview, offersResource, isPaying]);
274
+ }, [offerId, effectiveCurrency, lineItemsForPreview, offersResource, isPaying]);
270
275
  return {
271
276
  offer,
272
277
  isLoading,
@@ -54,19 +54,27 @@ export const useTranslation = (options = {}) => {
54
54
  const { defaultLanguage = 'en', currentLanguage } = options;
55
55
  // Get the current language from query params, browser, or fallback to default
56
56
  const locale = useMemo(() => {
57
+ // Normalizes language codes like 'fr-FR' or 'pt_BR' to just 'fr' / 'pt'
58
+ const normalizeLanguageCode = (code) => {
59
+ if (!code)
60
+ return undefined;
61
+ return code.split(/[-_]/)[0].toLowerCase();
62
+ };
57
63
  if (currentLanguage)
58
64
  return currentLanguage;
59
65
  // Check for language query parameter
60
66
  if (typeof window !== 'undefined') {
61
67
  const urlParams = new URLSearchParams(window.location.search);
62
68
  const langFromQuery = urlParams.get('locale');
63
- if (langFromQuery)
64
- return langFromQuery;
69
+ const normalizedFromQuery = normalizeLanguageCode(langFromQuery);
70
+ if (normalizedFromQuery)
71
+ return normalizedFromQuery;
65
72
  }
66
73
  // Try to get browser language
67
74
  if (typeof navigator !== 'undefined') {
68
- const browserLang = navigator.language.split('-')[0]; // e.g., 'en-US' -> 'en'
69
- return browserLang;
75
+ const browserLang = normalizeLanguageCode(navigator.language); // e.g., 'en-US' -> 'en'
76
+ if (browserLang)
77
+ return browserLang;
70
78
  }
71
79
  return defaultLanguage;
72
80
  }, [defaultLanguage, currentLanguage]);
@@ -8,12 +8,13 @@
8
8
  */
9
9
  import { TagadaClient, TagadaClientConfig, TagadaState } from '../core/client';
10
10
  import { ApiClient } from '../core/resources/apiClient';
11
+ import { CheckoutResource } from '../core/resources/checkout';
11
12
  /**
12
13
  * Factory function to create a Tagada Client instance.
13
14
  * Features (like funnel) can be toggled via the config.
14
15
  */
15
16
  export declare function createTagadaClient(config?: TagadaClientConfig): TagadaClient;
16
- export { TagadaClient, ApiClient };
17
+ export { TagadaClient, ApiClient, CheckoutResource };
17
18
  export type { TagadaClientConfig, TagadaState };
18
19
  export { FunnelActionType } from '../core/resources/funnel';
19
20
  export type { FunnelAction, FunnelNavigationResult, SimpleFunnelContext } from '../core/resources/funnel';
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { TagadaClient } from '../core/client';
10
10
  import { ApiClient } from '../core/resources/apiClient';
11
+ import { CheckoutResource } from '../core/resources/checkout';
11
12
  /**
12
13
  * Factory function to create a Tagada Client instance.
13
14
  * Features (like funnel) can be toggled via the config.
@@ -16,7 +17,7 @@ export function createTagadaClient(config = {}) {
16
17
  return new TagadaClient(config);
17
18
  }
18
19
  // Re-export Core Classes
19
- export { TagadaClient, ApiClient };
20
+ export { TagadaClient, ApiClient, CheckoutResource };
20
21
  export { FunnelActionType } from '../core/resources/funnel';
21
22
  // Re-export Utilities
22
23
  export * from '../core/utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/plugin-sdk",
3
- "version": "3.0.9",
3
+ "version": "3.0.14",
4
4
  "description": "Modern React SDK for building Tagada Pay plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -73,7 +73,9 @@
73
73
  "@basis-theory/basis-theory-react": "^1.32.5",
74
74
  "@basis-theory/web-threeds": "^1.0.1",
75
75
  "@google-pay/button-react": "^3.0.10",
76
+ "@tagadapay/plugin-sdk": "link:",
76
77
  "@tanstack/react-query": "^5.90.2",
78
+ "@ua-parser-js/pro-enterprise": "^2.0.6",
77
79
  "axios": "^1.10.0",
78
80
  "iso3166-2-db": "^2.3.11",
79
81
  "path-to-regexp": "^8.2.0",