@tagadapay/plugin-sdk 3.1.5 → 3.1.9
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.
- package/README.md +1129 -1129
- package/build-cdn.js +220 -113
- package/dist/external-tracker.js +1225 -558
- package/dist/external-tracker.min.js +2 -2
- package/dist/external-tracker.min.js.map +4 -4
- package/dist/react/hooks/useApplePay.js +25 -36
- package/dist/react/hooks/usePaymentPolling.d.ts +9 -3
- package/dist/react/providers/TagadaProvider.js +5 -5
- package/dist/react/utils/money.d.ts +4 -3
- package/dist/react/utils/money.js +39 -6
- package/dist/react/utils/trackingUtils.js +1 -0
- package/dist/tagada-sdk.js +10142 -0
- package/dist/tagada-sdk.min.js +43 -0
- package/dist/tagada-sdk.min.js.map +7 -0
- package/dist/v2/core/client.js +34 -2
- package/dist/v2/core/config/environment.js +9 -2
- package/dist/v2/core/funnelClient.d.ts +180 -2
- package/dist/v2/core/funnelClient.js +289 -6
- package/dist/v2/core/resources/apiClient.js +1 -1
- package/dist/v2/core/resources/checkout.d.ts +68 -0
- package/dist/v2/core/resources/funnel.d.ts +25 -0
- package/dist/v2/core/resources/payments.d.ts +70 -3
- package/dist/v2/core/resources/payments.js +72 -7
- package/dist/v2/core/utils/index.d.ts +1 -0
- package/dist/v2/core/utils/index.js +2 -0
- package/dist/v2/core/utils/pluginConfig.d.ts +8 -0
- package/dist/v2/core/utils/pluginConfig.js +68 -5
- package/dist/v2/core/utils/previewMode.d.ts +7 -0
- package/dist/v2/core/utils/previewMode.js +72 -14
- package/dist/v2/core/utils/previewModeIndicator.d.ts +19 -0
- package/dist/v2/core/utils/previewModeIndicator.js +414 -0
- package/dist/v2/core/utils/tokenStorage.d.ts +4 -0
- package/dist/v2/core/utils/tokenStorage.js +15 -1
- package/dist/v2/index.d.ts +9 -3
- package/dist/v2/index.js +8 -3
- package/dist/v2/react/components/ApplePayButton.d.ts +22 -123
- package/dist/v2/react/components/ApplePayButton.js +247 -317
- package/dist/v2/react/components/FunnelScriptInjector.d.ts +3 -1
- package/dist/v2/react/components/FunnelScriptInjector.js +255 -162
- package/dist/v2/react/components/GooglePayButton.d.ts +2 -0
- package/dist/v2/react/components/GooglePayButton.js +80 -64
- package/dist/v2/react/components/PreviewModeIndicator.d.ts +46 -0
- package/dist/v2/react/components/PreviewModeIndicator.js +113 -0
- package/dist/v2/react/hooks/useApplePayCheckout.d.ts +16 -0
- package/dist/v2/react/hooks/useApplePayCheckout.js +193 -0
- package/dist/v2/react/hooks/useFunnel.d.ts +48 -6
- package/dist/v2/react/hooks/useFunnel.js +25 -5
- package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +10 -0
- package/dist/v2/react/hooks/useGoogleAutocomplete.js +48 -0
- package/dist/v2/react/hooks/useGooglePayCheckout.d.ts +21 -0
- package/dist/v2/react/hooks/useGooglePayCheckout.js +198 -0
- package/dist/v2/react/hooks/usePaymentPolling.d.ts +15 -3
- package/dist/v2/react/hooks/usePaymentPolling.js +31 -9
- package/dist/v2/react/hooks/usePaymentQuery.d.ts +34 -2
- package/dist/v2/react/hooks/usePaymentQuery.js +731 -7
- package/dist/v2/react/hooks/usePaymentRetrieve.d.ts +26 -0
- package/dist/v2/react/hooks/usePaymentRetrieve.js +175 -0
- package/dist/v2/react/hooks/usePixelTracking.d.ts +56 -0
- package/dist/v2/react/hooks/usePixelTracking.js +508 -0
- package/dist/v2/react/hooks/useStepConfig.d.ts +64 -0
- package/dist/v2/react/hooks/useStepConfig.js +53 -0
- package/dist/v2/react/index.d.ts +15 -5
- package/dist/v2/react/index.js +8 -2
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +1 -0
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +41 -13
- package/dist/v2/react/providers/TagadaProvider.js +24 -23
- package/dist/v2/standalone/external-tracker.d.ts +2 -0
- package/dist/v2/standalone/external-tracker.js +6 -3
- package/package.json +112 -112
- package/dist/v2/react/hooks/useApplePay.d.ts +0 -16
- package/dist/v2/react/hooks/useApplePay.js +0 -247
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Retrieve Hook using TanStack Query (V2)
|
|
3
|
+
* Handles payment status retrieval after external redirects
|
|
4
|
+
* This is useful for processors that require server-side status checks (e.g., some 3DS flows)
|
|
5
|
+
*/
|
|
6
|
+
export interface RetrieveResult {
|
|
7
|
+
retrieveResult?: {
|
|
8
|
+
status?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
success?: boolean;
|
|
11
|
+
};
|
|
12
|
+
paymentId: string;
|
|
13
|
+
transactionCreated?: boolean;
|
|
14
|
+
status?: string;
|
|
15
|
+
transactionId?: string;
|
|
16
|
+
message?: string;
|
|
17
|
+
success?: boolean;
|
|
18
|
+
error?: any;
|
|
19
|
+
}
|
|
20
|
+
export interface PaymentRetrieveHook {
|
|
21
|
+
startRetrievePolling: (paymentId: string) => Promise<void>;
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
error: string | null;
|
|
24
|
+
isPolling: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function usePaymentRetrieve(): PaymentRetrieveHook;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Retrieve Hook using TanStack Query (V2)
|
|
3
|
+
* Handles payment status retrieval after external redirects
|
|
4
|
+
* This is useful for processors that require server-side status checks (e.g., some 3DS flows)
|
|
5
|
+
*/
|
|
6
|
+
import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
|
7
|
+
import { PaymentsResource } from '../../core/resources/payments';
|
|
8
|
+
import { usePaymentPolling } from './usePaymentPolling';
|
|
9
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
10
|
+
export function usePaymentRetrieve() {
|
|
11
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
12
|
+
const [error, setError] = useState(null);
|
|
13
|
+
// Create payments resource client
|
|
14
|
+
const paymentsResource = useMemo(() => {
|
|
15
|
+
try {
|
|
16
|
+
return new PaymentsResource(getGlobalApiClient());
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new Error('Failed to initialize payments resource: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
|
20
|
+
}
|
|
21
|
+
}, []);
|
|
22
|
+
const { startPolling } = usePaymentPolling();
|
|
23
|
+
// Refs to prevent multiple simultaneous calls
|
|
24
|
+
const isPollingRef = useRef(false);
|
|
25
|
+
const pollIntervalRef = useRef(null);
|
|
26
|
+
const attemptsRef = useRef(0);
|
|
27
|
+
const isPageLoadedRef = useRef(false);
|
|
28
|
+
// Check if page is fully loaded
|
|
29
|
+
const checkPageLoaded = useCallback(() => {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
// If already loaded, resolve immediately
|
|
32
|
+
if (document.readyState === 'complete') {
|
|
33
|
+
isPageLoadedRef.current = true;
|
|
34
|
+
resolve();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Wait for load event
|
|
38
|
+
const handleLoad = () => {
|
|
39
|
+
isPageLoadedRef.current = true;
|
|
40
|
+
window.removeEventListener('load', handleLoad);
|
|
41
|
+
resolve();
|
|
42
|
+
};
|
|
43
|
+
window.addEventListener('load', handleLoad);
|
|
44
|
+
// Fallback: resolve after a short delay if load event doesn't fire
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
if (!isPageLoadedRef.current) {
|
|
47
|
+
isPageLoadedRef.current = true;
|
|
48
|
+
window.removeEventListener('load', handleLoad);
|
|
49
|
+
resolve();
|
|
50
|
+
}
|
|
51
|
+
}, 1000);
|
|
52
|
+
});
|
|
53
|
+
}, []);
|
|
54
|
+
// Cleanup function
|
|
55
|
+
const cleanup = useCallback(() => {
|
|
56
|
+
if (pollIntervalRef.current) {
|
|
57
|
+
clearInterval(pollIntervalRef.current);
|
|
58
|
+
pollIntervalRef.current = null;
|
|
59
|
+
}
|
|
60
|
+
isPollingRef.current = false;
|
|
61
|
+
attemptsRef.current = 0;
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
// Clean up query parameters
|
|
64
|
+
if (typeof window !== 'undefined') {
|
|
65
|
+
const newUrl = window.location.pathname;
|
|
66
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
67
|
+
}
|
|
68
|
+
}, []);
|
|
69
|
+
// Start retrieve polling
|
|
70
|
+
const startRetrievePolling = useCallback(async (paymentId) => {
|
|
71
|
+
// Prevent multiple simultaneous calls
|
|
72
|
+
if (isPollingRef.current) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Wait for page to be fully loaded
|
|
76
|
+
await checkPageLoaded();
|
|
77
|
+
// Double-check after page load
|
|
78
|
+
if (isPollingRef.current) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
isPollingRef.current = true;
|
|
82
|
+
setIsLoading(true);
|
|
83
|
+
attemptsRef.current = 0;
|
|
84
|
+
const maxAttempts = 10;
|
|
85
|
+
const pollInterval = 3000; // 3 seconds
|
|
86
|
+
const checkRetrieve = async () => {
|
|
87
|
+
try {
|
|
88
|
+
attemptsRef.current++;
|
|
89
|
+
const result = await paymentsResource.retrievePayment(paymentId);
|
|
90
|
+
const status = result?.retrieveResult?.status || result?.status;
|
|
91
|
+
// Fetch payment to check for requireAction
|
|
92
|
+
const payment = await paymentsResource.getPaymentStatus(paymentId);
|
|
93
|
+
// Check if payment requires action
|
|
94
|
+
if (payment?.requireAction !== 'none' && payment?.requireActionData && !payment?.requireActionData?.processed) {
|
|
95
|
+
cleanup();
|
|
96
|
+
// Payment requires new action - would need to be handled by parent component
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Check if payment is succeeded
|
|
100
|
+
if (result?.retrieveResult?.success && status === 'succeeded') {
|
|
101
|
+
cleanup();
|
|
102
|
+
// Start regular polling to handle UI updates
|
|
103
|
+
startPolling(paymentId, {
|
|
104
|
+
onSuccess: () => {
|
|
105
|
+
// Payment succeeded after retrieve
|
|
106
|
+
},
|
|
107
|
+
onFailure: (errorMsg) => {
|
|
108
|
+
setError(errorMsg);
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Check if payment is declined or error
|
|
114
|
+
if (status === 'declined' || status === 'error') {
|
|
115
|
+
cleanup();
|
|
116
|
+
const errorMsg = result?.retrieveResult?.message || result?.message || 'Payment failed';
|
|
117
|
+
setError(errorMsg);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// If still pending and haven't reached max attempts, continue polling
|
|
121
|
+
if (attemptsRef.current < maxAttempts && status === 'pending') {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Max attempts reached or unknown status
|
|
125
|
+
if (attemptsRef.current >= maxAttempts) {
|
|
126
|
+
cleanup();
|
|
127
|
+
const errorMsg = 'Payment status check timed out. Please check your payment status manually.';
|
|
128
|
+
setError(errorMsg);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// On error, continue polling unless we've reached max attempts
|
|
133
|
+
if (attemptsRef.current >= maxAttempts) {
|
|
134
|
+
cleanup();
|
|
135
|
+
const errorMsg = error instanceof Error ? error.message : 'Failed to retrieve payment status';
|
|
136
|
+
setError(errorMsg);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
// Initial check
|
|
141
|
+
await checkRetrieve();
|
|
142
|
+
// Set up polling interval
|
|
143
|
+
pollIntervalRef.current = setInterval(async () => {
|
|
144
|
+
if (attemptsRef.current >= maxAttempts || !isPollingRef.current) {
|
|
145
|
+
cleanup();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
await checkRetrieve();
|
|
149
|
+
}, pollInterval);
|
|
150
|
+
}, [paymentsResource, startPolling, cleanup, checkPageLoaded]);
|
|
151
|
+
// Cleanup on unmount
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
return () => {
|
|
154
|
+
cleanup();
|
|
155
|
+
};
|
|
156
|
+
}, [cleanup]);
|
|
157
|
+
// Handle retrieve mode from URL query parameters
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (typeof window === 'undefined')
|
|
160
|
+
return;
|
|
161
|
+
// Check for payment retrieve mode in URL
|
|
162
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
163
|
+
const paymentMode = urlParams.get('mode');
|
|
164
|
+
const paymentIdFromUrl = urlParams.get('paymentId');
|
|
165
|
+
if (paymentMode === 'retrieve' && paymentIdFromUrl) {
|
|
166
|
+
void startRetrievePolling(paymentIdFromUrl);
|
|
167
|
+
}
|
|
168
|
+
}, [startRetrievePolling]);
|
|
169
|
+
return {
|
|
170
|
+
startRetrievePolling,
|
|
171
|
+
isLoading,
|
|
172
|
+
error,
|
|
173
|
+
isPolling: isPollingRef.current,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePixelTracking Hook & Provider
|
|
3
|
+
*
|
|
4
|
+
* SDK-level pixel tracking based on runtime stepConfig.pixels injected
|
|
5
|
+
* by the CRM. This mirrors the CMS pixel context pattern but uses the
|
|
6
|
+
* funnel step configuration as the source of truth instead of store
|
|
7
|
+
* integrations.
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
export type StandardPixelEvent = 'PageView' | 'ViewContent' | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'Purchase' | 'Lead' | 'CompleteRegistration' | 'Conversion';
|
|
11
|
+
export interface PixelTrackingContextValue {
|
|
12
|
+
track: (eventName: StandardPixelEvent, parameters?: Record<string, any>) => void;
|
|
13
|
+
pixelsInitialized: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Provider that initializes pixels based on stepConfig.pixels
|
|
17
|
+
* and exposes a simple track(event, params) API.
|
|
18
|
+
*/
|
|
19
|
+
export declare function PixelTrackingProvider({ children }: {
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Hook to access SDK pixel tracking.
|
|
24
|
+
* Must be used within TagadaProvider (which wraps PixelTrackingProvider).
|
|
25
|
+
*/
|
|
26
|
+
export declare function usePixelTracking(): PixelTrackingContextValue;
|
|
27
|
+
declare global {
|
|
28
|
+
interface FacebookPixelFunction {
|
|
29
|
+
(...args: unknown[]): void;
|
|
30
|
+
callMethod?: (...args: unknown[]) => void;
|
|
31
|
+
queue?: unknown[];
|
|
32
|
+
loaded?: boolean;
|
|
33
|
+
version?: string;
|
|
34
|
+
}
|
|
35
|
+
interface TikTokPixelFunction {
|
|
36
|
+
(...args: unknown[]): void;
|
|
37
|
+
methods?: string[];
|
|
38
|
+
setAndDefer?: (target: TikTokPixelFunction, method: string) => void;
|
|
39
|
+
load?: (pixelId: string) => void;
|
|
40
|
+
page?: () => void;
|
|
41
|
+
track?: (eventName: string, params: Record<string, unknown>) => void;
|
|
42
|
+
queue?: unknown[];
|
|
43
|
+
}
|
|
44
|
+
interface SnapchatPixelFunction {
|
|
45
|
+
(...args: unknown[]): void;
|
|
46
|
+
handleRequest?: (...args: unknown[]) => void;
|
|
47
|
+
queue?: unknown[];
|
|
48
|
+
}
|
|
49
|
+
interface Window {
|
|
50
|
+
fbq?: FacebookPixelFunction;
|
|
51
|
+
_fbq?: FacebookPixelFunction;
|
|
52
|
+
ttq?: TikTokPixelFunction;
|
|
53
|
+
snaptr?: SnapchatPixelFunction;
|
|
54
|
+
dataLayer?: any[];
|
|
55
|
+
}
|
|
56
|
+
}
|