@economist/web-apple-pay 1.1.0 → 1.2.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 +6 -2
- package/dist/index.js +76 -0
- package/dist/src/apple-pay-button.js +76 -0
- package/dist/src/clients/payment-checkout/config.d.ts +1 -0
- package/dist/src/clients/payment-checkout/detects.js +3 -0
- package/dist/src/clients/payment-checkout/index.d.ts +1 -0
- package/dist/src/clients/payment-checkout/index.js +59 -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/types.d.ts +14 -0
- package/dist/src/clients/payment-checkout/types.js +14 -0
- package/dist/src/index.js +76 -0
- package/dist/src/types/offer.types.d.ts +0 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ import { configureApplePay, defineApplePayElements } from '@economist/web-apple-
|
|
|
32
32
|
configureApplePay({
|
|
33
33
|
merchantId: 'merchant.com.economist.your-app',
|
|
34
34
|
debugBypassEnabled: false,
|
|
35
|
+
// required: wallet API base URL for session and checkout calls
|
|
36
|
+
walletApiBaseUrl: 'https://bff-test.economist.com',
|
|
35
37
|
});
|
|
36
38
|
|
|
37
39
|
defineApplePayElements();
|
|
@@ -57,11 +59,13 @@ When clicked, the button creates and opens `teg-apple-pay-modal` automatically.
|
|
|
57
59
|
### `configureApplePay(config)`
|
|
58
60
|
|
|
59
61
|
Sets package-level runtime configuration used by Apple Pay availability checks.
|
|
62
|
+
Call this once during app startup.
|
|
60
63
|
|
|
61
64
|
`config` shape:
|
|
62
65
|
|
|
63
66
|
- `merchantId` (`string`, required): Apple Pay merchant identifier used for active-card checks.
|
|
64
67
|
- `debugBypassEnabled` (`boolean`, optional): allows `?BYPASS_APPLE_PAY_CHECKS=1` query param to bypass capability checks in non-production-style debugging flows.
|
|
68
|
+
- `walletApiBaseUrl` (`string`, required): base URL for wallet API requests.
|
|
65
69
|
|
|
66
70
|
If `merchantId` is not configured, Apple Pay availability checks return `false` and the button hides itself.
|
|
67
71
|
|
|
@@ -94,7 +98,7 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
94
98
|
## Public API
|
|
95
99
|
|
|
96
100
|
- `defineApplePayElements()`: registers both custom elements.
|
|
97
|
-
- `configureApplePay(config)`: sets required runtime config (merchant ID and optional debug bypass).
|
|
101
|
+
- `configureApplePay(config)`: sets required runtime config (merchant ID and wallet API base URL, with optional debug bypass).
|
|
98
102
|
- `ApplePayButton`: button component class.
|
|
99
103
|
- `ApplePayModal`: modal component class.
|
|
100
104
|
- `ensureApplePayLogoSymbol()`: logo symbol injection helper.
|
|
@@ -106,7 +110,7 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
106
110
|
|
|
107
111
|
Check:
|
|
108
112
|
|
|
109
|
-
- `configureApplePay(...)` was called before rendering (with a valid `merchantId`)
|
|
113
|
+
- `configureApplePay(...)` was called before rendering (with a valid `merchantId` and `walletApiBaseUrl`)
|
|
110
114
|
- device/browser supports Apple Pay checks (Safari/Apple device logic)
|
|
111
115
|
- query string/feature flag gating for your page is satisfied
|
|
112
116
|
- offer variant is not excluded (`bundle`, `insider_print`)
|
package/dist/index.js
CHANGED
|
@@ -775,6 +775,9 @@ var isApplePayAvailable = async () => {
|
|
|
775
775
|
}
|
|
776
776
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
777
777
|
if (!merchantId) {
|
|
778
|
+
console.warn(
|
|
779
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
780
|
+
);
|
|
778
781
|
return false;
|
|
779
782
|
}
|
|
780
783
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -784,6 +787,67 @@ var isApplePayAvailable = async () => {
|
|
|
784
787
|
}
|
|
785
788
|
};
|
|
786
789
|
|
|
790
|
+
// src/clients/payment-checkout/types.ts
|
|
791
|
+
var ApiError = class extends Error {
|
|
792
|
+
status;
|
|
793
|
+
body;
|
|
794
|
+
constructor(status, body) {
|
|
795
|
+
super(`API request failed with status ${status}`);
|
|
796
|
+
this.name = "ApiError";
|
|
797
|
+
this.status = status;
|
|
798
|
+
this.body = body;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
// src/clients/payment-checkout/index.ts
|
|
803
|
+
var getWalletApiBaseUrl = () => {
|
|
804
|
+
const config = getApplePayConfig();
|
|
805
|
+
if (!config?.walletApiBaseUrl) {
|
|
806
|
+
throw new Error(
|
|
807
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
return config.walletApiBaseUrl;
|
|
811
|
+
};
|
|
812
|
+
var apiFetch = async (path, options = {}) => {
|
|
813
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
814
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
815
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
816
|
+
const headers = new Headers(options.headers);
|
|
817
|
+
if (!headers.has("Accept")) {
|
|
818
|
+
headers.set("Accept", "application/json");
|
|
819
|
+
}
|
|
820
|
+
if (!headers.has("Content-Type")) {
|
|
821
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
822
|
+
headers.set("Content-Type", "application/json");
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
826
|
+
...options,
|
|
827
|
+
headers
|
|
828
|
+
});
|
|
829
|
+
if (!response.ok) {
|
|
830
|
+
const contentType = response.headers.get("content-type") || "";
|
|
831
|
+
if (contentType.includes("application/json")) {
|
|
832
|
+
const errorBody = await response.json();
|
|
833
|
+
throw new ApiError(response.status, errorBody);
|
|
834
|
+
}
|
|
835
|
+
const errorText = await response.text();
|
|
836
|
+
throw new Error(
|
|
837
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
return response.json();
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// src/clients/payment-checkout/session.ts
|
|
844
|
+
var getExpressCheckoutSession = () => {
|
|
845
|
+
return apiFetch("/v1/wallet/session", {
|
|
846
|
+
method: "GET",
|
|
847
|
+
credentials: "include"
|
|
848
|
+
});
|
|
849
|
+
};
|
|
850
|
+
|
|
787
851
|
// src/apple-pay-button.ts
|
|
788
852
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
789
853
|
var APPLE_PAY_EXCLUDED_VARIANTS = ["bundle", "insider_print"];
|
|
@@ -841,6 +905,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
841
905
|
this.style.display = "none";
|
|
842
906
|
return;
|
|
843
907
|
}
|
|
908
|
+
const sessionData = await this.#fetchSession();
|
|
909
|
+
if (sessionData?.loggedIn && (sessionData.userType === "active-subscription" || sessionData.userType === "b2b-user")) {
|
|
910
|
+
this.style.display = "none";
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
844
913
|
this.style.removeProperty("display");
|
|
845
914
|
ensureApplePayLogoSymbol();
|
|
846
915
|
const template = document.createElement("template");
|
|
@@ -883,6 +952,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
883
952
|
button.setAttribute("disabled", "");
|
|
884
953
|
button.setAttribute("aria-disabled", "true");
|
|
885
954
|
}
|
|
955
|
+
async #fetchSession() {
|
|
956
|
+
try {
|
|
957
|
+
return await getExpressCheckoutSession();
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
886
962
|
};
|
|
887
963
|
|
|
888
964
|
// src/index.ts
|
|
@@ -770,6 +770,9 @@ var isApplePayAvailable = async () => {
|
|
|
770
770
|
}
|
|
771
771
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
772
772
|
if (!merchantId) {
|
|
773
|
+
console.warn(
|
|
774
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
775
|
+
);
|
|
773
776
|
return false;
|
|
774
777
|
}
|
|
775
778
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -779,6 +782,67 @@ var isApplePayAvailable = async () => {
|
|
|
779
782
|
}
|
|
780
783
|
};
|
|
781
784
|
|
|
785
|
+
// src/clients/payment-checkout/types.ts
|
|
786
|
+
var ApiError = class extends Error {
|
|
787
|
+
status;
|
|
788
|
+
body;
|
|
789
|
+
constructor(status, body) {
|
|
790
|
+
super(`API request failed with status ${status}`);
|
|
791
|
+
this.name = "ApiError";
|
|
792
|
+
this.status = status;
|
|
793
|
+
this.body = body;
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/clients/payment-checkout/index.ts
|
|
798
|
+
var getWalletApiBaseUrl = () => {
|
|
799
|
+
const config = getApplePayConfig();
|
|
800
|
+
if (!config?.walletApiBaseUrl) {
|
|
801
|
+
throw new Error(
|
|
802
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
return config.walletApiBaseUrl;
|
|
806
|
+
};
|
|
807
|
+
var apiFetch = async (path, options = {}) => {
|
|
808
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
809
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
810
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
811
|
+
const headers = new Headers(options.headers);
|
|
812
|
+
if (!headers.has("Accept")) {
|
|
813
|
+
headers.set("Accept", "application/json");
|
|
814
|
+
}
|
|
815
|
+
if (!headers.has("Content-Type")) {
|
|
816
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
817
|
+
headers.set("Content-Type", "application/json");
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
821
|
+
...options,
|
|
822
|
+
headers
|
|
823
|
+
});
|
|
824
|
+
if (!response.ok) {
|
|
825
|
+
const contentType = response.headers.get("content-type") || "";
|
|
826
|
+
if (contentType.includes("application/json")) {
|
|
827
|
+
const errorBody = await response.json();
|
|
828
|
+
throw new ApiError(response.status, errorBody);
|
|
829
|
+
}
|
|
830
|
+
const errorText = await response.text();
|
|
831
|
+
throw new Error(
|
|
832
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
return response.json();
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
// src/clients/payment-checkout/session.ts
|
|
839
|
+
var getExpressCheckoutSession = () => {
|
|
840
|
+
return apiFetch("/v1/wallet/session", {
|
|
841
|
+
method: "GET",
|
|
842
|
+
credentials: "include"
|
|
843
|
+
});
|
|
844
|
+
};
|
|
845
|
+
|
|
782
846
|
// src/apple-pay-button.ts
|
|
783
847
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
784
848
|
var APPLE_PAY_EXCLUDED_VARIANTS = ["bundle", "insider_print"];
|
|
@@ -836,6 +900,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
836
900
|
this.style.display = "none";
|
|
837
901
|
return;
|
|
838
902
|
}
|
|
903
|
+
const sessionData = await this.#fetchSession();
|
|
904
|
+
if (sessionData?.loggedIn && (sessionData.userType === "active-subscription" || sessionData.userType === "b2b-user")) {
|
|
905
|
+
this.style.display = "none";
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
839
908
|
this.style.removeProperty("display");
|
|
840
909
|
ensureApplePayLogoSymbol();
|
|
841
910
|
const template = document.createElement("template");
|
|
@@ -878,6 +947,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
878
947
|
button.setAttribute("disabled", "");
|
|
879
948
|
button.setAttribute("aria-disabled", "true");
|
|
880
949
|
}
|
|
950
|
+
async #fetchSession() {
|
|
951
|
+
try {
|
|
952
|
+
return await getExpressCheckoutSession();
|
|
953
|
+
} catch {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
881
957
|
};
|
|
882
958
|
export {
|
|
883
959
|
ApplePayButton
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface ApplePayRuntimeConfig {
|
|
2
2
|
merchantId: string;
|
|
3
3
|
debugBypassEnabled?: boolean;
|
|
4
|
+
walletApiBaseUrl: string;
|
|
4
5
|
}
|
|
5
6
|
export declare const configureApplePay: (config: ApplePayRuntimeConfig) => void;
|
|
6
7
|
export declare const getApplePayConfig: () => ApplePayRuntimeConfig | null;
|
|
@@ -29,6 +29,9 @@ var isApplePayAvailable = async () => {
|
|
|
29
29
|
}
|
|
30
30
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
31
31
|
if (!merchantId) {
|
|
32
|
+
console.warn(
|
|
33
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
34
|
+
);
|
|
32
35
|
return false;
|
|
33
36
|
}
|
|
34
37
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const apiFetch: <T>(path: string, options?: RequestInit) => Promise<T>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var getApplePayConfig = () => runtimeConfig;
|
|
4
|
+
|
|
5
|
+
// src/clients/payment-checkout/types.ts
|
|
6
|
+
var ApiError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
body;
|
|
9
|
+
constructor(status, body) {
|
|
10
|
+
super(`API request failed with status ${status}`);
|
|
11
|
+
this.name = "ApiError";
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/clients/payment-checkout/index.ts
|
|
18
|
+
var getWalletApiBaseUrl = () => {
|
|
19
|
+
const config = getApplePayConfig();
|
|
20
|
+
if (!config?.walletApiBaseUrl) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return config.walletApiBaseUrl;
|
|
26
|
+
};
|
|
27
|
+
var apiFetch = async (path, options = {}) => {
|
|
28
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
29
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
30
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
31
|
+
const headers = new Headers(options.headers);
|
|
32
|
+
if (!headers.has("Accept")) {
|
|
33
|
+
headers.set("Accept", "application/json");
|
|
34
|
+
}
|
|
35
|
+
if (!headers.has("Content-Type")) {
|
|
36
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
37
|
+
headers.set("Content-Type", "application/json");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
41
|
+
...options,
|
|
42
|
+
headers
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const contentType = response.headers.get("content-type") || "";
|
|
46
|
+
if (contentType.includes("application/json")) {
|
|
47
|
+
const errorBody = await response.json();
|
|
48
|
+
throw new ApiError(response.status, errorBody);
|
|
49
|
+
}
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
throw new Error(
|
|
52
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return response.json();
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
apiFetch
|
|
59
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var getApplePayConfig = () => runtimeConfig;
|
|
4
|
+
|
|
5
|
+
// src/clients/payment-checkout/types.ts
|
|
6
|
+
var ApiError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
body;
|
|
9
|
+
constructor(status, body) {
|
|
10
|
+
super(`API request failed with status ${status}`);
|
|
11
|
+
this.name = "ApiError";
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/clients/payment-checkout/index.ts
|
|
18
|
+
var getWalletApiBaseUrl = () => {
|
|
19
|
+
const config = getApplePayConfig();
|
|
20
|
+
if (!config?.walletApiBaseUrl) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return config.walletApiBaseUrl;
|
|
26
|
+
};
|
|
27
|
+
var apiFetch = async (path, options = {}) => {
|
|
28
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
29
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
30
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
31
|
+
const headers = new Headers(options.headers);
|
|
32
|
+
if (!headers.has("Accept")) {
|
|
33
|
+
headers.set("Accept", "application/json");
|
|
34
|
+
}
|
|
35
|
+
if (!headers.has("Content-Type")) {
|
|
36
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
37
|
+
headers.set("Content-Type", "application/json");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
41
|
+
...options,
|
|
42
|
+
headers
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const contentType = response.headers.get("content-type") || "";
|
|
46
|
+
if (contentType.includes("application/json")) {
|
|
47
|
+
const errorBody = await response.json();
|
|
48
|
+
throw new ApiError(response.status, errorBody);
|
|
49
|
+
}
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
throw new Error(
|
|
52
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return response.json();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/clients/payment-checkout/session.ts
|
|
59
|
+
var getExpressCheckoutSession = () => {
|
|
60
|
+
return apiFetch("/v1/wallet/session", {
|
|
61
|
+
method: "GET",
|
|
62
|
+
credentials: "include"
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export {
|
|
66
|
+
getExpressCheckoutSession
|
|
67
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type SessionResponse = {
|
|
2
|
+
loggedIn: false;
|
|
3
|
+
userType: 'new-eligible-user';
|
|
4
|
+
} | {
|
|
5
|
+
loggedIn: true;
|
|
6
|
+
emailAddress: string;
|
|
7
|
+
contactId: string;
|
|
8
|
+
userType: 'active-subscription' | 'b2b-user' | 'new-eligible-user';
|
|
9
|
+
};
|
|
10
|
+
export declare class ApiError extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly body: unknown;
|
|
13
|
+
constructor(status: number, body: unknown);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/clients/payment-checkout/types.ts
|
|
2
|
+
var ApiError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
body;
|
|
5
|
+
constructor(status, body) {
|
|
6
|
+
super(`API request failed with status ${status}`);
|
|
7
|
+
this.name = "ApiError";
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.body = body;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
ApiError
|
|
14
|
+
};
|
package/dist/src/index.js
CHANGED
|
@@ -775,6 +775,9 @@ var isApplePayAvailable = async () => {
|
|
|
775
775
|
}
|
|
776
776
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
777
777
|
if (!merchantId) {
|
|
778
|
+
console.warn(
|
|
779
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
780
|
+
);
|
|
778
781
|
return false;
|
|
779
782
|
}
|
|
780
783
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -784,6 +787,67 @@ var isApplePayAvailable = async () => {
|
|
|
784
787
|
}
|
|
785
788
|
};
|
|
786
789
|
|
|
790
|
+
// src/clients/payment-checkout/types.ts
|
|
791
|
+
var ApiError = class extends Error {
|
|
792
|
+
status;
|
|
793
|
+
body;
|
|
794
|
+
constructor(status, body) {
|
|
795
|
+
super(`API request failed with status ${status}`);
|
|
796
|
+
this.name = "ApiError";
|
|
797
|
+
this.status = status;
|
|
798
|
+
this.body = body;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
// src/clients/payment-checkout/index.ts
|
|
803
|
+
var getWalletApiBaseUrl = () => {
|
|
804
|
+
const config = getApplePayConfig();
|
|
805
|
+
if (!config?.walletApiBaseUrl) {
|
|
806
|
+
throw new Error(
|
|
807
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
return config.walletApiBaseUrl;
|
|
811
|
+
};
|
|
812
|
+
var apiFetch = async (path, options = {}) => {
|
|
813
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
814
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
815
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
816
|
+
const headers = new Headers(options.headers);
|
|
817
|
+
if (!headers.has("Accept")) {
|
|
818
|
+
headers.set("Accept", "application/json");
|
|
819
|
+
}
|
|
820
|
+
if (!headers.has("Content-Type")) {
|
|
821
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
822
|
+
headers.set("Content-Type", "application/json");
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
826
|
+
...options,
|
|
827
|
+
headers
|
|
828
|
+
});
|
|
829
|
+
if (!response.ok) {
|
|
830
|
+
const contentType = response.headers.get("content-type") || "";
|
|
831
|
+
if (contentType.includes("application/json")) {
|
|
832
|
+
const errorBody = await response.json();
|
|
833
|
+
throw new ApiError(response.status, errorBody);
|
|
834
|
+
}
|
|
835
|
+
const errorText = await response.text();
|
|
836
|
+
throw new Error(
|
|
837
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
return response.json();
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// src/clients/payment-checkout/session.ts
|
|
844
|
+
var getExpressCheckoutSession = () => {
|
|
845
|
+
return apiFetch("/v1/wallet/session", {
|
|
846
|
+
method: "GET",
|
|
847
|
+
credentials: "include"
|
|
848
|
+
});
|
|
849
|
+
};
|
|
850
|
+
|
|
787
851
|
// src/apple-pay-button.ts
|
|
788
852
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
789
853
|
var APPLE_PAY_EXCLUDED_VARIANTS = ["bundle", "insider_print"];
|
|
@@ -841,6 +905,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
841
905
|
this.style.display = "none";
|
|
842
906
|
return;
|
|
843
907
|
}
|
|
908
|
+
const sessionData = await this.#fetchSession();
|
|
909
|
+
if (sessionData?.loggedIn && (sessionData.userType === "active-subscription" || sessionData.userType === "b2b-user")) {
|
|
910
|
+
this.style.display = "none";
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
844
913
|
this.style.removeProperty("display");
|
|
845
914
|
ensureApplePayLogoSymbol();
|
|
846
915
|
const template = document.createElement("template");
|
|
@@ -883,6 +952,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
883
952
|
button.setAttribute("disabled", "");
|
|
884
953
|
button.setAttribute("aria-disabled", "true");
|
|
885
954
|
}
|
|
955
|
+
async #fetchSession() {
|
|
956
|
+
try {
|
|
957
|
+
return await getExpressCheckoutSession();
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
886
962
|
};
|
|
887
963
|
|
|
888
964
|
// src/index.ts
|
|
@@ -71,13 +71,3 @@ export type Offer = {
|
|
|
71
71
|
content?: Content;
|
|
72
72
|
meta_data?: MetaData;
|
|
73
73
|
};
|
|
74
|
-
/** Total number of items matching the relevant lookup. */
|
|
75
|
-
export type ResponseModelMetaTotal = {
|
|
76
|
-
total: number;
|
|
77
|
-
};
|
|
78
|
-
export type ResponsePostPricedSkuOffer = {
|
|
79
|
-
/** Offer list. */
|
|
80
|
-
data: Offer[] | null;
|
|
81
|
-
/** Set of key value pairs. */
|
|
82
|
-
meta: ResponseModelMetaTotal | null;
|
|
83
|
-
};
|