@tagadapay/plugin-sdk 1.0.2

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 (63) hide show
  1. package/README.md +475 -0
  2. package/dist/data/currencies.json +2410 -0
  3. package/dist/index.d.ts +33 -0
  4. package/dist/index.js +37 -0
  5. package/dist/react/components/DebugDrawer.d.ts +7 -0
  6. package/dist/react/components/DebugDrawer.js +368 -0
  7. package/dist/react/components/OffersDemo.d.ts +1 -0
  8. package/dist/react/components/OffersDemo.js +50 -0
  9. package/dist/react/components/index.d.ts +1 -0
  10. package/dist/react/components/index.js +1 -0
  11. package/dist/react/config/environment.d.ts +22 -0
  12. package/dist/react/config/environment.js +132 -0
  13. package/dist/react/config/payment.d.ts +23 -0
  14. package/dist/react/config/payment.js +52 -0
  15. package/dist/react/hooks/useAuth.d.ts +4 -0
  16. package/dist/react/hooks/useAuth.js +12 -0
  17. package/dist/react/hooks/useCheckout.d.ts +262 -0
  18. package/dist/react/hooks/useCheckout.js +325 -0
  19. package/dist/react/hooks/useCurrency.d.ts +4 -0
  20. package/dist/react/hooks/useCurrency.js +640 -0
  21. package/dist/react/hooks/useCustomer.d.ts +7 -0
  22. package/dist/react/hooks/useCustomer.js +14 -0
  23. package/dist/react/hooks/useEnvironment.d.ts +7 -0
  24. package/dist/react/hooks/useEnvironment.js +18 -0
  25. package/dist/react/hooks/useLocale.d.ts +2 -0
  26. package/dist/react/hooks/useLocale.js +43 -0
  27. package/dist/react/hooks/useOffers.d.ts +99 -0
  28. package/dist/react/hooks/useOffers.js +115 -0
  29. package/dist/react/hooks/useOrder.d.ts +44 -0
  30. package/dist/react/hooks/useOrder.js +77 -0
  31. package/dist/react/hooks/usePayment.d.ts +60 -0
  32. package/dist/react/hooks/usePayment.js +343 -0
  33. package/dist/react/hooks/usePaymentPolling.d.ts +45 -0
  34. package/dist/react/hooks/usePaymentPolling.js +146 -0
  35. package/dist/react/hooks/useProducts.d.ts +95 -0
  36. package/dist/react/hooks/useProducts.js +120 -0
  37. package/dist/react/hooks/useSession.d.ts +10 -0
  38. package/dist/react/hooks/useSession.js +17 -0
  39. package/dist/react/hooks/useThreeds.d.ts +38 -0
  40. package/dist/react/hooks/useThreeds.js +162 -0
  41. package/dist/react/hooks/useThreedsModal.d.ts +16 -0
  42. package/dist/react/hooks/useThreedsModal.js +328 -0
  43. package/dist/react/index.d.ts +26 -0
  44. package/dist/react/index.js +27 -0
  45. package/dist/react/providers/TagadaProvider.d.ts +55 -0
  46. package/dist/react/providers/TagadaProvider.js +471 -0
  47. package/dist/react/services/apiService.d.ts +149 -0
  48. package/dist/react/services/apiService.js +168 -0
  49. package/dist/react/types.d.ts +151 -0
  50. package/dist/react/types.js +4 -0
  51. package/dist/react/utils/__tests__/urlUtils.test.d.ts +1 -0
  52. package/dist/react/utils/__tests__/urlUtils.test.js +189 -0
  53. package/dist/react/utils/deviceInfo.d.ts +39 -0
  54. package/dist/react/utils/deviceInfo.js +163 -0
  55. package/dist/react/utils/jwtDecoder.d.ts +14 -0
  56. package/dist/react/utils/jwtDecoder.js +86 -0
  57. package/dist/react/utils/money.d.ts +2273 -0
  58. package/dist/react/utils/money.js +104 -0
  59. package/dist/react/utils/tokenStorage.d.ts +16 -0
  60. package/dist/react/utils/tokenStorage.js +52 -0
  61. package/dist/react/utils/urlUtils.d.ts +239 -0
  62. package/dist/react/utils/urlUtils.js +449 -0
  63. package/package.json +64 -0
