@tagadapay/plugin-sdk 2.4.38 → 2.5.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.
Files changed (112) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +2 -0
  3. package/dist/react/hooks/useCheckout.js +21 -33
  4. package/dist/react/hooks/useCheckoutSession.d.ts +19 -0
  5. package/dist/react/hooks/useCheckoutSession.js +108 -0
  6. package/dist/react/hooks/useCheckoutToken.d.ts +17 -0
  7. package/dist/react/hooks/useCheckoutToken.js +80 -0
  8. package/dist/react/hooks/useOrderBump.js +94 -29
  9. package/dist/react/hooks/useOrderBumpV2.d.ts +17 -0
  10. package/dist/react/hooks/useOrderBumpV2.js +95 -0
  11. package/dist/react/hooks/useOrderBumpV3.d.ts +23 -0
  12. package/dist/react/hooks/useOrderBumpV3.js +109 -0
  13. package/dist/react/hooks/usePayment.d.ts +1 -1
  14. package/dist/react/hooks/usePayment.js +2 -18
  15. package/dist/react/hooks/usePluginConfig.js +2 -13
  16. package/dist/react/hooks/usePostPurchases.js +11 -5
  17. package/dist/react/hooks/useProducts.js +2 -16
  18. package/dist/react/index.d.ts +9 -1
  19. package/dist/react/index.js +5 -1
  20. package/dist/react/providers/TagadaProvider.d.ts +0 -1
  21. package/dist/react/providers/TagadaProvider.js +16 -12
  22. package/dist/react/services/apiService.d.ts +1 -0
  23. package/dist/react/services/apiService.js +3 -0
  24. package/dist/v2/core/googleAutocomplete.d.ts +65 -0
  25. package/dist/v2/core/googleAutocomplete.js +94 -0
  26. package/dist/v2/core/index.d.ts +8 -0
  27. package/dist/v2/core/index.js +11 -0
  28. package/dist/v2/core/isoData.d.ts +50 -0
  29. package/dist/v2/core/isoData.js +103 -0
  30. package/dist/v2/core/resources/apiClient.d.ts +25 -0
  31. package/dist/v2/core/resources/apiClient.js +95 -0
  32. package/dist/v2/core/resources/checkout.d.ts +189 -0
  33. package/dist/v2/core/resources/checkout.js +119 -0
  34. package/dist/v2/core/resources/index.d.ts +13 -0
  35. package/dist/v2/core/resources/index.js +13 -0
  36. package/dist/v2/core/resources/offers.d.ts +98 -0
  37. package/dist/v2/core/resources/offers.js +115 -0
  38. package/dist/v2/core/resources/orders.d.ts +40 -0
  39. package/dist/v2/core/resources/orders.js +59 -0
  40. package/dist/v2/core/resources/payments.d.ts +140 -0
  41. package/dist/v2/core/resources/payments.js +126 -0
  42. package/dist/v2/core/resources/postPurchases.d.ts +182 -0
  43. package/dist/v2/core/resources/postPurchases.js +116 -0
  44. package/dist/v2/core/resources/products.d.ts +29 -0
  45. package/dist/v2/core/resources/products.js +49 -0
  46. package/dist/v2/core/resources/promotions.d.ts +45 -0
  47. package/dist/v2/core/resources/promotions.js +87 -0
  48. package/dist/v2/core/resources/threeds.d.ts +23 -0
  49. package/dist/v2/core/resources/threeds.js +15 -0
  50. package/dist/v2/core/utils/checkout.d.ts +24 -0
  51. package/dist/v2/core/utils/checkout.js +30 -0
  52. package/dist/v2/core/utils/currency.d.ts +28 -0
  53. package/dist/v2/core/utils/currency.js +272 -0
  54. package/dist/v2/core/utils/index.d.ts +12 -0
  55. package/dist/v2/core/utils/index.js +12 -0
  56. package/dist/v2/core/utils/order.d.ts +159 -0
  57. package/dist/v2/core/utils/order.js +42 -0
  58. package/dist/v2/core/utils/orderBump.d.ts +40 -0
  59. package/dist/v2/core/utils/orderBump.js +47 -0
  60. package/dist/v2/core/utils/pluginConfig.d.ts +43 -0
  61. package/dist/v2/core/utils/pluginConfig.js +155 -0
  62. package/dist/v2/core/utils/postPurchases.d.ts +32 -0
  63. package/dist/v2/core/utils/postPurchases.js +42 -0
  64. package/dist/v2/core/utils/products.d.ts +58 -0
  65. package/dist/v2/core/utils/products.js +64 -0
  66. package/dist/v2/core/utils/promotions.d.ts +24 -0
  67. package/dist/v2/core/utils/promotions.js +30 -0
  68. package/dist/v2/index.d.ts +19 -0
  69. package/dist/v2/index.js +15 -0
  70. package/dist/v2/react/components/DebugDrawer.d.ts +7 -0
  71. package/dist/v2/react/components/DebugDrawer.js +383 -0
  72. package/dist/v2/react/hooks/useApiQuery.d.ts +28 -0
  73. package/dist/v2/react/hooks/useApiQuery.js +84 -0
  74. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +39 -0
  75. package/dist/v2/react/hooks/useCheckoutQuery.js +208 -0
  76. package/dist/v2/react/hooks/useCheckoutToken.d.ts +17 -0
  77. package/dist/v2/react/hooks/useCheckoutToken.js +80 -0
  78. package/dist/v2/react/hooks/useCurrency.d.ts +9 -0
  79. package/dist/v2/react/hooks/useCurrency.js +21 -0
  80. package/dist/v2/react/hooks/useGeoLocation.d.ts +138 -0
  81. package/dist/v2/react/hooks/useGeoLocation.js +126 -0
  82. package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +74 -0
  83. package/dist/v2/react/hooks/useGoogleAutocomplete.js +207 -0
  84. package/dist/v2/react/hooks/useISOData.d.ts +61 -0
  85. package/dist/v2/react/hooks/useISOData.js +176 -0
  86. package/dist/v2/react/hooks/useOffersQuery.d.ts +65 -0
  87. package/dist/v2/react/hooks/useOffersQuery.js +353 -0
  88. package/dist/v2/react/hooks/useOrderBumpQuery.d.ts +20 -0
  89. package/dist/v2/react/hooks/useOrderBumpQuery.js +88 -0
  90. package/dist/v2/react/hooks/useOrderQuery.d.ts +29 -0
  91. package/dist/v2/react/hooks/useOrderQuery.js +98 -0
  92. package/dist/v2/react/hooks/usePaymentPolling.d.ts +45 -0
  93. package/dist/v2/react/hooks/usePaymentPolling.js +153 -0
  94. package/dist/v2/react/hooks/usePaymentQuery.d.ts +19 -0
  95. package/dist/v2/react/hooks/usePaymentQuery.js +283 -0
  96. package/dist/v2/react/hooks/usePluginConfig.d.ts +16 -0
  97. package/dist/v2/react/hooks/usePluginConfig.js +36 -0
  98. package/dist/v2/react/hooks/usePostPurchasesQuery.d.ts +63 -0
  99. package/dist/v2/react/hooks/usePostPurchasesQuery.js +365 -0
  100. package/dist/v2/react/hooks/useProductsQuery.d.ts +31 -0
  101. package/dist/v2/react/hooks/useProductsQuery.js +102 -0
  102. package/dist/v2/react/hooks/usePromotionsQuery.d.ts +28 -0
  103. package/dist/v2/react/hooks/usePromotionsQuery.js +97 -0
  104. package/dist/v2/react/hooks/useThreeds.d.ts +36 -0
  105. package/dist/v2/react/hooks/useThreeds.js +166 -0
  106. package/dist/v2/react/hooks/useThreedsModal.d.ts +13 -0
  107. package/dist/v2/react/hooks/useThreedsModal.js +343 -0
  108. package/dist/v2/react/index.d.ts +38 -0
  109. package/dist/v2/react/index.js +27 -0
  110. package/dist/v2/react/providers/TagadaProvider.d.ts +63 -0
  111. package/dist/v2/react/providers/TagadaProvider.js +680 -0
  112. package/package.json +10 -3
