@economist/web-apple-pay 0.1.1-beta.0
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 +186 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1642 -0
- package/dist/src/apple-pay-button.d.ts +45 -0
- package/dist/src/apple-pay-button.js +1621 -0
- package/dist/src/apple-pay-button.stories.js +1934 -0
- package/dist/src/apple-pay-logo.d.ts +1 -0
- package/dist/src/apple-pay-logo.js +14 -0
- package/dist/src/apple-pay-modal.d.ts +12 -0
- package/dist/src/apple-pay-modal.js +442 -0
- package/dist/src/apple-pay-modal.stories.js +1778 -0
- package/dist/src/clients/payment-checkout/apple-session.d.ts +18 -0
- package/dist/src/clients/payment-checkout/apple-session.js +243 -0
- package/dist/src/clients/payment-checkout/billing-contact-details.d.ts +21 -0
- package/dist/src/clients/payment-checkout/billing-contact-details.js +109 -0
- package/dist/src/clients/payment-checkout/config.d.ts +9 -0
- package/dist/src/clients/payment-checkout/config.js +23 -0
- package/dist/src/clients/payment-checkout/contact-validation.d.ts +21 -0
- package/dist/src/clients/payment-checkout/contact-validation.js +50 -0
- package/dist/src/clients/payment-checkout/detects.d.ts +3 -0
- package/dist/src/clients/payment-checkout/detects.js +56 -0
- package/dist/src/clients/payment-checkout/index.d.ts +5 -0
- package/dist/src/clients/payment-checkout/index.js +83 -0
- package/dist/src/clients/payment-checkout/messages.d.ts +33 -0
- package/dist/src/clients/payment-checkout/messages.js +19 -0
- package/dist/src/clients/payment-checkout/payment-handler.d.ts +36 -0
- package/dist/src/clients/payment-checkout/payment-handler.js +389 -0
- package/dist/src/clients/payment-checkout/session.d.ts +2 -0
- package/dist/src/clients/payment-checkout/session.js +67 -0
- package/dist/src/clients/payment-checkout/shipping-contact-details.d.ts +10 -0
- package/dist/src/clients/payment-checkout/shipping-contact-details.js +83 -0
- package/dist/src/clients/payment-checkout/types.d.ts +118 -0
- package/dist/src/clients/payment-checkout/types.js +14 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.js +1642 -0
- package/dist/src/stories/fixtures/offer.d.ts +2 -0
- package/dist/src/stories/fixtures/offer.js +28 -0
- package/dist/src/stories/utils/story-env.d.ts +11 -0
- package/dist/src/stories/utils/story-env.js +148 -0
- package/dist/src/types/html-template.d.js +0 -0
- package/dist/src/types/offer.types.d.ts +73 -0
- package/dist/src/types/offer.types.js +0 -0
- package/dist/src/utils/billing-countries.d.ts +19 -0
- package/dist/src/utils/billing-countries.js +263 -0
- package/dist/src/utils/define.d.ts +1 -0
- package/dist/src/utils/define.js +9 -0
- package/dist/src/utils/expressCheckoutRedirect.d.ts +55 -0
- package/dist/src/utils/expressCheckoutRedirect.js +46 -0
- package/dist/src/utils/expressCheckoutTracking.d.ts +64 -0
- package/dist/src/utils/expressCheckoutTracking.js +84 -0
- package/dist/src/utils/pricing.d.ts +1 -0
- package/dist/src/utils/pricing.js +60 -0
- package/dist/src/utils/recaptcha.d.ts +22 -0
- package/dist/src/utils/recaptcha.js +54 -0
- package/package.json +64 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/stories/fixtures/offer.ts
|
|
2
|
+
var STORYBOOK_SAMPLE_OFFER = {
|
|
3
|
+
sku_id: "TEG-APPLEPAY-STORY-001",
|
|
4
|
+
display_name: "Economist Digital",
|
|
5
|
+
price: {
|
|
6
|
+
purchase: 12,
|
|
7
|
+
pre_discount: 24,
|
|
8
|
+
currency_code: "USD",
|
|
9
|
+
discounted: true,
|
|
10
|
+
tax: { inclusive: false }
|
|
11
|
+
},
|
|
12
|
+
product: {
|
|
13
|
+
type: "subscription",
|
|
14
|
+
variant: "digital",
|
|
15
|
+
offer_type: "standard"
|
|
16
|
+
},
|
|
17
|
+
subscription_options: {
|
|
18
|
+
free_trial: false,
|
|
19
|
+
renewal_interval: { duration: 1, unit: "month" },
|
|
20
|
+
renewal_price: 12,
|
|
21
|
+
auto_renewal: true,
|
|
22
|
+
variable_term: false,
|
|
23
|
+
display_name: "Monthly"
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export {
|
|
27
|
+
STORYBOOK_SAMPLE_OFFER
|
|
28
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionResponse } from '../../clients/payment-checkout/types';
|
|
2
|
+
export type ApplePayStoryEnvironmentOptions = {
|
|
3
|
+
applePaySupported: boolean;
|
|
4
|
+
sessionResponse?: SessionResponse;
|
|
5
|
+
sessionStatus?: number;
|
|
6
|
+
debugBypassEnabled?: boolean;
|
|
7
|
+
bypassApplePayChecks?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const applyApplePayStoryEnvironment: ({ applePaySupported, sessionResponse, sessionStatus, debugBypassEnabled, bypassApplePayChecks, }: ApplePayStoryEnvironmentOptions) => void;
|
|
10
|
+
export declare const withApplePayStoryEnvironment: <TArgs>(options: ApplePayStoryEnvironmentOptions, renderFn: (args: TArgs) => HTMLElement) => (args: TArgs) => HTMLElement;
|
|
11
|
+
export declare const clickWhenElementReady: (root: ParentNode, selector: string, maxAttempts?: number) => void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var configureApplePay = (config) => {
|
|
4
|
+
console.log("[web-apple-pay] configureApplePay called", {
|
|
5
|
+
merchantId: config.merchantId,
|
|
6
|
+
walletApiBaseUrl: config.walletApiBaseUrl,
|
|
7
|
+
debugBypassEnabled: config.debugBypassEnabled,
|
|
8
|
+
recaptchaSiteKey: config.recaptchaSiteKey ? "***" : void 0
|
|
9
|
+
});
|
|
10
|
+
runtimeConfig = {
|
|
11
|
+
...config
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
var resetApplePayConfig = () => {
|
|
15
|
+
console.log("[web-apple-pay] resetApplePayConfig called");
|
|
16
|
+
runtimeConfig = null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/stories/utils/story-env.ts
|
|
20
|
+
var STORYBOOK_WALLET_BASE_URL = "https://storybook-wallet.economist.com";
|
|
21
|
+
var STORYBOOK_SAFARI_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15";
|
|
22
|
+
var defaultSessionResponse = {
|
|
23
|
+
loggedIn: false,
|
|
24
|
+
userType: "new-eligible-user"
|
|
25
|
+
};
|
|
26
|
+
var resetStoryEnvironment = null;
|
|
27
|
+
var createFetchMock = (sessionResponse, sessionStatus = 200) => {
|
|
28
|
+
return async (input) => {
|
|
29
|
+
const requestUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
30
|
+
if (requestUrl.endsWith("/v1/wallet/session")) {
|
|
31
|
+
if (sessionStatus >= 400) {
|
|
32
|
+
return new Response("Session initialization failed", {
|
|
33
|
+
status: sessionStatus,
|
|
34
|
+
statusText: "Session Init Error"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return new Response(JSON.stringify(sessionResponse), {
|
|
38
|
+
status: 200,
|
|
39
|
+
headers: { "content-type": "application/json" }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return new Response("Not Found", {
|
|
43
|
+
status: 404,
|
|
44
|
+
statusText: "Not Found"
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
var applyApplePayStoryEnvironment = ({
|
|
49
|
+
applePaySupported,
|
|
50
|
+
sessionResponse = defaultSessionResponse,
|
|
51
|
+
sessionStatus = 200,
|
|
52
|
+
debugBypassEnabled = false,
|
|
53
|
+
bypassApplePayChecks = false
|
|
54
|
+
}) => {
|
|
55
|
+
if (resetStoryEnvironment) {
|
|
56
|
+
resetStoryEnvironment();
|
|
57
|
+
resetStoryEnvironment = null;
|
|
58
|
+
}
|
|
59
|
+
const originalFetch = globalThis.fetch;
|
|
60
|
+
const originalHref = window.location.href;
|
|
61
|
+
const originalUserAgent = navigator.userAgent;
|
|
62
|
+
const originalMaxTouchPoints = navigator.maxTouchPoints;
|
|
63
|
+
const originalApplePaySessionDescriptor = Object.getOwnPropertyDescriptor(
|
|
64
|
+
window,
|
|
65
|
+
"ApplePaySession"
|
|
66
|
+
);
|
|
67
|
+
const mockApplePaySession = {
|
|
68
|
+
canMakePayments: () => applePaySupported,
|
|
69
|
+
canMakePaymentsWithActiveCard: async () => applePaySupported
|
|
70
|
+
};
|
|
71
|
+
Object.defineProperty(window, "ApplePaySession", {
|
|
72
|
+
configurable: true,
|
|
73
|
+
writable: true,
|
|
74
|
+
value: mockApplePaySession
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(navigator, "userAgent", {
|
|
77
|
+
configurable: true,
|
|
78
|
+
writable: true,
|
|
79
|
+
value: STORYBOOK_SAFARI_UA
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(navigator, "maxTouchPoints", {
|
|
82
|
+
configurable: true,
|
|
83
|
+
writable: true,
|
|
84
|
+
value: 0
|
|
85
|
+
});
|
|
86
|
+
globalThis.fetch = createFetchMock(sessionResponse, sessionStatus);
|
|
87
|
+
const nextUrl = new URL(window.location.href);
|
|
88
|
+
if (bypassApplePayChecks) {
|
|
89
|
+
nextUrl.searchParams.set("BYPASS_APPLE_PAY_CHECKS", "1");
|
|
90
|
+
} else {
|
|
91
|
+
nextUrl.searchParams.delete("BYPASS_APPLE_PAY_CHECKS");
|
|
92
|
+
}
|
|
93
|
+
window.history.replaceState({}, "", nextUrl.toString());
|
|
94
|
+
configureApplePay({
|
|
95
|
+
merchantId: "merchant.com.economist.storybook",
|
|
96
|
+
walletApiBaseUrl: STORYBOOK_WALLET_BASE_URL,
|
|
97
|
+
debugBypassEnabled
|
|
98
|
+
});
|
|
99
|
+
resetStoryEnvironment = () => {
|
|
100
|
+
resetApplePayConfig();
|
|
101
|
+
globalThis.fetch = originalFetch;
|
|
102
|
+
window.history.replaceState({}, "", originalHref);
|
|
103
|
+
Object.defineProperty(navigator, "userAgent", {
|
|
104
|
+
configurable: true,
|
|
105
|
+
writable: true,
|
|
106
|
+
value: originalUserAgent
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(navigator, "maxTouchPoints", {
|
|
109
|
+
configurable: true,
|
|
110
|
+
writable: true,
|
|
111
|
+
value: originalMaxTouchPoints
|
|
112
|
+
});
|
|
113
|
+
if (originalApplePaySessionDescriptor) {
|
|
114
|
+
Object.defineProperty(
|
|
115
|
+
window,
|
|
116
|
+
"ApplePaySession",
|
|
117
|
+
originalApplePaySessionDescriptor
|
|
118
|
+
);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
delete window.ApplePaySession;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
var withApplePayStoryEnvironment = (options, renderFn) => (args) => {
|
|
125
|
+
applyApplePayStoryEnvironment(options);
|
|
126
|
+
return renderFn(args);
|
|
127
|
+
};
|
|
128
|
+
var clickWhenElementReady = (root, selector, maxAttempts = 5) => {
|
|
129
|
+
let attempts = 0;
|
|
130
|
+
const tryClick = () => {
|
|
131
|
+
const element = root.querySelector(selector);
|
|
132
|
+
if (element) {
|
|
133
|
+
element.click();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (attempts >= maxAttempts) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
attempts += 1;
|
|
140
|
+
requestAnimationFrame(tryClick);
|
|
141
|
+
};
|
|
142
|
+
requestAnimationFrame(tryClick);
|
|
143
|
+
};
|
|
144
|
+
export {
|
|
145
|
+
applyApplePayStoryEnvironment,
|
|
146
|
+
clickWhenElementReady,
|
|
147
|
+
withApplePayStoryEnvironment
|
|
148
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export type ProductVariant = 'bundle' | 'digital' | 'espresso' | 'espressopod' | 'podcast' | 'insider_digital' | 'insider_print';
|
|
2
|
+
export type PeriodUnit = 'week' | 'month' | 'year';
|
|
3
|
+
export type Period = {
|
|
4
|
+
duration: number;
|
|
5
|
+
unit: PeriodUnit;
|
|
6
|
+
};
|
|
7
|
+
export type Tax = {
|
|
8
|
+
inclusive: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type Price = {
|
|
11
|
+
purchase: number;
|
|
12
|
+
pre_discount?: number;
|
|
13
|
+
currency_code: string;
|
|
14
|
+
discounted: boolean;
|
|
15
|
+
tax?: Tax;
|
|
16
|
+
};
|
|
17
|
+
export type Product = {
|
|
18
|
+
type: string;
|
|
19
|
+
variant: ProductVariant;
|
|
20
|
+
offer_type: string;
|
|
21
|
+
};
|
|
22
|
+
export type TrialPeriod = {
|
|
23
|
+
duration: number;
|
|
24
|
+
unit: PeriodUnit;
|
|
25
|
+
};
|
|
26
|
+
export type RenewalInterval = {
|
|
27
|
+
duration: number;
|
|
28
|
+
unit: PeriodUnit;
|
|
29
|
+
};
|
|
30
|
+
export type SubscriptionOptions = {
|
|
31
|
+
free_trial: boolean;
|
|
32
|
+
trial_period?: TrialPeriod;
|
|
33
|
+
renewal_interval: RenewalInterval;
|
|
34
|
+
renewal_price?: number;
|
|
35
|
+
auto_renewal: boolean;
|
|
36
|
+
variable_term: boolean;
|
|
37
|
+
display_name: string;
|
|
38
|
+
introductory?: boolean;
|
|
39
|
+
sale_offer?: boolean;
|
|
40
|
+
bau_price?: string;
|
|
41
|
+
min_term_contract?: boolean;
|
|
42
|
+
min_term_contract_length?: string;
|
|
43
|
+
};
|
|
44
|
+
export type Restrictions = {
|
|
45
|
+
countries?: string[];
|
|
46
|
+
};
|
|
47
|
+
export type UnstructuredContent = {
|
|
48
|
+
features_html?: string;
|
|
49
|
+
custom_display_price?: string;
|
|
50
|
+
};
|
|
51
|
+
export type StructuredContent = {
|
|
52
|
+
custom_subscription_display_name?: string;
|
|
53
|
+
discount_percentages?: string[];
|
|
54
|
+
custom_detailed_display_price?: string;
|
|
55
|
+
};
|
|
56
|
+
export type Content = {
|
|
57
|
+
unstructured?: UnstructuredContent;
|
|
58
|
+
structured?: StructuredContent;
|
|
59
|
+
};
|
|
60
|
+
export type MetaData = {
|
|
61
|
+
can_checkout?: boolean;
|
|
62
|
+
product_path?: string;
|
|
63
|
+
};
|
|
64
|
+
export type Offer = {
|
|
65
|
+
sku_id: string;
|
|
66
|
+
price: Price;
|
|
67
|
+
display_name: string;
|
|
68
|
+
product: Product;
|
|
69
|
+
subscription_options: SubscriptionOptions;
|
|
70
|
+
restrictions?: Restrictions;
|
|
71
|
+
content?: Content;
|
|
72
|
+
meta_data?: MetaData;
|
|
73
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the list of country codes that are valid billing countries for an offer.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors sma-checkout `billingCountryOptions()` logic (options.ts:21):
|
|
5
|
+
* - `bundle` / `insider_print` offers → unrestricted (all countries)
|
|
6
|
+
* - EEA offer country → price-zone countries ∪ all EEA countries
|
|
7
|
+
* - Otherwise → price-zone countries only
|
|
8
|
+
*
|
|
9
|
+
* **Intentional deviation from sma-checkout:**
|
|
10
|
+
* The source (`get-zone-by-country.ts`) throws `Error('No price zone found for country …')`
|
|
11
|
+
* when the offer country is not in any price zone. This function returns all countries instead.
|
|
12
|
+
* Rationale: Web Components have no React error boundary — an uncaught throw would crash
|
|
13
|
+
* the host page silently. Returning all countries is the safe degradation: the Apple Pay
|
|
14
|
+
* session itself validates the billing address, so no invalid payment can succeed.
|
|
15
|
+
*
|
|
16
|
+
* @param offerCountry - ISO 3166-1 alpha-2 country code of the offer (e.g. `'GB'`)
|
|
17
|
+
* @param offerVariant - Product variant string (e.g. `'digital'`, `'bundle'`)
|
|
18
|
+
*/
|
|
19
|
+
export declare const getSupportedBillingCountries: (offerCountry: string, offerVariant: string) => string[];
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// src/data/price-zones.json
|
|
2
|
+
var price_zones_default = {
|
|
3
|
+
"AS-AS": [
|
|
4
|
+
"BD",
|
|
5
|
+
"BT",
|
|
6
|
+
"CK",
|
|
7
|
+
"FJ",
|
|
8
|
+
"ID",
|
|
9
|
+
"KH",
|
|
10
|
+
"KI",
|
|
11
|
+
"LA",
|
|
12
|
+
"LK",
|
|
13
|
+
"MH",
|
|
14
|
+
"MM",
|
|
15
|
+
"MN",
|
|
16
|
+
"MV",
|
|
17
|
+
"NC",
|
|
18
|
+
"NF",
|
|
19
|
+
"NP",
|
|
20
|
+
"NR",
|
|
21
|
+
"PF",
|
|
22
|
+
"PG",
|
|
23
|
+
"PK",
|
|
24
|
+
"PW",
|
|
25
|
+
"SB",
|
|
26
|
+
"TH",
|
|
27
|
+
"TL",
|
|
28
|
+
"TO",
|
|
29
|
+
"TV",
|
|
30
|
+
"VN",
|
|
31
|
+
"VU",
|
|
32
|
+
"WS"
|
|
33
|
+
],
|
|
34
|
+
"AS-AU": ["AU"],
|
|
35
|
+
"AS-CN": ["CN"],
|
|
36
|
+
"AS-HK": ["HK", "MO"],
|
|
37
|
+
"AS-IN": ["IN"],
|
|
38
|
+
"AS-JP": ["JP"],
|
|
39
|
+
"AS-KR": ["KR"],
|
|
40
|
+
"AS-MY": ["MY"],
|
|
41
|
+
"AS-NZ": ["NZ"],
|
|
42
|
+
"AS-PH": ["PH"],
|
|
43
|
+
"AS-SG": ["BN", "SG"],
|
|
44
|
+
"AS-TW": ["TW"],
|
|
45
|
+
"CE-AF": [
|
|
46
|
+
"DZ",
|
|
47
|
+
"AO",
|
|
48
|
+
"BJ",
|
|
49
|
+
"BW",
|
|
50
|
+
"BF",
|
|
51
|
+
"BI",
|
|
52
|
+
"CM",
|
|
53
|
+
"CV",
|
|
54
|
+
"CF",
|
|
55
|
+
"TD",
|
|
56
|
+
"CG",
|
|
57
|
+
"CD",
|
|
58
|
+
"CI",
|
|
59
|
+
"DJ",
|
|
60
|
+
"EG",
|
|
61
|
+
"GQ",
|
|
62
|
+
"ER",
|
|
63
|
+
"ET",
|
|
64
|
+
"GA",
|
|
65
|
+
"GM",
|
|
66
|
+
"GH",
|
|
67
|
+
"GN",
|
|
68
|
+
"GW",
|
|
69
|
+
"IL",
|
|
70
|
+
"JO",
|
|
71
|
+
"KE",
|
|
72
|
+
"LB",
|
|
73
|
+
"LS",
|
|
74
|
+
"LR",
|
|
75
|
+
"LY",
|
|
76
|
+
"MG",
|
|
77
|
+
"MW",
|
|
78
|
+
"ML",
|
|
79
|
+
"MR",
|
|
80
|
+
"MU",
|
|
81
|
+
"MA",
|
|
82
|
+
"MZ",
|
|
83
|
+
"NA",
|
|
84
|
+
"NE",
|
|
85
|
+
"NG",
|
|
86
|
+
"PS",
|
|
87
|
+
"RE",
|
|
88
|
+
"RW",
|
|
89
|
+
"ST",
|
|
90
|
+
"SN",
|
|
91
|
+
"SC",
|
|
92
|
+
"SL",
|
|
93
|
+
"ZA",
|
|
94
|
+
"SZ",
|
|
95
|
+
"TZ",
|
|
96
|
+
"TG",
|
|
97
|
+
"TN",
|
|
98
|
+
"UG",
|
|
99
|
+
"ZM",
|
|
100
|
+
"ZW"
|
|
101
|
+
],
|
|
102
|
+
"CE-CH": ["LI", "CH"],
|
|
103
|
+
"CE-DK": ["FO", "GL", "DK"],
|
|
104
|
+
"CE-EU": [
|
|
105
|
+
"AL",
|
|
106
|
+
"AD",
|
|
107
|
+
"AM",
|
|
108
|
+
"AT",
|
|
109
|
+
"AZ",
|
|
110
|
+
"BY",
|
|
111
|
+
"BE",
|
|
112
|
+
"BA",
|
|
113
|
+
"BG",
|
|
114
|
+
"HR",
|
|
115
|
+
"CY",
|
|
116
|
+
"CZ",
|
|
117
|
+
"EE",
|
|
118
|
+
"FI",
|
|
119
|
+
"FR",
|
|
120
|
+
"GE",
|
|
121
|
+
"DE",
|
|
122
|
+
"GI",
|
|
123
|
+
"GR",
|
|
124
|
+
"HU",
|
|
125
|
+
"IS",
|
|
126
|
+
"IE",
|
|
127
|
+
"IT",
|
|
128
|
+
"KZ",
|
|
129
|
+
"XK",
|
|
130
|
+
"KG",
|
|
131
|
+
"LV",
|
|
132
|
+
"LT",
|
|
133
|
+
"LU",
|
|
134
|
+
"MT",
|
|
135
|
+
"MD",
|
|
136
|
+
"MC",
|
|
137
|
+
"ME",
|
|
138
|
+
"NL",
|
|
139
|
+
"PL",
|
|
140
|
+
"PT",
|
|
141
|
+
"MK",
|
|
142
|
+
"RO",
|
|
143
|
+
"RS",
|
|
144
|
+
"SK",
|
|
145
|
+
"SI",
|
|
146
|
+
"ES",
|
|
147
|
+
"TJ",
|
|
148
|
+
"TR",
|
|
149
|
+
"TM",
|
|
150
|
+
"UA",
|
|
151
|
+
"UZ"
|
|
152
|
+
],
|
|
153
|
+
"CE-ME": ["AE", "BH", "KW", "OM", "QA", "SA"],
|
|
154
|
+
"CE-NO": ["NO"],
|
|
155
|
+
"CE-SE": ["SE"],
|
|
156
|
+
"LA-LA": [
|
|
157
|
+
"AI",
|
|
158
|
+
"AG",
|
|
159
|
+
"AR",
|
|
160
|
+
"AW",
|
|
161
|
+
"BS",
|
|
162
|
+
"BB",
|
|
163
|
+
"BZ",
|
|
164
|
+
"BM",
|
|
165
|
+
"BO",
|
|
166
|
+
"BR",
|
|
167
|
+
"KY",
|
|
168
|
+
"CL",
|
|
169
|
+
"CO",
|
|
170
|
+
"CR",
|
|
171
|
+
"DM",
|
|
172
|
+
"DO",
|
|
173
|
+
"EC",
|
|
174
|
+
"SV",
|
|
175
|
+
"FK",
|
|
176
|
+
"GF",
|
|
177
|
+
"GD",
|
|
178
|
+
"GT",
|
|
179
|
+
"GY",
|
|
180
|
+
"HT",
|
|
181
|
+
"HN",
|
|
182
|
+
"JM",
|
|
183
|
+
"MQ",
|
|
184
|
+
"MX",
|
|
185
|
+
"MS",
|
|
186
|
+
"NI",
|
|
187
|
+
"MP",
|
|
188
|
+
"PA",
|
|
189
|
+
"PY",
|
|
190
|
+
"PE",
|
|
191
|
+
"KN",
|
|
192
|
+
"LC",
|
|
193
|
+
"VC",
|
|
194
|
+
"SR",
|
|
195
|
+
"TT",
|
|
196
|
+
"TC",
|
|
197
|
+
"UY",
|
|
198
|
+
"VG",
|
|
199
|
+
"VI"
|
|
200
|
+
],
|
|
201
|
+
"NA-CA": ["CA"],
|
|
202
|
+
"NA-US": ["AS", "GU", "FM", "PR", "US"],
|
|
203
|
+
"UK-UK": ["GB"]
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// src/data/eea-countries.json
|
|
207
|
+
var eea_countries_default = [
|
|
208
|
+
"AT",
|
|
209
|
+
"BE",
|
|
210
|
+
"BG",
|
|
211
|
+
"HR",
|
|
212
|
+
"CY",
|
|
213
|
+
"CZ",
|
|
214
|
+
"DK",
|
|
215
|
+
"EE",
|
|
216
|
+
"FO",
|
|
217
|
+
"FI",
|
|
218
|
+
"FR",
|
|
219
|
+
"DE",
|
|
220
|
+
"GR",
|
|
221
|
+
"GL",
|
|
222
|
+
"HU",
|
|
223
|
+
"IS",
|
|
224
|
+
"IE",
|
|
225
|
+
"IT",
|
|
226
|
+
"LV",
|
|
227
|
+
"LI",
|
|
228
|
+
"LT",
|
|
229
|
+
"LU",
|
|
230
|
+
"MT",
|
|
231
|
+
"NL",
|
|
232
|
+
"NO",
|
|
233
|
+
"PL",
|
|
234
|
+
"PT",
|
|
235
|
+
"RO",
|
|
236
|
+
"SK",
|
|
237
|
+
"SI",
|
|
238
|
+
"ES",
|
|
239
|
+
"SE"
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
// src/utils/billing-countries.ts
|
|
243
|
+
var priceZones = price_zones_default;
|
|
244
|
+
var eeaCountries = eea_countries_default;
|
|
245
|
+
var ALL_COUNTRY_CODES = Object.values(priceZones).flat();
|
|
246
|
+
var getZoneByCountry = (country) => Object.keys(priceZones).find((key) => priceZones[key].includes(country)) ?? null;
|
|
247
|
+
var getSupportedBillingCountries = (offerCountry, offerVariant) => {
|
|
248
|
+
if (offerVariant === "bundle" || offerVariant === "insider_print") {
|
|
249
|
+
return [...ALL_COUNTRY_CODES];
|
|
250
|
+
}
|
|
251
|
+
const zone = getZoneByCountry(offerCountry);
|
|
252
|
+
if (!zone) {
|
|
253
|
+
return [...ALL_COUNTRY_CODES];
|
|
254
|
+
}
|
|
255
|
+
const zoneCountries = priceZones[zone];
|
|
256
|
+
if (eeaCountries.includes(offerCountry)) {
|
|
257
|
+
return Array.from(/* @__PURE__ */ new Set([...zoneCountries, ...eeaCountries]));
|
|
258
|
+
}
|
|
259
|
+
return [...zoneCountries];
|
|
260
|
+
};
|
|
261
|
+
export {
|
|
262
|
+
getSupportedBillingCountries
|
|
263
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const define: (component: string, instance: CustomElementConstructor) => void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized redirect URL builders for the Express Checkout payment handler.
|
|
3
|
+
*
|
|
4
|
+
* All redirects include a `returnUrl` parameter so downstream pages
|
|
5
|
+
* (/checkout/complete, onboarding) can return the user to the original article.
|
|
6
|
+
*
|
|
7
|
+
* Matches sma-checkout: src/lib/navigate-to-checkout/index.tsx
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Captures the current page URL (the article the user is reading).
|
|
11
|
+
* Must be called before any redirect occurs.
|
|
12
|
+
*/
|
|
13
|
+
export declare const captureOriginUrl: () => string;
|
|
14
|
+
/**
|
|
15
|
+
* Extracts only the `country` query param from the current page URL for
|
|
16
|
+
* forwarding to /checkout/complete. All other params are intentionally excluded.
|
|
17
|
+
*
|
|
18
|
+
* Matches sma-checkout: src/hooks/use-query-string/useCountryCodeQueryString
|
|
19
|
+
* Only `country` is forwarded — feature flags, UTM tags, and all other host-page
|
|
20
|
+
* params must NOT be propagated to /checkout/complete.
|
|
21
|
+
*/
|
|
22
|
+
export declare const buildQueryString: () => string;
|
|
23
|
+
/**
|
|
24
|
+
* Decodes a Commerce Services encoded SKU to the raw offer path.
|
|
25
|
+
* e.g. LO-L29mZmVyczIvTkEt... → /offers2/NA-US.DIGITAL.MAAR...
|
|
26
|
+
*
|
|
27
|
+
* Matches sma-checkout: src/lib/commerce-services/decode-sku.ts
|
|
28
|
+
*/
|
|
29
|
+
export declare const decodeSku: (sku: string) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Builds the success redirect URL.
|
|
32
|
+
* /checkout/complete?basketId={id}&lmo_offer={sku}&status={userStatus}&redirectToCheckout=true&returnUrl=...
|
|
33
|
+
*/
|
|
34
|
+
export declare const redirectToCheckoutComplete: (params: {
|
|
35
|
+
basketId: string;
|
|
36
|
+
status: "nex" | "lex";
|
|
37
|
+
skuId: string;
|
|
38
|
+
returnUrl: string;
|
|
39
|
+
queryString?: string;
|
|
40
|
+
}) => string;
|
|
41
|
+
/**
|
|
42
|
+
* Builds the fallback redirect URL for error scenarios.
|
|
43
|
+
* /checkout?lmo_offer={sku}&inlineError=...&returnUrl=...
|
|
44
|
+
*
|
|
45
|
+
* Builds on top of the current page URL (window.location.href) so that any
|
|
46
|
+
* existing query params (UTM tags, campaign flags) are preserved — matching
|
|
47
|
+
* sma-checkout: src/lib/navigate-to-checkout/index.tsx
|
|
48
|
+
*/
|
|
49
|
+
export declare const redirectToCheckoutFallback: (params: {
|
|
50
|
+
skuId: string;
|
|
51
|
+
returnUrl: string;
|
|
52
|
+
inlineError?: string;
|
|
53
|
+
emailError?: string;
|
|
54
|
+
email?: string;
|
|
55
|
+
}) => string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/utils/expressCheckoutRedirect.ts
|
|
2
|
+
var captureOriginUrl = () => window.location.href;
|
|
3
|
+
var buildQueryString = () => {
|
|
4
|
+
const countryCode = new URLSearchParams(window.location.search).get(
|
|
5
|
+
"country"
|
|
6
|
+
);
|
|
7
|
+
return countryCode ? `&country=${encodeURIComponent(countryCode)}` : "";
|
|
8
|
+
};
|
|
9
|
+
var decodeSku = (sku) => {
|
|
10
|
+
try {
|
|
11
|
+
return atob(sku.substring(sku.indexOf("-") + 1));
|
|
12
|
+
} catch {
|
|
13
|
+
return sku;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var redirectToCheckoutComplete = (params) => {
|
|
17
|
+
const url = new URL("/checkout/complete", window.location.origin);
|
|
18
|
+
url.searchParams.set("basketId", params.basketId);
|
|
19
|
+
if (params.queryString) {
|
|
20
|
+
const qs = params.queryString.startsWith("?") ? params.queryString.slice(1) : params.queryString;
|
|
21
|
+
new URLSearchParams(qs).forEach((v, k) => url.searchParams.set(k, v));
|
|
22
|
+
}
|
|
23
|
+
url.searchParams.set("lmo_offer", params.skuId);
|
|
24
|
+
url.searchParams.set("status", params.status);
|
|
25
|
+
url.searchParams.set("redirectToCheckout", "true");
|
|
26
|
+
url.searchParams.set("returnUrl", params.returnUrl);
|
|
27
|
+
return url.pathname + url.search;
|
|
28
|
+
};
|
|
29
|
+
var redirectToCheckoutFallback = (params) => {
|
|
30
|
+
const url = new URL(window.location.href);
|
|
31
|
+
url.pathname = "/checkout";
|
|
32
|
+
url.searchParams.set("lmo_offer", params.skuId);
|
|
33
|
+
if (params.inlineError)
|
|
34
|
+
url.searchParams.set("inlineError", params.inlineError);
|
|
35
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
36
|
+
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
37
|
+
url.searchParams.set("returnUrl", params.returnUrl);
|
|
38
|
+
return url.pathname + url.search;
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
buildQueryString,
|
|
42
|
+
captureOriginUrl,
|
|
43
|
+
decodeSku,
|
|
44
|
+
redirectToCheckoutComplete,
|
|
45
|
+
redirectToCheckoutFallback
|
|
46
|
+
};
|