@@ -0,0 +1,328 @@
1
+ import { useCallback } from 'react';
2
+ export function useThreedsModal() {
3
+ // Close the 3DS modal
4
+ const closeThreedsModal = useCallback((containerId = 'threedscontainer') => {
5
+ const container = document.getElementById(containerId);
6
+ const backdrop = document.getElementById(`${containerId}-backdrop`);
7
+ if (container && backdrop) {
8
+ // Animate out
9
+ container.style.transform = 'scale(0.95)';
10
+ container.style.opacity = '0';
11
+ backdrop.style.opacity = '0';
12
+ setTimeout(() => {
13
+ if (backdrop && document.body.contains(backdrop)) {
14
+ document.body.removeChild(backdrop);
15
+ }
16
+ // Remove escape key listener
17
+ document.removeEventListener('keydown', (e) => {
18
+ if (e.key === 'Escape')
19
+ closeThreedsModal(containerId);
20
+ });
21
+ }, 300);
22
+ }
23
+ }, []);
24
+ // Create and open a modal for 3DS authentication
25
+ const createThreedsModal = useCallback((options = {}) => {
26
+ const { containerId = 'threedscontainer', mode = 'auto-fit', onClose } = options;
27
+ // Remove any existing modal first
28
+ const existingContainer = document.getElementById(containerId);
29
+ const existingBackdrop = document.getElementById(`${containerId}-backdrop`);
30
+ if (existingContainer)
31
+ document.body.removeChild(existingContainer);
32
+ if (existingBackdrop)
33
+ document.body.removeChild(existingBackdrop);
34
+ // Create backdrop
35
+ const backdrop = document.createElement('div');
36
+ backdrop.id = `${containerId}-backdrop`;
37
+ Object.assign(backdrop.style, {
38
+ position: 'fixed',
39
+ top: '0',
40
+ left: '0',
41
+ width: '100%',
42
+ height: '100%',
43
+ backgroundColor: 'rgba(0, 0, 0, 0.6)',
44
+ zIndex: '9998',
45
+ display: 'flex',
46
+ justifyContent: 'center',
47
+ alignItems: 'center',
48
+ transition: 'opacity 0.3s ease',
49
+ opacity: '0',
50
+ });
51
+ // Create modal container
52
+ const container = document.createElement('div');
53
+ container.id = containerId;
54
+ // Check if mobile initially
55
+ let isMobile = window.innerWidth < 768;
56
+ // Base styles for both modes
57
+ const baseStyles = {
58
+ position: 'relative',
59
+ backgroundColor: 'white',
60
+ borderRadius: '12px',
61
+ boxShadow: '0 10px 25px rgba(0, 0, 0, 0.2)',
62
+ maxWidth: '100%',
63
+ overflow: 'hidden',
64
+ zIndex: '9999',
65
+ transition: 'transform 0.3s ease, opacity 0.3s ease, width 0.3s ease, height 0.3s ease',
66
+ transform: 'scale(0.95)',
67
+ opacity: '0',
68
+ };
69
+ // Function to apply styles based on screen size and mode
70
+ const applyResponsiveStyles = () => {
71
+ isMobile = window.innerWidth < 768;
72
+ backdrop.style.alignItems = 'center';
73
+ backdrop.style.justifyContent = 'center';
74
+ if (mode === 'fixed') {
75
+ if (isMobile) {
76
+ Object.assign(container.style, {
77
+ ...baseStyles,
78
+ position: 'fixed',
79
+ top: '0',
80
+ left: '0',
81
+ right: '0',
82
+ bottom: '0',
83
+ width: '100%',
84
+ height: '100%',
85
+ borderRadius: '0',
86
+ margin: '0',
87
+ backgroundColor: 'white',
88
+ transform: 'scale(0.95)',
89
+ opacity: '0',
90
+ maxHeight: '100%',
91
+ });
92
+ }
93
+ else {
94
+ Object.assign(container.style, {
95
+ ...baseStyles,
96
+ width: '550px',
97
+ height: '600px',
98
+ maxHeight: '85vh',
99
+ position: 'relative',
100
+ borderRadius: '12px',
101
+ margin: 'auto',
102
+ backgroundColor: 'white',
103
+ transform: 'scale(0.95)',
104
+ opacity: '0',
105
+ });
106
+ }
107
+ }
108
+ else {
109
+ // auto-fit mode
110
+ if (isMobile) {
111
+ Object.assign(container.style, {
112
+ ...baseStyles,
113
+ position: 'fixed',
114
+ top: '0',
115
+ left: '0',
116
+ right: '0',
117
+ bottom: '0',
118
+ width: '100%',
119
+ height: '100%',
120
+ borderRadius: '0',
121
+ margin: '0',
122
+ backgroundColor: 'white',
123
+ transform: 'scale(0.95)',
124
+ opacity: '0',
125
+ maxHeight: '100%',
126
+ });
127
+ }
128
+ else {
129
+ Object.assign(container.style, {
130
+ ...baseStyles,
131
+ width: '550px',
132
+ maxHeight: '85vh',
133
+ height: 'auto',
134
+ minHeight: '250px',
135
+ position: 'relative',
136
+ borderRadius: '12px',
137
+ margin: 'auto',
138
+ backgroundColor: 'white',
139
+ transform: 'scale(0.95)',
140
+ opacity: '0',
141
+ });
142
+ }
143
+ }
144
+ };
145
+ // Apply initial styles
146
+ applyResponsiveStyles();
147
+ // Create header
148
+ const header = document.createElement('div');
149
+ Object.assign(header.style, {
150
+ padding: '16px 20px',
151
+ borderBottom: '1px solid #eaeaea',
152
+ display: 'flex',
153
+ justifyContent: 'space-between',
154
+ alignItems: 'center',
155
+ backgroundColor: 'white',
156
+ });
157
+ // Add title
158
+ const title = document.createElement('h3');
159
+ title.textContent = 'Secure Authentication';
160
+ Object.assign(title.style, {
161
+ margin: '0',
162
+ fontSize: '18px',
163
+ fontWeight: '600',
164
+ color: '#333',
165
+ });
166
+ // Add close button
167
+ const closeButton = document.createElement('button');
168
+ closeButton.innerHTML = '&times;';
169
+ Object.assign(closeButton.style, {
170
+ background: 'none',
171
+ border: 'none',
172
+ fontSize: '24px',
173
+ cursor: 'pointer',
174
+ color: '#666',
175
+ padding: '0 5px',
176
+ lineHeight: '1',
177
+ });
178
+ // Create content area
179
+ const content = document.createElement('div');
180
+ content.id = `${containerId}-content`;
181
+ // Function to update content styles based on mode and screen size
182
+ const updateContentStyles = () => {
183
+ if (mode === 'fixed') {
184
+ Object.assign(content.style, {
185
+ height: isMobile ? 'calc(100% - 60px)' : 'calc(100% - 60px)',
186
+ width: '100%',
187
+ overflow: 'hidden',
188
+ backgroundColor: 'white',
189
+ });
190
+ }
191
+ else {
192
+ // auto-fit mode
193
+ if (isMobile) {
194
+ Object.assign(content.style, {
195
+ width: '100%',
196
+ height: 'calc(100% - 60px)',
197
+ overflow: 'auto',
198
+ padding: '16px',
199
+ backgroundColor: 'white',
200
+ });
201
+ }
202
+ else {
203
+ Object.assign(content.style, {
204
+ width: '100%',
205
+ overflow: 'auto',
206
+ padding: '20px',
207
+ maxHeight: 'calc(85vh - 60px)',
208
+ backgroundColor: 'white',
209
+ });
210
+ }
211
+ }
212
+ };
213
+ // Apply initial content styles
214
+ updateContentStyles();
215
+ // Update close handlers to call onClose callback
216
+ const handleClose = () => {
217
+ onClose?.();
218
+ closeThreedsModal(containerId);
219
+ };
220
+ // Update event listeners
221
+ closeButton.onclick = handleClose;
222
+ backdrop.onclick = (e) => {
223
+ if (e.target === backdrop) {
224
+ handleClose();
225
+ }
226
+ };
227
+ // Update escape key listener
228
+ const escKeyHandler = (e) => {
229
+ if (e.key === 'Escape') {
230
+ handleClose();
231
+ }
232
+ };
233
+ document.addEventListener('keydown', escKeyHandler);
234
+ // Assemble the modal
235
+ header.appendChild(title);
236
+ header.appendChild(closeButton);
237
+ container.appendChild(header);
238
+ container.appendChild(content);
239
+ backdrop.appendChild(container);
240
+ document.body.appendChild(backdrop);
241
+ // Animate in with a slight delay to ensure proper rendering
242
+ setTimeout(() => {
243
+ backdrop.style.opacity = '1';
244
+ container.style.transform = 'scale(1)';
245
+ container.style.opacity = '1';
246
+ }, 50);
247
+ // Function to adjust height in auto-fit mode
248
+ const adjustAutoFitHeight = () => {
249
+ if (!content)
250
+ return;
251
+ if (isMobile) {
252
+ content.style.height = 'calc(100% - 60px)';
253
+ content.style.overflowY = 'auto';
254
+ }
255
+ else {
256
+ const viewportHeight = window.innerHeight;
257
+ const contentHeight = content.scrollHeight;
258
+ const headerHeight = header.offsetHeight;
259
+ const maxModalHeight = viewportHeight * 0.85;
260
+ if (contentHeight + headerHeight < maxModalHeight) {
261
+ container.style.height = 'auto';
262
+ content.style.overflowY = 'visible';
263
+ }
264
+ else {
265
+ container.style.height = `${maxModalHeight}px`;
266
+ content.style.height = `${maxModalHeight - headerHeight}px`;
267
+ content.style.overflowY = 'auto';
268
+ }
269
+ }
270
+ };
271
+ // Handle window resize
272
+ const handleResize = () => {
273
+ const currentOpacity = container.style.opacity;
274
+ const currentTransform = container.style.transform;
275
+ applyResponsiveStyles();
276
+ updateContentStyles();
277
+ container.style.opacity = currentOpacity;
278
+ container.style.transform = currentTransform;
279
+ if (mode === 'auto-fit') {
280
+ adjustAutoFitHeight();
281
+ }
282
+ };
283
+ // Set up mutation observer to detect content changes
284
+ const contentObserver = new MutationObserver(() => {
285
+ if (mode === 'auto-fit') {
286
+ setTimeout(adjustAutoFitHeight, 50);
287
+ }
288
+ });
289
+ contentObserver.observe(content, {
290
+ childList: true,
291
+ subtree: true,
292
+ characterData: true,
293
+ attributes: true,
294
+ });
295
+ // For auto-fit mode, set up resize observer for content element
296
+ let resizeObserver = null;
297
+ if (mode === 'auto-fit') {
298
+ resizeObserver = new ResizeObserver(() => {
299
+ adjustAutoFitHeight();
300
+ });
301
+ resizeObserver.observe(content);
302
+ }
303
+ // Add window resize listener
304
+ window.addEventListener('resize', handleResize);
305
+ // Create a function to manually trigger height adjustment
306
+ const updateModalSize = () => {
307
+ if (mode === 'auto-fit') {
308
+ adjustAutoFitHeight();
309
+ }
310
+ };
311
+ return {
312
+ containerId,
313
+ getContentElement: () => document.getElementById(`${containerId}-content`),
314
+ updateModalSize,
315
+ cleanup: () => {
316
+ window.removeEventListener('resize', handleResize);
317
+ if (resizeObserver) {
318
+ resizeObserver.disconnect();
319
+ }
320
+ contentObserver.disconnect();
321
+ },
322
+ };
323
+ }, [closeThreedsModal]);
324
+ return {
325
+ createThreedsModal,
326
+ closeThreedsModal,
327
+ };
328
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * React SDK exports
3
+ */
4
+ export { TagadaProvider } from './providers/TagadaProvider';
5
+ export { useCheckout } from './hooks/useCheckout';
6
+ export { useProducts } from './hooks/useProducts';
7
+ export { useOffers } from './hooks/useOffers';
8
+ export { useSession } from './hooks/useSession';
9
+ export { useCurrency } from './hooks/useCurrency';
10
+ export { useCustomer } from './hooks/useCustomer';
11
+ export { useEnvironment } from './hooks/useEnvironment';
12
+ export { useLocale } from './hooks/useLocale';
13
+ export { useAuth } from './hooks/useAuth';
14
+ export { useOrder } from './hooks/useOrder';
15
+ export type { UseOrderOptions, UseOrderResult } from './hooks/useOrder';
16
+ export { usePayment } from './hooks/usePayment';
17
+ export { usePaymentPolling } from './hooks/usePaymentPolling';
18
+ export { useThreeds } from './hooks/useThreeds';
19
+ export { useThreedsModal } from './hooks/useThreedsModal';
20
+ export type { Customer, Session, AuthState, Locale, Currency, Store, Environment, EnvironmentConfig, Order, OrderItem, OrderSummary, OrderAddress, PickupPoint, } from './types';
21
+ export type { UseCheckoutOptions, UseCheckoutResult, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutData, Promotion, } from './hooks/useCheckout';
22
+ export type { Payment, PollingOptions, PaymentPollingHook } from './hooks/usePaymentPolling';
23
+ export type { PaymentInstrument, ThreedsSession, ThreedsChallenge, ThreedsOptions, ThreedsHook, ThreedsProvider, } from './hooks/useThreeds';
24
+ export type { ThreedsModalOptions, ThreedsModalInstance, ThreedsModalHook } from './hooks/useThreedsModal';
25
+ export type { ApplePayToken, CardPaymentMethod, PaymentResponse, PaymentOptions, PaymentInstrumentResponse, PaymentHook, } from './hooks/usePayment';
26
+ export { formatMoney, formatMoneyWithoutSymbol, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits, convertCurrency, formatSimpleMoney, } from './utils/money';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * React SDK exports
3
+ */
4
+ // Main entry point for Tagada Pay React SDK
5
+ // Provider exports
6
+ export { TagadaProvider } from './providers/TagadaProvider';
7
+ // Hook exports
8
+ export { useCheckout } from './hooks/useCheckout';
9
+ export { useProducts } from './hooks/useProducts';
10
+ export { useOffers } from './hooks/useOffers';
11
+ export { useSession } from './hooks/useSession';
12
+ export { useCurrency } from './hooks/useCurrency';
13
+ export { useCustomer } from './hooks/useCustomer';
14
+ export { useEnvironment } from './hooks/useEnvironment';
15
+ export { useLocale } from './hooks/useLocale';
16
+ export { useAuth } from './hooks/useAuth';
17
+ // Order hook exports
18
+ export { useOrder } from './hooks/useOrder';
19
+ // Payment hooks exports
20
+ export { usePayment } from './hooks/usePayment';
21
+ export { usePaymentPolling } from './hooks/usePaymentPolling';
22
+ export { useThreeds } from './hooks/useThreeds';
23
+ export { useThreedsModal } from './hooks/useThreedsModal';
24
+ // Component exports (if any)
25
+ // export { SomeComponent } from './components/SomeComponent';
26
+ // Utility exports
27
+ export { formatMoney, formatMoneyWithoutSymbol, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits, convertCurrency, formatSimpleMoney, } from './utils/money';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * TagadaProvider - Main provider component for the Tagada Pay React SDK
3
+ */
4
+ import { ReactNode } from 'react';
5
+ import { Customer, Session, AuthState, Locale, Currency, Store, Environment, EnvironmentConfig } from '../types';
6
+ import { ApiService } from '../services/apiService';
7
+ import { formatMoney, getCurrencyInfo, moneyStringOrNumberToMinorUnits, minorUnitsToMajorUnits, formatMoneyWithoutSymbol, convertCurrency, formatSimpleMoney } from '../utils/money';
8
+ interface TagadaContextValue {
9
+ auth: AuthState;
10
+ session: Session | null;
11
+ customer: Customer | null;
12
+ locale: Locale;
13
+ currency: Currency;
14
+ store: Store | null;
15
+ environment: EnvironmentConfig;
16
+ apiService: ApiService;
17
+ isLoading: boolean;
18
+ isInitialized: boolean;
19
+ debugMode: boolean;
20
+ debugCheckout: {
21
+ isActive: boolean;
22
+ data: any;
23
+ error: Error | null;
24
+ isLoading: boolean;
25
+ lastUpdated: Date | null;
26
+ };
27
+ updateCheckoutDebugData: (data: any, error?: Error | null, isLoading?: boolean) => void;
28
+ money: {
29
+ formatMoney: typeof formatMoney;
30
+ getCurrencyInfo: typeof getCurrencyInfo;
31
+ moneyStringOrNumberToMinorUnits: typeof moneyStringOrNumberToMinorUnits;
32
+ minorUnitsToMajorUnits: typeof minorUnitsToMajorUnits;
33
+ formatMoneyWithoutSymbol: typeof formatMoneyWithoutSymbol;
34
+ convertCurrency: typeof convertCurrency;
35
+ formatSimpleMoney: typeof formatSimpleMoney;
36
+ };
37
+ }
38
+ interface TagadaProviderProps {
39
+ children: ReactNode;
40
+ environment?: Environment;
41
+ customApiConfig?: Partial<EnvironmentConfig>;
42
+ developmentMode?: boolean;
43
+ debugMode?: boolean;
44
+ storeId?: string;
45
+ accountId?: string;
46
+ mockData?: {
47
+ customer?: Partial<Customer>;
48
+ session?: Partial<Session>;
49
+ store?: Partial<Store>;
50
+ };
51
+ }
52
+ export declare function TagadaProvider({ children, environment, customApiConfig, developmentMode, debugMode, // Remove default, will be set based on environment
53
+ storeId, accountId, mockData, }: TagadaProviderProps): import("react/jsx-runtime").JSX.Element;
54
+ export declare function useTagadaContext(): TagadaContextValue;
55
+ export {};