@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.
Files changed (81) hide show
  1. package/dist/external-tracker.js +160 -6
  2. package/dist/external-tracker.min.js +2 -2
  3. package/dist/external-tracker.min.js.map +4 -4
  4. package/dist/react/config/payment.d.ts +2 -2
  5. package/dist/react/config/payment.js +5 -5
  6. package/dist/react/hooks/usePayment.d.ts +7 -0
  7. package/dist/react/hooks/usePayment.js +1 -0
  8. package/dist/tagada-react-sdk-minimal.min.js +2 -2
  9. package/dist/tagada-react-sdk-minimal.min.js.map +4 -4
  10. package/dist/tagada-react-sdk.js +2220 -1428
  11. package/dist/tagada-react-sdk.min.js +2 -2
  12. package/dist/tagada-react-sdk.min.js.map +4 -4
  13. package/dist/tagada-sdk.js +3784 -128
  14. package/dist/tagada-sdk.min.js +2 -2
  15. package/dist/tagada-sdk.min.js.map +4 -4
  16. package/dist/v2/core/config/environment.d.ts +3 -3
  17. package/dist/v2/core/config/environment.js +7 -7
  18. package/dist/v2/core/funnelClient.d.ts +42 -0
  19. package/dist/v2/core/funnelClient.js +30 -0
  20. package/dist/v2/core/pixelTracker.d.ts +51 -0
  21. package/dist/v2/core/pixelTracker.js +425 -0
  22. package/dist/v2/core/resources/checkout.d.ts +45 -1
  23. package/dist/v2/core/resources/checkout.js +13 -3
  24. package/dist/v2/core/resources/funnel.d.ts +1 -1
  25. package/dist/v2/core/resources/geo.d.ts +50 -0
  26. package/dist/v2/core/resources/geo.js +35 -0
  27. package/dist/v2/core/resources/offers.d.ts +1 -1
  28. package/dist/v2/core/resources/offers.js +3 -1
  29. package/dist/v2/core/resources/payments.d.ts +19 -1
  30. package/dist/v2/core/resources/payments.js +8 -0
  31. package/dist/v2/core/resources/promotionEvents.d.ts +5 -0
  32. package/dist/v2/core/resources/promotionEvents.js +2 -0
  33. package/dist/v2/core/resources/promotions.d.ts +6 -1
  34. package/dist/v2/core/resources/promotions.js +6 -1
  35. package/dist/v2/core/resources/shippingRates.d.ts +18 -0
  36. package/dist/v2/core/resources/shippingRates.js +18 -0
  37. package/dist/v2/core/utils/clickIdResolver.d.ts +79 -0
  38. package/dist/v2/core/utils/clickIdResolver.js +169 -0
  39. package/dist/v2/core/utils/index.d.ts +2 -0
  40. package/dist/v2/core/utils/index.js +4 -0
  41. package/dist/v2/core/utils/metaEventId.d.ts +14 -0
  42. package/dist/v2/core/utils/metaEventId.js +16 -0
  43. package/dist/v2/index.d.ts +7 -0
  44. package/dist/v2/index.js +10 -0
  45. package/dist/v2/react/components/ApplePayButton.js +50 -0
  46. package/dist/v2/react/components/FunnelScriptInjector.js +158 -10
  47. package/dist/v2/react/components/GooglePayButton.js +39 -1
  48. package/dist/v2/react/components/StripeExpressButton.d.ts +8 -0
  49. package/dist/v2/react/components/StripeExpressButton.js +76 -3
  50. package/dist/v2/react/hooks/payment-actions/useNgeniusThreedsAction.d.ts +15 -0
  51. package/dist/v2/react/hooks/payment-actions/useNgeniusThreedsAction.js +166 -0
  52. package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.js +12 -0
  53. package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.js +1 -0
  54. package/dist/v2/react/hooks/useCheckoutQuery.js +41 -29
  55. package/dist/v2/react/hooks/useDiscountsQuery.js +4 -0
  56. package/dist/v2/react/hooks/useFunnel.d.ts +7 -0
  57. package/dist/v2/react/hooks/useFunnel.js +2 -1
  58. package/dist/v2/react/hooks/useISOData.js +25 -7
  59. package/dist/v2/react/hooks/usePaymentPolling.d.ts +1 -1
  60. package/dist/v2/react/hooks/usePixelTracking.d.ts +10 -5
  61. package/dist/v2/react/hooks/usePixelTracking.js +32 -374
  62. package/dist/v2/react/hooks/usePreviewOffer.d.ts +3 -1
  63. package/dist/v2/react/hooks/usePreviewOffer.js +8 -2
  64. package/dist/v2/react/hooks/usePromotionsQuery.js +9 -3
  65. package/dist/v2/react/hooks/useShippingRatesQuery.js +36 -21
  66. package/dist/v2/react/hooks/useStepConfig.d.ts +9 -0
  67. package/dist/v2/react/hooks/useStepConfig.js +5 -1
  68. package/dist/v2/react/index.d.ts +4 -0
  69. package/dist/v2/react/index.js +8 -0
  70. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +12 -4
  71. package/dist/v2/react/providers/TagadaProvider.js +13 -0
  72. package/dist/v2/standalone/apple-pay-service.d.ts +12 -0
  73. package/dist/v2/standalone/apple-pay-service.js +12 -0
  74. package/dist/v2/standalone/external-tracker.d.ts +1 -1
  75. package/dist/v2/standalone/google-pay-service.d.ts +9 -0
  76. package/dist/v2/standalone/google-pay-service.js +9 -0
  77. package/dist/v2/standalone/index.d.ts +11 -1
  78. package/dist/v2/standalone/index.js +30 -0
  79. package/dist/v2/standalone/payment-service.d.ts +72 -6
  80. package/dist/v2/standalone/payment-service.js +285 -65
  81. 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
- constructor(apiClient: ApiClient);
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
- return this.apiClient.post(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/apply`, {
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
- return this.apiClient.delete(`/api/v1/checkout-sessions/${checkoutSessionId}/promotions/${promotionId}`);
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.tagadapay.com)
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
  }
@@ -0,0 +1,5 @@
1
+ export declare const PROMOTION_APPLIED = "PROMOTION_APPLIED";
2
+ export declare const PROMOTION_REMOVED = "PROMOTION_REMOVED";
3
+ export interface PromotionEventPayload {
4
+ checkoutSessionId: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ export const PROMOTION_APPLIED = 'PROMOTION_APPLIED';
2
+ export const PROMOTION_REMOVED = 'PROMOTION_REMOVED';
@@ -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
- constructor(apiClient: ApiClient);
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;