@tagadapay/plugin-sdk 2.4.39 → 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 (106) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +2 -0
  3. package/dist/react/hooks/useCheckout.js +19 -2
  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 +92 -13
  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/usePostPurchases.js +11 -5
  14. package/dist/react/index.d.ts +8 -0
  15. package/dist/react/index.js +4 -0
  16. package/dist/react/services/apiService.d.ts +1 -0
  17. package/dist/react/services/apiService.js +3 -0
  18. package/dist/v2/core/googleAutocomplete.d.ts +65 -0
  19. package/dist/v2/core/googleAutocomplete.js +94 -0
  20. package/dist/v2/core/index.d.ts +8 -0
  21. package/dist/v2/core/index.js +11 -0
  22. package/dist/v2/core/isoData.d.ts +50 -0
  23. package/dist/v2/core/isoData.js +103 -0
  24. package/dist/v2/core/resources/apiClient.d.ts +25 -0
  25. package/dist/v2/core/resources/apiClient.js +95 -0
  26. package/dist/v2/core/resources/checkout.d.ts +189 -0
  27. package/dist/v2/core/resources/checkout.js +119 -0
  28. package/dist/v2/core/resources/index.d.ts +13 -0
  29. package/dist/v2/core/resources/index.js +13 -0
  30. package/dist/v2/core/resources/offers.d.ts +98 -0
  31. package/dist/v2/core/resources/offers.js +115 -0
  32. package/dist/v2/core/resources/orders.d.ts +40 -0
  33. package/dist/v2/core/resources/orders.js +59 -0
  34. package/dist/v2/core/resources/payments.d.ts +140 -0
  35. package/dist/v2/core/resources/payments.js +126 -0
  36. package/dist/v2/core/resources/postPurchases.d.ts +182 -0
  37. package/dist/v2/core/resources/postPurchases.js +116 -0
  38. package/dist/v2/core/resources/products.d.ts +29 -0
  39. package/dist/v2/core/resources/products.js +49 -0
  40. package/dist/v2/core/resources/promotions.d.ts +45 -0
  41. package/dist/v2/core/resources/promotions.js +87 -0
  42. package/dist/v2/core/resources/threeds.d.ts +23 -0
  43. package/dist/v2/core/resources/threeds.js +15 -0
  44. package/dist/v2/core/utils/checkout.d.ts +24 -0
  45. package/dist/v2/core/utils/checkout.js +30 -0
  46. package/dist/v2/core/utils/currency.d.ts +28 -0
  47. package/dist/v2/core/utils/currency.js +272 -0
  48. package/dist/v2/core/utils/index.d.ts +12 -0
  49. package/dist/v2/core/utils/index.js +12 -0
  50. package/dist/v2/core/utils/order.d.ts +159 -0
  51. package/dist/v2/core/utils/order.js +42 -0
  52. package/dist/v2/core/utils/orderBump.d.ts +40 -0
  53. package/dist/v2/core/utils/orderBump.js +47 -0
  54. package/dist/v2/core/utils/pluginConfig.d.ts +43 -0
  55. package/dist/v2/core/utils/pluginConfig.js +155 -0
  56. package/dist/v2/core/utils/postPurchases.d.ts +32 -0
  57. package/dist/v2/core/utils/postPurchases.js +42 -0
  58. package/dist/v2/core/utils/products.d.ts +58 -0
  59. package/dist/v2/core/utils/products.js +64 -0
  60. package/dist/v2/core/utils/promotions.d.ts +24 -0
  61. package/dist/v2/core/utils/promotions.js +30 -0
  62. package/dist/v2/index.d.ts +19 -0
  63. package/dist/v2/index.js +15 -0
  64. package/dist/v2/react/components/DebugDrawer.d.ts +7 -0
  65. package/dist/v2/react/components/DebugDrawer.js +383 -0
  66. package/dist/v2/react/hooks/useApiQuery.d.ts +28 -0
  67. package/dist/v2/react/hooks/useApiQuery.js +84 -0
  68. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +39 -0
  69. package/dist/v2/react/hooks/useCheckoutQuery.js +208 -0
  70. package/dist/v2/react/hooks/useCheckoutToken.d.ts +17 -0
  71. package/dist/v2/react/hooks/useCheckoutToken.js +80 -0
  72. package/dist/v2/react/hooks/useCurrency.d.ts +9 -0
  73. package/dist/v2/react/hooks/useCurrency.js +21 -0
  74. package/dist/v2/react/hooks/useGeoLocation.d.ts +138 -0
  75. package/dist/v2/react/hooks/useGeoLocation.js +126 -0
  76. package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +74 -0
  77. package/dist/v2/react/hooks/useGoogleAutocomplete.js +207 -0
  78. package/dist/v2/react/hooks/useISOData.d.ts +61 -0
  79. package/dist/v2/react/hooks/useISOData.js +176 -0
  80. package/dist/v2/react/hooks/useOffersQuery.d.ts +65 -0
  81. package/dist/v2/react/hooks/useOffersQuery.js +353 -0
  82. package/dist/v2/react/hooks/useOrderBumpQuery.d.ts +20 -0
  83. package/dist/v2/react/hooks/useOrderBumpQuery.js +88 -0
  84. package/dist/v2/react/hooks/useOrderQuery.d.ts +29 -0
  85. package/dist/v2/react/hooks/useOrderQuery.js +98 -0
  86. package/dist/v2/react/hooks/usePaymentPolling.d.ts +45 -0
  87. package/dist/v2/react/hooks/usePaymentPolling.js +153 -0
  88. package/dist/v2/react/hooks/usePaymentQuery.d.ts +19 -0
  89. package/dist/v2/react/hooks/usePaymentQuery.js +283 -0
  90. package/dist/v2/react/hooks/usePluginConfig.d.ts +16 -0
  91. package/dist/v2/react/hooks/usePluginConfig.js +36 -0
  92. package/dist/v2/react/hooks/usePostPurchasesQuery.d.ts +63 -0
  93. package/dist/v2/react/hooks/usePostPurchasesQuery.js +365 -0
  94. package/dist/v2/react/hooks/useProductsQuery.d.ts +31 -0
  95. package/dist/v2/react/hooks/useProductsQuery.js +102 -0
  96. package/dist/v2/react/hooks/usePromotionsQuery.d.ts +28 -0
  97. package/dist/v2/react/hooks/usePromotionsQuery.js +97 -0
  98. package/dist/v2/react/hooks/useThreeds.d.ts +36 -0
  99. package/dist/v2/react/hooks/useThreeds.js +166 -0
  100. package/dist/v2/react/hooks/useThreedsModal.d.ts +13 -0
  101. package/dist/v2/react/hooks/useThreedsModal.js +343 -0
  102. package/dist/v2/react/index.d.ts +38 -0
  103. package/dist/v2/react/index.js +27 -0
  104. package/dist/v2/react/providers/TagadaProvider.d.ts +63 -0
  105. package/dist/v2/react/providers/TagadaProvider.js +680 -0
  106. package/package.json +10 -3
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Google Autocomplete Hook - V2 Implementation
3
+ * Compatible with V1 interface while using V2 core architecture
4
+ */
5
+ import { useCallback, useEffect, useRef, useState } from 'react';
6
+ /**
7
+ * React hook for Google Places Autocomplete with automatic script injection
8
+ * Automatically loads the Google Maps JavaScript API with Places library
9
+ */
10
+ export function useGoogleAutocomplete(options) {
11
+ const { apiKey, libraries = ['places'], version = 'weekly', language, region } = options;
12
+ const [predictions, setPredictions] = useState([]);
13
+ const [isLoading, setIsLoading] = useState(false);
14
+ const [isScriptLoaded, setIsScriptLoaded] = useState(false);
15
+ const autocompleteServiceRef = useRef(null);
16
+ const placesServiceRef = useRef(null);
17
+ const scriptLoadedRef = useRef(false);
18
+ // Inject Google Maps script
19
+ useEffect(() => {
20
+ if (!apiKey) {
21
+ console.error('Google Maps API key is required');
22
+ return;
23
+ }
24
+ if (scriptLoadedRef.current || window.google?.maps) {
25
+ setIsScriptLoaded(true);
26
+ return;
27
+ }
28
+ // Check if script is already being loaded
29
+ const existingScript = document.querySelector('script[src*="maps.googleapis.com"]');
30
+ if (existingScript) {
31
+ // Wait for existing script to load
32
+ const checkLoaded = () => {
33
+ if (window.google?.maps?.places?.AutocompleteService) {
34
+ setIsScriptLoaded(true);
35
+ scriptLoadedRef.current = true;
36
+ }
37
+ else {
38
+ setTimeout(checkLoaded, 100);
39
+ }
40
+ };
41
+ checkLoaded();
42
+ return;
43
+ }
44
+ // Create and inject the script
45
+ const script = document.createElement('script');
46
+ const params = new URLSearchParams({
47
+ key: apiKey,
48
+ libraries: libraries.join(','),
49
+ v: version,
50
+ });
51
+ if (language)
52
+ params.append('language', language);
53
+ if (region)
54
+ params.append('region', region);
55
+ script.src = `https://maps.googleapis.com/maps/api/js?${params.toString()}`;
56
+ script.async = true;
57
+ script.defer = true;
58
+ script.onload = () => {
59
+ console.log('🗺️ Google Maps API loaded successfully');
60
+ setIsScriptLoaded(true);
61
+ scriptLoadedRef.current = true;
62
+ };
63
+ script.onerror = () => {
64
+ console.error('Failed to load Google Maps API');
65
+ };
66
+ document.head.appendChild(script);
67
+ // Cleanup function
68
+ return () => {
69
+ // Note: We don't remove the script as it might be used by other components
70
+ // The script will remain in the DOM for the session
71
+ };
72
+ }, [apiKey, libraries, version, language, region]);
73
+ // Initialize Google Places services
74
+ const initializeServices = useCallback(() => {
75
+ if (typeof window === 'undefined')
76
+ return false;
77
+ if (!window.google?.maps?.places?.AutocompleteService) {
78
+ return false;
79
+ }
80
+ if (!autocompleteServiceRef.current) {
81
+ autocompleteServiceRef.current = new window.google.maps.places.AutocompleteService();
82
+ }
83
+ if (!placesServiceRef.current) {
84
+ // Create a dummy map for PlacesService (required by Google API)
85
+ const map = new window.google.maps.Map(document.createElement('div'));
86
+ placesServiceRef.current = new window.google.maps.places.PlacesService(map);
87
+ }
88
+ return true;
89
+ }, []);
90
+ // Search for place predictions
91
+ const searchPlaces = useCallback((input, countryRestriction) => {
92
+ if (!isScriptLoaded) {
93
+ console.warn('Google Maps API not yet loaded');
94
+ return;
95
+ }
96
+ if (!initializeServices()) {
97
+ console.error('Google Places services not available');
98
+ return;
99
+ }
100
+ if (input.length < 3) {
101
+ setPredictions([]);
102
+ return;
103
+ }
104
+ setIsLoading(true);
105
+ const request = {
106
+ input,
107
+ ...(countryRestriction && {
108
+ componentRestrictions: { country: countryRestriction.toLowerCase() },
109
+ }),
110
+ };
111
+ autocompleteServiceRef.current.getPlacePredictions(request, (results, status) => {
112
+ setIsLoading(false);
113
+ if (status === window.google.maps.places.PlacesServiceStatus.OK && results) {
114
+ setPredictions(results);
115
+ console.log(`🔍 Found ${results.length} predictions for "${input}"`);
116
+ }
117
+ else {
118
+ setPredictions([]);
119
+ if (status !== window.google.maps.places.PlacesServiceStatus.ZERO_RESULTS) {
120
+ console.warn('Google Places prediction failed:', status);
121
+ }
122
+ }
123
+ });
124
+ }, [initializeServices, isScriptLoaded]);
125
+ // Get detailed place information
126
+ const getPlaceDetails = useCallback((placeId) => {
127
+ return new Promise((resolve) => {
128
+ if (!isScriptLoaded) {
129
+ console.warn('Google Maps API not yet loaded');
130
+ resolve(null);
131
+ return;
132
+ }
133
+ if (!initializeServices()) {
134
+ console.error('Google Places services not available');
135
+ resolve(null);
136
+ return;
137
+ }
138
+ const request = {
139
+ placeId,
140
+ fields: ['place_id', 'formatted_address', 'address_components', 'geometry'],
141
+ };
142
+ placesServiceRef.current.getDetails(request, (place, status) => {
143
+ if (status === window.google.maps.places.PlacesServiceStatus.OK && place) {
144
+ console.log('📍 Got place details:', place);
145
+ resolve(place);
146
+ }
147
+ else {
148
+ console.error('Failed to get place details:', status);
149
+ resolve(null);
150
+ }
151
+ });
152
+ });
153
+ }, [initializeServices, isScriptLoaded]);
154
+ // Extract structured address components from Google place
155
+ const extractAddressComponents = useCallback((place) => {
156
+ const extracted = {
157
+ streetNumber: '',
158
+ route: '',
159
+ locality: '',
160
+ administrativeAreaLevel1: '',
161
+ administrativeAreaLevel1Long: '',
162
+ country: '',
163
+ postalCode: '',
164
+ };
165
+ console.log('🏗️ Extracted address components:', place.address_components);
166
+ place.address_components?.forEach((component) => {
167
+ const types = component.types;
168
+ if (types.includes('street_number')) {
169
+ extracted.streetNumber = component.long_name;
170
+ }
171
+ if (types.includes('route')) {
172
+ extracted.route = component.long_name;
173
+ }
174
+ if (types.includes('locality')) {
175
+ extracted.locality = component.long_name;
176
+ }
177
+ if (types.includes('administrative_area_level_2') && !extracted.locality) {
178
+ extracted.locality = component.long_name;
179
+ }
180
+ if (types.includes('administrative_area_level_1')) {
181
+ extracted.administrativeAreaLevel1 = component.short_name;
182
+ extracted.administrativeAreaLevel1Long = component.long_name;
183
+ }
184
+ if (types.includes('country')) {
185
+ extracted.country = component.short_name;
186
+ }
187
+ if (types.includes('postal_code')) {
188
+ extracted.postalCode = component.long_name;
189
+ }
190
+ });
191
+ console.log('🏗️ Extracted address components:', extracted);
192
+ return extracted;
193
+ }, []);
194
+ // Clear predictions
195
+ const clearPredictions = useCallback(() => {
196
+ setPredictions([]);
197
+ }, []);
198
+ return {
199
+ predictions,
200
+ isLoading,
201
+ isScriptLoaded,
202
+ searchPlaces,
203
+ getPlaceDetails,
204
+ extractAddressComponents,
205
+ clearPredictions,
206
+ };
207
+ }
@@ -0,0 +1,61 @@
1
+ import { type SupportedLanguage } from '../../../data/iso3166';
2
+ export interface ISOCountry {
3
+ iso: string;
4
+ iso3: string;
5
+ numeric: number;
6
+ name: string;
7
+ }
8
+ export interface ISORegion {
9
+ iso: string;
10
+ name: string;
11
+ }
12
+ export interface UseISODataResult {
13
+ countries: Record<string, ISOCountry>;
14
+ getRegions: (countryCode: string) => ISORegion[];
15
+ findRegion: (countryCode: string, regionCode: string) => ISORegion | null;
16
+ mapGoogleToISO: (googleState: string, googleStateLong: string, countryCode: string) => ISORegion | null;
17
+ isLanguageLoaded: boolean;
18
+ registeredLanguages: SupportedLanguage[];
19
+ }
20
+ /**
21
+ * React hook for accessing ISO3166 countries and regions data with dynamic language loading
22
+ * @param language - Language code (supports: en, ru, de, fr, es, zh, hi, pt, ja, ar, it, he)
23
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
24
+ * @param disputeSetting - Territorial dispute perspective (currently only UN is supported)
25
+ * @returns Object with countries data and helper functions
26
+ */
27
+ export declare function useISOData(language?: SupportedLanguage, autoImport?: boolean, disputeSetting?: string): UseISODataResult;
28
+ /**
29
+ * Get available languages for ISO data
30
+ */
31
+ export declare function getAvailableLanguages(): SupportedLanguage[];
32
+ /**
33
+ * Hook to manually import and register a language
34
+ * @param language - Language code to import
35
+ * @returns Object with loading state and error handling
36
+ */
37
+ export declare function useLanguageImport(language: SupportedLanguage): {
38
+ importLanguage: () => Promise<void>;
39
+ isLoading: boolean;
40
+ error: string | null;
41
+ isRegistered: boolean;
42
+ };
43
+ /**
44
+ * Get list of countries as options for select components
45
+ * @param language - Language code (defaults to 'en')
46
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
47
+ */
48
+ export declare function useCountryOptions(language?: SupportedLanguage, autoImport?: boolean): {
49
+ value: string;
50
+ label: string;
51
+ }[];
52
+ /**
53
+ * Get list of regions/states for a country as options for select components
54
+ * @param countryCode - ISO country code
55
+ * @param language - Language code (defaults to 'en')
56
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
57
+ */
58
+ export declare function useRegionOptions(countryCode: string, language?: SupportedLanguage, autoImport?: boolean): {
59
+ value: string;
60
+ label: string;
61
+ }[];
@@ -0,0 +1,176 @@
1
+ import { useMemo, useEffect, useState, useCallback } from 'react';
2
+ // Import the pre-built ISO data functions
3
+ import { getCountries, getStatesForCountry, importLanguage, isLanguageRegistered, getRegisteredLanguages } from '../../../data/iso3166';
4
+ /**
5
+ * React hook for accessing ISO3166 countries and regions data with dynamic language loading
6
+ * @param language - Language code (supports: en, ru, de, fr, es, zh, hi, pt, ja, ar, it, he)
7
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
8
+ * @param disputeSetting - Territorial dispute perspective (currently only UN is supported)
9
+ * @returns Object with countries data and helper functions
10
+ */
11
+ export function useISOData(language = 'en', autoImport = true, disputeSetting = 'UN') {
12
+ const [isLanguageLoaded, setIsLanguageLoaded] = useState(isLanguageRegistered(language));
13
+ const [registeredLanguages, setRegisteredLanguages] = useState(getRegisteredLanguages);
14
+ // Auto-import language if not registered and autoImport is true
15
+ useEffect(() => {
16
+ if (!isLanguageRegistered(language) && autoImport && language !== 'en') {
17
+ importLanguage(language)
18
+ .then(() => {
19
+ setIsLanguageLoaded(true);
20
+ setRegisteredLanguages(getRegisteredLanguages());
21
+ })
22
+ .catch((error) => {
23
+ console.error(`Failed to auto-import language ${language}:`, error);
24
+ });
25
+ }
26
+ }, [language, autoImport]);
27
+ const data = useMemo(() => {
28
+ try {
29
+ // Get countries from pre-built data with language support
30
+ const countriesArray = getCountries(language);
31
+ // Transform to our expected format (Record<string, ISOCountry>)
32
+ const countries = {};
33
+ countriesArray.forEach((country) => {
34
+ countries[country.code] = {
35
+ iso: country.code,
36
+ iso3: country.iso3 || '',
37
+ numeric: country.numeric || 0,
38
+ name: country.name,
39
+ };
40
+ });
41
+ // Helper to load regions for a specific country
42
+ const getRegions = (countryCode) => {
43
+ try {
44
+ const states = getStatesForCountry(countryCode, language);
45
+ return states.map((state) => ({
46
+ iso: state.code,
47
+ name: state.name,
48
+ }));
49
+ }
50
+ catch {
51
+ return []; // Return empty array if no regions
52
+ }
53
+ };
54
+ // Find a specific region by ISO code
55
+ const findRegion = (countryCode, regionCode) => {
56
+ const regions = getRegions(countryCode);
57
+ return regions.find((region) => region.iso === regionCode) ?? null;
58
+ };
59
+ // Map Google Places state to ISO region (proven 100% success rate)
60
+ const mapGoogleToISO = (googleState, googleStateLong, countryCode) => {
61
+ const regions = getRegions(countryCode);
62
+ if (regions.length === 0)
63
+ return null;
64
+ // Strategy 1: Exact ISO code match (86% success rate)
65
+ let match = regions.find((r) => r.iso === googleState);
66
+ if (match)
67
+ return match;
68
+ // Strategy 2: Name matching (14% success rate)
69
+ match = regions.find((r) => r.name.toLowerCase() === googleState.toLowerCase());
70
+ if (match)
71
+ return match;
72
+ match = regions.find((r) => r.name.toLowerCase() === googleStateLong.toLowerCase());
73
+ if (match)
74
+ return match;
75
+ // Strategy 3: Partial name matching (fallback)
76
+ match = regions.find((r) => r.name.toLowerCase().includes(googleStateLong.toLowerCase()) ||
77
+ googleStateLong.toLowerCase().includes(r.name.toLowerCase()));
78
+ return match ?? null;
79
+ };
80
+ return {
81
+ countries,
82
+ getRegions,
83
+ findRegion,
84
+ mapGoogleToISO,
85
+ isLanguageLoaded,
86
+ registeredLanguages,
87
+ };
88
+ }
89
+ catch (error) {
90
+ console.error(`Failed to load ISO data for language: ${language}`, error);
91
+ return {
92
+ countries: {},
93
+ getRegions: () => [],
94
+ findRegion: () => null,
95
+ mapGoogleToISO: () => null,
96
+ isLanguageLoaded,
97
+ registeredLanguages,
98
+ };
99
+ }
100
+ }, [language, disputeSetting, isLanguageLoaded, registeredLanguages]);
101
+ return data;
102
+ }
103
+ /**
104
+ * Get available languages for ISO data
105
+ */
106
+ export function getAvailableLanguages() {
107
+ // Return all available languages (not just registered ones)
108
+ return ['en', 'ru', 'de', 'fr', 'es', 'zh', 'hi', 'pt', 'ja', 'ar', 'it', 'he'];
109
+ }
110
+ /**
111
+ * Hook to manually import and register a language
112
+ * @param language - Language code to import
113
+ * @returns Object with loading state and error handling
114
+ */
115
+ export function useLanguageImport(language) {
116
+ const [isLoading, setIsLoading] = useState(false);
117
+ const [error, setError] = useState(null);
118
+ const importLanguageData = useCallback(async () => {
119
+ if (isLanguageRegistered(language)) {
120
+ return; // Already registered
121
+ }
122
+ setIsLoading(true);
123
+ setError(null);
124
+ try {
125
+ await importLanguage(language);
126
+ }
127
+ catch (err) {
128
+ setError(err instanceof Error ? err.message : 'Failed to import language');
129
+ }
130
+ finally {
131
+ setIsLoading(false);
132
+ }
133
+ }, [language]);
134
+ return {
135
+ importLanguage: importLanguageData,
136
+ isLoading,
137
+ error,
138
+ isRegistered: isLanguageRegistered(language),
139
+ };
140
+ }
141
+ /**
142
+ * Get list of countries as options for select components
143
+ * @param language - Language code (defaults to 'en')
144
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
145
+ */
146
+ export function useCountryOptions(language = 'en', autoImport = true) {
147
+ const { countries } = useISOData(language, autoImport);
148
+ return useMemo(() => {
149
+ return Object.entries(countries)
150
+ .map(([code, country]) => ({
151
+ value: code,
152
+ label: country.name,
153
+ }))
154
+ .sort((a, b) => a.label.localeCompare(b.label));
155
+ }, [countries]);
156
+ }
157
+ /**
158
+ * Get list of regions/states for a country as options for select components
159
+ * @param countryCode - ISO country code
160
+ * @param language - Language code (defaults to 'en')
161
+ * @param autoImport - Whether to automatically import the language if not registered (default: true)
162
+ */
163
+ export function useRegionOptions(countryCode, language = 'en', autoImport = true) {
164
+ const { getRegions } = useISOData(language, autoImport);
165
+ return useMemo(() => {
166
+ if (!countryCode)
167
+ return [];
168
+ const regions = getRegions(countryCode);
169
+ return regions
170
+ .map((region) => ({
171
+ value: region.iso,
172
+ label: region.name,
173
+ }))
174
+ .sort((a, b) => a.label.localeCompare(b.label));
175
+ }, [countryCode, getRegions]);
176
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Offers Hook using TanStack Query
3
+ * Handles offers with automatic caching
4
+ */
5
+ import { Offer } from '../../core/resources/offers';
6
+ import { CheckoutSessionState, OrderSummary, CurrencyOptions } from '../../core/resources/postPurchases';
7
+ export interface UseOffersQueryOptions {
8
+ /**
9
+ * Array of offer IDs to fetch
10
+ */
11
+ offerIds?: string[];
12
+ /**
13
+ * Whether to fetch offers automatically on mount
14
+ * @default true
15
+ */
16
+ enabled?: boolean;
17
+ /**
18
+ * Return URL for checkout sessions
19
+ */
20
+ returnUrl?: string;
21
+ }
22
+ export interface UseOffersQueryResult {
23
+ offers: Offer[];
24
+ isLoading: boolean;
25
+ error: Error | null;
26
+ refetch: () => Promise<void>;
27
+ createCheckoutSession: (offerId: string, options?: {
28
+ returnUrl?: string;
29
+ }) => Promise<{
30
+ checkoutUrl: string;
31
+ }>;
32
+ payOffer: (offerId: string, orderId?: string) => Promise<void>;
33
+ transformToCheckout: (offerId: string, options?: {
34
+ returnUrl?: string;
35
+ }) => Promise<{
36
+ checkoutUrl: string;
37
+ }>;
38
+ getOffer: (offerId: string) => Offer | undefined;
39
+ getTotalValue: () => number;
40
+ getTotalSavings: () => number;
41
+ payWithCheckoutSession: (checkoutSessionId: string, orderId?: string) => Promise<void>;
42
+ initCheckoutSession: (offerId: string, orderId: string, customerId?: string) => Promise<{
43
+ checkoutSessionId: string;
44
+ }>;
45
+ getCheckoutSessionState: (offerId: string) => CheckoutSessionState | null;
46
+ initializeOfferCheckout: (offerId: string) => Promise<void>;
47
+ getAvailableVariants: (offerId: string, productId: string) => {
48
+ variantId: string;
49
+ variantName: string;
50
+ variantSku: string | null;
51
+ variantDefault: boolean | null;
52
+ variantExternalId: string | null;
53
+ priceId: string;
54
+ currencyOptions: CurrencyOptions;
55
+ }[];
56
+ selectVariant: (offerId: string, productId: string, variantId: string) => Promise<void>;
57
+ getOrderSummary: (offerId: string) => OrderSummary | null;
58
+ isLoadingVariants: (offerId: string, productId: string) => boolean;
59
+ isUpdatingOrderSummary: (offerId: string) => boolean;
60
+ confirmPurchase: (offerId: string, options?: {
61
+ draft?: boolean;
62
+ returnUrl?: string;
63
+ }) => Promise<void>;
64
+ }
65
+ export declare function useOffersQuery(options?: UseOffersQueryOptions): UseOffersQueryResult;