@tagadapay/plugin-sdk 3.1.25 → 4.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.
- package/dist/external-tracker.js +160 -6
- package/dist/external-tracker.min.js +2 -2
- package/dist/external-tracker.min.js.map +4 -4
- package/dist/react/config/payment.d.ts +2 -2
- package/dist/react/config/payment.js +5 -5
- package/dist/react/hooks/usePayment.d.ts +7 -0
- package/dist/react/hooks/usePayment.js +1 -0
- package/dist/tagada-react-sdk-minimal.min.js +2 -2
- package/dist/tagada-react-sdk-minimal.min.js.map +4 -4
- package/dist/tagada-react-sdk.js +2220 -1428
- package/dist/tagada-react-sdk.min.js +2 -2
- package/dist/tagada-react-sdk.min.js.map +4 -4
- package/dist/tagada-sdk.js +3784 -128
- package/dist/tagada-sdk.min.js +2 -2
- package/dist/tagada-sdk.min.js.map +4 -4
- package/dist/v2/core/config/environment.d.ts +3 -3
- package/dist/v2/core/config/environment.js +7 -7
- package/dist/v2/core/funnelClient.d.ts +42 -0
- package/dist/v2/core/funnelClient.js +30 -0
- package/dist/v2/core/pixelTracker.d.ts +51 -0
- package/dist/v2/core/pixelTracker.js +425 -0
- package/dist/v2/core/resources/checkout.d.ts +45 -1
- package/dist/v2/core/resources/checkout.js +13 -3
- package/dist/v2/core/resources/funnel.d.ts +1 -1
- package/dist/v2/core/resources/geo.d.ts +50 -0
- package/dist/v2/core/resources/geo.js +35 -0
- package/dist/v2/core/resources/offers.d.ts +1 -1
- package/dist/v2/core/resources/offers.js +3 -1
- package/dist/v2/core/resources/payments.d.ts +19 -1
- package/dist/v2/core/resources/payments.js +8 -0
- package/dist/v2/core/resources/promotionEvents.d.ts +5 -0
- package/dist/v2/core/resources/promotionEvents.js +2 -0
- package/dist/v2/core/resources/promotions.d.ts +6 -1
- package/dist/v2/core/resources/promotions.js +6 -1
- package/dist/v2/core/resources/shippingRates.d.ts +18 -0
- package/dist/v2/core/resources/shippingRates.js +18 -0
- package/dist/v2/core/utils/clickIdResolver.d.ts +79 -0
- package/dist/v2/core/utils/clickIdResolver.js +169 -0
- package/dist/v2/core/utils/index.d.ts +2 -0
- package/dist/v2/core/utils/index.js +4 -0
- package/dist/v2/core/utils/metaEventId.d.ts +14 -0
- package/dist/v2/core/utils/metaEventId.js +16 -0
- package/dist/v2/index.d.ts +7 -0
- package/dist/v2/index.js +10 -0
- package/dist/v2/react/components/ApplePayButton.js +50 -0
- package/dist/v2/react/components/FunnelScriptInjector.js +158 -10
- package/dist/v2/react/components/GooglePayButton.js +39 -1
- package/dist/v2/react/components/StripeExpressButton.d.ts +8 -0
- package/dist/v2/react/components/StripeExpressButton.js +76 -3
- package/dist/v2/react/hooks/payment-actions/useNgeniusThreedsAction.d.ts +15 -0
- package/dist/v2/react/hooks/payment-actions/useNgeniusThreedsAction.js +166 -0
- package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.js +12 -0
- package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.js +1 -0
- package/dist/v2/react/hooks/useCheckoutQuery.js +41 -29
- package/dist/v2/react/hooks/useDiscountsQuery.js +4 -0
- package/dist/v2/react/hooks/useFunnel.d.ts +7 -0
- package/dist/v2/react/hooks/useFunnel.js +2 -1
- package/dist/v2/react/hooks/useISOData.js +25 -7
- package/dist/v2/react/hooks/usePaymentPolling.d.ts +1 -1
- package/dist/v2/react/hooks/usePixelTracking.d.ts +10 -5
- package/dist/v2/react/hooks/usePixelTracking.js +32 -374
- package/dist/v2/react/hooks/usePreviewOffer.d.ts +3 -1
- package/dist/v2/react/hooks/usePreviewOffer.js +8 -2
- package/dist/v2/react/hooks/usePromotionsQuery.js +9 -3
- package/dist/v2/react/hooks/useShippingRatesQuery.js +36 -21
- package/dist/v2/react/hooks/useStepConfig.d.ts +9 -0
- package/dist/v2/react/hooks/useStepConfig.js +5 -1
- package/dist/v2/react/index.d.ts +4 -0
- package/dist/v2/react/index.js +8 -0
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +12 -4
- package/dist/v2/react/providers/TagadaProvider.js +13 -0
- package/dist/v2/standalone/apple-pay-service.d.ts +12 -0
- package/dist/v2/standalone/apple-pay-service.js +12 -0
- package/dist/v2/standalone/external-tracker.d.ts +1 -1
- package/dist/v2/standalone/google-pay-service.d.ts +9 -0
- package/dist/v2/standalone/google-pay-service.js +9 -0
- package/dist/v2/standalone/index.d.ts +11 -1
- package/dist/v2/standalone/index.js +30 -0
- package/dist/v2/standalone/payment-service.d.ts +72 -6
- package/dist/v2/standalone/payment-service.js +285 -65
- package/package.json +2 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { OrderAddress } from '../types';
|
|
6
6
|
import { ApiClient } from './apiClient';
|
|
7
|
+
import { EventBus } from '../utils/eventBus';
|
|
7
8
|
export type PaymentMethodName = 'card' | 'paypal' | 'klarna' | 'apple_pay' | 'google_pay' | 'link' | 'bridge' | 'whop' | 'zelle' | 'hipay' | 'crypto' | 'convesiopay' | 'oceanpayment' | 'afterpay' | 'ideal' | 'bancontact' | 'giropay' | 'sepa_debit' | (string & {});
|
|
8
9
|
export interface CheckoutLineItem {
|
|
9
10
|
externalProductId?: string | null;
|
|
@@ -86,6 +87,43 @@ export interface Upsell {
|
|
|
86
87
|
triggers: UpsellTrigger[];
|
|
87
88
|
orderBumpOffers: CheckoutOrderBumpOffer[];
|
|
88
89
|
}
|
|
90
|
+
export interface CheckoutOfferLineItem {
|
|
91
|
+
id: string;
|
|
92
|
+
productId: string;
|
|
93
|
+
variantId: string;
|
|
94
|
+
priceId: string;
|
|
95
|
+
quantity: number;
|
|
96
|
+
variant?: {
|
|
97
|
+
id: string;
|
|
98
|
+
name?: string | null;
|
|
99
|
+
imageUrl?: string | null;
|
|
100
|
+
} | null;
|
|
101
|
+
product?: {
|
|
102
|
+
id: string;
|
|
103
|
+
name?: string | null;
|
|
104
|
+
} | null;
|
|
105
|
+
price?: {
|
|
106
|
+
id: string;
|
|
107
|
+
currencyOptions?: Record<string, {
|
|
108
|
+
amount: number;
|
|
109
|
+
}> | null;
|
|
110
|
+
} | null;
|
|
111
|
+
}
|
|
112
|
+
/** Tiered checkout offer (offers row, type='checkout_offer'), nested into the
|
|
113
|
+
* checkout session response alongside store.upsells so the same fetch path
|
|
114
|
+
* delivers both. The CheckoutOfferSelector chunk consumes these. */
|
|
115
|
+
export interface CheckoutOfferRecord {
|
|
116
|
+
id: string;
|
|
117
|
+
type: string;
|
|
118
|
+
titleTrans: Record<string, string>;
|
|
119
|
+
summaries?: Array<{
|
|
120
|
+
currency?: string;
|
|
121
|
+
totalAmount?: number;
|
|
122
|
+
totalAdjustedAmount?: number;
|
|
123
|
+
[key: string]: unknown;
|
|
124
|
+
}> | null;
|
|
125
|
+
offerLineItems: CheckoutOfferLineItem[];
|
|
126
|
+
}
|
|
89
127
|
export interface Store {
|
|
90
128
|
id: string;
|
|
91
129
|
accountId: string;
|
|
@@ -93,6 +131,7 @@ export interface Store {
|
|
|
93
131
|
presentmentCurrencies: string[];
|
|
94
132
|
chargeCurrencies: string[];
|
|
95
133
|
upsells: Upsell[];
|
|
134
|
+
offers?: CheckoutOfferRecord[];
|
|
96
135
|
emailDomains: string[];
|
|
97
136
|
integrations: unknown[];
|
|
98
137
|
}
|
|
@@ -302,7 +341,8 @@ export interface CheckoutData {
|
|
|
302
341
|
}
|
|
303
342
|
export declare class CheckoutResource {
|
|
304
343
|
private apiClient;
|
|
305
|
-
|
|
344
|
+
private bus?;
|
|
345
|
+
constructor(apiClient: ApiClient, bus?: EventBus | undefined);
|
|
306
346
|
/**
|
|
307
347
|
* Initialize a new checkout session (sync mode)
|
|
308
348
|
* Response time: 2-5 seconds (full processing)
|
|
@@ -505,6 +545,10 @@ export declare class CheckoutResource {
|
|
|
505
545
|
shippingAddress: Partial<OrderAddress>;
|
|
506
546
|
billingAddress?: Partial<OrderAddress>;
|
|
507
547
|
differentBillingAddress?: boolean;
|
|
548
|
+
cartCustomAttributes?: Array<{
|
|
549
|
+
name: string;
|
|
550
|
+
value: string;
|
|
551
|
+
}>;
|
|
508
552
|
}): Promise<{
|
|
509
553
|
success: boolean;
|
|
510
554
|
errors?: Record<string, {
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* Checkout Resource Client
|
|
3
3
|
* Axios-based API client for checkout endpoints
|
|
4
4
|
*/
|
|
5
|
+
import { PROMOTION_APPLIED, PROMOTION_REMOVED } from './promotionEvents';
|
|
5
6
|
export class CheckoutResource {
|
|
6
|
-
constructor(apiClient) {
|
|
7
|
+
constructor(apiClient, bus) {
|
|
7
8
|
this.apiClient = apiClient;
|
|
9
|
+
this.bus = bus;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* Initialize a new checkout session (sync mode)
|
|
@@ -131,15 +133,23 @@ export class CheckoutResource {
|
|
|
131
133
|
* Apply promotion code
|
|
132
134
|
*/
|
|
133
135
|
async applyPromotionCode(checkoutSessionId, code) {
|
|
134
|
-
|
|
136
|
+
const result = await this.apiClient.post(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/apply`, {
|
|
135
137
|
code,
|
|
136
138
|
});
|
|
139
|
+
if (result.success) {
|
|
140
|
+
void this.bus?.emit(PROMOTION_APPLIED, { checkoutSessionId });
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
137
143
|
}
|
|
138
144
|
/**
|
|
139
145
|
* Remove promotion
|
|
140
146
|
*/
|
|
141
147
|
async removePromotion(checkoutSessionId, promotionId) {
|
|
142
|
-
|
|
148
|
+
const result = await this.apiClient.delete(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/${promotionId}`);
|
|
149
|
+
if (result.success) {
|
|
150
|
+
void this.bus?.emit(PROMOTION_REMOVED, { checkoutSessionId });
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
143
153
|
}
|
|
144
154
|
/**
|
|
145
155
|
* Get applied promotions
|
|
@@ -405,7 +405,7 @@ export interface SimpleFunnelContext<TCustom = {}> {
|
|
|
405
405
|
* ✅ Environment context (staging or production)
|
|
406
406
|
* - Determined at session initialization based on entry URL
|
|
407
407
|
* - Ensures all navigation stays in the same environment
|
|
408
|
-
* - 'staging': Uses funnel.config (alias domains like funnel--store.cdn.
|
|
408
|
+
* - 'staging': Uses funnel.config (alias domains like funnel--store.cdn.tagada.io)
|
|
409
409
|
* - 'production': Uses funnel.productionConfig (custom domains)
|
|
410
410
|
*/
|
|
411
411
|
environment?: 'staging' | 'production';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Geo Resource Client
|
|
3
|
+
* API client for IP geolocation endpoint
|
|
4
|
+
*/
|
|
5
|
+
import { ApiClient } from './apiClient';
|
|
6
|
+
export interface GeoLocationData {
|
|
7
|
+
ip_address?: string | null;
|
|
8
|
+
city?: string | null;
|
|
9
|
+
region?: string | null;
|
|
10
|
+
region_iso_code?: string | null;
|
|
11
|
+
postal_code?: string | null;
|
|
12
|
+
country?: string | null;
|
|
13
|
+
country_code?: string | null;
|
|
14
|
+
country_is_eu?: boolean | null;
|
|
15
|
+
continent?: string | null;
|
|
16
|
+
continent_code?: string | null;
|
|
17
|
+
latitude?: number | null;
|
|
18
|
+
longitude?: number | null;
|
|
19
|
+
security?: {
|
|
20
|
+
is_vpn?: boolean | null;
|
|
21
|
+
} | null;
|
|
22
|
+
timezone?: {
|
|
23
|
+
name?: string | null;
|
|
24
|
+
abbreviation?: string | null;
|
|
25
|
+
gmt_offset?: number | null;
|
|
26
|
+
current_time?: string | null;
|
|
27
|
+
is_dst?: boolean | null;
|
|
28
|
+
} | null;
|
|
29
|
+
currency?: {
|
|
30
|
+
currency_name?: string | null;
|
|
31
|
+
currency_code?: string | null;
|
|
32
|
+
} | null;
|
|
33
|
+
}
|
|
34
|
+
export declare class GeoResource {
|
|
35
|
+
private apiClient;
|
|
36
|
+
constructor(apiClient: ApiClient);
|
|
37
|
+
/**
|
|
38
|
+
* Get geolocation data from the visitor's IP address
|
|
39
|
+
*/
|
|
40
|
+
getGeoLocation(): Promise<GeoLocationData>;
|
|
41
|
+
/**
|
|
42
|
+
* Get geolocation data for a specific IP address
|
|
43
|
+
*/
|
|
44
|
+
getGeoLocationByIp(ip: string): Promise<GeoLocationData>;
|
|
45
|
+
/**
|
|
46
|
+
* Convenience: get just the country code from IP geolocation
|
|
47
|
+
* Returns ISO 3166-1 alpha-2 code (e.g. 'US', 'FR') or null
|
|
48
|
+
*/
|
|
49
|
+
detectCountry(): Promise<string | null>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Geo Resource Client
|
|
3
|
+
* API client for IP geolocation endpoint
|
|
4
|
+
*/
|
|
5
|
+
export class GeoResource {
|
|
6
|
+
constructor(apiClient) {
|
|
7
|
+
this.apiClient = apiClient;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get geolocation data from the visitor's IP address
|
|
11
|
+
*/
|
|
12
|
+
async getGeoLocation() {
|
|
13
|
+
return this.apiClient.get('/api/v1/geo');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get geolocation data for a specific IP address
|
|
17
|
+
*/
|
|
18
|
+
async getGeoLocationByIp(ip) {
|
|
19
|
+
return this.apiClient.get(`/api/v1/geo?ip=${encodeURIComponent(ip)}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Convenience: get just the country code from IP geolocation
|
|
23
|
+
* Returns ISO 3166-1 alpha-2 code (e.g. 'US', 'FR') or null
|
|
24
|
+
*/
|
|
25
|
+
async detectCountry() {
|
|
26
|
+
try {
|
|
27
|
+
const data = await this.getGeoLocation();
|
|
28
|
+
const code = data?.country_code;
|
|
29
|
+
return code && typeof code === 'string' && code.length === 2 ? code : null;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -240,7 +240,7 @@ export declare class OffersResource {
|
|
|
240
240
|
productId?: string;
|
|
241
241
|
variantId: string;
|
|
242
242
|
quantity: number;
|
|
243
|
-
}>, returnUrl?: string, mainOrderId?: string): Promise<{
|
|
243
|
+
}>, returnUrl?: string, mainOrderId?: string, initiatedBy?: 'merchant' | 'customer'): Promise<{
|
|
244
244
|
preview: any;
|
|
245
245
|
checkout: {
|
|
246
246
|
checkoutUrl: string;
|
|
@@ -68,13 +68,14 @@ export class OffersResource {
|
|
|
68
68
|
* @param returnUrl - Optional return URL for checkout
|
|
69
69
|
* @param mainOrderId - Optional main order ID (for upsells)
|
|
70
70
|
*/
|
|
71
|
-
async payPreviewedOffer(offerId, currency = '', lineItems, returnUrl, mainOrderId) {
|
|
71
|
+
async payPreviewedOffer(offerId, currency = '', lineItems, returnUrl, mainOrderId, initiatedBy) {
|
|
72
72
|
console.log('💳 [OffersResource] Calling pay-preview API:', {
|
|
73
73
|
offerId,
|
|
74
74
|
currency,
|
|
75
75
|
lineItems,
|
|
76
76
|
returnUrl,
|
|
77
77
|
mainOrderId,
|
|
78
|
+
initiatedBy,
|
|
78
79
|
endpoint: `/api/v1/offers/${offerId}/pay-preview`,
|
|
79
80
|
});
|
|
80
81
|
const response = await this.apiClient.post(`/api/v1/offers/${offerId}/pay-preview`, {
|
|
@@ -83,6 +84,7 @@ export class OffersResource {
|
|
|
83
84
|
lineItems,
|
|
84
85
|
returnUrl: returnUrl || (typeof window !== 'undefined' ? window.location.href : ''),
|
|
85
86
|
mainOrderId,
|
|
87
|
+
...(initiatedBy ? { initiatedBy } : {}),
|
|
86
88
|
});
|
|
87
89
|
console.log('📥 [OffersResource] Pay-preview API response:', response);
|
|
88
90
|
return response;
|
|
@@ -10,7 +10,7 @@ export interface Payment {
|
|
|
10
10
|
subStatus: string;
|
|
11
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' | 'stripe_express_checkout';
|
|
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' | 'ngenius_3ds';
|
|
14
14
|
url?: string;
|
|
15
15
|
processed: boolean;
|
|
16
16
|
processorId?: string;
|
|
@@ -112,6 +112,14 @@ export interface PaymentOptions {
|
|
|
112
112
|
* Payment method type (e.g., 'klarna', 'afterpay', 'paypal')
|
|
113
113
|
*/
|
|
114
114
|
paymentMethod?: string;
|
|
115
|
+
/**
|
|
116
|
+
* Shipping rate selected by the customer at checkout. Forwarded to
|
|
117
|
+
* `processPaymentDirect` so the order is created with the right shipping
|
|
118
|
+
* even if the session's stored rate hasn't fully round-tripped or got
|
|
119
|
+
* cleared (race conditions). The backend treats this as authoritative
|
|
120
|
+
* when present, otherwise falls back to the session's stored rate.
|
|
121
|
+
*/
|
|
122
|
+
shippingRateId?: string;
|
|
115
123
|
/** @deprecated Use onPaymentSuccess instead - this will be removed in v3 */
|
|
116
124
|
onSuccess?: (response: PaymentResponse) => void;
|
|
117
125
|
/** @deprecated Use onPaymentFailed instead - this will be removed in v3 */
|
|
@@ -247,6 +255,7 @@ export declare class PaymentsResource {
|
|
|
247
255
|
processorId?: string;
|
|
248
256
|
paymentMethod?: string;
|
|
249
257
|
isExpress?: boolean;
|
|
258
|
+
shippingRateId?: string;
|
|
250
259
|
}): Promise<PaymentResponse>;
|
|
251
260
|
/**
|
|
252
261
|
* Get card payment instruments for customer
|
|
@@ -304,4 +313,13 @@ export declare class PaymentsResource {
|
|
|
304
313
|
status: 'succeeded' | 'failed' | 'pending';
|
|
305
314
|
paymentIntentId: string;
|
|
306
315
|
}): Promise<Payment>;
|
|
316
|
+
/**
|
|
317
|
+
* Complete N-Genius payment after WebSDK 3DS flow finishes.
|
|
318
|
+
* Verifies state from N-Genius server-side and updates the payment record.
|
|
319
|
+
*/
|
|
320
|
+
ngeniusThreedsComplete(data: {
|
|
321
|
+
paymentId: string;
|
|
322
|
+
orderReference: string;
|
|
323
|
+
paymentReference: string;
|
|
324
|
+
}): Promise<Payment>;
|
|
307
325
|
}
|
|
@@ -148,6 +148,7 @@ export class PaymentsResource {
|
|
|
148
148
|
...(options.processorId && { processorId: options.processorId }),
|
|
149
149
|
...(options.paymentMethod && { paymentMethod: options.paymentMethod }),
|
|
150
150
|
...(options.isExpress && { isExpress: options.isExpress }),
|
|
151
|
+
...(options.shippingRateId && { shippingRateId: options.shippingRateId }),
|
|
151
152
|
};
|
|
152
153
|
console.log('[PaymentsResource] Request body being sent:', JSON.stringify(requestBody, null, 2));
|
|
153
154
|
const response = await this.apiClient.post('/api/public/v1/checkout/pay-v2', requestBody);
|
|
@@ -206,4 +207,11 @@ export class PaymentsResource {
|
|
|
206
207
|
async updateThreedsStatus(data) {
|
|
207
208
|
return this.apiClient.post('/api/v1/threeds/status', data);
|
|
208
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Complete N-Genius payment after WebSDK 3DS flow finishes.
|
|
212
|
+
* Verifies state from N-Genius server-side and updates the payment record.
|
|
213
|
+
*/
|
|
214
|
+
async ngeniusThreedsComplete(data) {
|
|
215
|
+
return this.apiClient.post('/api/v1/payments/ngenius/threeds-complete', data);
|
|
216
|
+
}
|
|
209
217
|
}
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { ApiClient } from './apiClient';
|
|
6
6
|
import { Promotion } from './checkout';
|
|
7
|
+
import { EventBus } from '../utils/eventBus';
|
|
8
|
+
import { PROMOTION_APPLIED, PROMOTION_REMOVED, PromotionEventPayload } from './promotionEvents';
|
|
9
|
+
export { PROMOTION_APPLIED, PROMOTION_REMOVED };
|
|
10
|
+
export type { PromotionEventPayload };
|
|
7
11
|
export interface PromotionCodeValidation {
|
|
8
12
|
isValid: boolean;
|
|
9
13
|
code: string;
|
|
@@ -18,7 +22,8 @@ export interface PromotionCodeValidation {
|
|
|
18
22
|
}
|
|
19
23
|
export declare class PromotionsResource {
|
|
20
24
|
private apiClient;
|
|
21
|
-
|
|
25
|
+
private bus?;
|
|
26
|
+
constructor(apiClient: ApiClient, bus?: EventBus | undefined);
|
|
22
27
|
/**
|
|
23
28
|
* Get applied promotions for a checkout session
|
|
24
29
|
*/
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
* Promotions Resource Client
|
|
3
3
|
* Axios-based API client for promotion endpoints
|
|
4
4
|
*/
|
|
5
|
+
import { PROMOTION_APPLIED, PROMOTION_REMOVED } from './promotionEvents';
|
|
6
|
+
export { PROMOTION_APPLIED, PROMOTION_REMOVED };
|
|
5
7
|
export class PromotionsResource {
|
|
6
|
-
constructor(apiClient) {
|
|
8
|
+
constructor(apiClient, bus) {
|
|
7
9
|
this.apiClient = apiClient;
|
|
10
|
+
this.bus = bus;
|
|
8
11
|
}
|
|
9
12
|
/**
|
|
10
13
|
* Get applied promotions for a checkout session
|
|
@@ -19,6 +22,7 @@ export class PromotionsResource {
|
|
|
19
22
|
try {
|
|
20
23
|
const response = await this.apiClient.post(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/apply`, { code: code.trim() });
|
|
21
24
|
if (response.success) {
|
|
25
|
+
void this.bus?.emit(PROMOTION_APPLIED, { checkoutSessionId });
|
|
22
26
|
return { success: true, promotion: response.promotion };
|
|
23
27
|
}
|
|
24
28
|
else {
|
|
@@ -47,6 +51,7 @@ export class PromotionsResource {
|
|
|
47
51
|
try {
|
|
48
52
|
const response = await this.apiClient.delete(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/${promotionId}`);
|
|
49
53
|
if (response.success) {
|
|
54
|
+
void this.bus?.emit(PROMOTION_REMOVED, { checkoutSessionId });
|
|
50
55
|
return { success: true };
|
|
51
56
|
}
|
|
52
57
|
else {
|
|
@@ -29,6 +29,11 @@ export interface ShippingRatesPreviewResponse {
|
|
|
29
29
|
apiKey: string | null;
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
export interface SelectPreviewShippingRateResponse {
|
|
33
|
+
success: boolean;
|
|
34
|
+
selectedRateId: string | null;
|
|
35
|
+
rates: ShippingRate[];
|
|
36
|
+
}
|
|
32
37
|
export declare class ShippingRatesResource {
|
|
33
38
|
private apiClient;
|
|
34
39
|
constructor(apiClient: ApiClient);
|
|
@@ -48,4 +53,17 @@ export declare class ShippingRatesResource {
|
|
|
48
53
|
* Useful for showing rates before user enters email
|
|
49
54
|
*/
|
|
50
55
|
previewShippingRates(sessionId: string, params: ShippingRatesPreviewParams): Promise<ShippingRatesPreviewResponse>;
|
|
56
|
+
/**
|
|
57
|
+
* Preview shipping rates for a country AND persist the auto-selected rate on the session.
|
|
58
|
+
*
|
|
59
|
+
* Difference with `previewShippingRates` (which is read-only):
|
|
60
|
+
* - the server picks the highlighted (or cheapest) rate for `countryCode`
|
|
61
|
+
* - it writes `checkoutSession.shippingRateId` to the DB
|
|
62
|
+
* - the next `getCheckout()` will return a summary that includes shipping cost
|
|
63
|
+
*
|
|
64
|
+
* Use this from the studio when geolocation (or any client-side hint) determines a country
|
|
65
|
+
* BEFORE the user submits the full address. Otherwise the wallet sheet (Apple Pay, etc.) will
|
|
66
|
+
* be opened with a stale total that doesn't include shipping fees.
|
|
67
|
+
*/
|
|
68
|
+
selectPreviewShippingRate(sessionId: string, params: ShippingRatesPreviewParams): Promise<SelectPreviewShippingRateResponse>;
|
|
51
69
|
}
|
|
@@ -31,4 +31,22 @@ export class ShippingRatesResource {
|
|
|
31
31
|
}
|
|
32
32
|
return this.apiClient.get(`/api/v1/checkout-sessions/${sessionId}/shipping-rates/preview?${queryParams.toString()}`);
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Preview shipping rates for a country AND persist the auto-selected rate on the session.
|
|
36
|
+
*
|
|
37
|
+
* Difference with `previewShippingRates` (which is read-only):
|
|
38
|
+
* - the server picks the highlighted (or cheapest) rate for `countryCode`
|
|
39
|
+
* - it writes `checkoutSession.shippingRateId` to the DB
|
|
40
|
+
* - the next `getCheckout()` will return a summary that includes shipping cost
|
|
41
|
+
*
|
|
42
|
+
* Use this from the studio when geolocation (or any client-side hint) determines a country
|
|
43
|
+
* BEFORE the user submits the full address. Otherwise the wallet sheet (Apple Pay, etc.) will
|
|
44
|
+
* be opened with a stale total that doesn't include shipping fees.
|
|
45
|
+
*/
|
|
46
|
+
async selectPreviewShippingRate(sessionId, params) {
|
|
47
|
+
return this.apiClient.post(`/api/v1/checkout-sessions/${sessionId}/shipping-rates/select-preview`, {
|
|
48
|
+
countryCode: params.countryCode,
|
|
49
|
+
...(params.stateCode ? { stateCode: params.stateCode } : {}),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
34
52
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click-ID resolver — pure, runtime-agnostic utility.
|
|
3
|
+
*
|
|
4
|
+
* Many ad-trackers (ClickFlare, Voluum, Binom, RedTrack, ClickMagick, …) all
|
|
5
|
+
* follow the same pattern: assign a `click_id` on the visitor's first ad-click
|
|
6
|
+
* on the lander, then expect that id to flow end-to-end (lander → checkout →
|
|
7
|
+
* thank-you) so they can match a server postback to the original visit.
|
|
8
|
+
*
|
|
9
|
+
* This module:
|
|
10
|
+
* - Resolves the click id from URL query params (preferred — survives the
|
|
11
|
+
* redirect chain) and first-party cookies (fallback — set by the tracker's
|
|
12
|
+
* lander script).
|
|
13
|
+
* - Publishes the resolved value to `window.TagadaPay.tracking` so merchant-
|
|
14
|
+
* authored postback snippets in `stepConfig.scripts` can read it without
|
|
15
|
+
* re-implementing URL/cookie scraping.
|
|
16
|
+
*
|
|
17
|
+
* No React, no SDK class dependencies — works from React provider, standalone
|
|
18
|
+
* SDK, the studio builder, the external-tracker bundle, or a raw <script>.
|
|
19
|
+
*
|
|
20
|
+
* The lists are intentionally explicit (not regexes) so we never accidentally
|
|
21
|
+
* promote a random param to a "click id" — they are the exact identifiers
|
|
22
|
+
* documented by each tracker / ad platform.
|
|
23
|
+
*/
|
|
24
|
+
/** URL query-param names ad trackers / ad platforms use for click ids.
|
|
25
|
+
*
|
|
26
|
+
* Order matters — the resolver returns the FIRST matching entry, so put
|
|
27
|
+
* tracker-specific canonical names BEFORE generic fallbacks like
|
|
28
|
+
* `click_id` or `clickid`. This is why ClickFlare's `cf_click_id` comes
|
|
29
|
+
* before `click_id`, and why the per-tracker canonical token (`cid` for
|
|
30
|
+
* Voluum, `rtkclickid` for RedTrack, `cmc_tid` for ClickMagick) comes
|
|
31
|
+
* first within its own block.
|
|
32
|
+
*/
|
|
33
|
+
export declare const CLICK_ID_URL_PARAMS: readonly ["cf_click_id", "cid", "rtkclickid", "cmc_tid", "cmc_id", "cmcid", "clickid", "click_id", "gclid", "gbraid", "wbraid", "fbclid", "msclkid", "ttclid", "twclid", "li_fat_id", "epik", "dclid", "yclid", "irclickid"];
|
|
34
|
+
/** Cookie names ad trackers store their click ids under.
|
|
35
|
+
*
|
|
36
|
+
* Same ordering rule as URL params: canonical first-party cookies first
|
|
37
|
+
* (e.g. `rtkclickid-store` for RedTrack), legacy fallbacks last.
|
|
38
|
+
*/
|
|
39
|
+
export declare const CLICK_ID_COOKIES: readonly ["cf_click_id", "cfclid", "rtkclickid-store", "_rtkclickid", "rtkclickid", "_voluum", "_voluumclickid", "_binom", "_binomclickid", "_mck", "cmcid", "skro-click-id", "click_id"];
|
|
40
|
+
export type ClickIdSource = 'url' | 'cookie';
|
|
41
|
+
export interface ResolvedClickId {
|
|
42
|
+
/** The first matching click id, or null. */
|
|
43
|
+
clickId: string | null;
|
|
44
|
+
/** Where it was sourced from. */
|
|
45
|
+
source: ClickIdSource | null;
|
|
46
|
+
/** Which key (param name or cookie name) matched. */
|
|
47
|
+
key: string | null;
|
|
48
|
+
/** Every click-id-shaped value found, namespaced as `url:foo` / `cookie:bar`. */
|
|
49
|
+
all: Record<string, string>;
|
|
50
|
+
}
|
|
51
|
+
export interface TagadaTrackingGlobal extends ResolvedClickId {
|
|
52
|
+
/** ms since epoch when the resolver last ran. */
|
|
53
|
+
resolvedAt: number;
|
|
54
|
+
}
|
|
55
|
+
declare global {
|
|
56
|
+
interface Window {
|
|
57
|
+
TagadaPay?: {
|
|
58
|
+
tracking?: TagadaTrackingGlobal;
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the visitor's click id. Pure — no side effects, safe in SSR.
|
|
65
|
+
*
|
|
66
|
+
* Resolution order:
|
|
67
|
+
* 1. URL params (in CLICK_ID_URL_PARAMS order) — most authoritative.
|
|
68
|
+
* 2. Cookies (in CLICK_ID_COOKIES order) — fallback.
|
|
69
|
+
*/
|
|
70
|
+
export declare function resolveClickId(): ResolvedClickId;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve and merge tracking metadata into `window.TagadaPay.tracking`.
|
|
73
|
+
*
|
|
74
|
+
* Idempotent and namespace-safe: we only ever touch the `tracking` key, never
|
|
75
|
+
* other namespaces (e.g. `order` set by the thank-you page).
|
|
76
|
+
*
|
|
77
|
+
* Returns the published value, or `null` when called outside a browser.
|
|
78
|
+
*/
|
|
79
|
+
export declare function publishTrackingGlobal(): TagadaTrackingGlobal | null;
|