@paypal/checkout-components 5.0.344 → 5.0.345-alpha-bb62853.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/package.json +1 -1
- package/src/lib/security.js +12 -1
- package/src/three-domain-secure/component.jsx +117 -14
- package/src/three-domain-secure/component.test.js +99 -8
- package/src/three-domain-secure/interface.js +12 -5
- package/src/three-domain-secure/types.js +77 -0
- package/src/three-domain-secure/utils.jsx +108 -0
- package/src/ui/overlay/index.jsx +3 -0
- package/src/ui/overlay/overlay.jsx +228 -0
- package/src/ui/overlay/style.jsx +380 -0
package/package.json
CHANGED
package/src/lib/security.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { isSameDomain } from "@krakenjs/cross-domain-utils/src";
|
|
4
4
|
import { supportsPopups } from "@krakenjs/belter/src";
|
|
5
|
-
import { isPayPalDomain } from "@paypal/sdk-client/src";
|
|
5
|
+
import { getEnv, isPayPalDomain } from "@paypal/sdk-client/src";
|
|
6
|
+
import { ENV } from "@paypal/sdk-constants/src";
|
|
6
7
|
|
|
7
8
|
export function allowIframe(): boolean {
|
|
8
9
|
if (!isPayPalDomain()) {
|
|
@@ -28,3 +29,13 @@ export function allowIframe(): boolean {
|
|
|
28
29
|
export const protectedExport = (unprotectedExport) =>
|
|
29
30
|
isPayPalDomain() ? unprotectedExport : undefined;
|
|
30
31
|
/* eslint-enable no-confusing-arrow */
|
|
32
|
+
|
|
33
|
+
// $FlowIssue
|
|
34
|
+
export const localOrStageExport = (unprotectedExport) => {
|
|
35
|
+
const env = getEnv();
|
|
36
|
+
if (env === ENV.LOCAL || env === ENV.STAGE) {
|
|
37
|
+
return unprotectedExport;
|
|
38
|
+
} else {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
+
/* eslint-disable eslint-comments/disable-enable-pair */
|
|
3
|
+
/* eslint-disable no-restricted-globals, promise/no-native */
|
|
2
4
|
import { type LoggerType } from "@krakenjs/beaver-logger/src";
|
|
5
|
+
import { type ZoidComponent } from "@krakenjs/zoid/src";
|
|
3
6
|
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
4
|
-
import { create, type ZoidComponent } from "@krakenjs/zoid/src";
|
|
5
7
|
import { FPTI_KEY } from "@paypal/sdk-constants/src";
|
|
6
8
|
|
|
7
9
|
import { ValidationError } from "../lib";
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
import {
|
|
12
|
+
requestData,
|
|
13
|
+
responseBody,
|
|
14
|
+
Request,
|
|
15
|
+
MerchantPayloadData,
|
|
16
|
+
SdkConfig,
|
|
17
|
+
threeDSResponse,
|
|
18
|
+
} from "./types";
|
|
19
|
+
import { getThreeDomainSecureComponent } from "./utils";
|
|
12
20
|
|
|
13
21
|
const parseSdkConfig = ({ sdkConfig, logger }): SdkConfig => {
|
|
14
|
-
if (!sdkConfig.
|
|
22
|
+
if (!sdkConfig.authenticationToken) {
|
|
15
23
|
throw new ValidationError(
|
|
16
24
|
`script data attribute sdk-client-token is required but was not passed`
|
|
17
25
|
);
|
|
@@ -23,32 +31,127 @@ const parseSdkConfig = ({ sdkConfig, logger }): SdkConfig => {
|
|
|
23
31
|
|
|
24
32
|
return sdkConfig;
|
|
25
33
|
};
|
|
34
|
+
|
|
35
|
+
const parseMerchantPayload = ({
|
|
36
|
+
merchantPayload,
|
|
37
|
+
}: {|
|
|
38
|
+
merchantPayload: MerchantPayloadData,
|
|
39
|
+
|}): requestData => {
|
|
40
|
+
const { threeDSRequested, amount, currency, nonce, transactionContext } =
|
|
41
|
+
merchantPayload;
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
intent: "THREE_DS_VERIFICATION",
|
|
45
|
+
payment_source: {
|
|
46
|
+
card: {
|
|
47
|
+
single_use_token: nonce,
|
|
48
|
+
verification_method: threeDSRequested
|
|
49
|
+
? "SCA_ALWAYS"
|
|
50
|
+
: "SCA_WHEN_REQUIRED",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
amount: {
|
|
54
|
+
currency_code: currency,
|
|
55
|
+
value: amount,
|
|
56
|
+
},
|
|
57
|
+
...transactionContext,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
26
61
|
export interface ThreeDomainSecureComponentInterface {
|
|
27
|
-
isEligible():
|
|
28
|
-
show():
|
|
62
|
+
isEligible(): Promise<boolean>;
|
|
63
|
+
show(): Promise<threeDSResponse>;
|
|
29
64
|
}
|
|
30
65
|
export class ThreeDomainSecureComponent {
|
|
31
66
|
logger: LoggerType;
|
|
67
|
+
request: Request;
|
|
32
68
|
sdkConfig: SdkConfig;
|
|
33
|
-
|
|
69
|
+
authenticationURL: string;
|
|
70
|
+
threeDSIframe: ZoidComponent;
|
|
34
71
|
constructor({
|
|
35
72
|
logger,
|
|
73
|
+
request,
|
|
36
74
|
sdkConfig,
|
|
37
75
|
}: {|
|
|
38
76
|
logger: LoggerType,
|
|
77
|
+
request: Request,
|
|
39
78
|
sdkConfig: SdkConfig,
|
|
40
79
|
|}) {
|
|
41
80
|
this.logger = logger;
|
|
81
|
+
this.request = request;
|
|
42
82
|
this.sdkConfig = parseSdkConfig({ sdkConfig, logger });
|
|
43
83
|
}
|
|
44
84
|
|
|
45
|
-
isEligible():
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
85
|
+
async isEligible(merchantPayload: MerchantPayloadData): Promise<boolean> {
|
|
86
|
+
const data = parseMerchantPayload({ merchantPayload });
|
|
87
|
+
try {
|
|
88
|
+
// $FlowFixMe
|
|
89
|
+
const { status, links } = await this.request<requestData, responseBody>({
|
|
90
|
+
method: "POST",
|
|
91
|
+
url: `https://te-test-qa.qa.paypal.com:12326/v2/payments/payment`,
|
|
92
|
+
data,
|
|
93
|
+
accessToken: this.sdkConfig.authenticationToken,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
let responseStatus = false;
|
|
97
|
+
|
|
98
|
+
if (status === "PAYER_ACTION_REQUIRED") {
|
|
99
|
+
this.authenticationURL = links.find(
|
|
100
|
+
(link) => link.rel === "payer-action"
|
|
101
|
+
).href;
|
|
102
|
+
responseStatus = true;
|
|
103
|
+
this.threeDSIframe = getThreeDomainSecureComponent(
|
|
104
|
+
this.authenticationURL
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return responseStatus;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
this.logger.warn(error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
49
112
|
}
|
|
50
113
|
|
|
51
|
-
show() {
|
|
52
|
-
|
|
114
|
+
show(): Promise<threeDSResponse> {
|
|
115
|
+
if (!this.threeDSIframe) {
|
|
116
|
+
throw new ValidationError(`Ineligible for three domain secure`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const promise = new ZalgoPromise();
|
|
120
|
+
const cancelThreeDS = () => {
|
|
121
|
+
return ZalgoPromise.try(() => {
|
|
122
|
+
// eslint-disable-next-line no-console
|
|
123
|
+
console.log("cancelled");
|
|
124
|
+
}).then(() => {
|
|
125
|
+
// eslint-disable-next-line no-use-before-define
|
|
126
|
+
instance.close();
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const instance = this.threeDSIframe({
|
|
131
|
+
onSuccess: (data) => {
|
|
132
|
+
// const {threeDSRefID, authentication_status, liability_shift } = data;
|
|
133
|
+
// let enrichedNonce;
|
|
134
|
+
// if(threeDSRefID) {
|
|
135
|
+
// enrichedNonce = await updateNonceWith3dsData(threeDSRefID, this.fastlaneNonce)
|
|
136
|
+
// }
|
|
137
|
+
|
|
138
|
+
return promise.resolve(data);
|
|
139
|
+
},
|
|
140
|
+
onClose: cancelThreeDS,
|
|
141
|
+
onError: (err) => {
|
|
142
|
+
return promise.reject(
|
|
143
|
+
new Error(
|
|
144
|
+
`Error with obtaining 3DS contingency, ${JSON.stringify(err)}`
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const TARGET_ELEMENT = {
|
|
150
|
+
BODY: "body",
|
|
151
|
+
};
|
|
152
|
+
return instance
|
|
153
|
+
.renderTo(window.parent, TARGET_ELEMENT.BODY)
|
|
154
|
+
.then(() => promise)
|
|
155
|
+
.finally(instance.close);
|
|
53
156
|
}
|
|
54
157
|
}
|
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
+
/* eslint-disable eslint-comments/disable-enable-pair */
|
|
3
|
+
/* eslint-disable no-restricted-globals, promise/no-native, compat/compat */
|
|
2
4
|
import { describe, expect, vi } from "vitest";
|
|
3
5
|
|
|
4
6
|
import { ThreeDomainSecureComponent } from "./component";
|
|
5
7
|
|
|
6
8
|
const defaultSdkConfig = {
|
|
7
|
-
|
|
9
|
+
authenticationToken: "sdk-client-token",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const defaultEligibilityResponse = {
|
|
13
|
+
status: "PAYER_ACTION_REQUIRED",
|
|
14
|
+
links: [{ href: "https://testurl.com", rel: "payer-action" }],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const defaultMerchantPayload = {
|
|
18
|
+
amount: "1.00",
|
|
19
|
+
currency: "USD",
|
|
20
|
+
nonce: "test-nonce",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const mockEligibilityRequest = (body = defaultEligibilityResponse) => {
|
|
24
|
+
return vi.fn().mockResolvedValue(body);
|
|
8
25
|
};
|
|
9
26
|
|
|
10
27
|
const createThreeDomainSecureComponent = ({
|
|
11
28
|
sdkConfig = defaultSdkConfig,
|
|
29
|
+
request = mockEligibilityRequest(),
|
|
12
30
|
logger = {
|
|
13
31
|
info: vi.fn().mockReturnThis(),
|
|
14
32
|
warn: vi.fn().mockReturnThis(),
|
|
@@ -18,8 +36,11 @@ const createThreeDomainSecureComponent = ({
|
|
|
18
36
|
},
|
|
19
37
|
} = {}) =>
|
|
20
38
|
new ThreeDomainSecureComponent({
|
|
39
|
+
// $FlowFixMe
|
|
21
40
|
sdkConfig,
|
|
22
41
|
// $FlowIssue
|
|
42
|
+
request,
|
|
43
|
+
// $FlowIssue
|
|
23
44
|
logger,
|
|
24
45
|
});
|
|
25
46
|
|
|
@@ -28,17 +49,87 @@ afterEach(() => {
|
|
|
28
49
|
});
|
|
29
50
|
|
|
30
51
|
describe("three domain secure component - isEligible method", () => {
|
|
31
|
-
test("should return
|
|
32
|
-
const
|
|
33
|
-
const eligibility = await
|
|
52
|
+
test("should return true if payer action required", async () => {
|
|
53
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent();
|
|
54
|
+
const eligibility = await threeDomainSecureClient.isEligible(
|
|
55
|
+
defaultMerchantPayload
|
|
56
|
+
);
|
|
57
|
+
expect(eligibility).toEqual(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("should return false if payer action is not returned", async () => {
|
|
61
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent({
|
|
62
|
+
request: () =>
|
|
63
|
+
Promise.resolve({ ...defaultEligibilityResponse, status: "SUCCESS" }),
|
|
64
|
+
});
|
|
65
|
+
const eligibility = await threeDomainSecureClient.isEligible(
|
|
66
|
+
defaultMerchantPayload
|
|
67
|
+
);
|
|
34
68
|
expect(eligibility).toEqual(false);
|
|
35
69
|
});
|
|
70
|
+
|
|
71
|
+
test("should assign correct URL to authenticationURL", async () => {
|
|
72
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent({
|
|
73
|
+
request: () =>
|
|
74
|
+
Promise.resolve({
|
|
75
|
+
...defaultEligibilityResponse,
|
|
76
|
+
links: [
|
|
77
|
+
{ href: "https://not-payer-action.com", rel: "not-payer-action" },
|
|
78
|
+
...defaultEligibilityResponse.links,
|
|
79
|
+
],
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
await threeDomainSecureClient.isEligible(defaultMerchantPayload);
|
|
83
|
+
expect(threeDomainSecureClient.authenticationURL).toEqual(
|
|
84
|
+
"https://testurl.com"
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("create payload with correctly parameters", async () => {
|
|
89
|
+
const mockedRequest = mockEligibilityRequest();
|
|
90
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent({
|
|
91
|
+
request: mockedRequest,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await threeDomainSecureClient.isEligible(defaultMerchantPayload);
|
|
95
|
+
|
|
96
|
+
expect(mockedRequest).toHaveBeenCalledWith(
|
|
97
|
+
expect.objectContaining({
|
|
98
|
+
data: expect.objectContaining({
|
|
99
|
+
intent: "THREE_DS_VERIFICATION",
|
|
100
|
+
payment_source: expect.objectContaining({
|
|
101
|
+
card: expect.objectContaining({
|
|
102
|
+
single_use_token: defaultMerchantPayload.nonce,
|
|
103
|
+
verification_method: "SCA_WHEN_REQUIRED",
|
|
104
|
+
}),
|
|
105
|
+
}),
|
|
106
|
+
amount: expect.objectContaining({
|
|
107
|
+
currency_code: defaultMerchantPayload.currency,
|
|
108
|
+
value: defaultMerchantPayload.amount,
|
|
109
|
+
}),
|
|
110
|
+
}),
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("catch errors from the API", async () => {
|
|
116
|
+
const mockRequest = vi.fn().mockRejectedValue(new Error("Error with API"));
|
|
117
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent({
|
|
118
|
+
request: mockRequest,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect.assertions(2);
|
|
122
|
+
await expect(() =>
|
|
123
|
+
threeDomainSecureClient.isEligible(defaultMerchantPayload)
|
|
124
|
+
).rejects.toThrow(new Error("Error with API"));
|
|
125
|
+
expect(mockRequest).toHaveBeenCalled();
|
|
126
|
+
});
|
|
36
127
|
});
|
|
37
128
|
|
|
38
129
|
describe("three domain descure component - show method", () => {
|
|
39
|
-
test.
|
|
40
|
-
const
|
|
41
|
-
|
|
130
|
+
test.todo("should return a zoid component", () => {
|
|
131
|
+
const threeDomainSecureClient = createThreeDomainSecureComponent();
|
|
132
|
+
threeDomainSecureClient.show();
|
|
42
133
|
// create test for zoid component
|
|
43
134
|
});
|
|
44
135
|
});
|
|
@@ -49,7 +140,7 @@ describe("three domain secure component - initialization", () => {
|
|
|
49
140
|
createThreeDomainSecureComponent({
|
|
50
141
|
sdkConfig: {
|
|
51
142
|
...defaultSdkConfig,
|
|
52
|
-
|
|
143
|
+
authenticationToken: "",
|
|
53
144
|
},
|
|
54
145
|
})
|
|
55
146
|
).toThrowError(
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getLogger,
|
|
4
|
+
getPayPalAPIDomain,
|
|
5
|
+
getUserIDToken,
|
|
6
|
+
} from "@paypal/sdk-client/src";
|
|
3
7
|
|
|
8
|
+
import { callRestAPI, localOrStageExport } from "../lib";
|
|
4
9
|
import type { LazyExport } from "../types";
|
|
5
|
-
import { protectedExport } from "../lib";
|
|
6
10
|
|
|
7
11
|
import {
|
|
8
12
|
ThreeDomainSecureComponent,
|
|
@@ -14,12 +18,15 @@ export const ThreeDomainSecureClient: LazyExport<ThreeDomainSecureComponentInter
|
|
|
14
18
|
__get__: () => {
|
|
15
19
|
const threeDomainSecureInstance = new ThreeDomainSecureComponent({
|
|
16
20
|
logger: getLogger(),
|
|
21
|
+
// $FlowIssue ZalgoPromise vs Promise
|
|
22
|
+
request: callRestAPI,
|
|
17
23
|
sdkConfig: {
|
|
18
|
-
|
|
24
|
+
authenticationToken: getUserIDToken(),
|
|
25
|
+
paypalApiDomain: getPayPalAPIDomain(),
|
|
19
26
|
},
|
|
20
27
|
});
|
|
21
|
-
return
|
|
22
|
-
isEligible: () => threeDomainSecureInstance.isEligible(),
|
|
28
|
+
return localOrStageExport({
|
|
29
|
+
isEligible: (payload) => threeDomainSecureInstance.isEligible(payload),
|
|
23
30
|
show: () => threeDomainSecureInstance.show(),
|
|
24
31
|
});
|
|
25
32
|
},
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
/* eslint-disable no-restricted-globals, promise/no-native */
|
|
3
|
+
export type MerchantPayloadData = {|
|
|
4
|
+
amount: string,
|
|
5
|
+
currency: string,
|
|
6
|
+
nonce: string,
|
|
7
|
+
threeDSRequested?: boolean,
|
|
8
|
+
transactionContext?: Object,
|
|
9
|
+
|};
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line no-undef
|
|
12
|
+
export type Request = <TRequestData, TResponse>({|
|
|
13
|
+
method?: string,
|
|
14
|
+
url: string,
|
|
15
|
+
// eslint-disable-next-line no-undef
|
|
16
|
+
data: TRequestData,
|
|
17
|
+
accessToken: ?string,
|
|
18
|
+
// eslint-disable-next-line no-undef
|
|
19
|
+
|}) => Promise<TResponse>;
|
|
20
|
+
|
|
21
|
+
export type requestData = {|
|
|
22
|
+
intent: "THREE_DS_VERIFICATION",
|
|
23
|
+
payment_source: {|
|
|
24
|
+
card: {|
|
|
25
|
+
single_use_token: string,
|
|
26
|
+
verification_method: string,
|
|
27
|
+
|},
|
|
28
|
+
|},
|
|
29
|
+
amount: {|
|
|
30
|
+
currency_code: string,
|
|
31
|
+
value: string,
|
|
32
|
+
|},
|
|
33
|
+
transaction_context?: {|
|
|
34
|
+
soft_descriptor?: string,
|
|
35
|
+
|},
|
|
36
|
+
|};
|
|
37
|
+
|
|
38
|
+
export type responseBody = {|
|
|
39
|
+
payment_id: string,
|
|
40
|
+
status: string,
|
|
41
|
+
intent: string,
|
|
42
|
+
payment_source: {|
|
|
43
|
+
card: {|
|
|
44
|
+
last_digits: string,
|
|
45
|
+
type: string,
|
|
46
|
+
name: string,
|
|
47
|
+
expiry: string,
|
|
48
|
+
|},
|
|
49
|
+
|},
|
|
50
|
+
amount: {|
|
|
51
|
+
currency_code: string,
|
|
52
|
+
value: string,
|
|
53
|
+
|},
|
|
54
|
+
transaction_context: {|
|
|
55
|
+
soft_descriptor: string,
|
|
56
|
+
|},
|
|
57
|
+
links: $ReadOnlyArray<{|
|
|
58
|
+
href: string,
|
|
59
|
+
rel: string,
|
|
60
|
+
method: string,
|
|
61
|
+
|}>,
|
|
62
|
+
|};
|
|
63
|
+
|
|
64
|
+
export type SdkConfig = {|
|
|
65
|
+
authenticationToken: ?string,
|
|
66
|
+
paypalApiDomain: string,
|
|
67
|
+
|};
|
|
68
|
+
|
|
69
|
+
export type threeDSResponse = {|
|
|
70
|
+
liabilityShift: string,
|
|
71
|
+
authenticationStatus: string,
|
|
72
|
+
nonce?: string,
|
|
73
|
+
|};
|
|
74
|
+
|
|
75
|
+
export type TDSResult = {||};
|
|
76
|
+
|
|
77
|
+
/* eslint-enable no-restricted-globals, promise/no-native */
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
/** @jsx node */
|
|
3
|
+
/* eslint max-lines: 0 */
|
|
4
|
+
|
|
5
|
+
import { node, dom } from "@krakenjs/jsx-pragmatic/src";
|
|
6
|
+
import { create, type ZoidComponent } from "@krakenjs/zoid/src";
|
|
7
|
+
import { inlineMemoize, noop } from "@krakenjs/belter/src";
|
|
8
|
+
import { getCSPNonce } from "@paypal/sdk-client/src";
|
|
9
|
+
|
|
10
|
+
import { Overlay } from "../ui/overlay";
|
|
11
|
+
|
|
12
|
+
import { threeDSResponse } from "./types";
|
|
13
|
+
|
|
14
|
+
export type TDSProps = {|
|
|
15
|
+
action: string,
|
|
16
|
+
xcomponent: string,
|
|
17
|
+
flow: string,
|
|
18
|
+
orderID: string,
|
|
19
|
+
onSuccess: (threeDSResponse) => void,
|
|
20
|
+
onError: (mixed) => void,
|
|
21
|
+
sdkMeta: string,
|
|
22
|
+
content?: void | {|
|
|
23
|
+
windowMessage?: string,
|
|
24
|
+
continueMessage?: string,
|
|
25
|
+
cancelMessage?: string,
|
|
26
|
+
interrogativeMessage?: string,
|
|
27
|
+
|},
|
|
28
|
+
nonce: string,
|
|
29
|
+
|};
|
|
30
|
+
|
|
31
|
+
export type TDSComponent = ZoidComponent<TDSProps>;
|
|
32
|
+
|
|
33
|
+
export function getThreeDomainSecureComponent(payerActionUrll): TDSComponent {
|
|
34
|
+
return inlineMemoize(getThreeDomainSecureComponent, () => {
|
|
35
|
+
const component = create({
|
|
36
|
+
tag: "three-domain-secure-client",
|
|
37
|
+
url: payerActionUrll,
|
|
38
|
+
|
|
39
|
+
attributes: {
|
|
40
|
+
iframe: {
|
|
41
|
+
scrolling: "no",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
containerTemplate: ({
|
|
46
|
+
context,
|
|
47
|
+
focus,
|
|
48
|
+
close,
|
|
49
|
+
frame,
|
|
50
|
+
prerenderFrame,
|
|
51
|
+
doc,
|
|
52
|
+
event,
|
|
53
|
+
props,
|
|
54
|
+
}) => {
|
|
55
|
+
return (
|
|
56
|
+
<Overlay
|
|
57
|
+
context={context}
|
|
58
|
+
close={close}
|
|
59
|
+
focus={focus}
|
|
60
|
+
event={event}
|
|
61
|
+
frame={frame}
|
|
62
|
+
prerenderFrame={prerenderFrame}
|
|
63
|
+
content={props.content}
|
|
64
|
+
nonce={props.nonce}
|
|
65
|
+
/>
|
|
66
|
+
).render(dom({ doc }));
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
props: {
|
|
70
|
+
xcomponent: {
|
|
71
|
+
type: "string",
|
|
72
|
+
queryParam: true,
|
|
73
|
+
value: () => "1",
|
|
74
|
+
},
|
|
75
|
+
onSuccess: {
|
|
76
|
+
type: "function",
|
|
77
|
+
alias: "onContingencyResult",
|
|
78
|
+
decorate: ({ value, onError }) => {
|
|
79
|
+
return (err, result) => {
|
|
80
|
+
if (err) {
|
|
81
|
+
return onError(err);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return value(result);
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
content: {
|
|
89
|
+
type: "object",
|
|
90
|
+
required: false,
|
|
91
|
+
},
|
|
92
|
+
nonce: {
|
|
93
|
+
type: "string",
|
|
94
|
+
default: getCSPNonce,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (component.isChild()) {
|
|
100
|
+
window.xchild = {
|
|
101
|
+
props: component.xprops,
|
|
102
|
+
close: noop,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return component;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
/** @jsx node */
|
|
3
|
+
/* eslint max-lines: off, react/jsx-max-depth: off */
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
isIos,
|
|
7
|
+
isIpadOs,
|
|
8
|
+
isFirefox,
|
|
9
|
+
animate,
|
|
10
|
+
noop,
|
|
11
|
+
destroyElement,
|
|
12
|
+
uniqueID,
|
|
13
|
+
supportsPopups,
|
|
14
|
+
type EventEmitterType,
|
|
15
|
+
toCSS,
|
|
16
|
+
} from "@krakenjs/belter/src";
|
|
17
|
+
import { EVENT, CONTEXT } from "@krakenjs/zoid/src";
|
|
18
|
+
import { node, type ElementNode } from "@krakenjs/jsx-pragmatic/src";
|
|
19
|
+
import { LOGO_COLOR, PPLogo, PayPalLogo } from "@paypal/sdk-logos/src";
|
|
20
|
+
import { type ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
21
|
+
|
|
22
|
+
import { getContainerStyle, getSandboxStyle, CLASS } from "./style";
|
|
23
|
+
|
|
24
|
+
export type OverlayProps = {|
|
|
25
|
+
context: $Values<typeof CONTEXT>,
|
|
26
|
+
close: () => ZalgoPromise<void>,
|
|
27
|
+
focus: () => ZalgoPromise<void>,
|
|
28
|
+
event: EventEmitterType,
|
|
29
|
+
frame: ?HTMLElement,
|
|
30
|
+
prerenderFrame: ?HTMLElement,
|
|
31
|
+
content?: void | {|
|
|
32
|
+
windowMessage?: string,
|
|
33
|
+
continueMessage?: string,
|
|
34
|
+
cancelMessage?: string,
|
|
35
|
+
interrogativeMessage?: string,
|
|
36
|
+
|},
|
|
37
|
+
autoResize?: boolean,
|
|
38
|
+
hideCloseButton?: boolean,
|
|
39
|
+
nonce: string,
|
|
40
|
+
fullScreen?: boolean,
|
|
41
|
+
|};
|
|
42
|
+
export function Overlay({
|
|
43
|
+
context,
|
|
44
|
+
close,
|
|
45
|
+
focus,
|
|
46
|
+
event,
|
|
47
|
+
frame,
|
|
48
|
+
prerenderFrame,
|
|
49
|
+
content = {},
|
|
50
|
+
autoResize,
|
|
51
|
+
hideCloseButton,
|
|
52
|
+
nonce,
|
|
53
|
+
fullScreen = false,
|
|
54
|
+
}: OverlayProps): ElementNode {
|
|
55
|
+
const uid = `paypal-overlay-${uniqueID()}`;
|
|
56
|
+
const overlayIframeName = `__paypal_checkout_sandbox_${uid}__`;
|
|
57
|
+
|
|
58
|
+
function closeCheckout(e) {
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
close();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function displayFocusWarning() {
|
|
65
|
+
const overlayIframe: ?HTMLIFrameElement =
|
|
66
|
+
// $FlowFixMe
|
|
67
|
+
document.getElementsByName(overlayIframeName)?.[0];
|
|
68
|
+
const iframeDocument = overlayIframe?.contentWindow.document;
|
|
69
|
+
const warningElement = iframeDocument?.getElementsByClassName(
|
|
70
|
+
"paypal-checkout-focus-warning"
|
|
71
|
+
)?.[0];
|
|
72
|
+
|
|
73
|
+
if (!warningElement) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
warningElement.innerText = `Still can't see it? Select "Window" in your toolbar to find "Log in to your PayPal account"`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function focusCheckout(e) {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
e.stopPropagation();
|
|
82
|
+
|
|
83
|
+
if (!supportsPopups()) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (isIos() || isIpadOs()) {
|
|
88
|
+
// Note: alerts block the event loop until they are closed.
|
|
89
|
+
// eslint-disable-next-line no-alert
|
|
90
|
+
window.alert("Please switch tabs to reactivate the PayPal window");
|
|
91
|
+
} else if (isFirefox()) {
|
|
92
|
+
displayFocusWarning();
|
|
93
|
+
}
|
|
94
|
+
focus();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const setupAnimations = (name) => {
|
|
98
|
+
return (el) => {
|
|
99
|
+
const showContainer = () => animate(el, `show-${name}`, noop);
|
|
100
|
+
const hideContainer = () => animate(el, `hide-${name}`, noop);
|
|
101
|
+
event.on(EVENT.DISPLAY, showContainer);
|
|
102
|
+
event.on(EVENT.CLOSE, hideContainer);
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const setupAutoResize = (el) => {
|
|
107
|
+
event.on(EVENT.RESIZE, ({ width: newWidth, height: newHeight }) => {
|
|
108
|
+
if (typeof newWidth === "number") {
|
|
109
|
+
el.style.width = toCSS(newWidth);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (typeof newHeight === "number") {
|
|
113
|
+
el.style.height = toCSS(newHeight);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const outletOnRender = (el) => {
|
|
119
|
+
setupAnimations("component")(el);
|
|
120
|
+
if (autoResize) {
|
|
121
|
+
setupAutoResize(el);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
let outlet;
|
|
126
|
+
|
|
127
|
+
if (frame && prerenderFrame) {
|
|
128
|
+
frame.classList.add(CLASS.COMPONENT_FRAME);
|
|
129
|
+
prerenderFrame.classList.add(CLASS.PRERENDER_FRAME);
|
|
130
|
+
|
|
131
|
+
prerenderFrame.classList.add(CLASS.VISIBLE);
|
|
132
|
+
frame.classList.add(CLASS.INVISIBLE);
|
|
133
|
+
|
|
134
|
+
event.on(EVENT.RENDERED, () => {
|
|
135
|
+
prerenderFrame.classList.remove(CLASS.VISIBLE);
|
|
136
|
+
prerenderFrame.classList.add(CLASS.INVISIBLE);
|
|
137
|
+
|
|
138
|
+
frame.classList.remove(CLASS.INVISIBLE);
|
|
139
|
+
frame.classList.add(CLASS.VISIBLE);
|
|
140
|
+
|
|
141
|
+
setTimeout(() => {
|
|
142
|
+
destroyElement(prerenderFrame);
|
|
143
|
+
}, 1);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
outlet = (
|
|
147
|
+
<div class={CLASS.OUTLET} onRender={outletOnRender}>
|
|
148
|
+
<node el={frame} />
|
|
149
|
+
<node el={prerenderFrame} />
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<div
|
|
156
|
+
id={uid}
|
|
157
|
+
onRender={setupAnimations("container")}
|
|
158
|
+
class="paypal-checkout-sandbox"
|
|
159
|
+
>
|
|
160
|
+
<style nonce={nonce}>{getSandboxStyle({ uid })}</style>
|
|
161
|
+
<iframe
|
|
162
|
+
title="PayPal Checkout Overlay"
|
|
163
|
+
name={overlayIframeName}
|
|
164
|
+
scrolling="no"
|
|
165
|
+
class={`paypal-checkout-sandbox-iframe${fullScreen ? "-full" : ""}`}
|
|
166
|
+
>
|
|
167
|
+
<html>
|
|
168
|
+
<body>
|
|
169
|
+
<div
|
|
170
|
+
dir="auto"
|
|
171
|
+
id={uid}
|
|
172
|
+
onClick={focusCheckout}
|
|
173
|
+
class={`paypal-overlay-context-${context} paypal-checkout-overlay`}
|
|
174
|
+
>
|
|
175
|
+
{!hideCloseButton && (
|
|
176
|
+
<a
|
|
177
|
+
href="#"
|
|
178
|
+
class="paypal-checkout-close"
|
|
179
|
+
onClick={closeCheckout}
|
|
180
|
+
aria-label="close"
|
|
181
|
+
role="button"
|
|
182
|
+
/>
|
|
183
|
+
)}
|
|
184
|
+
{!fullScreen && (
|
|
185
|
+
<div class="paypal-checkout-modal">
|
|
186
|
+
<div class="paypal-checkout-logo" dir="ltr">
|
|
187
|
+
<PPLogo logoColor={LOGO_COLOR.WHITE} />
|
|
188
|
+
<PayPalLogo logoColor={LOGO_COLOR.WHITE} />
|
|
189
|
+
</div>
|
|
190
|
+
{content.windowMessage && (
|
|
191
|
+
<div class="paypal-checkout-message">
|
|
192
|
+
{content.windowMessage}
|
|
193
|
+
</div>
|
|
194
|
+
)}
|
|
195
|
+
<div class="paypal-checkout-focus-warning" />
|
|
196
|
+
{content.continueMessage && (
|
|
197
|
+
<div class="paypal-checkout-continue">
|
|
198
|
+
{/* This handler should be guarded with e.stopPropagation.
|
|
199
|
+
This will stop the event from bubbling up to the overlay click handler
|
|
200
|
+
and causing unexpected behavior. */}
|
|
201
|
+
<a onClick={focusCheckout} href="#">
|
|
202
|
+
{content.continueMessage}
|
|
203
|
+
</a>
|
|
204
|
+
</div>
|
|
205
|
+
)}
|
|
206
|
+
<div class="paypal-checkout-loader">
|
|
207
|
+
<div class="paypal-spinner" />
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
)}
|
|
211
|
+
<div
|
|
212
|
+
class={
|
|
213
|
+
fullScreen
|
|
214
|
+
? "paypal-checkout-iframe-container-full"
|
|
215
|
+
: "paypal-checkout-iframe-container"
|
|
216
|
+
}
|
|
217
|
+
>
|
|
218
|
+
{outlet}
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<style nonce={nonce}>{getContainerStyle({ uid })}</style>
|
|
222
|
+
</div>
|
|
223
|
+
</body>
|
|
224
|
+
</html>
|
|
225
|
+
</iframe>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
import { CONTEXT } from "@krakenjs/zoid/src";
|
|
4
|
+
|
|
5
|
+
export const CLASS = {
|
|
6
|
+
OUTLET: "outlet",
|
|
7
|
+
VISIBLE: "visible",
|
|
8
|
+
INVISIBLE: "invisible",
|
|
9
|
+
COMPONENT_FRAME: "component-frame",
|
|
10
|
+
PRERENDER_FRAME: "prerender-frame",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function getSandboxStyle({ uid }: {| uid: string |}): string {
|
|
14
|
+
return `
|
|
15
|
+
#${uid}.paypal-checkout-sandbox {
|
|
16
|
+
display: block;
|
|
17
|
+
position: fixed;
|
|
18
|
+
top: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 100%;
|
|
23
|
+
width: 100vw;
|
|
24
|
+
height: 100vh;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
max-height: 100%;
|
|
27
|
+
min-width: 100%;
|
|
28
|
+
min-height: 100%;
|
|
29
|
+
|
|
30
|
+
z-index: 2147483647;
|
|
31
|
+
|
|
32
|
+
animation-duration: 0.3s;
|
|
33
|
+
animation-iteration-count: 1;
|
|
34
|
+
animation-fill-mode: forwards !important;
|
|
35
|
+
opacity: 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#${uid}.paypal-checkout-sandbox .paypal-checkout-sandbox-iframe {
|
|
39
|
+
display: block;
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 0;
|
|
42
|
+
left: 0;
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#${uid}.paypal-checkout-sandbox .paypal-checkout-sandbox-iframe-full {
|
|
48
|
+
border: 0;
|
|
49
|
+
height: 100%;
|
|
50
|
+
width: 100vw;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@keyframes show-container {
|
|
54
|
+
from {
|
|
55
|
+
opacity: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
to {
|
|
59
|
+
opacity: 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@keyframes hide-container {
|
|
64
|
+
from {
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
50% {
|
|
69
|
+
opacity: 1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
to {
|
|
73
|
+
opacity: 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function getContainerStyle({ uid }: {| uid: string |}): string {
|
|
80
|
+
return `
|
|
81
|
+
#${uid} {
|
|
82
|
+
position: absolute;
|
|
83
|
+
z-index: 2147483647;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
|
|
89
|
+
transform: translate3d(0, 0, 0);
|
|
90
|
+
|
|
91
|
+
background-color: black;
|
|
92
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
93
|
+
background: radial-gradient(50% 50%, ellipse closest-corner, rgba(0,0,0,0.6) 1%, rgba(0,0,0,0.8) 100%);
|
|
94
|
+
|
|
95
|
+
color: #fff;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#${uid} a {
|
|
99
|
+
color: #fff;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#${uid} .paypal-checkout-close:before,
|
|
103
|
+
#${uid} .paypal-checkout-close:after {
|
|
104
|
+
background-color: #fff;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#${uid}.paypal-overlay-context-${CONTEXT.POPUP} {
|
|
108
|
+
cursor: pointer;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#${uid} a {
|
|
112
|
+
text-decoration: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#${uid} .paypal-checkout-modal {
|
|
116
|
+
font-family: "HelveticaNeue", "HelveticaNeue-Light", "Helvetica Neue Light", helvetica, arial, sans-serif;
|
|
117
|
+
font-size: 14px;
|
|
118
|
+
text-align: center;
|
|
119
|
+
|
|
120
|
+
box-sizing: border-box;
|
|
121
|
+
max-width: 350px;
|
|
122
|
+
top: 50%;
|
|
123
|
+
left: 50%;
|
|
124
|
+
position: absolute;
|
|
125
|
+
transform: translateX(-50%) translateY(-50%);
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
text-align: center;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#${uid}.paypal-overlay-loading .paypal-checkout-message, #${uid}.paypal-overlay-loading .paypal-checkout-continue {
|
|
131
|
+
display: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.paypal-checkout-loader {
|
|
135
|
+
display: none;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#${uid}.paypal-overlay-loading .paypal-checkout-loader {
|
|
139
|
+
display: block;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-logo {
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
margin-bottom: 30px;
|
|
145
|
+
display: inline-block;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-logo img {
|
|
149
|
+
height: 36px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-logo img.paypal-checkout-logo-pp {
|
|
153
|
+
margin-right: 10px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-message {
|
|
157
|
+
font-size: 15px;
|
|
158
|
+
line-height: 1.5;
|
|
159
|
+
padding: 10px 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-message, #${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-continue {
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-continue {
|
|
167
|
+
font-size: 15px;
|
|
168
|
+
line-height: 1.35;
|
|
169
|
+
padding: 10px 0;
|
|
170
|
+
font-weight: bold;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#${uid} .paypal-checkout-modal .paypal-checkout-continue a {
|
|
174
|
+
border-bottom: 1px solid white;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#${uid} .paypal-checkout-close {
|
|
178
|
+
position: absolute;
|
|
179
|
+
right: 16px;
|
|
180
|
+
top: 16px;
|
|
181
|
+
width: 16px;
|
|
182
|
+
height: 16px;
|
|
183
|
+
opacity: 0.6;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
#${uid}.paypal-overlay-loading .paypal-checkout-close {
|
|
187
|
+
display: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
#${uid} .paypal-checkout-close:hover {
|
|
191
|
+
opacity: 1;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
#${uid} .paypal-checkout-close:before, .paypal-checkout-close:after {
|
|
195
|
+
position: absolute;
|
|
196
|
+
left: 8px;
|
|
197
|
+
content: ' ';
|
|
198
|
+
height: 16px;
|
|
199
|
+
width: 2px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#${uid} .paypal-checkout-close:before {
|
|
203
|
+
transform: rotate(45deg);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
#${uid} .paypal-checkout-close:after {
|
|
207
|
+
transform: rotate(-45deg);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
#${uid} .paypal-checkout-focus-warning {
|
|
211
|
+
font-size: 14px;
|
|
212
|
+
line-height: 1.35;
|
|
213
|
+
padding: 10px 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#${uid} .paypal-checkout-iframe-container {
|
|
217
|
+
display: none;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container,
|
|
221
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container > .${CLASS.OUTLET},
|
|
222
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container > .${CLASS.OUTLET} > iframe {
|
|
223
|
+
max-height: 95vh;
|
|
224
|
+
max-width: 95vw;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full,
|
|
228
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full > .${CLASS.OUTLET},
|
|
229
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full > .${CLASS.OUTLET} > iframe {
|
|
230
|
+
height: 100vh;
|
|
231
|
+
max-width: 100vw;
|
|
232
|
+
width: 100vw;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@media screen and (max-width: 470px) {
|
|
236
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container,
|
|
237
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container > .${CLASS.OUTLET},
|
|
238
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container > .${CLASS.OUTLET} > iframe {
|
|
239
|
+
max-height: 85vh;
|
|
240
|
+
}
|
|
241
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full,
|
|
242
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full > .${CLASS.OUTLET},
|
|
243
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container-full > .${CLASS.OUTLET} > iframe {
|
|
244
|
+
height: 100vh;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container {
|
|
249
|
+
|
|
250
|
+
display: block;
|
|
251
|
+
|
|
252
|
+
position: absolute;
|
|
253
|
+
|
|
254
|
+
top: 50%;
|
|
255
|
+
left: 50%;
|
|
256
|
+
|
|
257
|
+
min-width: 450px;
|
|
258
|
+
|
|
259
|
+
transform: translate(-50%, -50%);
|
|
260
|
+
transform: translate3d(-50%, -50%, 0);
|
|
261
|
+
|
|
262
|
+
border-radius: 10px;
|
|
263
|
+
overflow: hidden;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} {
|
|
267
|
+
|
|
268
|
+
position: relative;
|
|
269
|
+
|
|
270
|
+
transition: all 0.3s ease;
|
|
271
|
+
animation-duration: 0.3s;
|
|
272
|
+
animation-fill-mode: forwards !important;
|
|
273
|
+
|
|
274
|
+
min-width: 450px;
|
|
275
|
+
max-width: 450px;
|
|
276
|
+
width: 450px;
|
|
277
|
+
height: 535px;
|
|
278
|
+
|
|
279
|
+
background-color: white;
|
|
280
|
+
|
|
281
|
+
overflow: auto;
|
|
282
|
+
|
|
283
|
+
opacity: 0;
|
|
284
|
+
transform: scale3d(.3, .3, .3);
|
|
285
|
+
|
|
286
|
+
-webkit-overflow-scrolling: touch;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} > iframe {
|
|
290
|
+
position: absolute;
|
|
291
|
+
top: 0;
|
|
292
|
+
left: 0;
|
|
293
|
+
transition: opacity .4s ease-in-out;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} > iframe.${CLASS.COMPONENT_FRAME} {
|
|
297
|
+
z-index: 100;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} > iframe.${CLASS.PRERENDER_FRAME} {
|
|
301
|
+
z-index: 200;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} > iframe.${CLASS.VISIBLE} {
|
|
305
|
+
opacity: 1;
|
|
306
|
+
z-index: 200;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} > iframe.${CLASS.INVISIBLE} {
|
|
310
|
+
opacity: 0;
|
|
311
|
+
z-index: 100;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@media screen and (max-width: 470px) {
|
|
315
|
+
|
|
316
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .paypal-checkout-iframe-container,
|
|
317
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} {
|
|
318
|
+
min-width: 100%;
|
|
319
|
+
min-width: calc(100% - 20px);
|
|
320
|
+
|
|
321
|
+
max-width: 100%;
|
|
322
|
+
max-width: calc(100% - 20px);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
#${uid}.paypal-overlay-context-${CONTEXT.IFRAME} .${CLASS.OUTLET} iframe {
|
|
327
|
+
width: 1px;
|
|
328
|
+
min-width: 100%;
|
|
329
|
+
height: 100%;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@keyframes show-component {
|
|
333
|
+
from {
|
|
334
|
+
opacity: 0;
|
|
335
|
+
transform: scale3d(.3, .3, .3);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
to {
|
|
339
|
+
opacity: 1;
|
|
340
|
+
transform: scale3d(1, 1, 1);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
@keyframes hide-component {
|
|
345
|
+
from {
|
|
346
|
+
opacity: 1;
|
|
347
|
+
transform: scale3d(1, 1, 1);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
to {
|
|
351
|
+
opacity: 0;
|
|
352
|
+
transform: scale3d(.3, .3, .3);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.paypal-spinner {
|
|
357
|
+
height: 30px;
|
|
358
|
+
width: 30px;
|
|
359
|
+
display: inline-block;
|
|
360
|
+
box-sizing: content-box;
|
|
361
|
+
opacity: 1;
|
|
362
|
+
filter: alpha(opacity=100);
|
|
363
|
+
animation: rotation .7s infinite linear;
|
|
364
|
+
border-left: 8px solid rgba(0, 0, 0, .2);
|
|
365
|
+
border-right: 8px solid rgba(0, 0, 0, .2);
|
|
366
|
+
border-bottom: 8px solid rgba(0, 0, 0, .2);
|
|
367
|
+
border-top: 8px solid #fff;
|
|
368
|
+
border-radius: 100%
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
@keyframes rotation {
|
|
372
|
+
from {
|
|
373
|
+
transform: rotate(0deg)
|
|
374
|
+
}
|
|
375
|
+
to {
|
|
376
|
+
transform: rotate(359deg)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
`;
|
|
380
|
+
}
|