@tagadapay/plugin-sdk 2.6.0 → 2.6.4

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,15 @@
1
+ import type { CustomerInfos } from '../types';
2
+ export interface UseCustomerInfosOptions {
3
+ customerId?: string | null;
4
+ enabled?: boolean;
5
+ }
6
+ export interface UseCustomerInfosResult {
7
+ data: CustomerInfos | null;
8
+ isLoading: boolean;
9
+ error: Error | null;
10
+ refetch: () => Promise<void>;
11
+ }
12
+ /**
13
+ * useCustomerInfos - Fetches customer infos from `/api/v1/customers/{customerId}` with `storeId` param
14
+ */
15
+ export declare function useCustomerInfos(options: UseCustomerInfosOptions): UseCustomerInfosResult;
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { useTagadaContext } from '../providers/TagadaProvider';
4
+ import { usePluginConfig } from './usePluginConfig';
5
+ /**
6
+ * useCustomerInfos - Fetches customer infos from `/api/v1/customers/{customerId}` with `storeId` param
7
+ */
8
+ export function useCustomerInfos(options) {
9
+ const { apiService } = useTagadaContext();
10
+ const { storeId } = usePluginConfig();
11
+ const stableOptions = useMemo(() => {
12
+ return {
13
+ customerId: options.customerId ?? null,
14
+ enabled: options.enabled ?? true,
15
+ };
16
+ }, [options.customerId, options.enabled]);
17
+ const isEnabled = useMemo(() => {
18
+ return Boolean(stableOptions.enabled && stableOptions.customerId && storeId);
19
+ }, [stableOptions.enabled, stableOptions.customerId, storeId]);
20
+ const [data, setData] = useState(null);
21
+ const [isLoading, setIsLoading] = useState(false);
22
+ const [error, setError] = useState(null);
23
+ const fetchCustomerInfos = useCallback(async () => {
24
+ if (!isEnabled)
25
+ return;
26
+ if (!stableOptions.customerId || !storeId)
27
+ return;
28
+ setIsLoading(true);
29
+ setError(null);
30
+ try {
31
+ const response = await apiService.fetch(`/api/v1/customers/${stableOptions.customerId}`, {
32
+ method: 'GET',
33
+ params: { storeId },
34
+ });
35
+ setData(response ?? null);
36
+ }
37
+ catch (err) {
38
+ const safeError = err instanceof Error ? err : new Error('Failed to fetch customer infos');
39
+ setError(safeError);
40
+ }
41
+ finally {
42
+ setIsLoading(false);
43
+ }
44
+ }, [apiService, isEnabled, stableOptions.customerId, storeId]);
45
+ useEffect(() => {
46
+ void fetchCustomerInfos();
47
+ }, [fetchCustomerInfos]);
48
+ return {
49
+ data,
50
+ isLoading,
51
+ error,
52
+ refetch: fetchCustomerInfos,
53
+ };
54
+ }
@@ -0,0 +1,14 @@
1
+ import type { OrderWithRelations } from '../types';
2
+ export interface UseCustomerOrdersOptions {
3
+ customerId?: string | null;
4
+ enabled?: boolean;
5
+ }
6
+ export interface UseCustomerOrdersResult {
7
+ data: {
8
+ orders: OrderWithRelations[];
9
+ } | null;
10
+ isLoading: boolean;
11
+ error: Error | null;
12
+ refetch: () => Promise<void>;
13
+ }
14
+ export declare function useCustomerOrders(options: UseCustomerOrdersOptions): UseCustomerOrdersResult;
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { useTagadaContext } from '../providers/TagadaProvider';
4
+ import { usePluginConfig } from './usePluginConfig';
5
+ export function useCustomerOrders(options) {
6
+ const { apiService } = useTagadaContext();
7
+ const { storeId } = usePluginConfig();
8
+ const stableOptions = useMemo(() => {
9
+ return {
10
+ customerId: options.customerId ?? null,
11
+ enabled: options.enabled ?? true,
12
+ };
13
+ }, [options.customerId, options.enabled]);
14
+ const isEnabled = useMemo(() => {
15
+ return Boolean(stableOptions.enabled && stableOptions.customerId && storeId);
16
+ }, [stableOptions.enabled, stableOptions.customerId, storeId]);
17
+ const [data, setData] = useState(null);
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [error, setError] = useState(null);
20
+ const fetchOrders = useCallback(async () => {
21
+ if (!isEnabled)
22
+ return;
23
+ if (!stableOptions.customerId || !storeId)
24
+ return;
25
+ setIsLoading(true);
26
+ setError(null);
27
+ try {
28
+ const response = await apiService.fetch(`/api/v1/orders/customer/${stableOptions.customerId}`, {
29
+ method: 'GET',
30
+ params: { storeId },
31
+ });
32
+ setData(response ?? null);
33
+ }
34
+ catch (err) {
35
+ const safeError = err instanceof Error ? err : new Error('Failed to fetch customer orders');
36
+ setError(safeError);
37
+ }
38
+ finally {
39
+ setIsLoading(false);
40
+ }
41
+ }, [apiService, isEnabled, stableOptions.customerId, storeId]);
42
+ useEffect(() => {
43
+ void fetchOrders();
44
+ }, [fetchOrders]);
45
+ return {
46
+ data,
47
+ isLoading,
48
+ error,
49
+ refetch: fetchOrders,
50
+ };
51
+ }
@@ -0,0 +1,56 @@
1
+ export interface Subscription {
2
+ id: string;
3
+ status: string;
4
+ createdAt: string;
5
+ currency: string;
6
+ cancelAtPeriodEnd: boolean;
7
+ currentPeriodEnd: string | null;
8
+ currentPeriodStart: string | null;
9
+ quantity: number;
10
+ trialEnd: string | null;
11
+ customerId: string;
12
+ customerEmail: string;
13
+ customerName: string;
14
+ priceCurrencyOptions: Record<string, {
15
+ rate: number;
16
+ amount: number;
17
+ lock: boolean;
18
+ date: string;
19
+ }>;
20
+ priceInterval: string;
21
+ priceIntervalCount: number;
22
+ priceRecurring: boolean;
23
+ productId: string;
24
+ priceId: string;
25
+ productTitle: string;
26
+ }
27
+ export interface SubscriptionsResponse {
28
+ items: Subscription[];
29
+ pagination: {
30
+ page: number;
31
+ pageSize: number;
32
+ hasNext: boolean;
33
+ nextPage: number | null;
34
+ previousPage: number | null;
35
+ totalItems: number;
36
+ };
37
+ }
38
+ export interface UseCustomerSubscriptionsOptions {
39
+ customerId?: string | null;
40
+ enabled?: boolean;
41
+ }
42
+ export interface UseCustomerSubscriptionsResult {
43
+ data: SubscriptionsResponse | null;
44
+ isLoading: boolean;
45
+ error: Error | null;
46
+ refetch: () => Promise<void>;
47
+ resumeSubscription: (subscriptionId: string) => Promise<{
48
+ success: boolean;
49
+ error?: string;
50
+ }>;
51
+ cancelSubscription: (subscriptionId: string) => Promise<{
52
+ success: boolean;
53
+ error?: string;
54
+ }>;
55
+ }
56
+ export declare function useCustomerSubscriptions(options: UseCustomerSubscriptionsOptions): UseCustomerSubscriptionsResult;
@@ -0,0 +1,77 @@
1
+ 'use client';
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { useTagadaContext } from '../providers/TagadaProvider';
4
+ export function useCustomerSubscriptions(options) {
5
+ const { apiService } = useTagadaContext();
6
+ const stableOptions = useMemo(() => {
7
+ return {
8
+ customerId: options.customerId ?? null,
9
+ enabled: options.enabled ?? true,
10
+ };
11
+ }, [options.customerId, options.enabled]);
12
+ const isEnabled = useMemo(() => {
13
+ return Boolean(stableOptions.enabled && stableOptions.customerId);
14
+ }, [stableOptions.enabled, stableOptions.customerId]);
15
+ const [data, setData] = useState(null);
16
+ const [isLoading, setIsLoading] = useState(false);
17
+ const [error, setError] = useState(null);
18
+ const fetchSubscriptions = useCallback(async () => {
19
+ if (!isEnabled)
20
+ return;
21
+ setIsLoading(true);
22
+ setError(null);
23
+ try {
24
+ // Token-authenticated request; backend infers customer from token
25
+ const response = await apiService.fetch(`/api/v1/subscriptions`, {
26
+ method: 'GET',
27
+ });
28
+ setData(response ?? null);
29
+ }
30
+ catch (err) {
31
+ const safeError = err instanceof Error ? err : new Error('Failed to fetch subscriptions');
32
+ setError(safeError);
33
+ }
34
+ finally {
35
+ setIsLoading(false);
36
+ }
37
+ }, [apiService, isEnabled]);
38
+ useEffect(() => {
39
+ void fetchSubscriptions();
40
+ }, [fetchSubscriptions]);
41
+ const resumeSubscription = useCallback(async (subscriptionId) => {
42
+ try {
43
+ await apiService.fetch(`/api/v1/subscriptions/resume`, {
44
+ method: 'POST',
45
+ body: { subscriptionId },
46
+ });
47
+ await fetchSubscriptions();
48
+ return { success: true };
49
+ }
50
+ catch (err) {
51
+ const errorMessage = err instanceof Error ? err.message : 'Failed to resume subscription';
52
+ return { success: false, error: errorMessage };
53
+ }
54
+ }, [apiService, fetchSubscriptions]);
55
+ const cancelSubscription = useCallback(async (subscriptionId) => {
56
+ try {
57
+ await apiService.fetch(`/api/v1/subscriptions/cancel`, {
58
+ method: 'POST',
59
+ body: { subscriptionId },
60
+ });
61
+ await fetchSubscriptions();
62
+ return { success: true };
63
+ }
64
+ catch (err) {
65
+ const errorMessage = err instanceof Error ? err.message : 'Failed to cancel subscription';
66
+ return { success: false, error: errorMessage };
67
+ }
68
+ }, [apiService, fetchSubscriptions]);
69
+ return {
70
+ data,
71
+ isLoading,
72
+ error,
73
+ refetch: fetchSubscriptions,
74
+ resumeSubscription,
75
+ cancelSubscription,
76
+ };
77
+ }
@@ -30,9 +30,17 @@ type ExpressShippingMethod = {
30
30
  identifier: string;
31
31
  detail: string;
32
32
  };