@@ -0,0 +1,109 @@
1
+ import { useState, useCallback, useEffect } from 'react';
2
+ import { useTagadaContext } from '../providers/TagadaProvider';
3
+ import { useCheckoutSession } from './useCheckoutSession';
4
+ /**
5
+ * Composable order bump hook that works with a specific checkout token
6
+ * This allows multiple order bumps to work with different checkout sessions
7
+ */
8
+ export function useOrderBumpV3(options) {
9
+ const { apiService, refreshCoordinator } = useTagadaContext();
10
+ const { checkoutToken, offerId, productId, orderBumpType = 'primary' } = options;
11
+ // Use the composable checkout session hook
12
+ const { checkout, isLoading: checkoutLoading, error: checkoutError, refresh: refreshCheckout } = useCheckoutSession({
13
+ checkoutToken,
14
+ autoRefresh: false, // We'll handle refreshes manually
15
+ });
16
+ // Check if order bump is selected from checkout session line items
17
+ const checkOrderBumpSelection = useCallback(() => {
18
+ console.log('🔧 useOrderBumpV3: Checking order bump selection', {
19
+ checkoutToken: checkoutToken ? checkoutToken.substring(0, 8) + '...' : null,
20
+ offerId,
21
+ productId,
22
+ hasCheckout: !!checkout,
23
+ hasSession: !!checkout?.checkoutSession,
24
+ hasLineItems: !!checkout?.checkoutSession?.sessionLineItems
25
+ });
26
+ if (!checkout?.checkoutSession?.sessionLineItems) {
27
+ console.log('🔧 useOrderBumpV3: No session line items available');
28
+ return false;
29
+ }
30
+ const targetProductId = productId || offerId; // Fallback to offerId if productId not provided
31
+ console.log('🔧 useOrderBumpV3: Looking for product ID:', targetProductId);
32
+ const isSelected = checkout.checkoutSession.sessionLineItems.some((item) => {
33
+ const matches = item.isOrderBump === true && item.productId === targetProductId;
34
+ console.log('🔧 useOrderBumpV3: Checking item:', {
35
+ itemId: item.id,
36
+ productId: item.productId,
37
+ isOrderBump: item.isOrderBump,
38
+ targetProductId,
39
+ offerId,
40
+ matches
41
+ });
42
+ return matches;
43
+ });
44
+ console.log('🔧 useOrderBumpV3: Selection result:', isSelected);
45
+ return isSelected;
46
+ }, [checkout?.checkoutSession?.sessionLineItems, offerId, productId]);
47
+ // Initialize state based on current checkout session
48
+ const [isSelected, setIsSelected] = useState(() => checkOrderBumpSelection());
49
+ const [isToggling, setIsToggling] = useState(false);
50
+ const [error, setError] = useState(null);
51
+ // Update isSelected when checkout session changes
52
+ useEffect(() => {
53
+ const isSelectedFromSession = checkOrderBumpSelection();
54
+ setIsSelected(isSelectedFromSession);
55
+ }, [checkOrderBumpSelection]);
56
+ const toggle = useCallback(async (selected) => {
57
+ if (!checkout?.checkoutSession?.id) {
58
+ console.warn('useOrderBumpV3: No checkout session available yet');
59
+ return { success: false, error: 'Checkout session not ready' };
60
+ }
61
+ const targetState = selected ?? !isSelected;
62
+ // Optimistic update
63
+ setIsSelected(targetState);
64
+ setIsToggling(true);
65
+ setError(null);
66
+ try {
67
+ const response = await apiService.fetch(`/api/v1/checkout-sessions/${checkout.checkoutSession.id}/toggle-order-bump`, {
68
+ method: 'POST',
69
+ body: {
70
+ orderBumpOfferId: offerId,
71
+ selected: targetState,
72
+ },
73
+ });
74
+ if (response.success) {
75
+ // Refresh the checkout session to get updated data
76
+ await refreshCheckout();
77
+ // Notify other hooks that order bump data changed
78
+ await refreshCoordinator.notifyOrderBumpChanged();
79
+ // Also notify checkout hooks that data changed
80
+ await refreshCoordinator.notifyCheckoutChanged();
81
+ return { success: true };
82
+ }
83
+ else {
84
+ // Revert optimistic update
85
+ setIsSelected(!targetState);
86
+ return { success: false, error: response.error };
87
+ }
88
+ }
89
+ catch (err) {
90
+ // Revert optimistic update
91
+ setIsSelected(!targetState);
92
+ const error = err instanceof Error ? err : new Error('Failed to toggle order bump');
93
+ setError(error);
94
+ return { success: false, error: error.message };
95
+ }
96
+ finally {
97
+ setIsToggling(false);
98
+ }
99
+ }, [checkout?.checkoutSession?.id, offerId, isSelected, apiService, refreshCoordinator, refreshCheckout]);
100
+ return {
101
+ isSelected,
102
+ isLoading: checkoutLoading,
103
+ isToggling,
104
+ error: error || checkoutError,
105
+ toggle,
106
+ isReady: !!checkout?.checkoutSession?.id,
107
+ checkout,
108
+ };
109
+ }
@@ -83,7 +83,7 @@ export interface PaymentInstrumentCustomer {
83
83
  token: string;
84
84
  isDefault: boolean;
85
85
  isActive: boolean;
86
- metadata: {};
86
+ metadata: Record<string, unknown>;
87
87
  customerId: string;
88
88
  accountId: string;
89
89
  createdAt: string;
@@ -1,7 +1,7 @@
1
1
  import { useBasisTheory } from '@basis-theory/basis-theory-react';
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { getBasisTheoryApiKey } from '../config/payment';
4
- import { useTagadaContextSafe } from '../providers/TagadaProvider';
4
+ import { useTagadaContext } from '../providers/TagadaProvider';
5
5
  import { usePaymentPolling } from './usePaymentPolling';
6
6
  import { useThreeds } from './useThreeds';
7
7
  // Helper function to format expiry date
@@ -16,23 +16,7 @@ const getCardMonthAndYear = (expiryDate) => {
16
16
  };
17
17
  };
