@tagadapay/plugin-sdk 2.6.18 → 2.7.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.
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Customer Resource Client
3
+ * Handles customer-related API operations
4
+ */
5
+ import { ApiClient } from './apiClient';
6
+ export interface CustomerAddress {
7
+ firstName: string | null;
8
+ lastName: string | null;
9
+ address1: string | null;
10
+ address2: string | null;
11
+ city: string | null;
12
+ province: string | null;
13
+ country: string | null;
14
+ zip: string | null;
15
+ phone: string | null;
16
+ email?: string | null;
17
+ }
18
+ export interface CustomerOrderSummary {
19
+ id: string;
20
+ totalPrice: number;
21
+ currency: string;
22
+ createdAt: string;
23
+ status: string;
24
+ }
25
+ export interface CustomerInfos {
26
+ customer: {
27
+ id: string;
28
+ email: string | null;
29
+ firstName: string | null;
30
+ lastName: string | null;
31
+ externalCustomerId: string | null;
32
+ lastOrderId: string | null;
33
+ accountId: string;
34
+ storeId: string;
35
+ billingAddress: CustomerAddress | null;
36
+ shippingAddress: Omit<CustomerAddress, 'email'> | null;
37
+ currency: string | null;
38
+ locale: string | null;
39
+ draft: boolean;
40
+ acceptsMarketing: boolean;
41
+ createdAt: string;
42
+ updatedAt: string;
43
+ metadata: Record<string, any>;
44
+ device: any | null;
45
+ orders: CustomerOrderSummary[];
46
+ subscriptions: any[];
47
+ };
48
+ promotionCodes: any[];
49
+ }
50
+ export interface OrderWithRelations {
51
+ id: string;
52
+ currency: string;
53
+ paidAmount: number;
54
+ status: string;
55
+ createdAt: string;
56
+ metadata?: Record<string, any>;
57
+ items: any[];
58
+ summaries?: any[];
59
+ shippingAddress?: any;
60
+ billingAddress?: any;
61
+ pickupAddress?: any;
62
+ checkoutSession?: {
63
+ returnUrl?: string;
64
+ [key: string]: any;
65
+ };
66
+ relatedOrders?: any[];
67
+ customer?: any;
68
+ store?: any;
69
+ account?: {
70
+ id: string;
71
+ name?: string;
72
+ };
73
+ payments?: any[];
74
+ promotions?: any[];
75
+ subscriptions?: any[];
76
+ adjustments: any[];
77
+ }
78
+ export interface Subscription {
79
+ id: string;
80
+ status: string;
81
+ createdAt: string;
82
+ currency: string;
83
+ cancelAtPeriodEnd: boolean;
84
+ currentPeriodEnd: string | null;
85
+ currentPeriodStart: string | null;
86
+ quantity: number;
87
+ trialEnd: string | null;
88
+ customerId: string;
89
+ customerEmail: string;
90
+ customerName: string;
91
+ priceCurrencyOptions: Record<string, {
92
+ rate: number;
93
+ amount: number;
94
+ lock: boolean;
95
+ date: string;
96
+ }>;
97
+ priceInterval: string;
98
+ priceIntervalCount: number;
99
+ priceRecurring: boolean;
100
+ productId: string;
101
+ priceId: string;
102
+ productTitle: string;
103
+ }
104
+ export interface SubscriptionsResponse {
105
+ items: Subscription[];
106
+ pagination: {
107
+ page: number;
108
+ pageSize: number;
109
+ hasNext: boolean;
110
+ nextPage: number | null;
111
+ previousPage: number | null;
112
+ totalItems: number;
113
+ };
114
+ }
115
+ export declare class CustomerResource {
116
+ private apiClient;
117
+ constructor(apiClient: ApiClient);
118
+ /**
119
+ * Get customer information by ID
120
+ */
121
+ getCustomerInfos(customerId: string, storeId: string): Promise<CustomerInfos>;
122
+ /**
123
+ * Update customer information
124
+ */
125
+ updateCustomer(customerId: string, data: {
126
+ email?: string;
127
+ firstName?: string;
128
+ lastName?: string;
129
+ acceptsMarketing?: boolean;
130
+ metadata?: Record<string, any>;
131
+ }): Promise<CustomerInfos>;
132
+ /**
133
+ * Get customer orders
134
+ */
135
+ getCustomerOrders(customerId: string, storeId: string): Promise<{
136
+ orders: OrderWithRelations[];
137
+ }>;
138
+ /**
139
+ * Get customer subscriptions
140
+ */
141
+ getCustomerSubscriptions(): Promise<SubscriptionsResponse>;
142
+ /**
143
+ * Resume a subscription
144
+ */
145
+ resumeSubscription(subscriptionId: string): Promise<void>;
146
+ /**
147
+ * Cancel a subscription
148
+ */
149
+ cancelSubscription(subscriptionId: string): Promise<void>;
150
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Customer Resource Client
3
+ * Handles customer-related API operations
4
+ */
5
+ export class CustomerResource {
6
+ constructor(apiClient) {
7
+ this.apiClient = apiClient;
8
+ }
9
+ /**
10
+ * Get customer information by ID
11
+ */
12
+ async getCustomerInfos(customerId, storeId) {
13
+ return this.apiClient.get(`/api/v1/customers/${customerId}`, {
14
+ params: { storeId },
15
+ });
16
+ }
17
+ /**
18
+ * Update customer information
19
+ */
20
+ async updateCustomer(customerId, data) {
21
+ return this.apiClient.patch(`/api/v1/customers/${customerId}`, data);
22
+ }
23
+ /**
24
+ * Get customer orders
25
+ */
26
+ async getCustomerOrders(customerId, storeId) {
27
+ return this.apiClient.get(`/api/v1/orders/customer/${customerId}`, {
28
+ params: { storeId },
29
+ });
30
+ }
31
+ /**
32
+ * Get customer subscriptions
33
+ */
34
+ async getCustomerSubscriptions() {
35
+ return this.apiClient.get('/api/v1/subscriptions');
36
+ }
37
+ /**
38
+ * Resume a subscription
39
+ */
40
+ async resumeSubscription(subscriptionId) {
41
+ return this.apiClient.post('/api/v1/subscriptions/resume', {
42
+ subscriptionId,
43
+ });
44
+ }
45
+ /**
46
+ * Cancel a subscription
47
+ */
48
+ async cancelSubscription(subscriptionId) {
49
+ return this.apiClient.post('/api/v1/subscriptions/cancel', {
50
+ subscriptionId,
51
+ });
52
+ }
53
+ }
@@ -4,15 +4,17 @@
4
4
  */
5
5
  export * from './apiClient';
6
6
  export * from './checkout';
7
+ export * from './customer';
7
8
  export * from './discounts';
9
+ export * from './funnel';
8
10
  export * from './offers';
9
11
  export * from './orders';
10
12
  export * from './payments';
11
13
  export * from './postPurchases';
12
14
  export * from './products';
13
15
  export * from './promotions';
16
+ export * from './session';
14
17
  export * from './shippingRates';
15
18
  export * from './storeConfig';
16
19
  export * from './threeds';
17
20
  export * from './vipOffers';
18
- export * from './funnel';
@@ -4,15 +4,17 @@
4
4
  */
5
5
  export * from './apiClient';
6
6
  export * from './checkout';
7
+ export * from './customer';
7
8
  export * from './discounts';
9
+ export * from './funnel';
8
10
  export * from './offers';
9
11
  export * from './orders';
10
12
  export * from './payments';
11
13
  export * from './postPurchases';
12
14
  export * from './products';
13
15
  export * from './promotions';
16
+ export * from './session';
14
17
  export * from './shippingRates';
15
18
  export * from './storeConfig';
16
19
  export * from './threeds';
17
20
  export * from './vipOffers';
18
- export * from './funnel';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Session Resource Client
3
+ * Handles authentication and session management
4
+ */
5
+ import { ApiClient } from './apiClient';
6
+ export interface RequestCodeResponse {
7
+ success: boolean;
8
+ error?: string;
9
+ }
10
+ export interface VerifyCodeResponse {
11
+ success: boolean;
12
+ token?: string;
13
+ sessionId?: string;
14
+ error?: string;
15
+ }
16
+ export declare class SessionResource {
17
+ private apiClient;
18
+ constructor(apiClient: ApiClient);
19
+ /**
20
+ * Request verification code for email
21
+ */
22
+ requestCode(email: string, storeId: string): Promise<RequestCodeResponse>;
23
+ /**
24
+ * Verify code and login
25
+ */
26
+ verifyCode(email: string, code: string, storeId: string): Promise<VerifyCodeResponse>;
27
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Session Resource Client
3
+ * Handles authentication and session management
4
+ */
5
+ export class SessionResource {
6
+ constructor(apiClient) {
7
+ this.apiClient = apiClient;
8
+ }
9
+ /**
10
+ * Request verification code for email
11
+ */
12
+ async requestCode(email, storeId) {
13
+ try {
14
+ await this.apiClient.post('/api/v1/cms/session/request-code', {
15
+ email,
16
+ storeId,
17
+ });
18
+ return { success: true };
19
+ }
20
+ catch (error) {
21
+ return {
22
+ success: false,
23
+ error: error instanceof Error ? error.message : 'Failed to send code',
24
+ };
25
+ }
26
+ }
27
+ /**
28
+ * Verify code and login
29
+ */
30
+ async verifyCode(email, code, storeId) {
31
+ try {
32
+ const response = await this.apiClient.post('/api/v1/cms/session/login', {
33
+ email,
34
+ code,
35
+ storeId,
36
+ });
37
+ if (!response) {
38
+ return {
39
+ success: false,
40
+ error: 'Invalid code',
41
+ };
42
+ }
43
+ return {
44
+ success: true,
45
+ token: response.token,
46
+ sessionId: response.sessionId,
47
+ };
48
+ }
49
+ catch (error) {
50
+ return {
51
+ success: false,
52
+ error: error instanceof Error ? error.message : 'Failed to verify code',
53
+ };
54
+ }
55
+ }
56
+ }
@@ -20,5 +20,13 @@ export type { ShippingRate, ShippingRatesResponse } from './core/resources/shipp
20
20
  export type { ApplyDiscountResponse, Discount, DiscountCodeValidation, RemoveDiscountResponse } from './core/resources/discounts';
21
21
  export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './core/resources/vipOffers';
22
22
  export type { StoreConfig } from './core/resources/storeConfig';
23
- export type { FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelContextUpdateRequest, FunnelContextUpdateResponse } from './core/resources/funnel';
24
- export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useVipOffers, useFunnel, useSimpleFunnel } from './react';
23
+ export type { FunnelContextUpdateRequest, FunnelContextUpdateResponse, FunnelEvent, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from './core/resources/funnel';
24
+ export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
25
+ export type { TranslateFunction, UseTranslationOptions, UseTranslationResult } from './react/hooks/useTranslation';
26
+ export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './react/hooks/useClubOffers';
27
+ export type { UseLoginOptions, UseLoginResult } from './react/hooks/useLogin';
28
+ export type { CustomerAddress, CustomerInfos, CustomerOrderSummary, OrderWithRelations, Subscription, SubscriptionsResponse } from './core/resources/customer';
29
+ export type { UseCustomerResult } from './react/hooks/useCustomer';
30
+ export type { UseCustomerInfosOptions, UseCustomerInfosResult } from './react/hooks/useCustomerInfos';
31
+ export type { UseCustomerOrdersOptions, UseCustomerOrdersResult } from './react/hooks/useCustomerOrders';
32
+ export type { UseCustomerSubscriptionsOptions, UseCustomerSubscriptionsResult } from './react/hooks/useCustomerSubscriptions';
package/dist/v2/index.js CHANGED
@@ -12,4 +12,4 @@ export * from './core/utils/currency';
12
12
  export * from './core/utils/pluginConfig';
13
13
  export * from './core/utils/products';
14
14
  // React exports (hooks and components only, types are exported above)
15
- export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useVipOffers, useFunnel, useSimpleFunnel } from './react';
15
+ export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * useAuth - Hook to access authentication state (v2)
3
+ * Uses TagadaContext for auth state management
4
+ */
5
+ import { AuthState } from '../../../react/types';
6
+ export declare function useAuth(): AuthState & {
7
+ isInitialized: boolean;
8
+ };
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { useTagadaContext } from '../providers/TagadaProvider';
3
+ export function useAuth() {
4
+ const { auth, isInitialized } = useTagadaContext();
5
+ return {
6
+ ...auth,
7
+ isInitialized,
8
+ };
9
+ }
@@ -0,0 +1,101 @@
1
+ export interface ClubOfferItem {
2
+ id: string;
3
+ productId: string;
4
+ variantId: string;
5
+ product: {
6
+ name: string;
7
+ description: string;
8
+ };
9
+ variant: {
10
+ name: string;
11
+ description: string;
12
+ imageUrl: string;
13
+ grams: number;
14
+ };
15
+ unitAmount: number;
16
+ quantity: number;
17
+ amount: number;
18
+ adjustedAmount: number;
19
+ }
20
+ export interface ClubOfferSummary {
21
+ currency: string;
22
+ totalAmount: number;
23
+ totalAdjustedAmount: number;
24
+ items: ClubOfferItem[];
25
+ }
26
+ export interface ClubOfferLineItem {
27
+ id: string;
28
+ quantity: number;
29
+ price: {
30
+ variant: {
31
+ id: string;
32
+ name: string;
33
+ description: string | null;
34
+ imageUrl: string;
35
+ grams: number;
36
+ product: {
37
+ id: string;
38
+ name: string;
39
+ description: string;
40
+ };
41
+ };
42
+ };
43
+ }
44
+ export interface ClubOffer {
45
+ id: string;
46
+ titleTrans: {
47
+ en: string;
48
+ };
49
+ summaries: ClubOfferSummary[];
50
+ offerLineItems: ClubOfferLineItem[];
51
+ }
52
+ export interface UseClubOffersOptions {
53
+ /**
54
+ * Whether to fetch club offers automatically on mount
55
+ * @default true
56
+ */
57
+ enabled?: boolean;
58
+ /**
59
+ * Return URL for payment
60
+ */
61
+ returnUrl?: string;
62
+ }
63
+ export interface UseClubOffersResult {
64
+ /**
65
+ * Array of fetched club offers
66
+ */
67
+ offers: ClubOffer[];
68
+ /**
69
+ * Loading state
70
+ */
71
+ isLoading: boolean;
72
+ /**
73
+ * Error state
74
+ */
75
+ error: Error | null;
76
+ /**
77
+ * Refetch club offers
78
+ */
79
+ refetch: () => Promise<void>;
80
+ /**
81
+ * Get club offer by ID from the loaded offers
82
+ */
83
+ getOffer: (offerId: string) => ClubOffer | undefined;
84
+ /**
85
+ * Get total value of all club offers
86
+ */
87
+ getTotalValue: () => number;
88
+ /**
89
+ * Get total savings across all club offers
90
+ */
91
+ getTotalSavings: () => number;
92
+ /**
93
+ * Clear error state
94
+ */
95
+ clearError: () => void;
96
+ /**
97
+ * Pay for a club offer
98
+ */
99
+ payOffer: (offerId: string, returnUrl?: string) => Promise<void>;
100
+ }
101
+ export declare function useClubOffers(options?: UseClubOffersOptions): UseClubOffersResult;
@@ -0,0 +1,126 @@
1
+ 'use client';
2
+ /**
3
+ * useClubOffers - Hook for club-specific offers (v2)
4
+ * Extends the offers functionality with club filtering
5
+ */
6
+ import { useMutation, useQuery } from '@tanstack/react-query';
7
+ import { useCallback, useMemo } from 'react';
8
+ import { OffersResource } from '../../core/resources/offers';
9
+ import { useTagadaContext } from '../providers/TagadaProvider';
10
+ import { getGlobalApiClient } from './useApiQuery';
11
+ import { usePluginConfig } from './usePluginConfig';
12
+ /**
13
+ * Transform generic Offer to ClubOffer format
14
+ */
15
+ function transformToClubOffer(offer) {
16
+ return {
17
+ id: offer.id,
18
+ titleTrans: offer.titleTrans,
19
+ summaries: offer.summaries.map((summary) => ({
20
+ currency: summary.currency,
21
+ totalAmount: summary.totalAmount,
22
+ totalAdjustedAmount: summary.totalAdjustedAmount,
23
+ items: summary.items.map((item) => ({
24
+ id: item.id,
25
+ productId: item.id, // Using item ID as productId fallback
26
+ variantId: item.id, // Using item ID as variantId fallback
27
+ product: item.product,
28
+ variant: {
29
+ name: item.variant.name,
30
+ description: '', // Not available in base Offer
31
+ imageUrl: item.variant.imageUrl,
32
+ grams: 0, // Not available in base Offer
33
+ },
34
+ unitAmount: item.unitAmount,
35
+ quantity: item.quantity,
36
+ amount: item.amount,
37
+ adjustedAmount: item.adjustedAmount,
38
+ })),
39
+ })),
40
+ offerLineItems: [], // Not available in base Offer
41
+ };
42
+ }
43
+ export function useClubOffers(options = {}) {
44
+ const { enabled = true, returnUrl } = options;
45
+ const { storeId } = usePluginConfig();
46
+ const { isSessionInitialized } = useTagadaContext();
47
+ // Create offers resource client
48
+ const offersResource = useMemo(() => {
49
+ try {
50
+ return new OffersResource(getGlobalApiClient());
51
+ }
52
+ catch (error) {
53
+ throw new Error('Failed to initialize offers resource: ' +
54
+ (error instanceof Error ? error.message : 'Unknown error'));
55
+ }
56
+ }, []);
57
+ // Create query key
58
+ const queryKey = useMemo(() => ['club-offers', { storeId }], [storeId]);
59
+ // Fetch club offers using TanStack Query
60
+ const { data: offers = [], isLoading, error, refetch, } = useQuery({
61
+ queryKey,
62
+ enabled: enabled && !!storeId && isSessionInitialized,
63
+ queryFn: async () => {
64
+ if (!storeId) {
65
+ throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
66
+ }
67
+ // Fetch all offers and filter for club type
68
+ // Note: The API endpoint should support a 'type' parameter
69
+ const response = await getGlobalApiClient().get(`/api/v1/stores/${storeId}/offers`, {
70
+ params: {
71
+ type: 'club',
72
+ },
73
+ });
74
+ // Transform to club offer format
75
+ return (response.offers || []).map(transformToClubOffer);
76
+ },
77
+ staleTime: 5 * 60 * 1000, // 5 minutes
78
+ refetchOnWindowFocus: false,
79
+ });
80
+ // Pay offer mutation
81
+ const payOfferMutation = useMutation({
82
+ mutationFn: async ({ offerId, returnUrl }) => {
83
+ const url = returnUrl || (typeof window !== 'undefined' ? window.location.href : '');
84
+ return await offersResource.payOffer(offerId);
85
+ },
86
+ onError: (error) => {
87
+ console.error('[SDK] Failed to pay offer:', error);
88
+ },
89
+ });
90
+ // Helper functions
91
+ const getOffer = useCallback((offerId) => {
92
+ return offers.find((offer) => offer.id === offerId);
93
+ }, [offers]);
94
+ const getTotalValue = useCallback(() => {
95
+ return offers.reduce((total, offer) => {
96
+ const firstSummary = offer.summaries[0];
97
+ return total + (firstSummary?.totalAdjustedAmount || 0);
98
+ }, 0);
99
+ }, [offers]);
100
+ const getTotalSavings = useCallback(() => {
101
+ return offers.reduce((total, offer) => {
102
+ const firstSummary = offer.summaries[0];
103
+ return total + (firstSummary?.totalAmount - firstSummary?.totalAdjustedAmount || 0);
104
+ }, 0);
105
+ }, [offers]);
106
+ const clearError = useCallback(() => {
107
+ // TanStack Query doesn't have a direct clearError method
108
+ // Error will be cleared on next successful fetch
109
+ }, []);
110
+ const payOffer = useCallback(async (offerId, returnUrl) => {
111
+ await payOfferMutation.mutateAsync({ offerId, returnUrl });
112
+ }, [payOfferMutation]);
113
+ return {
114
+ offers,
115
+ isLoading,
116
+ error,
117
+ refetch: async () => {
118
+ await refetch();
119
+ },
120
+ getOffer,
121
+ getTotalValue,
122
+ getTotalSavings,
123
+ clearError,
124
+ payOffer,
125
+ };
126
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * useCustomer - Hook to access current customer data (v2)
3
+ */
4
+ import { Customer } from '../../../react/types';
5
+ export interface UseCustomerResult {
6
+ customer: Customer | null;
7
+ isAuthenticated: boolean;
8
+ isLoading: boolean;
9
+ isAnonymous: boolean;
10
+ }
11
+ export declare function useCustomer(): UseCustomerResult;
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { useTagadaContext } from '../providers/TagadaProvider';
3
+ export function useCustomer() {
4
+ const { customer, isLoading } = useTagadaContext();
5
+ return {
6
+ customer,
7
+ isAuthenticated: customer?.isAuthenticated || false,
8
+ isLoading,
9
+ isAnonymous: customer?.role === 'anonymous',
10
+ };
11
+ }
@@ -0,0 +1,12 @@
1
+ import { CustomerInfos } from '../../core/resources/customer';
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
+ export declare function useCustomerInfos(options?: UseCustomerInfosOptions): UseCustomerInfosResult;
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+ /**
3
+ * useCustomerInfos - Hook to fetch customer information (v2)
4
+ * Fetches customer infos from `/api/v1/customers/{customerId}` with `storeId` param
5
+ */
6
+ import { useQuery } from '@tanstack/react-query';
7
+ import { useMemo } from 'react';
8
+ import { CustomerResource } from '../../core/resources/customer';
9
+ import { useTagadaContext } from '../providers/TagadaProvider';
10
+ import { getGlobalApiClient } from './useApiQuery';
11
+ import { usePluginConfig } from './usePluginConfig';
12
+ export function useCustomerInfos(options = {}) {
13
+ const { storeId } = usePluginConfig();
14
+ const { isSessionInitialized } = useTagadaContext();
15
+ const { customerId = null, enabled = true } = options;
16
+ // Create customer resource client
17
+ const customerResource = useMemo(() => {
18
+ try {
19
+ return new CustomerResource(getGlobalApiClient());
20
+ }
21
+ catch (error) {
22
+ throw new Error('Failed to initialize customer resource: ' +
23
+ (error instanceof Error ? error.message : 'Unknown error'));
24
+ }
25
+ }, []);
26
+ // Determine if query should be enabled
27
+ const isEnabled = useMemo(() => {
28
+ return Boolean(enabled && customerId && storeId && isSessionInitialized);
29
+ }, [enabled, customerId, storeId, isSessionInitialized]);
30
+ // Create query key
31
+ const queryKey = useMemo(() => ['customer-infos', { customerId, storeId }], [customerId, storeId]);
32
+ // Fetch customer infos using TanStack Query
33
+ const { data = null, isLoading, error, refetch, } = useQuery({
34
+ queryKey,
35
+ enabled: isEnabled,
36
+ queryFn: async () => {
37
+ if (!customerId || !storeId) {
38
+ return null;
39
+ }
40
+ return await customerResource.getCustomerInfos(customerId, storeId);
41
+ },
42
+ staleTime: 5 * 60 * 1000, // 5 minutes
43
+ refetchOnWindowFocus: false,
44
+ });
45
+ return {
46
+ data,
47
+ isLoading,
48
+ error,
49
+ refetch: async () => {
50
+ await refetch();
51
+ },
52
+ };
53
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * useCustomerOrders - Hook to fetch customer orders (v2)
3
+ */
4
+ import { OrderWithRelations } from '../../core/resources/customer';
5
+ export interface UseCustomerOrdersOptions {
6
+ customerId?: string | null;
7
+ enabled?: boolean;
8
+ }
9
+ export interface UseCustomerOrdersResult {
10
+ data: {
11
+ orders: OrderWithRelations[];
12
+ } | null;
13
+ isLoading: boolean;
14
+ error: Error | null;
15
+ refetch: () => Promise<void>;
16
+ }
17
+ export declare function useCustomerOrders(options?: UseCustomerOrdersOptions): UseCustomerOrdersResult;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * useCustomerOrders - Hook to fetch customer orders (v2)
3
+ */
4
+ import { useQuery } from '@tanstack/react-query';
5
+ import { useMemo } from 'react';
6
+ import { CustomerResource } from '../../core/resources/customer';
7
+ import { useTagadaContext } from '../providers/TagadaProvider';
8
+ import { getGlobalApiClient } from './useApiQuery';
9
+ import { usePluginConfig } from './usePluginConfig';
10
+ export function useCustomerOrders(options = {}) {
11
+ const { storeId } = usePluginConfig();
12
+ const { isSessionInitialized } = useTagadaContext();
13
+ const { customerId = null, enabled = true } = options;
14
+ // Create customer resource client
15
+ const customerResource = useMemo(() => {
16
+ try {
17
+ return new CustomerResource(getGlobalApiClient());
18
+ }
19
+ catch (error) {
20
+ throw new Error('Failed to initialize customer resource: ' +
21
+ (error instanceof Error ? error.message : 'Unknown error'));
22
+ }
23
+ }, []);
24
+ // Determine if query should be enabled
25
+ const isEnabled = useMemo(() => {
26
+ return Boolean(enabled && customerId && storeId && isSessionInitialized);
27
+ }, [enabled, customerId, storeId, isSessionInitialized]);
28
+ // Create query key
29
+ const queryKey = useMemo(() => ['customer-orders', { customerId, storeId }], [customerId, storeId]);
30
+ // Fetch customer orders using TanStack Query
31
+ const { data = null, isLoading, error, refetch, } = useQuery({
32
+ queryKey,
33
+ enabled: isEnabled,
34
+ queryFn: async () => {
35
+ if (!customerId || !storeId) {
36
+ return null;
37
+ }
38
+ return await customerResource.getCustomerOrders(customerId, storeId);
39
+ },
40
+ staleTime: 5 * 60 * 1000, // 5 minutes
41
+ refetchOnWindowFocus: false,
42
+ });
43
+ return {
44
+ data,
45
+ isLoading,
46
+ error,
47
+ refetch: async () => {
48
+ await refetch();
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * useCustomerSubscriptions - Hook to manage customer subscriptions (v2)
3
+ */
4
+ import { SubscriptionsResponse } from '../../core/resources/customer';
5
+ export interface UseCustomerSubscriptionsOptions {
6
+ customerId?: string | null;
7
+ enabled?: boolean;
8
+ }
9
+ export interface UseCustomerSubscriptionsResult {
10
+ data: SubscriptionsResponse | null;
11
+ isLoading: boolean;
12
+ error: Error | null;
13
+ refetch: () => Promise<void>;
14
+ resumeSubscription: (subscriptionId: string) => Promise<{
15
+ success: boolean;
16
+ error?: string;
17
+ }>;
18
+ cancelSubscription: (subscriptionId: string) => Promise<{
19
+ success: boolean;
20
+ error?: string;
21
+ }>;
22
+ }
23
+ export declare function useCustomerSubscriptions(options?: UseCustomerSubscriptionsOptions): UseCustomerSubscriptionsResult;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * useCustomerSubscriptions - Hook to manage customer subscriptions (v2)
3
+ */
4
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
5
+ import { useCallback, useMemo } from 'react';
6
+ import { CustomerResource } from '../../core/resources/customer';
7
+ import { useTagadaContext } from '../providers/TagadaProvider';
8
+ import { getGlobalApiClient } from './useApiQuery';
9
+ export function useCustomerSubscriptions(options = {}) {
10
+ const { isSessionInitialized } = useTagadaContext();
11
+ const queryClient = useQueryClient();
12
+ const { customerId = null, enabled = true } = options;
13
+ // Create customer resource client
14
+ const customerResource = useMemo(() => {
15
+ try {
16
+ return new CustomerResource(getGlobalApiClient());
17
+ }
18
+ catch (error) {
19
+ throw new Error('Failed to initialize customer resource: ' +
20
+ (error instanceof Error ? error.message : 'Unknown error'));
21
+ }
22
+ }, []);
23
+ // Determine if query should be enabled
24
+ const isEnabled = useMemo(() => {
25
+ return Boolean(enabled && customerId && isSessionInitialized);
26
+ }, [enabled, customerId, isSessionInitialized]);
27
+ // Create query key
28
+ const queryKey = useMemo(() => ['customer-subscriptions', { customerId }], [customerId]);
29
+ // Fetch customer subscriptions using TanStack Query
30
+ const { data = null, isLoading, error, refetch, } = useQuery({
31
+ queryKey,
32
+ enabled: isEnabled,
33
+ queryFn: async () => {
34
+ if (!customerId) {
35
+ return null;
36
+ }
37
+ return await customerResource.getCustomerSubscriptions();
38
+ },
39
+ staleTime: 5 * 60 * 1000, // 5 minutes
40
+ refetchOnWindowFocus: false,
41
+ });
42
+ // Resume subscription mutation
43
+ const resumeMutation = useMutation({
44
+ mutationFn: async (subscriptionId) => {
45
+ return await customerResource.resumeSubscription(subscriptionId);
46
+ },
47
+ onSuccess: () => {
48
+ // Invalidate and refetch subscriptions
49
+ void queryClient.invalidateQueries({ queryKey });
50
+ },
51
+ });
52
+ // Cancel subscription mutation
53
+ const cancelMutation = useMutation({
54
+ mutationFn: async (subscriptionId) => {
55
+ return await customerResource.cancelSubscription(subscriptionId);
56
+ },
57
+ onSuccess: () => {
58
+ // Invalidate and refetch subscriptions
59
+ void queryClient.invalidateQueries({ queryKey });
60
+ },
61
+ });
62
+ // Resume subscription
63
+ const resumeSubscription = useCallback(async (subscriptionId) => {
64
+ try {
65
+ await resumeMutation.mutateAsync(subscriptionId);
66
+ return { success: true };
67
+ }
68
+ catch (err) {
69
+ const errorMessage = err instanceof Error ? err.message : 'Failed to resume subscription';
70
+ return { success: false, error: errorMessage };
71
+ }
72
+ }, [resumeMutation]);
73
+ // Cancel subscription
74
+ const cancelSubscription = useCallback(async (subscriptionId) => {
75
+ try {
76
+ await cancelMutation.mutateAsync(subscriptionId);
77
+ return { success: true };
78
+ }
79
+ catch (err) {
80
+ const errorMessage = err instanceof Error ? err.message : 'Failed to cancel subscription';
81
+ return { success: false, error: errorMessage };
82
+ }
83
+ }, [cancelMutation]);
84
+ return {
85
+ data,
86
+ isLoading,
87
+ error,
88
+ refetch: async () => {
89
+ await refetch();
90
+ },
91
+ resumeSubscription,
92
+ cancelSubscription,
93
+ };
94
+ }
@@ -0,0 +1,53 @@
1
+ export interface UseLoginOptions {
2
+ /**
3
+ * Callback when login is successful
4
+ */
5
+ onSuccess?: (token: string) => void;
6
+ /**
7
+ * Callback when an error occurs
8
+ */
9
+ onError?: (error: Error) => void;
10
+ }
11
+ export interface UseLoginResult {
12
+ /**
13
+ * Request verification code for email
14
+ */
15
+ requestCode: (email: string) => Promise<{
16
+ success: boolean;
17
+ error?: string;
18
+ }>;
19
+ /**
20
+ * Verify code and complete login
21
+ */
22
+ verifyCode: (email: string, code: string) => Promise<{
23
+ success: boolean;
24
+ token?: string;
25
+ sessionId?: string;
26
+ error?: string;
27
+ }>;
28
+ /**
29
+ * Combined loading state (true if either request or verify is loading)
30
+ */
31
+ isLoading: boolean;
32
+ /**
33
+ * Loading state for request code
34
+ */
35
+ isRequestingCode: boolean;
36
+ /**
37
+ * Loading state for verify code
38
+ */
39
+ isVerifyingCode: boolean;
40
+ /**
41
+ * Combined error state
42
+ */
43
+ error: Error | null;
44
+ /**
45
+ * Error from request code
46
+ */
47
+ requestCodeError: Error | null;
48
+ /**
49
+ * Error from verify code
50
+ */
51
+ verifyCodeError: Error | null;
52
+ }
53
+ export declare function useLogin(options?: UseLoginOptions): UseLoginResult;
@@ -0,0 +1,75 @@
1
+ 'use client';
2
+ /**
3
+ * useLogin - Hook for authentication (v2)
4
+ * Handles email/code authentication flow
5
+ */
6
+ import { useMutation } from '@tanstack/react-query';
7
+ import { useCallback, useMemo } from 'react';
8
+ import { setClientToken } from '../../../react/utils/tokenStorage';
9
+ import { SessionResource } from '../../core/resources/session';
10
+ import { getGlobalApiClient } from './useApiQuery';
11
+ import { usePluginConfig } from './usePluginConfig';
12
+ export function useLogin(options = {}) {
13
+ const { onSuccess, onError } = options;
14
+ const { storeId } = usePluginConfig();
15
+ // Create session resource client
16
+ const sessionResource = useMemo(() => {
17
+ try {
18
+ return new SessionResource(getGlobalApiClient());
19
+ }
20
+ catch (error) {
21
+ throw new Error('Failed to initialize session resource: ' +
22
+ (error instanceof Error ? error.message : 'Unknown error'));
23
+ }
24
+ }, []);
25
+ // Request code mutation
26
+ const requestCodeMutation = useMutation({
27
+ mutationFn: async (email) => {
28
+ if (!storeId) {
29
+ throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
30
+ }
31
+ return await sessionResource.requestCode(email, storeId);
32
+ },
33
+ onError: (error) => {
34
+ console.error('[SDK] Failed to request code:', error);
35
+ onError?.(error);
36
+ },
37
+ });
38
+ // Verify code mutation
39
+ const verifyCodeMutation = useMutation({
40
+ mutationFn: async ({ email, code }) => {
41
+ if (!storeId) {
42
+ throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
43
+ }
44
+ const result = await sessionResource.verifyCode(email, code, storeId);
45
+ if (result.success && result.token) {
46
+ // Store the token
47
+ setClientToken(result.token);
48
+ // Call success callback
49
+ onSuccess?.(result.token);
50
+ }
51
+ return result;
52
+ },
53
+ onError: (error) => {
54
+ console.error('[SDK] Failed to verify code:', error);
55
+ onError?.(error);
56
+ },
57
+ });
58
+ // Action functions
59
+ const requestCode = useCallback(async (email) => {
60
+ return await requestCodeMutation.mutateAsync(email);
61
+ }, [requestCodeMutation]);
62
+ const verifyCode = useCallback(async (email, code) => {
63
+ return await verifyCodeMutation.mutateAsync({ email, code });
64
+ }, [verifyCodeMutation]);
65
+ return {
66
+ requestCode,
67
+ verifyCode,
68
+ isLoading: requestCodeMutation.isPending || verifyCodeMutation.isPending,
69
+ isRequestingCode: requestCodeMutation.isPending,
70
+ isVerifyingCode: verifyCodeMutation.isPending,
71
+ error: requestCodeMutation.error || verifyCodeMutation.error,
72
+ requestCodeError: requestCodeMutation.error,
73
+ verifyCodeError: verifyCodeMutation.error,
74
+ };
75
+ }
@@ -29,7 +29,7 @@ export const useTranslation = (options = {}) => {
29
29
  // Check for language query parameter
30
30
  if (typeof window !== 'undefined') {
31
31
  const urlParams = new URLSearchParams(window.location.search);
32
- const langFromQuery = urlParams.get('language');
32
+ const langFromQuery = urlParams.get('locale');
33
33
  if (langFromQuery)
34
34
  return langFromQuery;
35
35
  }
@@ -6,11 +6,18 @@ export { ExpressPaymentMethodsProvider } from './providers/ExpressPaymentMethods
6
6
  export { TagadaProvider, useTagadaContext } from './providers/TagadaProvider';
7
7
  export { ApplePayButton } from './components/ApplePayButton';
8
8
  export { GooglePayButton } from './components/GooglePayButton';
9
+ export { useAuth } from './hooks/useAuth';
9
10
  export { useCheckoutToken } from './hooks/useCheckoutToken';
11
+ export { useClubOffers } from './hooks/useClubOffers';
12
+ export { useCustomer } from './hooks/useCustomer';
13
+ export { useCustomerInfos } from './hooks/useCustomerInfos';
14
+ export { useCustomerOrders } from './hooks/useCustomerOrders';
15
+ export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
10
16
  export { useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
11
17
  export { useGeoLocation } from './hooks/useGeoLocation';
12
18
  export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
13
19
  export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
20
+ export { useLogin } from './hooks/useLogin';
14
21
  export { usePluginConfig } from './hooks/usePluginConfig';
15
22
  export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
16
23
  export { useCheckoutQuery as useCheckout } from './hooks/useCheckoutQuery';
@@ -27,18 +34,27 @@ export { useShippingRatesQuery as useShippingRates } from './hooks/useShippingRa
27
34
  export { useStoreConfigQuery as useStoreConfig } from './hooks/useStoreConfigQuery';
28
35
  export { useThreeds } from './hooks/useThreeds';
29
36
  export { useThreedsModal } from './hooks/useThreedsModal';
37
+ export { useTranslation } from './hooks/useTranslation';
30
38
  export { useVipOffersQuery as useVipOffers } from './hooks/useVipOffersQuery';
31
39
  export { useFunnel, useSimpleFunnel } from './hooks/useFunnel';
32
40
  export type { UseCheckoutTokenOptions, UseCheckoutTokenResult } from './hooks/useCheckoutToken';
41
+ export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './hooks/useClubOffers';
42
+ export type { UseCustomerResult } from './hooks/useCustomer';
43
+ export type { UseCustomerInfosOptions, UseCustomerInfosResult } from './hooks/useCustomerInfos';
44
+ export type { UseCustomerOrdersOptions, UseCustomerOrdersResult } from './hooks/useCustomerOrders';
45
+ export type { UseCustomerSubscriptionsOptions, UseCustomerSubscriptionsResult } from './hooks/useCustomerSubscriptions';
33
46
  export type { ExpressPaymentMethodsContextType, ExpressPaymentMethodsProviderProps } from './hooks/useExpressPaymentMethods';
47
+ export type { UseLoginOptions, UseLoginResult } from './hooks/useLogin';
34
48
  export type { ApplePayButtonProps } from './components/ApplePayButton';
35
49
  export type { GooglePayButtonProps } from './components/GooglePayButton';
36
50
  export type { GeoLocationData, UseGeoLocationOptions, UseGeoLocationReturn } from './hooks/useGeoLocation';
37
51
  export type { ExtractedAddress, GooglePlaceDetails, GooglePrediction, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
38
52
  export type { ISOCountry, ISORegion, UseISODataResult } from './hooks/useISOData';
39
53
  export type { UsePluginConfigOptions, UsePluginConfigResult } from './hooks/usePluginConfig';
54
+ export type { TranslateFunction, UseTranslationOptions, UseTranslationResult } from './hooks/useTranslation';
40
55
  export type { UseCheckoutQueryOptions as UseCheckoutOptions, UseCheckoutQueryResult as UseCheckoutResult } from './hooks/useCheckoutQuery';
41
56
  export type { UseDiscountsQueryOptions as UseDiscountsOptions, UseDiscountsQueryResult as UseDiscountsResult } from './hooks/useDiscountsQuery';
57
+ export type { FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext, UseFunnelOptions, UseFunnelResult } from './hooks/useFunnel';
42
58
  export type { UseOffersQueryOptions as UseOffersOptions, UseOffersQueryResult as UseOffersResult } from './hooks/useOffersQuery';
43
59
  export type { UseOrderBumpQueryOptions as UseOrderBumpOptions, UseOrderBumpQueryResult as UseOrderBumpResult } from './hooks/useOrderBumpQuery';
44
60
  export type { UseOrderQueryOptions as UseOrderOptions, UseOrderQueryResult as UseOrderResult } from './hooks/useOrderQuery';
@@ -50,6 +66,5 @@ export type { UseShippingRatesQueryOptions as UseShippingRatesOptions, UseShippi
50
66
  export type { UseStoreConfigQueryOptions as UseStoreConfigOptions, UseStoreConfigQueryResult as UseStoreConfigResult } from './hooks/useStoreConfigQuery';
51
67
  export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession } from './hooks/useThreeds';
52
68
  export type { UseVipOffersQueryOptions as UseVipOffersOptions, UseVipOffersQueryResult as UseVipOffersResult } from './hooks/useVipOffersQuery';
53
- export type { UseFunnelOptions, UseFunnelResult, FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from './hooks/useFunnel';
54
69
  export { formatMoney } from '../../react/utils/money';
55
70
  export type OrderItem = import('../core/utils/order').OrderLineItem;
@@ -9,11 +9,18 @@ export { TagadaProvider, useTagadaContext } from './providers/TagadaProvider';
9
9
  export { ApplePayButton } from './components/ApplePayButton';
10
10
  export { GooglePayButton } from './components/GooglePayButton';
11
11
  // Hooks
12
+ export { useAuth } from './hooks/useAuth';
12
13
  export { useCheckoutToken } from './hooks/useCheckoutToken';
14
+ export { useClubOffers } from './hooks/useClubOffers';
15
+ export { useCustomer } from './hooks/useCustomer';
16
+ export { useCustomerInfos } from './hooks/useCustomerInfos';
17
+ export { useCustomerOrders } from './hooks/useCustomerOrders';
18
+ export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
13
19
  export { useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
14
20
  export { useGeoLocation } from './hooks/useGeoLocation';
15
21
  export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
16
22
  export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
23
+ export { useLogin } from './hooks/useLogin';
17
24
  export { usePluginConfig } from './hooks/usePluginConfig';
18
25
  // TanStack Query hooks (recommended)
19
26
  export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
@@ -31,6 +38,7 @@ export { useShippingRatesQuery as useShippingRates } from './hooks/useShippingRa
31
38
  export { useStoreConfigQuery as useStoreConfig } from './hooks/useStoreConfigQuery';
32
39
  export { useThreeds } from './hooks/useThreeds';
33
40
  export { useThreedsModal } from './hooks/useThreedsModal';
41
+ export { useTranslation } from './hooks/useTranslation';
34
42
  export { useVipOffersQuery as useVipOffers } from './hooks/useVipOffersQuery';
35
43
  // Funnel hooks
36
44
  export { useFunnel, useSimpleFunnel } from './hooks/useFunnel';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/plugin-sdk",
3
- "version": "2.6.18",
3
+ "version": "2.7.0",
4
4
  "description": "Modern React SDK for building Tagada Pay plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,79 +0,0 @@
1
- /**
2
- * Single Discount Hook using TanStack Query
3
- * Fetches a specific discount for a given store
4
- */
5
- import { UseQueryResult } from '@tanstack/react-query';
6
- export interface StoreDiscountRuleAmount {
7
- rate: number;
8
- amount: number;
9
- lock: boolean;
10
- date: string;
11
- }
12
- export interface StoreDiscountRule {
13
- id: string;
14
- createdAt: string;
15
- updatedAt: string;
16
- promotionId: string;
17
- type: string;
18
- productId: string | null;
19
- minimumQuantity: number | null;
20
- minimumAmount: Record<string, StoreDiscountRuleAmount> | null;
21
- variantIds: string[] | null;
22
- }
23
- export interface StoreDiscountAction {
24
- id: string;
25
- createdAt: string;
26
- updatedAt: string;
27
- promotionId: string;
28
- type: string;
29
- adjustmentAmount: number | null;
30
- adjustmentPercentage: number | null;
31
- adjustmentType: string | null;
32
- freeShipping: boolean | null;
33
- priceIdToAdd: string | null;
34
- productIdToAdd: string | null;
35
- variantIdToAdd: string | null;
36
- subscriptionFreeTrialDuration: number | null;
37
- subscriptionFreeTrialDurationType: string | null;
38
- targetProductId: string | null;
39
- targetVariantIds: string[] | null;
40
- maxQuantityDiscounted: number | null;
41
- appliesOnEachItem: boolean | null;
42
- }
43
- export interface StoreDiscount {
44
- id: string;
45
- createdAt: string;
46
- updatedAt: string;
47
- storeId: string;
48
- accountId: string;
49
- name: string;
50
- code: string;
51
- automatic: boolean;
52
- usageLimit: number | null;
53
- usageCount: number;
54
- startDate: string;
55
- endDate: string | null;
56
- enabled: boolean;
57
- archived: boolean;
58
- ruleOperator: string;
59
- externalId: string | null;
60
- combinesWithOrderLevelDiscounts: boolean;
61
- combinesWithLineItemDiscounts: boolean;
62
- combinesWithShippingDiscounts: boolean;
63
- forceCombine: boolean;
64
- isTemporary: boolean;
65
- rules: StoreDiscountRule[];
66
- actions: StoreDiscountAction[];
67
- }
68
- export interface UseDiscountQueryOptions {
69
- storeId?: string;
70
- discountId?: string;
71
- enabled?: boolean;
72
- }
73
- export interface UseDiscountQueryResult<TData = StoreDiscount> {
74
- discount: TData | undefined;
75
- isLoading: boolean;
76
- error: Error | null;
77
- refetch: UseQueryResult<TData>['refetch'];
78
- }
79
- export declare function useDiscountQuery<TData = StoreDiscount>(options: UseDiscountQueryOptions): UseDiscountQueryResult<TData>;
@@ -1,24 +0,0 @@
1
- /**
2
- * Single Discount Hook using TanStack Query
3
- * Fetches a specific discount for a given store
4
- */
5
- import { useMemo } from 'react';
6
- import { useApiQuery } from './useApiQuery';
7
- import { usePluginConfig } from './usePluginConfig';
8
- export function useDiscountQuery(options) {
9
- const { storeId: storeIdFromConfig } = usePluginConfig();
10
- const { storeId = storeIdFromConfig, discountId, enabled = true } = options;
11
- const key = useMemo(() => ['discount', storeId, discountId], [storeId, discountId]);
12
- const url = useMemo(() => {
13
- if (!storeId || !discountId)
14
- return null;
15
- return `/api/v1/stores/${storeId}/discounts/${discountId}`;
16
- }, [storeId, discountId]);
17
- const query = useApiQuery(key, url, { enabled });
18
- return {
19
- discount: query.data,
20
- isLoading: query.isLoading,
21
- error: query.error || null,
22
- refetch: query.refetch,
23
- };
24
- }