33
- export interface ExpressPaymentContextType {
33
+ export interface ExpressPaymentMethodsContextType {
34
+ paymentMethods: PaymentMethod[] | undefined;
34
35
  applePayPaymentMethod?: PaymentMethod;
35
36
  googlePayPaymentMethod?: PaymentMethod;
37
+ paypalPaymentMethod?: PaymentMethod;
38
+ klarnaPaymentMethod?: PaymentMethod;
39
+ availableExpressPaymentMethodIds: string[];
40
+ setAvailableExpressPaymentMethodIds: (value: string[]) => void;
41
+ handleAddExpressId: (id: string) => void;
42
+ shippingMethods: ExpressShippingMethod[];
43
+ lineItems: ExpressOrderLineItem[];
36
44
  reComputeOrderSummary: () => Promise<{
37
45
  lineItems: ExpressOrderLineItem[];
38
46
  total: {
@@ -41,12 +49,6 @@ export interface ExpressPaymentContextType {
41
49
  };
42
50
  shippingMethods: ExpressShippingMethod[];
43
51
  } | undefined>;
44
- loading?: boolean;
45
- availableExpressPaymentMethodIds: string[];
46
- setAvailableExpressPaymentMethodIds: (value: string[]) => void;
47
- shippingMethods: ExpressShippingMethod[];
48
- lineItems: ExpressOrderLineItem[];
49
- handleAddExpressId: (id: string) => void;
50
52
  updateCheckoutSessionValues: (input: {
51
53
  data: {
52
54
  shippingAddress: Address;
@@ -58,14 +60,15 @@ export interface ExpressPaymentContextType {
58
60
  email: string;
59
61
  };
60
62
  }) => Promise<void>;
63
+ loading?: boolean;
61
64
  error: string | null;
62
65
  setError: (error: string | null) => void;
63
66
  }
64
- interface ExpressPaymentProviderProps {
67
+ interface ExpressPaymentMethodsProviderProps {
65
68
  children: ReactNode;
66
69
  customerId?: string;
67
70
  checkout?: CheckoutData;
68
71
  }
69
- export declare const ExpressPaymentProvider: React.FC<ExpressPaymentProviderProps>;
70
- export declare const useExpressPayment: () => ExpressPaymentContextType;
72
+ export declare const ExpressPaymentMethodsProvider: React.FC<ExpressPaymentMethodsProviderProps>;
73
+ export declare const useExpressPaymentMethods: () => ExpressPaymentMethodsContextType;
71
74
  export {};
@@ -3,8 +3,8 @@ import React, { createContext, useCallback, useContext, useMemo, useState } from
3
3
  import { useTagadaContext } from '../providers/TagadaProvider';
4
4
  import { useOrderSummary } from './useOrderSummary';
5
5
  import { useShippingRates } from './useShippingRates';
6
- const ExpressPaymentContext = createContext(undefined);
7
- export const ExpressPaymentProvider = ({ children, customerId, checkout, }) => {
6
+ const ExpressPaymentMethodsContext = createContext(undefined);
7
+ export const ExpressPaymentMethodsProvider = ({ children, customerId, checkout, }) => {
8
8
  const { apiService } = useTagadaContext();
9
9
  const [availableExpressPaymentMethodIds, setAvailableExpressPaymentMethodIds] = useState([]);
10
10
  const [error, setError] = useState(null);
@@ -37,7 +37,7 @@ export const ExpressPaymentProvider = ({ children, customerId, checkout, }) => {
37
37
  return () => {
38
38
  mounted = false;
39
39
  };
40
- }, [apiService, checkoutSessionId]);
40
+ }, [apiService, checkoutSessionId, checkout]);
41
41
  const handleAddExpressId = (id) => {
42
42
  setAvailableExpressPaymentMethodIds((prev) => (prev.includes(id) ? prev : [...prev, id]));
43
43
  };
@@ -128,14 +128,20 @@ export const ExpressPaymentProvider = ({ children, customerId, checkout, }) => {
128
128
  body: input,
129
129
  });
130
130
  }, [apiService, customerId]);