18
18
  export function usePayment() {
19
- const context = useTagadaContextSafe();
20
- // If context is not ready yet, return loading state
21
- if (!context) {
22
- return {
23
- processCardPayment: async () => ({ paymentId: '', payment: {} }),
24
- processApplePayPayment: async () => ({ paymentId: '', payment: {} }),
25
- processPaymentWithInstrument: async () => ({ paymentId: '', payment: {} }),
26
- createCardPaymentInstrument: async () => ({ id: '', token: '', type: 'card' }),
27
- createApplePayPaymentInstrument: async () => ({ id: '', token: '', type: 'apple_pay' }),
28
- getCardPaymentInstruments: async () => [],
29
- isLoading: false,
30
- error: null,
31
- clearError: () => { },
32
- currentPaymentId: null,
33
- };
34
- }
35
- const { apiService, environment } = context;
19
+ const { apiService, environment } = useTagadaContext();
36
20
  const [isLoading, setIsLoading] = useState(false);
37
21
  const [error, setError] = useState(null);
38
22
  const [currentPaymentId, setCurrentPaymentId] = useState(null);
@@ -18,7 +18,7 @@
18
18
  * - Headers for store/account info
19
19
  * - Meta tags for deployment config
20
20
  */
21
- import { useTagadaContextSafe } from '../providers/TagadaProvider';
21
+ import { useTagadaContext } from '../providers/TagadaProvider';
22
22
  // Simple cache for plugin configuration
23
23
  let cachedConfig = null;
24
24
  let configPromise = null;
@@ -161,18 +161,7 @@ export const loadPluginConfig = async (configVariant = 'default', rawConfig) =>
161
161
  * Gets config from TagadaProvider context (no parameters needed)
162
162
  */
163
163
  export const usePluginConfig = () => {
164
- const context = useTagadaContextSafe();
165
- // If context is not ready yet, return loading state
166
- if (!context) {
167
- return {
168
- storeId: undefined,
169
- accountId: undefined,
170
- basePath: '/',
171
- config: {},
172
- loading: true,
173
- };
174
- }
175
- const { pluginConfig, pluginConfigLoading } = context;
164
+ const { pluginConfig, pluginConfigLoading } = useTagadaContext();
176
165
  return {
177
166
  storeId: pluginConfig.storeId,
178
167
  accountId: pluginConfig.accountId,
@@ -24,7 +24,7 @@ export function usePostPurchases(options) {
24
24
  // Auto-initialize checkout sessions if enabled
25
25
  if (autoInitializeCheckout && fetchedOffers.length > 0) {
26
26
  for (const offer of fetchedOffers) {
27
- await initializeOfferCheckout(offer.id);
27
+ void initializeOfferCheckout(offer.id);
28
28
  }
29
29
  }
30
30
  }
@@ -69,9 +69,13 @@ export function usePostPurchases(options) {
69
69
  method: 'POST',
70
70
  body: JSON.stringify({
71
71
  checkoutSessionId,
72
+ draft: false,
73
+ returnUrl: window.location.href,
72
74
  metadata: {
73
75
  comingFromPostPurchase: true,
74
76
  postOrder: orderId,
77
+ upsell: true,
78
+ source: 'post_purchase_offer',
75
79
  },
76
80
  }),
77
81
  });
@@ -244,6 +248,8 @@ export function usePostPurchases(options) {
244
248
  metadata: {
245
249
  comingFromPostPurchase: true,
246
250
  postOrder: orderId,
251
+ upsell: true,
252
+ source: 'post_purchase_offer',
247
253
  },
248
254
  }),
249
255
  });
