@tagadapay/plugin-sdk 3.1.22 → 3.1.25
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/build-cdn.js +274 -6
- package/dist/external-tracker.js +476 -6774
- package/dist/external-tracker.min.js +2 -25
- package/dist/external-tracker.min.js.map +4 -4
- package/dist/react/config/payment.d.ts +14 -4
- package/dist/react/config/payment.js +47 -9
- package/dist/react/hooks/useCheckout.d.ts +3 -0
- package/dist/react/hooks/useCheckout.js +11 -3
- package/dist/react/hooks/usePluginConfig.js +9 -10
- package/dist/react/providers/TagadaProvider.js +1 -1
- package/dist/tagada-react-sdk-minimal.min.js +36 -0
- package/dist/tagada-react-sdk-minimal.min.js.map +7 -0
- package/dist/tagada-react-sdk.js +37988 -0
- package/dist/tagada-react-sdk.min.js +78 -0
- package/dist/tagada-react-sdk.min.js.map +7 -0
- package/dist/tagada-sdk.js +7847 -6420
- package/dist/tagada-sdk.min.js +4 -22
- package/dist/tagada-sdk.min.js.map +4 -4
- package/dist/v2/cdn-react-minimal.d.ts +23 -0
- package/dist/v2/cdn-react-minimal.js +26 -0
- package/dist/v2/core/client.js +2 -1
- package/dist/v2/core/config/environment.js +2 -1
- package/dist/v2/core/funnelClient.d.ts +106 -10
- package/dist/v2/core/funnelClient.js +122 -28
- package/dist/v2/core/index.d.ts +0 -1
- package/dist/v2/core/index.js +0 -2
- package/dist/v2/core/isoData.d.ts +4 -4
- package/dist/v2/core/isoData.js +7 -7
- package/dist/v2/core/pixelMapping.js +64 -26
- package/dist/v2/core/resources/apiClient.d.ts +18 -14
- package/dist/v2/core/resources/apiClient.js +151 -109
- package/dist/v2/core/resources/checkout.d.ts +10 -0
- package/dist/v2/core/resources/checkout.js +6 -0
- package/dist/v2/core/resources/expressPaymentMethods.d.ts +1 -0
- package/dist/v2/core/resources/index.d.ts +1 -1
- package/dist/v2/core/resources/index.js +1 -1
- package/dist/v2/core/resources/offers.js +4 -4
- package/dist/v2/core/resources/payments.d.ts +8 -2
- package/dist/v2/core/resources/payments.js +1 -0
- package/dist/v2/core/resources/postPurchases.d.ts +17 -0
- package/dist/v2/core/resources/postPurchases.js +20 -0
- package/dist/v2/core/utils/currency.d.ts +3 -0
- package/dist/v2/core/utils/currency.js +40 -2
- package/dist/v2/core/utils/deviceInfo.d.ts +1 -10
- package/dist/v2/core/utils/deviceInfo.js +153 -76
- package/dist/v2/core/utils/order.d.ts +2 -0
- package/dist/v2/core/utils/pluginConfig.js +18 -22
- package/dist/v2/core/utils/previewMode.js +12 -0
- package/dist/v2/index.d.ts +4 -3
- package/dist/v2/index.js +4 -2
- package/dist/v2/react/components/ApplePayButton.js +39 -16
- package/dist/v2/react/components/FunnelScriptInjector.js +145 -77
- package/dist/v2/react/components/StripeExpressButton.d.ts +13 -0
- package/dist/v2/react/components/StripeExpressButton.js +170 -0
- package/dist/v2/react/components/WhopCheckout.js +7 -1
- package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.js +1 -0
- package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.js +21 -3
- package/dist/v2/react/hooks/useApiQuery.d.ts +1 -1
- package/dist/v2/react/hooks/useApiQuery.js +1 -1
- package/dist/v2/react/hooks/useApplePayCheckout.js +8 -8
- package/dist/v2/react/hooks/useCheckoutQuery.d.ts +10 -0
- package/dist/v2/react/hooks/useCheckoutQuery.js +27 -15
- package/dist/v2/react/hooks/useFunnel.d.ts +15 -4
- package/dist/v2/react/hooks/useFunnel.js +8 -4
- package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +2 -0
- package/dist/v2/react/hooks/useGoogleAutocomplete.js +29 -15
- package/dist/v2/react/hooks/useISOData.d.ts +2 -5
- package/dist/v2/react/hooks/useISOData.js +25 -26
- package/dist/v2/react/hooks/usePaymentPolling.d.ts +2 -2
- package/dist/v2/react/hooks/usePixelTracking.js +151 -70
- package/dist/v2/react/hooks/usePostPurchasesQuery.js +34 -2
- package/dist/v2/react/hooks/usePreviewOffer.js +1 -1
- package/dist/v2/react/hooks/useRemappableParams.d.ts +2 -6
- package/dist/v2/react/hooks/useRemappableParams.js +23 -23
- package/dist/v2/react/hooks/useSetPaymentMethod.d.ts +16 -0
- package/dist/v2/react/hooks/useSetPaymentMethod.js +33 -0
- package/dist/v2/react/hooks/useStepConfig.d.ts +23 -6
- package/dist/v2/react/hooks/useStepConfig.js +14 -7
- package/dist/v2/react/hooks/useTranslation.js +23 -8
- package/dist/v2/react/index.d.ts +8 -1
- package/dist/v2/react/index.js +3 -0
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +8 -0
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +106 -10
- package/dist/v2/react/providers/TagadaProvider.js +5 -5
- package/dist/v2/standalone/index.d.ts +21 -3
- package/dist/v2/standalone/index.js +25 -3
- package/dist/v2/standalone/payment-service.d.ts +134 -0
- package/dist/v2/standalone/payment-service.js +929 -0
- package/package.json +4 -2
|
@@ -8,9 +8,9 @@ export interface Payment {
|
|
|
8
8
|
id: string;
|
|
9
9
|
status: string;
|
|
10
10
|
subStatus: string;
|
|
11
|
-
requireAction: 'none' | 'redirect' | 'redirect_to_payment' | 'error' | 'radar';
|
|
11
|
+
requireAction: 'none' | 'redirect' | 'redirect_to_payment' | 'error' | 'radar' | 'stripe_express_checkout';
|
|
12
12
|
requireActionData?: {
|
|
13
|
-
type: 'redirect' | 'redirect_to_payment' | 'threeds_auth' | 'processor_auth' | 'error' | 'stripe_radar' | 'finix_radar' | 'radar' | 'kesspay_auth' | 'trustflow_auth' | 'mastercard_auth';
|
|
13
|
+
type: 'redirect' | 'redirect_to_payment' | 'threeds_auth' | 'processor_auth' | 'error' | 'stripe_radar' | 'finix_radar' | 'radar' | 'kesspay_auth' | 'trustflow_auth' | 'mastercard_auth' | 'stripe_express_checkout';
|
|
14
14
|
url?: string;
|
|
15
15
|
processed: boolean;
|
|
16
16
|
processorId?: string;
|
|
@@ -32,6 +32,10 @@ export interface Payment {
|
|
|
32
32
|
orderId?: string;
|
|
33
33
|
publishableKey?: string;
|
|
34
34
|
};
|
|
35
|
+
stripeExpressCheckout?: {
|
|
36
|
+
clientSecret: string;
|
|
37
|
+
publishableKey?: string;
|
|
38
|
+
};
|
|
35
39
|
provider?: string;
|
|
36
40
|
isTest?: boolean;
|
|
37
41
|
};
|
|
@@ -242,6 +246,7 @@ export declare class PaymentsResource {
|
|
|
242
246
|
paymentFlowId?: string;
|
|
243
247
|
processorId?: string;
|
|
244
248
|
paymentMethod?: string;
|
|
249
|
+
isExpress?: boolean;
|
|
245
250
|
}): Promise<PaymentResponse>;
|
|
246
251
|
/**
|
|
247
252
|
* Get card payment instruments for customer
|
|
@@ -274,6 +279,7 @@ export declare class PaymentsResource {
|
|
|
274
279
|
error?: string;
|
|
275
280
|
}>;
|
|
276
281
|
saveRadarSession(data: {
|
|
282
|
+
paymentId?: string;
|
|
277
283
|
orderId?: string;
|
|
278
284
|
checkoutSessionId?: string;
|
|
279
285
|
finixRadarSessionId?: string;
|
|
@@ -147,6 +147,7 @@ export class PaymentsResource {
|
|
|
147
147
|
...(options.paymentFlowId && { paymentFlowId: options.paymentFlowId }),
|
|
148
148
|
...(options.processorId && { processorId: options.processorId }),
|
|
149
149
|
...(options.paymentMethod && { paymentMethod: options.paymentMethod }),
|
|
150
|
+
...(options.isExpress && { isExpress: options.isExpress }),
|
|
150
151
|
};
|
|
151
152
|
console.log('[PaymentsResource] Request body being sent:', JSON.stringify(requestBody, null, 2));
|
|
152
153
|
const response = await this.apiClient.post('/api/public/v1/checkout/pay-v2', requestBody);
|
|
@@ -110,6 +110,7 @@ export interface CheckoutSessionState {
|
|
|
110
110
|
selectedVariants: Record<string, string>;
|
|
111
111
|
loadingVariants: Record<string, boolean>;
|
|
112
112
|
isUpdatingSummary: boolean;
|
|
113
|
+
isWhop?: boolean;
|
|
113
114
|
}
|
|
114
115
|
export declare class PostPurchasesResource {
|
|
115
116
|
private apiClient;
|
|
@@ -172,6 +173,22 @@ export declare class PostPurchasesResource {
|
|
|
172
173
|
* Get order summary for a checkout session
|
|
173
174
|
*/
|
|
174
175
|
getOrderSummary(sessionId: string, includeVariantOptions?: boolean): Promise<any>;
|
|
176
|
+
/**
|
|
177
|
+
* Get payment methods for a checkout session
|
|
178
|
+
*/
|
|
179
|
+
getPaymentMethods(checkoutSessionId: string): Promise<{
|
|
180
|
+
type: string;
|
|
181
|
+
}[]>;
|
|
182
|
+
/**
|
|
183
|
+
* Charge a Whop post-purchase using the stored payment method from the original order
|
|
184
|
+
*/
|
|
185
|
+
chargeWhopPostPurchase(params: {
|
|
186
|
+
checkoutSessionId: string;
|
|
187
|
+
orderId: string;
|
|
188
|
+
storeId: string;
|
|
189
|
+
}): Promise<{
|
|
190
|
+
checkoutRequestId: string;
|
|
191
|
+
}>;
|
|
175
192
|
/**
|
|
176
193
|
* Update line items for a checkout session
|
|
177
194
|
*/
|
|
@@ -108,6 +108,26 @@ export class PostPurchasesResource {
|
|
|
108
108
|
includeVariantOptions,
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Get payment methods for a checkout session
|
|
113
|
+
*/
|
|
114
|
+
async getPaymentMethods(checkoutSessionId) {
|
|
115
|
+
return this.apiClient.get(`/api/v1/payment-methods?checkoutSessionId=${encodeURIComponent(checkoutSessionId)}`);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Charge a Whop post-purchase using the stored payment method from the original order
|
|
119
|
+
*/
|
|
120
|
+
async chargeWhopPostPurchase(params) {
|
|
121
|
+
return this.apiClient.post(`/api/v1/checkout-sessions/${params.checkoutSessionId}/whop-charge-payment`, {
|
|
122
|
+
checkoutSessionId: params.checkoutSessionId,
|
|
123
|
+
orderId: params.orderId,
|
|
124
|
+
storeId: params.storeId,
|
|
125
|
+
metadata: {
|
|
126
|
+
comingFromPostPurchase: true,
|
|
127
|
+
originalOrderId: params.orderId,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
111
131
|
/**
|
|
112
132
|
* Update line items for a checkout session
|
|
113
133
|
*/
|
|
@@ -7,6 +7,8 @@ export interface Currency {
|
|
|
7
7
|
symbol: string;
|
|
8
8
|
name: string;
|
|
9
9
|
decimalPlaces: number;
|
|
10
|
+
/** True when the currency was explicitly set via URL param or persisted storage (not a SDK/store default) */
|
|
11
|
+
isExplicit: boolean;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* Format money amount from minor units (cents) to a formatted string
|
|
@@ -27,6 +29,7 @@ export declare class CurrencyUtils {
|
|
|
27
29
|
* Get currency from context or fallback to default
|
|
28
30
|
*/
|
|
29
31
|
static getCurrency(context: any, defaultCurrency?: string): Currency;
|
|
32
|
+
private static getCookieValue;
|
|
30
33
|
/**
|
|
31
34
|
* Get currency symbol
|
|
32
35
|
*/
|
|
@@ -47,9 +47,25 @@ export class CurrencyUtils {
|
|
|
47
47
|
* Get currency from context or fallback to default
|
|
48
48
|
*/
|
|
49
49
|
static getCurrency(context, defaultCurrency = 'USD') {
|
|
50
|
-
// Handle case where context.currency might be a Currency object or string
|
|
51
50
|
let currencyCode;
|
|
52
|
-
|
|
51
|
+
let isExplicit = false;
|
|
52
|
+
// 1. URL ?currency= param takes highest priority (set by CRM preview, storefront links, or currency selector)
|
|
53
|
+
const urlCurrency = typeof window !== 'undefined'
|
|
54
|
+
? new URLSearchParams(window.location.search).get('currency')
|
|
55
|
+
: null;
|
|
56
|
+
// 2. Persisted tgd_currency from storage/cookie (survives navigation between funnel steps)
|
|
57
|
+
const storedCurrency = typeof window !== 'undefined'
|
|
58
|
+
? (localStorage.getItem('tgd_currency') || CurrencyUtils.getCookieValue('tgd_currency'))
|
|
59
|
+
: null;
|
|
60
|
+
if (urlCurrency) {
|
|
61
|
+
currencyCode = urlCurrency.toUpperCase();
|
|
62
|
+
isExplicit = true;
|
|
63
|
+
}
|
|
64
|
+
else if (storedCurrency) {
|
|
65
|
+
currencyCode = storedCurrency.toUpperCase();
|
|
66
|
+
isExplicit = true;
|
|
67
|
+
}
|
|
68
|
+
else if (typeof context?.currency === 'string') {
|
|
53
69
|
currencyCode = context.currency;
|
|
54
70
|
}
|
|
55
71
|
else if (context?.currency?.code) {
|
|
@@ -61,13 +77,35 @@ export class CurrencyUtils {
|
|
|
61
77
|
else {
|
|
62
78
|
currencyCode = defaultCurrency;
|
|
63
79
|
}
|
|
80
|
+
// Validate against store's presentment currencies when available.
|
|
81
|
+
// This catches both explicit overrides (URL/storage) and fallback values that
|
|
82
|
+
// reference a currency the store doesn't support.
|
|
83
|
+
const presentment = context?.store?.presentmentCurrencies;
|
|
84
|
+
if (presentment?.length && !presentment.includes(currencyCode)) {
|
|
85
|
+
console.warn(`[CurrencyUtils] Currency "${currencyCode}" is not in store presentmentCurrencies [${presentment.join(', ')}]. Falling back to ${presentment[0]}.`);
|
|
86
|
+
currencyCode = presentment[0];
|
|
87
|
+
// Update persisted storage so subsequent renders don't keep requesting the unsupported currency
|
|
88
|
+
if (isExplicit && typeof window !== 'undefined') {
|
|
89
|
+
try {
|
|
90
|
+
localStorage.setItem('tgd_currency', currencyCode);
|
|
91
|
+
}
|
|
92
|
+
catch { }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
64
95
|
return {
|
|
65
96
|
code: currencyCode,
|
|
66
97
|
symbol: this.getCurrencySymbol(currencyCode),
|
|
67
98
|
name: this.getCurrencyName(currencyCode),
|
|
68
99
|
decimalPlaces: this.getDecimalPlaces(currencyCode),
|
|
100
|
+
isExplicit,
|
|
69
101
|
};
|
|
70
102
|
}
|
|
103
|
+
static getCookieValue(name) {
|
|
104
|
+
if (typeof document === 'undefined')
|
|
105
|
+
return null;
|
|
106
|
+
const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
|
|
107
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
108
|
+
}
|
|
71
109
|
/**
|
|
72
110
|
* Get currency symbol
|
|
73
111
|
*/
|
|
@@ -5,7 +5,6 @@ export interface DeviceInfo {
|
|
|
5
5
|
major: string;
|
|
6
6
|
name: string;
|
|
7
7
|
version: string;
|
|
8
|
-
type?: string;
|
|
9
8
|
};
|
|
10
9
|
os: {
|
|
11
10
|
name: string;
|
|
@@ -36,21 +35,13 @@ export interface DeviceInfo {
|
|
|
36
35
|
isAppleSilicon: boolean;
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Get browser locale
|
|
41
|
-
*/
|
|
42
38
|
export declare function getBrowserLocale(): string;
|
|
43
|
-
/**
|
|
44
|
-
* Collect all device information using UAParser
|
|
45
|
-
*/
|
|
46
39
|
export declare function collectDeviceInfo(): DeviceInfo;
|
|
47
|
-
/**
|
|
48
|
-
* Get URL parameters for session initialization
|
|
49
|
-
*/
|
|
50
40
|
export declare function getUrlParams(): {
|
|
51
41
|
locale?: string;
|
|
52
42
|
currency?: string;
|
|
53
43
|
utmSource?: string;
|
|
54
44
|
utmMedium?: string;
|
|
55
45
|
utmCampaign?: string;
|
|
46
|
+
gclid?: string;
|
|
56
47
|
};
|
|
@@ -1,44 +1,159 @@
|
|
|
1
|
-
import { UAParser } from '@ua-parser-js/pro-enterprise';
|
|
2
|
-
import { isBot, isChromeFamily, isStandalonePWA, isAppleSilicon, } from '@ua-parser-js/pro-enterprise/helpers';
|
|
3
|
-
/**
|
|
4
|
-
* Get screen resolution
|
|
5
|
-
*/
|
|
6
1
|
function getScreenResolution() {
|
|
7
|
-
return {
|
|
8
|
-
width: window.screen.width,
|
|
9
|
-
height: window.screen.height,
|
|
10
|
-
};
|
|
2
|
+
return { width: window.screen.width, height: window.screen.height };
|
|
11
3
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Get timezone
|
|
14
|
-
*/
|
|
15
4
|
function getTimeZone() {
|
|
16
5
|
try {
|
|
17
6
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
18
7
|
}
|
|
19
|
-
catch
|
|
20
|
-
console.error('Failed to get timezone:', error);
|
|
8
|
+
catch {
|
|
21
9
|
return 'UTC';
|
|
22
10
|
}
|
|
23
11
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Get browser locale
|
|
26
|
-
*/
|
|
27
12
|
export function getBrowserLocale() {
|
|
28
13
|
try {
|
|
29
14
|
return navigator.language || 'en-US';
|
|
30
15
|
}
|
|
31
|
-
catch
|
|
32
|
-
console.error('Failed to get browser locale:', error);
|
|
16
|
+
catch {
|
|
33
17
|
return 'en-US';
|
|
34
18
|
}
|
|
35
19
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Lightweight UA parsing — no third-party library needed
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const UA = typeof navigator !== 'undefined' ? navigator.userAgent : '';
|
|
24
|
+
/** Extract first match's groups from a UA string */
|
|
25
|
+
function match(ua, ...patterns) {
|
|
26
|
+
for (const p of patterns) {
|
|
27
|
+
const m = ua.match(p);
|
|
28
|
+
if (m)
|
|
29
|
+
return m;
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function parseBrowser(ua) {
|
|
34
|
+
// Order matters — more specific first
|
|
35
|
+
const tests = [
|
|
36
|
+
[/EdgA?\/([\d.]+)/i, 'Edge'],
|
|
37
|
+
[/OPR\/([\d.]+)/i, 'Opera'],
|
|
38
|
+
[/Brave\/([\d.]+)/i, 'Brave'],
|
|
39
|
+
[/Vivaldi\/([\d.]+)/i, 'Vivaldi'],
|
|
40
|
+
[/SamsungBrowser\/([\d.]+)/i, 'Samsung Internet'],
|
|
41
|
+
[/UCBrowser\/([\d.]+)/i, 'UC Browser'],
|
|
42
|
+
[/Firefox\/([\d.]+)/i, 'Firefox'],
|
|
43
|
+
[/CriOS\/([\d.]+)/i, 'Chrome'], // Chrome on iOS
|
|
44
|
+
[/FxiOS\/([\d.]+)/i, 'Firefox'], // Firefox on iOS
|
|
45
|
+
[/Chrome\/([\d.]+)/i, 'Chrome'],
|
|
46
|
+
[/Version\/([\d.]+).*Safari/i, 'Safari'],
|
|
47
|
+
[/Safari\/([\d.]+)/i, 'Safari'],
|
|
48
|
+
];
|
|
49
|
+
for (const [re, name] of tests) {
|
|
50
|
+
const m = ua.match(re);
|
|
51
|
+
if (m) {
|
|
52
|
+
const version = m[1] || '';
|
|
53
|
+
return { name, version, major: version.split('.')[0] || '' };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { name: '', version: '', major: '' };
|
|
57
|
+
}
|
|
58
|
+
function parseOS(ua) {
|
|
59
|
+
const m = match(ua, /Windows NT ([\d.]+)/i) ||
|
|
60
|
+
match(ua, /Mac OS X ([\d_.]+)/i) ||
|
|
61
|
+
match(ua, /Android ([\d.]+)/i) ||
|
|
62
|
+
match(ua, /iPhone OS ([\d_]+)/i) ||
|
|
63
|
+
match(ua, /iPad.*OS ([\d_]+)/i) ||
|
|
64
|
+
match(ua, /CrOS[\w ]*\/([\d.]+)/i) ||
|
|
65
|
+
match(ua, /Linux/i);
|
|
66
|
+
if (!m)
|
|
67
|
+
return { name: '', version: '' };
|
|
68
|
+
const raw = m[0];
|
|
69
|
+
const version = (m[1] || '').replace(/_/g, '.');
|
|
70
|
+
if (/Windows/i.test(raw)) {
|
|
71
|
+
const ntMap = {
|
|
72
|
+
'10.0': '10', '6.3': '8.1', '6.2': '8', '6.1': '7', '6.0': 'Vista', '5.1': 'XP',
|
|
73
|
+
};
|
|
74
|
+
return { name: 'Windows', version: ntMap[version] || version };
|
|
75
|
+
}
|
|
76
|
+
if (/Mac OS X/i.test(raw))
|
|
77
|
+
return { name: 'macOS', version };
|
|
78
|
+
if (/Android/i.test(raw))
|
|
79
|
+
return { name: 'Android', version };
|
|
80
|
+
if (/iPhone|iPad/i.test(raw))
|
|
81
|
+
return { name: 'iOS', version };
|
|
82
|
+
if (/CrOS/i.test(raw))
|
|
83
|
+
return { name: 'Chrome OS', version };
|
|
84
|
+
if (/Linux/i.test(raw))
|
|
85
|
+
return { name: 'Linux', version: '' };
|
|
86
|
+
return { name: '', version: '' };
|
|
87
|
+
}
|
|
88
|
+
function parseDevice(ua) {
|
|
89
|
+
if (/iPad/i.test(ua))
|
|
90
|
+
return { type: 'tablet', vendor: 'Apple', model: 'iPad' };
|
|
91
|
+
if (/iPhone/i.test(ua))
|
|
92
|
+
return { type: 'mobile', vendor: 'Apple', model: 'iPhone' };
|
|
93
|
+
if (/iPod/i.test(ua))
|
|
94
|
+
return { type: 'mobile', vendor: 'Apple', model: 'iPod' };
|
|
95
|
+
if (/Android/i.test(ua)) {
|
|
96
|
+
const m = ua.match(/Android[\s\d.]+;\s*([^)]+?)(?:\s+Build)/i);
|
|
97
|
+
const mobile = /Mobile/i.test(ua);
|
|
98
|
+
return { type: mobile ? 'mobile' : 'tablet', model: m?.[1]?.trim() };
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
function parseEngine(ua) {
|
|
103
|
+
const m = match(ua, /AppleWebKit\/([\d.]+)/i) ||
|
|
104
|
+
match(ua, /Gecko\/([\d.]+)/i) ||
|
|
105
|
+
match(ua, /Trident\/([\d.]+)/i) ||
|
|
106
|
+
match(ua, /Presto\/([\d.]+)/i);
|
|
107
|
+
if (!m)
|
|
108
|
+
return { name: '', version: '' };
|
|
109
|
+
const raw = m[0];
|
|
110
|
+
const version = m[1] || '';
|
|
111
|
+
if (/AppleWebKit/i.test(raw))
|
|
112
|
+
return { name: 'WebKit', version };
|
|
113
|
+
if (/Gecko/i.test(raw))
|
|
114
|
+
return { name: 'Gecko', version };
|
|
115
|
+
if (/Trident/i.test(raw))
|
|
116
|
+
return { name: 'Trident', version };
|
|
117
|
+
if (/Presto/i.test(raw))
|
|
118
|
+
return { name: 'Presto', version };
|
|
119
|
+
return { name: '', version: '' };
|
|
120
|
+
}
|
|
121
|
+
function parseCPU(ua) {
|
|
122
|
+
if (/x86_64|x64|amd64|Win64/i.test(ua))
|
|
123
|
+
return { architecture: 'amd64' };
|
|
124
|
+
if (/ia32|x86/i.test(ua))
|
|
125
|
+
return { architecture: 'ia32' };
|
|
126
|
+
if (/aarch64|arm64/i.test(ua))
|
|
127
|
+
return { architecture: 'arm64' };
|
|
128
|
+
if (/arm/i.test(ua))
|
|
129
|
+
return { architecture: 'arm' };
|
|
130
|
+
return { architecture: '' };
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Flags
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
function detectIsBot() {
|
|
136
|
+
if (navigator.webdriver)
|
|
137
|
+
return true;
|
|
138
|
+
return /bot|crawl|spider|slurp|Googlebot|bingbot|yandex|baidu|duckduck|facebookexternalhit|Twitterbot|linkedinbot|embedly|quora|pinterest|redditbot|Slackbot|Discordbot|WhatsApp|TelegramBot|Applebot/i.test(UA);
|
|
139
|
+
}
|
|
140
|
+
function detectIsChromeFamily(browserName) {
|
|
141
|
+
return /Chrome|Chromium|Edge|Brave|Opera|Vivaldi|Arc/i.test(browserName);
|
|
142
|
+
}
|
|
143
|
+
function detectIsStandalonePWA() {
|
|
144
|
+
return window.matchMedia('(display-mode: standalone)').matches
|
|
145
|
+
|| navigator.standalone === true;
|
|
146
|
+
}
|
|
147
|
+
function detectIsAppleSilicon(osName) {
|
|
148
|
+
if (!/mac/i.test(osName))
|
|
149
|
+
return false;
|
|
150
|
+
return navigator.maxTouchPoints > 0;
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Main
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
39
155
|
export function collectDeviceInfo() {
|
|
40
156
|
if (typeof window === 'undefined') {
|
|
41
|
-
// Server-side fallback
|
|
42
157
|
return {
|
|
43
158
|
userAgent: {
|
|
44
159
|
name: '',
|
|
@@ -50,75 +165,36 @@ export function collectDeviceInfo() {
|
|
|
50
165
|
},
|
|
51
166
|
screenResolution: { width: 0, height: 0 },
|
|
52
167
|
timeZone: 'UTC',
|
|
53
|
-
flags: {
|
|
54
|
-
isBot: false,
|
|
55
|
-
isChromeFamily: false,
|
|
56
|
-
isStandalonePWA: false,
|
|
57
|
-
isAppleSilicon: false,
|
|
58
|
-
},
|
|
168
|
+
flags: { isBot: false, isChromeFamily: false, isStandalonePWA: false, isAppleSilicon: false },
|
|
59
169
|
};
|
|
60
170
|
}
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
171
|
+
const browser = parseBrowser(UA);
|
|
172
|
+
const os = parseOS(UA);
|
|
173
|
+
const device = parseDevice(UA);
|
|
174
|
+
const engine = parseEngine(UA);
|
|
175
|
+
const cpu = parseCPU(UA);
|
|
64
176
|
let flags;
|
|
65
177
|
try {
|
|
66
178
|
flags = {
|
|
67
|
-
isBot:
|
|
68
|
-
isChromeFamily:
|
|
69
|
-
isStandalonePWA:
|
|
70
|
-
isAppleSilicon:
|
|
179
|
+
isBot: detectIsBot(),
|
|
180
|
+
isChromeFamily: detectIsChromeFamily(browser.name),
|
|
181
|
+
isStandalonePWA: detectIsStandalonePWA(),
|
|
182
|
+
isAppleSilicon: detectIsAppleSilicon(os.name),
|
|
71
183
|
};
|
|
72
184
|
}
|
|
73
|
-
catch
|
|
74
|
-
|
|
75
|
-
flags = {
|
|
76
|
-
isBot: false,
|
|
77
|
-
isChromeFamily: false,
|
|
78
|
-
isStandalonePWA: false,
|
|
79
|
-
isAppleSilicon: false,
|
|
80
|
-
};
|
|
185
|
+
catch {
|
|
186
|
+
flags = { isBot: false, isChromeFamily: false, isStandalonePWA: false, isAppleSilicon: false };
|
|
81
187
|
}
|
|
82
188
|
return {
|
|
83
|
-
userAgent: {
|
|
84
|
-
name: result.ua,
|
|
85
|
-
browser: {
|
|
86
|
-
major: result.browser.major || '',
|
|
87
|
-
name: result.browser.name || '',
|
|
88
|
-
version: result.browser.version || '',
|
|
89
|
-
type: result.browser.type,
|
|
90
|
-
},
|
|
91
|
-
os: {
|
|
92
|
-
name: result.os.name || '',
|
|
93
|
-
version: result.os.version || '',
|
|
94
|
-
},
|
|
95
|
-
device: result.device.model || result.device.type || result.device.vendor
|
|
96
|
-
? {
|
|
97
|
-
model: result.device.model,
|
|
98
|
-
type: result.device.type,
|
|
99
|
-
vendor: result.device.vendor,
|
|
100
|
-
}
|
|
101
|
-
: undefined,
|
|
102
|
-
engine: {
|
|
103
|
-
name: result.engine.name || '',
|
|
104
|
-
version: result.engine.version || '',
|
|
105
|
-
},
|
|
106
|
-
cpu: {
|
|
107
|
-
architecture: result.cpu.architecture || '',
|
|
108
|
-
},
|
|
109
|
-
},
|
|
189
|
+
userAgent: { name: UA, browser, os, device, engine, cpu },
|
|
110
190
|
screenResolution: getScreenResolution(),
|
|
111
191
|
timeZone: getTimeZone(),
|
|
112
192
|
flags,
|
|
113
193
|
};
|
|
114
194
|
}
|
|
115
|
-
/**
|
|
116
|
-
* Get URL parameters for session initialization
|
|
117
|
-
*/
|
|
118
195
|
export function getUrlParams() {
|
|
119
|
-
if (typeof window === 'undefined')
|
|
196
|
+
if (typeof window === 'undefined')
|
|
120
197
|
return {};
|
|
121
|
-
}
|
|
122
198
|
const params = new URLSearchParams(window.location.search);
|
|
123
199
|
return {
|
|
124
200
|
locale: params.get('locale') || undefined,
|
|
@@ -126,5 +202,6 @@ export function getUrlParams() {
|
|
|
126
202
|
utmSource: params.get('utm_source') || undefined,
|
|
127
203
|
utmMedium: params.get('utm_medium') || undefined,
|
|
128
204
|
utmCampaign: params.get('utm_campaign') || undefined,
|
|
205
|
+
gclid: params.get('gclid') || undefined,
|
|
129
206
|
};
|
|
130
207
|
}
|
|
@@ -24,6 +24,7 @@ export interface OrderLineItem {
|
|
|
24
24
|
totalBillingCycles: number;
|
|
25
25
|
unitAmountAfterFirstCycle: number;
|
|
26
26
|
subscriptionSettings?: Record<string, unknown> | null;
|
|
27
|
+
properties?: Record<string, unknown>;
|
|
27
28
|
orderLineItemProduct: {
|
|
28
29
|
id: string;
|
|
29
30
|
name: string;
|
|
@@ -46,6 +47,7 @@ export interface OrderLineItem {
|
|
|
46
47
|
}
|
|
47
48
|
export interface Order {
|
|
48
49
|
id: string;
|
|
50
|
+
orderNumber: number;
|
|
49
51
|
storeId: string;
|
|
50
52
|
accountId: string;
|
|
51
53
|
createdAt: string;
|
|
@@ -159,6 +159,22 @@ const getMetaContent = (name) => {
|
|
|
159
159
|
const metaTag = document.querySelector(`meta[name="${name}"]`);
|
|
160
160
|
return metaTag?.getAttribute('content') || undefined;
|
|
161
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* Read config from window global (preferred) or fall back to x-plugin-config meta tag
|
|
164
|
+
* (retrocompat with old deployments that still inject the meta tag).
|
|
165
|
+
*/
|
|
166
|
+
const readWindowConfig = () => {
|
|
167
|
+
if (typeof window !== 'undefined' && window.__TAGADA_PLUGIN_CONFIG__) {
|
|
168
|
+
return window.__TAGADA_PLUGIN_CONFIG__;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const encoded = getMetaContent('x-plugin-config');
|
|
172
|
+
if (encoded)
|
|
173
|
+
return JSON.parse(decodeURIComponent(encoded));
|
|
174
|
+
}
|
|
175
|
+
catch { /* ignore */ }
|
|
176
|
+
return {};
|
|
177
|
+
};
|
|
162
178
|
/**
|
|
163
179
|
* Synchronously get plugin config from meta tags
|
|
164
180
|
* This is a lightweight sync alternative to loadPluginConfig
|
|
@@ -173,16 +189,7 @@ export function getPluginConfig() {
|
|
|
173
189
|
const storeId = getMetaContent('x-plugin-store-id');
|
|
174
190
|
const accountId = getMetaContent('x-plugin-account-id');
|
|
175
191
|
const basePath = getMetaContent('x-plugin-base-path') || '/';
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
const encodedConfig = getMetaContent('x-plugin-config');
|
|
179
|
-
if (encodedConfig) {
|
|
180
|
-
config = JSON.parse(decodeURIComponent(encodedConfig));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
console.warn('[TagadaSDK] Failed to parse plugin config from meta tag:', error);
|
|
185
|
-
}
|
|
192
|
+
const config = readWindowConfig();
|
|
186
193
|
return { storeId, accountId, basePath, config };
|
|
187
194
|
}
|
|
188
195
|
/**
|
|
@@ -206,18 +213,7 @@ const loadProductionConfig = async () => {
|
|
|
206
213
|
return null;
|
|
207
214
|
}
|
|
208
215
|
const basePath = getMetaContent('x-plugin-base-path') || '/';
|
|
209
|
-
|
|
210
|
-
let config = {};
|
|
211
|
-
try {
|
|
212
|
-
const encodedConfig = getMetaContent('x-plugin-config');
|
|
213
|
-
if (encodedConfig) {
|
|
214
|
-
const decodedConfig = decodeURIComponent(encodedConfig);
|
|
215
|
-
config = JSON.parse(decodedConfig);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
console.warn('⚠️ Failed to parse plugin config from meta tag:', error);
|
|
220
|
-
}
|
|
216
|
+
const config = readWindowConfig();
|
|
221
217
|
// Final validation
|
|
222
218
|
if (!accountId) {
|
|
223
219
|
console.warn('⚠️ Plugin config: Account ID not found in meta tags');
|
|
@@ -360,6 +360,18 @@ function persistSDKParamsFromURL() {
|
|
|
360
360
|
if (urlBaseUrl) {
|
|
361
361
|
setClientBaseUrl(urlBaseUrl);
|
|
362
362
|
}
|
|
363
|
+
// Persist currency if in URL (survives navigation between funnel steps)
|
|
364
|
+
const urlCurrency = urlParams.get('currency');
|
|
365
|
+
if (urlCurrency) {
|
|
366
|
+
setInStorage(STORAGE_KEYS.CURRENCY, urlCurrency.toUpperCase());
|
|
367
|
+
setInCookie(STORAGE_KEYS.CURRENCY, urlCurrency.toUpperCase(), 86400);
|
|
368
|
+
}
|
|
369
|
+
// Persist locale if in URL
|
|
370
|
+
const urlLocale = urlParams.get('locale');
|
|
371
|
+
if (urlLocale) {
|
|
372
|
+
setInStorage(STORAGE_KEYS.LOCALE, urlLocale);
|
|
373
|
+
setInCookie(STORAGE_KEYS.LOCALE, urlLocale, 86400);
|
|
374
|
+
}
|
|
363
375
|
}
|
|
364
376
|
/**
|
|
365
377
|
* Set funnel tracking mode in storage for persistence
|
package/dist/v2/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export * from './core/utils/pluginConfig';
|
|
|
13
13
|
export * from './core/utils/previewMode';
|
|
14
14
|
export { injectPreviewModeIndicator, isIndicatorInjected, removePreviewModeIndicator } from './core/utils/previewModeIndicator';
|
|
15
15
|
export * from './core/utils/products';
|
|
16
|
-
export { getAssignedPaymentFlowId, getAssignedScripts, getAssignedStaticResources, getAssignedStepConfig, getLocalFunnelConfig, loadLocalFunnelConfig } from './core/funnelClient';
|
|
17
|
-
export type { LocalFunnelConfig, PixelsConfig, RuntimeStepConfig } from './core/funnelClient';
|
|
16
|
+
export { getAssignedPaymentFlowId, getAssignedScripts, getAssignedStaticResources, getAssignedResources, getAssignedStepConfig, getAssignedOrderBumpOfferIds, getAssignedUpsellOfferIds, getLocalFunnelConfig, getEnabledMethods, getExpressMethods, getExpressMethodsByProcessor, findMethod, isMethodEnabled, loadLocalFunnelConfig } from './core/funnelClient';
|
|
17
|
+
export type { LocalFunnelConfig, PaymentMethodConfig, PaymentSetupConfig, PaymentSetupMethod, PixelsConfig, RuntimeStepConfig } from './core/funnelClient';
|
|
18
18
|
export * from './core/pathRemapping';
|
|
19
19
|
export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion } from './core/resources/checkout';
|
|
20
20
|
export type { Order, OrderLineItem } from './core/utils/order';
|
|
@@ -28,8 +28,9 @@ export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './co
|
|
|
28
28
|
export type { StoreConfig } from './core/resources/storeConfig';
|
|
29
29
|
export { FunnelActionType } from './core/resources/funnel';
|
|
30
30
|
export type { BackNavigationActionData, CartUpdatedActionData, DirectNavigationActionData, FormSubmitActionData, FunnelContextUpdateRequest, FunnelContextUpdateResponse, FunnelAction as FunnelEvent, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelNavigationAction, FunnelNavigationResult, NextAction, OfferAcceptedActionData, OfferDeclinedActionData, PaymentFailedActionData, PaymentSuccessActionData, SimpleFunnelContext } from './core/resources/funnel';
|
|
31
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, PreviewModeIndicator, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useApplePayCheckout, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useGooglePayCheckout, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePaymentRetrieve, usePixelTracking, usePluginConfig, usePostPurchases, usePreloadQuery, usePreviewOffer, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStepConfig, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers, WhopCheckout, useWhopPaymentPolling } from './react';
|
|
31
|
+
export { ApplePayButton, StripeExpressButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, PreviewModeIndicator, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useApplePayCheckout, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useGooglePayCheckout, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePaymentRetrieve, usePixelTracking, usePluginConfig, usePostPurchases, usePreloadQuery, usePreviewOffer, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStepConfig, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers, useSetPaymentMethod, WhopCheckout, useWhopPaymentPolling } from './react';
|
|
32
32
|
export type { DebugScript } from './react';
|
|
33
|
+
export type { PaymentMethodName } from './react';
|
|
33
34
|
export type { TranslateFunction, TranslationText, UseTranslationOptions, UseTranslationResult } from './react/hooks/useTranslation';
|
|
34
35
|
export type { FunnelContextValue } from './react/hooks/useFunnel';
|
|
35
36
|
export type { UseApplePayCheckoutOptions } from './react/hooks/useApplePayCheckout';
|
package/dist/v2/index.js
CHANGED
|
@@ -15,11 +15,13 @@ export * from './core/utils/previewMode';
|
|
|
15
15
|
export { injectPreviewModeIndicator, isIndicatorInjected, removePreviewModeIndicator } from './core/utils/previewModeIndicator';
|
|
16
16
|
export * from './core/utils/products';
|
|
17
17
|
// Step config utilities (for reading runtime configuration from HTML)
|
|
18
|
-
export { getAssignedPaymentFlowId, getAssignedScripts, getAssignedStaticResources, getAssignedStepConfig, getLocalFunnelConfig,
|
|
18
|
+
export { getAssignedPaymentFlowId, getAssignedScripts, getAssignedStaticResources, getAssignedResources, getAssignedStepConfig, getAssignedOrderBumpOfferIds, getAssignedUpsellOfferIds, getLocalFunnelConfig,
|
|
19
|
+
// Payment setup config helpers
|
|
20
|
+
getEnabledMethods, getExpressMethods, getExpressMethodsByProcessor, findMethod, isMethodEnabled,
|
|
19
21
|
// Local development helpers
|
|
20
22
|
loadLocalFunnelConfig } from './core/funnelClient';
|
|
21
23
|
// Path remapping helpers (framework-agnostic)
|
|
22
24
|
export * from './core/pathRemapping';
|
|
23
25
|
export { FunnelActionType } from './core/resources/funnel';
|
|
24
26
|
// React exports (hooks and components only, types are exported above)
|
|
25
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, PreviewModeIndicator, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useApplePayCheckout, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useGooglePayCheckout, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePaymentRetrieve, usePixelTracking, usePluginConfig, usePostPurchases, usePreloadQuery, usePreviewOffer, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStepConfig, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers, WhopCheckout, useWhopPaymentPolling } from './react';
|
|
27
|
+
export { ApplePayButton, StripeExpressButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, PreviewModeIndicator, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useApplePayCheckout, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useGooglePayCheckout, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePaymentRetrieve, usePixelTracking, usePluginConfig, usePostPurchases, usePreloadQuery, usePreviewOffer, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStepConfig, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers, useSetPaymentMethod, WhopCheckout, useWhopPaymentPolling } from './react';
|