131
+ // Identify specific payment method types
131
132
  const enabledApplePayPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'apple_pay'), [paymentMethods]);
132
133
  const enabledGooglePayPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'google_pay'), [paymentMethods]);
134
+ const enabledPaypalPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'paypal'), [paymentMethods]);
135
+ const enabledKlarnaPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'klarna'), [paymentMethods]);
133
136
  const loading = !paymentMethods || isLoadingPaymentMethods || isLoadingOrderSummary;
134
137
  const contextValue = {
138
+ paymentMethods: paymentMethods || undefined,
135
139
  availableExpressPaymentMethodIds,
136
140
  setAvailableExpressPaymentMethodIds,
137
141
  applePayPaymentMethod: enabledApplePayPaymentMethod,
138
142
  googlePayPaymentMethod: enabledGooglePayPaymentMethod,
143
+ paypalPaymentMethod: enabledPaypalPaymentMethod,
144
+ klarnaPaymentMethod: enabledKlarnaPaymentMethod,
139
145
  shippingMethods,
140
146
  lineItems,
141
147
  reComputeOrderSummary,
@@ -146,13 +152,16 @@ export const ExpressPaymentProvider = ({ children, customerId, checkout, }) => {
146
152
  error,
147
153
  setError,
148
154
  };
149
- const hasAnyEnabled = Boolean(enabledApplePayPaymentMethod || enabledGooglePayPaymentMethod);
150
- return (_jsx(ExpressPaymentContext.Provider, { value: contextValue, children: hasAnyEnabled ? _jsx(_Fragment, { children: children }) : _jsx(_Fragment, {}) }));
155
+ const hasAnyEnabled = Boolean(enabledApplePayPaymentMethod ||
156
+ enabledGooglePayPaymentMethod ||
157
+ enabledPaypalPaymentMethod ||
158
+ enabledKlarnaPaymentMethod);
159
+ return (_jsx(ExpressPaymentMethodsContext.Provider, { value: contextValue, children: hasAnyEnabled ? _jsx(_Fragment, { children: children }) : _jsx(_Fragment, {}) }));
151
160
  };