@@ -268,17 +274,17 @@ export function usePostPurchases(options) {
268
274
  }));
269
275
  }, [checkoutSessions]);
270
276
  const getOrderSummary = useCallback((offerId) => {
271
- return checkoutSessions[offerId]?.orderSummary || null;
277
+ return checkoutSessions[offerId]?.orderSummary ?? null;
272
278
  }, [checkoutSessions]);
273
279
  const isLoadingVariants = useCallback((offerId, productId) => {
274
- return checkoutSessions[offerId]?.loadingVariants?.[productId] || false;
280
+ return checkoutSessions[offerId]?.loadingVariants?.[productId] ?? false;
275
281
  }, [checkoutSessions]);
276
282
  const isUpdatingOrderSummary = useCallback((offerId) => {
277
- return checkoutSessions[offerId]?.isUpdatingSummary || false;
283
+ return checkoutSessions[offerId]?.isUpdatingSummary ?? false;
278
284
  }, [checkoutSessions]);
279
285
  useEffect(() => {
280
286
  if (enabled && orderId) {
281
- fetchOffers();
287
+ void fetchOffers();
282
288
  }
283
289
  }, [enabled, orderId, fetchOffers]);
284
290
  const getOffer = useCallback((offerId) => {
@@ -1,23 +1,9 @@
1
1
  import { useCallback, useEffect, useMemo, useState } from 'react';
2
- import { useTagadaContextSafe } from '../providers/TagadaProvider';
2
+ import { useTagadaContext } from '../providers/TagadaProvider';
3
3
  import { usePluginConfig } from './usePluginConfig';
4
4
  export function useProducts(options = {}) {
5
- const context = useTagadaContextSafe();
5
+ const { apiService } = useTagadaContext();
6
6
  const { storeId } = usePluginConfig();
7
- // If context is not ready yet, return loading state
8
- if (!context) {
9
- return {
10
- products: [],
11
- isLoading: true,
12
- error: null,
13
- getVariant: () => undefined,
14
- getProduct: () => undefined,
15
- getAllVariants: () => [],
16
- filterVariants: () => [],
17
- refetch: async () => { },
18
- };
19
- }
20
- const { apiService } = context;
21
7
  const [products, setProducts] = useState([]);
22
8
  const [isLoading, setIsLoading] = useState(false);
23
9
  const [error, setError] = useState(null);
@@ -15,6 +15,10 @@ export { useLocale } from './hooks/useLocale';
15
15
  export { useLogin } from './hooks/useLogin';
16
16
  export { useOffers } from './hooks/useOffers';
17
17
  export { useOrderBump } from './hooks/useOrderBump';
18
+ export { useOrderBumpV2 } from './hooks/useOrderBumpV2';
19
+ export { useOrderBumpV3 } from './hooks/useOrderBumpV3';
20
+ export { useCheckoutToken } from './hooks/useCheckoutToken';
21
+ export { useCheckoutSession } from './hooks/useCheckoutSession';
18
22
  export { usePostPurchases } from './hooks/usePostPurchases';
19
23
  export { useProducts } from './hooks/useProducts';
20
24
  export { useSession } from './hooks/useSession';
@@ -22,7 +26,7 @@ export { useShippingRates } from './hooks/useShippingRates';
22
26
  export type { UseShippingRatesOptions, UseShippingRatesResult } from './hooks/useShippingRates';
23
27
  export { useTranslations } from './hooks/useTranslations';
24
28
  export { useVipOffers } from './hooks/useVipOffers';
25
- export { useTagadaContext, useTagadaContextSafe } from './providers/TagadaProvider';
29
+ export { useTagadaContext } from './providers/TagadaProvider';
26
30
  export { clearPluginConfigCache, debugPluginConfig, getPluginConfig, useBasePath, usePluginConfig } from './hooks/usePluginConfig';
27
31
  export type { PluginConfig } from './hooks/usePluginConfig';
28
32
  export { getAvailableLanguages, useCountryOptions, useISOData, useRegionOptions, useLanguageImport } from './hooks/useISOData';
@@ -41,6 +45,10 @@ export type { AuthState, Currency, Customer, Environment, EnvironmentConfig, Loc
41
45
  export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion, UseCheckoutOptions, UseCheckoutResult } from './hooks/useCheckout';
42
46
  export type { Discount, DiscountCodeValidation, UseDiscountsOptions, UseDiscountsResult } from './hooks/useDiscounts';
43
47
  export type { OrderBumpPreview, UseOrderBumpOptions, UseOrderBumpResult } from './hooks/useOrderBump';
48
+ export type { UseOrderBumpV2Options, UseOrderBumpV2Result } from './hooks/useOrderBumpV2';
49
+ export type { UseOrderBumpV3Options, UseOrderBumpV3Result } from './hooks/useOrderBumpV3';
50
+ export type { UseCheckoutTokenOptions, UseCheckoutTokenResult } from './hooks/useCheckoutToken';
51
+ export type { UseCheckoutSessionOptions, UseCheckoutSessionResult } from './hooks/useCheckoutSession';
44
52
  export type { UseVipOffersOptions, UseVipOffersResult, VipOffer, VipPreviewResponse } from './hooks/useVipOffers';
45
53
  export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferLineItem, PostPurchaseOfferSummary, UsePostPurchasesOptions, UsePostPurchasesResult } from './hooks/usePostPurchases';
46
54
  export type { Payment, PaymentPollingHook, PollingOptions } from './hooks/usePaymentPolling';
@@ -18,13 +18,17 @@ export { useLocale } from './hooks/useLocale';
18
18
  export { useLogin } from './hooks/useLogin';
19
19
  export { useOffers } from './hooks/useOffers';
20
20
  export { useOrderBump } from './hooks/useOrderBump';
21
+ export { useOrderBumpV2 } from './hooks/useOrderBumpV2';
22
+ export { useOrderBumpV3 } from './hooks/useOrderBumpV3';
23
+ export { useCheckoutToken } from './hooks/useCheckoutToken';
24
+ export { useCheckoutSession } from './hooks/useCheckoutSession';
21
25
  export { usePostPurchases } from './hooks/usePostPurchases';
22
26
  export { useProducts } from './hooks/useProducts';
23
27
  export { useSession } from './hooks/useSession';
24
28
  export { useShippingRates } from './hooks/useShippingRates';
25
29
  export { useTranslations } from './hooks/useTranslations';
26
30
  export { useVipOffers } from './hooks/useVipOffers';
27
- export { useTagadaContext, useTagadaContextSafe } from './providers/TagadaProvider';
31
+ export { useTagadaContext } from './providers/TagadaProvider';
28
32
  // Plugin configuration hooks
29
33
  export { clearPluginConfigCache, debugPluginConfig, getPluginConfig, useBasePath, usePluginConfig } from './hooks/usePluginConfig';
30
34
  // ISO Data hooks
@@ -60,5 +60,4 @@ export declare function TagadaProvider({ children, environment, customApiConfig,
60
60
  localConfig, blockUntilSessionReady, // Default to new non-blocking behavior
61
61
  rawPluginConfig, }: TagadaProviderProps): import("react/jsx-runtime").JSX.Element;
62
62
  export declare function useTagadaContext(): TagadaContextValue;
63
- export declare function useTagadaContextSafe(): TagadaContextValue | null;
64
63
  export {};
@@ -66,8 +66,19 @@ rawPluginConfig, }) {
66
66
  hasLoggedRef.current = true;
67
67
  }
