fingerprintjs
57 строк · 1.9 Кб
1export const enum ApplePayState {
2/* Apple Pay is disabled on the user device. Seems like it's never returned on iOS (based on few observations). */
3Disabled = 0,
4/** Apple Pay is enabled on the user device */
5Enabled = 1,
6/** The browser doesn't have the API to work with Apple Pay */
7NoAPI = -1,
8/** Using Apple Pay isn't allowed because the page context isn't secure (not HTTPS) */
9NotAvailableInInsecureContext = -2,
10/**
11* Using Apple Pay isn't allowed because the code runs in a frame,
12* and the frame origin doesn't match the top level page origin.
13*/
14NotAvailableInFrame = -3,
15}
16
17export default function getApplePayState(): ApplePayState {
18const { ApplePaySession } = window
19
20if (typeof ApplePaySession?.canMakePayments !== 'function') {
21return ApplePayState.NoAPI
22}
23
24try {
25return ApplePaySession.canMakePayments() ? ApplePayState.Enabled : ApplePayState.Disabled
26} catch (error) {
27return getStateFromError(error)
28}
29}
30
31/**
32* The return type is a union instead of the enum, because it's too challenging to embed the const enum into another
33* project. Turning it into a union is a simple and an elegant solution.
34*
35* Warning for package users:
36* This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.
37*/
38export function getStateFromError(error: unknown): -2 | -3 {
39if (error instanceof Error) {
40// See full expected error messages in the test
41if (error.name === 'InvalidAccessError') {
42if (/\bfrom\b.*\binsecure\b/i.test(error.message)) {
43return ApplePayState.NotAvailableInInsecureContext
44}
45if (/\bdifferent\b.*\borigin\b.*top.level\b.*\bframe\b/i.test(error.message)) {
46return ApplePayState.NotAvailableInFrame
47}
48}
49if (error.name === 'SecurityError') {
50if (/\bthird.party iframes?.*\bnot.allowed\b/i.test(error.message)) {
51return ApplePayState.NotAvailableInFrame
52}
53}
54}
55
56throw error
57}
58