152
- export const useExpressPayment = () => {
153
- const context = useContext(ExpressPaymentContext);
161
+ export const useExpressPaymentMethods = () => {
162
+ const context = useContext(ExpressPaymentMethodsContext);
154
163
  if (context === undefined) {
155
- throw new Error('useExpressPayment must be used within an ExpressPaymentProvider');
164
+ throw new Error('useExpressPaymentMethods must be used within an ExpressPaymentMethodsProvider');
156
165
  }
157
166
  return context;
158
167
  };
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useState } from 'react';
2
2
  import { useTagadaContext } from '../providers/TagadaProvider';
3
- import { usePluginConfig } from './usePluginConfig';
4
3
  import { setClientToken } from '../utils/tokenStorage';
4
+ import { usePluginConfig } from './usePluginConfig';
5
5
  export function useLogin() {
6
6
  const [isLoading, setIsLoading] = useState(false);
7
7
  const [error, setError] = useState(null);
@@ -4,9 +4,14 @@
4
4
  export { TagadaProvider } from './providers/TagadaProvider';
5
5
  export { useAuth } from './hooks/useAuth';
6
6
  export { useCheckout } from './hooks/useCheckout';
7
+ export { useCheckoutSession } from './hooks/useCheckoutSession';
8
+ export { useCheckoutToken } from './hooks/useCheckoutToken';
7
9
  export { useClubOffers } from './hooks/useClubOffers';
8
10
  export { useCurrency } from './hooks/useCurrency';
9
11
  export { useCustomer } from './hooks/useCustomer';
12
+ export { useCustomerInfos } from './hooks/useCustomerInfos';
13
+ export { useCustomerOrders } from './hooks/useCustomerOrders';
14
+ export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
10
15
  export { useDiscounts } from './hooks/useDiscounts';
11
16
  export { useEnvironment } from './hooks/useEnvironment';
12
17
  export { useGeoLocation } from './hooks/useGeoLocation';
@@ -17,8 +22,6 @@ export { useOffers } from './hooks/useOffers';
17
22
  export { useOrderBump } from './hooks/useOrderBump';
18
23
  export { useOrderBumpV2 } from './hooks/useOrderBumpV2';
19
24
  export { useOrderBumpV3 } from './hooks/useOrderBumpV3';
20
- export { useCheckoutToken } from './hooks/useCheckoutToken';
21
- export { useCheckoutSession } from './hooks/useCheckoutSession';
22
25
  export { usePostPurchases } from './hooks/usePostPurchases';
23
26
  export { useProducts } from './hooks/useProducts';
24
27
  export { useSession } from './hooks/useSession';
@@ -29,7 +32,7 @@ export { useVipOffers } from './hooks/useVipOffers';
29
32
  export { useTagadaContext } from './providers/TagadaProvider';
30
33
  export { clearPluginConfigCache, debugPluginConfig, getPluginConfig, useBasePath, usePluginConfig } from './hooks/usePluginConfig';
31
34
  export type { PluginConfig } from './hooks/usePluginConfig';
32
- export { getAvailableLanguages, useCountryOptions, useISOData, useRegionOptions, useLanguageImport } from './hooks/useISOData';
35
+ export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
33
36
  export type { ISOCountry, ISORegion, UseISODataResult } from './hooks/useISOData';
34
37
  export type { GeoLocationData, UseGeoLocationOptions, UseGeoLocationReturn } from './hooks/useGeoLocation';
35
38
  export type { ExtractedAddress, GoogleAddressComponent, GooglePlaceDetails, GooglePrediction, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
@@ -40,15 +43,16 @@ export { usePaymentPolling } from './hooks/usePaymentPolling';
40
43
  export { useThreeds } from './hooks/useThreeds';
41
44
  export { useThreedsModal } from './hooks/useThreedsModal';
42
45
  export { useApplePay } from './hooks/useApplePay';
43
- export { ExpressPaymentProvider, useExpressPayment } from './hooks/useExpressPayment';
44
- export type { AuthState, Currency, Customer, Environment, EnvironmentConfig, Locale, Order, OrderAddress, OrderItem, OrderSummary, PickupPoint, Session, Store } from './types';
46
+ export { ExpressPaymentMethodsProvider, useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
47
+ export type { ExpressPaymentMethodsContextType } from './hooks/useExpressPaymentMethods';
48
+ export type { AuthState, Currency, Customer, CustomerInfos, Environment, EnvironmentConfig, Locale, Order, OrderAddress, OrderItem, OrderSummary, PickupPoint, Session, Store } from './types';
45
49
  export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion, UseCheckoutOptions, UseCheckoutResult } from './hooks/useCheckout';
46
50
  export type { Discount, DiscountCodeValidation, UseDiscountsOptions, UseDiscountsResult } from './hooks/useDiscounts';
51
+ export type { UseCheckoutSessionOptions, UseCheckoutSessionResult } from './hooks/useCheckoutSession';
52
+ export type { UseCheckoutTokenOptions, UseCheckoutTokenResult } from './hooks/useCheckoutToken';
47
53
  export type { OrderBumpPreview, UseOrderBumpOptions, UseOrderBumpResult } from './hooks/useOrderBump';
48
54
  export type { UseOrderBumpV2Options, UseOrderBumpV2Result } from './hooks/useOrderBumpV2';
49
55
  export type { UseOrderBumpV3Options, UseOrderBumpV3Result } from './hooks/useOrderBumpV3';
50
- export type { UseCheckoutTokenOptions, UseCheckoutTokenResult } from './hooks/useCheckoutToken';
51
- export type { UseCheckoutSessionOptions, UseCheckoutSessionResult } from './hooks/useCheckoutSession';
52
56
  export type { UseVipOffersOptions, UseVipOffersResult, VipOffer, VipPreviewResponse } from './hooks/useVipOffers';
53
57
  export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferLineItem, PostPurchaseOfferSummary, UsePostPurchasesOptions, UsePostPurchasesResult } from './hooks/usePostPurchases';
54
58
  export type { Payment, PaymentPollingHook, PollingOptions } from './hooks/usePaymentPolling';
@@ -7,9 +7,14 @@ export { TagadaProvider } from './providers/TagadaProvider';
7
7
  // Hook exports
8
8
  export { useAuth } from './hooks/useAuth';
9
9
  export { useCheckout } from './hooks/useCheckout';
10
+ export { useCheckoutSession } from './hooks/useCheckoutSession';
11
+ export { useCheckoutToken } from './hooks/useCheckoutToken';
10
12
  export { useClubOffers } from './hooks/useClubOffers';
11
13
  export { useCurrency } from './hooks/useCurrency';
12
14
  export { useCustomer } from './hooks/useCustomer';
15
+ export { useCustomerInfos } from './hooks/useCustomerInfos';
16
+ export { useCustomerOrders } from './hooks/useCustomerOrders';
17
+ export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
13
18
  export { useDiscounts } from './hooks/useDiscounts';
14
19
  export { useEnvironment } from './hooks/useEnvironment';
15
20
  export { useGeoLocation } from './hooks/useGeoLocation';
@@ -20,8 +25,6 @@ export { useOffers } from './hooks/useOffers';
20
25
  export { useOrderBump } from './hooks/useOrderBump';
21
26
  export { useOrderBumpV2 } from './hooks/useOrderBumpV2';
22
27
  export { useOrderBumpV3 } from './hooks/useOrderBumpV3';
23
- export { useCheckoutToken } from './hooks/useCheckoutToken';
24
- export { useCheckoutSession } from './hooks/useCheckoutSession';
25
28
  export { usePostPurchases } from './hooks/usePostPurchases';
26
29
  export { useProducts } from './hooks/useProducts';
27
30
  export { useSession } from './hooks/useSession';
@@ -32,7 +35,7 @@ export { useTagadaContext } from './providers/TagadaProvider';
32
35
  // Plugin configuration hooks
33
36
  export { clearPluginConfigCache, debugPluginConfig, getPluginConfig, useBasePath, usePluginConfig } from './hooks/usePluginConfig';
34
37
  // ISO Data hooks
35
- export { getAvailableLanguages, useCountryOptions, useISOData, useRegionOptions, useLanguageImport } from './hooks/useISOData';
38
+ export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
36
39
  // Order hook exports
37
40
  export { useOrder } from './hooks/useOrder';
38
41
  // Payment hooks exports
@@ -43,7 +46,8 @@ export { useThreedsModal } from './hooks/useThreedsModal';
43
46
  // Apple Pay hooks exports
44
47
  export { useApplePay } from './hooks/useApplePay';
45
48
  // Express Payment context exports
46
- export { ExpressPaymentProvider, useExpressPayment } from './hooks/useExpressPayment';
49
+ // Express Payment Methods (extended functionality)
50
+ export { ExpressPaymentMethodsProvider, useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
47
51
  // Component exports
48
52
  export { ApplePayButton, Button } from './components';
49
53
  // Utility exports
@@ -38,11 +38,11 @@ const InitializationLoader = () => (_jsxs("div", { style: {
38
38
  borderTop: '1.5px solid #9ca3af',
39
39
  borderRadius: '50%',
40
40
  animation: 'tagada-spin 1s linear infinite',
41
- } }), _jsx("span", { children: "Loading..." }), _jsx("style", { children: `
42
- @keyframes tagada-spin {
43
- 0% { transform: rotate(0deg); }
44
- 100% { transform: rotate(360deg); }
45
- }
41
+ } }), _jsx("span", { children: "Loading..." }), _jsx("style", { children: `
42
+ @keyframes tagada-spin {
43
+ 0% { transform: rotate(0deg); }
44
+ 100% { transform: rotate(360deg); }
45
+ }
46
46
  ` })] }));
47
47
  const TagadaContext = createContext(null);
48
48
  export function TagadaProvider({ children, environment, customApiConfig, debugMode, // Remove default, will be set based on environment
@@ -362,6 +362,58 @@ rawPluginConfig, }) {
362
362
  setIsLoading(false);
363
363
  }
364
364
  }, [apiService, hasAttemptedAnonymousToken, initializeSession, finalDebugMode]);
365
+ // Initialize token from storage or create anonymous token (extracted to stable callback)
366
+ const initializeToken = useCallback(async () => {
367
+ try {
368
+ console.debug('[SDK] Initializing token...');
369
+ setIsLoading(true);
370
+ // Check for existing token
371
+ const existingToken = getClientToken();
372
+ let tokenToUse = null;
373
+ // Check URL params for token
374
+ const urlParams = new URLSearchParams(window.location.search);
375
+ const queryToken = urlParams.get('token');
376
+ if (queryToken) {
377
+ console.debug('[SDK] Found token in URL params');
378
+ tokenToUse = queryToken;
379
+ setClientToken(queryToken);
380
+ }
381
+ else if (existingToken && !isTokenExpired(existingToken)) {
382
+ console.debug('[SDK] Using existing token from storage');
383
+ tokenToUse = existingToken;
384
+ }
385
+ else {
386
+ console.debug('[SDK] No valid token found');
387
+ // Determine storeId for anonymous token
388
+ const targetStoreId = storeId || 'default-store';
389
+ await createAnonymousToken(targetStoreId);
390
+ return;
391
+ }
392
+ if (tokenToUse) {
393
+ setToken(tokenToUse);
394
+ // Update the API service with the token
395
+ apiService.updateToken(tokenToUse);
396
+ // Decode token to get session data
397
+ const decodedSession = decodeJWTClient(tokenToUse);
398
+ if (decodedSession) {
399
+ setSession(decodedSession);
400
+ // Initialize session with API call
401
+ await initializeSession(decodedSession);
402
+ }
403
+ else {
404
+ console.error('[SDK] Failed to decode token');
405
+ setIsInitialized(true);
406
+ setIsSessionInitialized(false); // Session failed to initialize
407
+ setIsLoading(false);
408
+ }
409
+ }
410
+ }
411
+ catch (error) {
412
+ console.error('[SDK] Error initializing token:', error);
413
+ setIsInitialized(true);
414
+ setIsLoading(false);
415
+ }
416
+ }, [apiService, storeId, createAnonymousToken, initializeSession]);
365
417
  // Initialize token from storage or create anonymous token
366
418
  // This runs in the background after phases 1 & 2 complete, but doesn't block rendering
367
419
  useEffect(() => {
@@ -373,59 +425,19 @@ rawPluginConfig, }) {
373
425
  return;
374
426
  }
375
427
  isInitializing.current = true;
376
- const initializeToken = async () => {
377
- try {
378
- console.debug('[SDK] Initializing token...');
379
- setIsLoading(true);
380
- // Check for existing token
381
- const existingToken = getClientToken();
382
- let tokenToUse = null;
383
- // Check URL params for token
384
- const urlParams = new URLSearchParams(window.location.search);
385
- const queryToken = urlParams.get('token');
386
- if (queryToken) {
387
- console.debug('[SDK] Found token in URL params');
388
- tokenToUse = queryToken;
389
- setClientToken(queryToken);
390
- }
391
- else if (existingToken && !isTokenExpired(existingToken)) {
392
- console.debug('[SDK] Using existing token from storage');
393
- tokenToUse = existingToken;
394
- }
395
- else {
396
- console.debug('[SDK] No valid token found');
397
- // Determine storeId for anonymous token
398
- const targetStoreId = storeId || 'default-store';
399
- await createAnonymousToken(targetStoreId);
400
- return;
401
- }
402
- if (tokenToUse) {
403
- setToken(tokenToUse);
404
- // Update the API service with the token
405
- apiService.updateToken(tokenToUse);
406
- // Decode token to get session data
407
- const decodedSession = decodeJWTClient(tokenToUse);
408
- if (decodedSession) {
409
- setSession(decodedSession);
410
- // Initialize session with API call
411
- await initializeSession(decodedSession);
412
- }
413
- else {
414
- console.error('[SDK] Failed to decode token');
415
- setIsInitialized(true);
416
- setIsSessionInitialized(false); // Session failed to initialize
417
- setIsLoading(false);
418
- }
419
- }
420
- }
421
- catch (error) {
422
- console.error('[SDK] Error initializing token:', error);
423
- setIsInitialized(true);
424
- setIsLoading(false);
425
- }
426
- };
427
428
  void initializeToken();
428
- }, [storeId, createAnonymousToken, initializeSession, configLoading]);
429
+ }, [storeId, configLoading, initializeToken]);
430
+ useEffect(() => {
431
+ function onStorage() {
432
+ // Re-run initialization when token may have changed in another tab
433
+ isInitializing.current = false;
434
+ void initializeToken();
435
+ }
436
+ window.addEventListener('storage', onStorage);
437
+ return () => {
438
+ window.removeEventListener('storage', onStorage);
439
+ };
440
+ }, [initializeToken]);
429
441
  // Update auth state when customer/session changes
430
442
  useEffect(() => {
431
443
  setAuth({