68
68
  // Load plugin configuration directly (not using hook to avoid circular dependency)
69
- const [pluginConfig, setPluginConfig] = useState({ basePath: '/', config: {} });
70
- const [configLoading, setConfigLoading] = useState(true);
69
+ // Initialize with raw config if available to avoid empty config during loading
70
+ const [pluginConfig, setPluginConfig] = useState(() => {
71
+ if (rawPluginConfig) {
72
+ return {
73
+ storeId: rawPluginConfig.storeId,
74
+ accountId: rawPluginConfig.accountId,
75
+ basePath: rawPluginConfig.basePath ?? '/',
76
+ config: rawPluginConfig.config ?? {},
77
+ };
78
+ }
79
+ return { basePath: '/', config: {} };
80
+ });
81
+ const [configLoading, setConfigLoading] = useState(!rawPluginConfig);
71
82
  // Load plugin config on mount with the specified variant
72
83
  useEffect(() => {
73
84
  const loadConfig = async () => {
@@ -524,12 +535,9 @@ rawPluginConfig, }) {
524
535
  refreshCoordinator,
525
536
  ]);
526
537
  // Determine if we should show loading
527
- // Phase 1 & 2 are mandatory: config loading and storeId availability
528
- // Phase 3 (session initialization) is optional/non-blocking by default
529
- const shouldShowLoading = configLoading || (!storeId && configLoading);
530
- const canRenderChildren = blockUntilSessionReady
531
- ? !configLoading && storeId && isInitialized // Old behavior: wait for all phases
532
- : !configLoading && storeId; // New behavior: render after phases 1 & 2
538
+ // Always block until config is loaded (even if empty)
539
+ const shouldShowLoading = configLoading;
540
+ const canRenderChildren = !configLoading;
533
541
  return (_jsxs(TagadaContext.Provider, { value: contextValue, children: [shouldShowLoading && _jsx(InitializationLoader, {}), finalDebugMode && canRenderChildren && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => setIsDebugDrawerOpen(true), style: {
534
542
  position: 'fixed',
535
543
  bottom: '16px',
@@ -560,10 +568,6 @@ export function useTagadaContext() {
560
568
  }
561
569
  return context;
562
570
  }
563
- // Safe version that returns null instead of throwing
564
- export function useTagadaContextSafe() {
565
- return useContext(TagadaContext);
566
- }
567
571
  // Helper functions
568
572
  function getCurrencySymbol(code) {
569
573
  const symbols = {
@@ -49,6 +49,7 @@ export declare class ApiService {
49
49
  private onTokenClear?;
50
50
  constructor(options: ApiServiceOptions);
51
51
  updateToken(token: string | null): void;
52
+ getCurrentToken(): string | null;
52
53
  updateConfig(config: EnvironmentConfig): void;
53
54
  /**
54
55
  * Store the store ID in localStorage (deprecated - use usePluginConfig instead)
@@ -10,6 +10,9 @@ export class ApiService {
10
10
  updateToken(token) {
11
11
  this.token = token;
12
12
  }
13
+ getCurrentToken() {
14
+ return this.token;
15
+ }
13
16
  updateConfig(config) {
14
17
  this.config = config;
15
18
  }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Google Autocomplete Core
3
+ * Pure functions for Google Places API integration
4
+ */
5
+ export interface GooglePrediction {
6
+ place_id: string;
7
+ description: string;
8
+ structured_formatting?: {
9
+ main_text: string;
10
+ secondary_text: string;
11
+ };
12
+ }
13
+ export interface GooglePlaceDetails {
14
+ place_id: string;
15
+ formatted_address: string;
16
+ address_components: {
17
+ long_name: string;
18
+ short_name: string;
19
+ types: string[];
20
+ }[];
21
+ geometry: {
22
+ location: {
23
+ lat: number;
24
+ lng: number;
25
+ };
26
+ };
27
+ }
28
+ export interface AddressComponents {
29
+ streetNumber?: string;
30
+ route?: string;
31
+ city?: string;
32
+ state?: string;
33
+ postalCode?: string;
34
+ country?: string;
35
+ countryCode?: string;
36
+ locality?: string;
37
+ administrativeAreaLevel1?: string;
38
+ administrativeAreaLevel1Long?: string;
39
+ iso?: string;
40
+ }
41
+ export declare class GoogleAutocompleteCore {
42
+ private static apiKey;
43
+ private static service;
44
+ /**
45
+ * Initialize Google Places API
46
+ */
47
+ static initialize(apiKey: string): void;
48
+ /**
49
+ * Search for places
50
+ */
51
+ static searchPlaces(input: string, options?: {
52
+ types?: string[];
53
+ componentRestrictions?: {
54
+ country: string;
55
+ };
56
+ }): Promise<GooglePrediction[]>;
57
+ /**
58
+ * Get place details
59
+ */
60
+ static getPlaceDetails(placeId: string): Promise<GooglePlaceDetails | null>;
61
+ /**
62
+ * Extract address components from place details
63
+ */
64
+ static extractAddressComponents(placeDetails: GooglePlaceDetails): AddressComponents;
65
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Google Autocomplete Core
3
+ * Pure functions for Google Places API integration
4
+ */
5
+ export class GoogleAutocompleteCore {
6
+ /**
7
+ * Initialize Google Places API
8
+ */
9
+ static initialize(apiKey) {
10
+ this.apiKey = apiKey;
11
+ if (typeof window !== 'undefined' && window.google) {
12
+ this.service = new window.google.maps.places.AutocompleteService();
13
+ }
14
+ }
15
+ /**
16
+ * Search for places
17
+ */
18
+ static async searchPlaces(input, options = {}) {
19
+ if (!this.service || !input.trim()) {
20
+ return [];
21
+ }
22
+ return new Promise((resolve, reject) => {
23
+ this.service.getPlacePredictions({
24
+ input,
25
+ types: options.types || ['address'],
26
+ componentRestrictions: options.componentRestrictions,
27
+ }, (predictions, status) => {
28
+ if (status === window.google.maps.places.PlacesServiceStatus.OK && predictions) {
29
+ resolve(predictions);
30
+ }
31
+ else {
32
+ resolve([]);
33
+ }
34
+ });
35
+ });
36
+ }
37
+ /**
38
+ * Get place details
39
+ */
40
+ static async getPlaceDetails(placeId) {
41
+ if (typeof window === 'undefined' || !window.google) {
42
+ return null;
43
+ }
44
+ return new Promise((resolve, reject) => {
45
+ const service = new window.google.maps.places.PlacesService(document.createElement('div'));
46
+ service.getDetails({
47
+ placeId,
48
+ fields: ['place_id', 'formatted_address', 'address_components', 'geometry'],
49
+ }, (place, status) => {
50
+ if (status === window.google.maps.places.PlacesServiceStatus.OK && place) {
51
+ resolve(place);
52
+ }
53
+ else {
54
+ resolve(null);
55
+ }
56
+ });
57
+ });
58
+ }
59
+ /**
60
+ * Extract address components from place details
61
+ */
62
+ static extractAddressComponents(placeDetails) {
63
+ const components = {};
64
+ for (const component of placeDetails.address_components) {
65
+ const types = component.types;
66
+ if (types.includes('street_number')) {
67
+ components.streetNumber = component.long_name;
68
+ }
69
+ else if (types.includes('route')) {
70
+ components.route = component.long_name;
71
+ }
72
+ else if (types.includes('locality')) {
73
+ components.city = component.long_name;
74
+ components.locality = component.long_name;
75
+ }
76
+ else if (types.includes('administrative_area_level_1')) {
77
+ components.state = component.long_name;
78
+ components.administrativeAreaLevel1 = component.short_name;
79
+ components.administrativeAreaLevel1Long = component.long_name;
80
+ }
81
+ else if (types.includes('postal_code')) {
82
+ components.postalCode = component.long_name;
83
+ }
84
+ else if (types.includes('country')) {
85
+ components.country = component.long_name;
86
+ components.countryCode = component.short_name;
87
+ components.iso = component.short_name;
88
+ }
89
+ }
90
+ return components;
91
+ }
92
+ }
93
+ GoogleAutocompleteCore.apiKey = null;
94
+ GoogleAutocompleteCore.service = null;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core functions and utilities for TagadaPay Plugin SDK v2
3
+ * Structured with utils (pure functions) and resources (API clients)
4
+ */
5
+ export * from './utils';
6
+ export * from './resources';
7
+ export * from './googleAutocomplete';
8
+ export * from './isoData';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Core functions and utilities for TagadaPay Plugin SDK v2
3
+ * Structured with utils (pure functions) and resources (API clients)
4
+ */
5
+ // Export utilities (pure functions)
6
+ export * from './utils';
7
+ // Export resources (axios-based API clients)
8
+ export * from './resources';
9
+ // Export legacy files that are still needed
10
+ export * from './googleAutocomplete';
11
+ export * from './isoData';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ISO Data Core
3
+ * Pure functions for country and region data management
4
+ * Uses the existing iso3166 data functions
5
+ */
6
+ import { type SupportedLanguage } from '../../data/iso3166';
7
+ export interface ISOCountry {
8
+ iso: string;
9
+ iso3: string;
10
+ numeric: number;
11
+ name: string;
12
+ }
13
+ export interface ISORegion {
14
+ iso: string;
15
+ name: string;
16
+ }
17
+ export declare class ISODataCore {
18
+ /**
19
+ * Get countries data for a specific language
20
+ */
21
+ static getCountriesData(language?: SupportedLanguage): Record<string, ISOCountry>;
22
+ /**
23
+ * Get regions for a specific country
24
+ */
25
+ static getRegions(countryCode: string, language?: SupportedLanguage): ISORegion[];
26
+ /**
27
+ * Find a specific region by ISO code
28
+ */
29
+ static findRegion(countryCode: string, regionCode: string, language?: SupportedLanguage): ISORegion | null;
30
+ /**
31
+ * Map Google Places state to ISO region (proven 100% success rate)
32
+ */
33
+ static mapGoogleToISO(googleState: string, googleStateLong: string, countryCode: string, language?: SupportedLanguage): ISORegion | null;
34
+ /**
35
+ * Check if language is registered
36
+ */
37
+ static isLanguageRegistered(language: SupportedLanguage): boolean;
38
+ /**
39
+ * Get registered languages
40
+ */
41
+ static getRegisteredLanguages(): SupportedLanguage[];
42
+ /**
43
+ * Import language data
44
+ */
45
+ static importLanguage(language: SupportedLanguage): Promise<void>;
46
+ /**
47
+ * Get available languages for ISO data
48
+ */
49
+ static getAvailableLanguages(): SupportedLanguage[];
50
+ }