@paypal/checkout-components 5.0.386 → 5.0.388
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/dist/button.js +1 -1
- package/dist/test/button.js +1 -1
- package/package.json +2 -1
- package/src/funding/card/config.jsx +1 -0
- package/src/funding/credit/config.jsx +37 -3
- package/src/funding/funding.js +17 -4
- package/src/funding/funding.test.js +304 -16
- package/src/funding/paylater/config.jsx +2 -2
- package/src/funding/util.js +99 -0
- package/src/funding/util.test.js +282 -0
- package/src/funding/venmo/config.jsx +7 -8
- package/src/funding/venmo/config.test.js +17 -37
- package/src/hosted-buttons/types.js +1 -0
- package/src/hosted-buttons/utils.js +20 -4
- package/src/hosted-buttons/utils.test.js +88 -8
- package/src/marks/component.jsx +5 -0
- package/src/ui/buttons/buttons.jsx +2 -0
- package/src/ui/buttons/props.js +8 -1
- package/src/ui/buttons/props.test.js +2 -8
- package/src/ui/buttons/script.jsx +53 -2
- package/src/ui/buttons/styles/button.js +1 -28
- package/src/ui/buttons/styles/responsive.js +104 -24
- package/src/zoid/buttons/component.jsx +46 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paypal/checkout-components",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.388",
|
|
4
4
|
"description": "PayPal Checkout components, for integrating checkout products.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"jest-ssr": "jest test/ssr --env=node --no-cache --collectCoverage --collectCoverageFrom='src/' --coverageDirectory='coverage/jest'",
|
|
24
24
|
"karma": "cross-env NODE_ENV=test babel-node ./node_modules/.bin/karma start",
|
|
25
25
|
"lint": "eslint --ext .js --ext .jsx src/ test/ *.js",
|
|
26
|
+
"lint:fix": "eslint --ext .js --ext .jsx src/ test/ *.js --fix",
|
|
26
27
|
"postversion": "./scripts/postversion.sh",
|
|
27
28
|
"preversion": "./scripts/preversion.sh",
|
|
28
29
|
"reinstall": "rimraf flow-typed && rimraf node_modules && npm install && npm run flow-typed",
|
|
@@ -22,8 +22,12 @@ import {
|
|
|
22
22
|
DEFAULT,
|
|
23
23
|
BUTTON_FLOW,
|
|
24
24
|
} from "../../constants";
|
|
25
|
-
import {
|
|
26
|
-
|
|
25
|
+
import {
|
|
26
|
+
DEFAULT_FUNDING_CONFIG,
|
|
27
|
+
type FundingSourceConfig,
|
|
28
|
+
BasicLabel,
|
|
29
|
+
} from "../common";
|
|
30
|
+
import { WalletLabel, Logo as PayPalRebrandLogo } from "../paypal/template";
|
|
27
31
|
import { Text } from "../../ui/text";
|
|
28
32
|
|
|
29
33
|
import css from "./style.scoped.scss";
|
|
@@ -40,6 +44,14 @@ export function getCreditConfig(): FundingSourceConfig {
|
|
|
40
44
|
|
|
41
45
|
layouts: [BUTTON_LAYOUT.HORIZONTAL, BUTTON_LAYOUT.VERTICAL],
|
|
42
46
|
|
|
47
|
+
Label: ({ logo, experiment, ...props }) => {
|
|
48
|
+
// For rebrand, only show logo without labels
|
|
49
|
+
if (experiment?.isPaypalRebrandEnabled) {
|
|
50
|
+
return logo;
|
|
51
|
+
}
|
|
52
|
+
return BasicLabel({ logo, ...props });
|
|
53
|
+
},
|
|
54
|
+
|
|
43
55
|
Logo: ({
|
|
44
56
|
locale,
|
|
45
57
|
logoColor,
|
|
@@ -74,9 +86,31 @@ export function getCreditConfig(): FundingSourceConfig {
|
|
|
74
86
|
);
|
|
75
87
|
}
|
|
76
88
|
|
|
89
|
+
// Rebranded credit for DE locale uses "Später Bezahlen" text
|
|
90
|
+
if (locale.country === COUNTRY.DE) {
|
|
91
|
+
return (
|
|
92
|
+
<Style css={css} nonce={nonce}>
|
|
93
|
+
<PayPalRebrandLogo
|
|
94
|
+
logoColor={logoColor}
|
|
95
|
+
shouldApplyRebrandedStyles={shouldApplyRebrandedStyles}
|
|
96
|
+
env={env}
|
|
97
|
+
experiment={experiment}
|
|
98
|
+
fundingEligibility={fundingEligibility}
|
|
99
|
+
locale={locale}
|
|
100
|
+
/>
|
|
101
|
+
{__WEB__ ? (
|
|
102
|
+
<PPRebrandLogoExternalImage logoColor={logoColorPP} />
|
|
103
|
+
) : (
|
|
104
|
+
<PPRebrandLogoInlineSVG logoColor={logoColorPP} />
|
|
105
|
+
)}
|
|
106
|
+
<Text>{"Später Bezahlen"}</Text>
|
|
107
|
+
</Style>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
77
111
|
return (
|
|
78
112
|
<Style css={css} nonce={nonce}>
|
|
79
|
-
<
|
|
113
|
+
<PayPalRebrandLogo
|
|
80
114
|
logoColor={logoColor}
|
|
81
115
|
shouldApplyRebrandedStyles={shouldApplyRebrandedStyles}
|
|
82
116
|
locale={locale}
|
package/src/funding/funding.js
CHANGED
|
@@ -16,6 +16,7 @@ import type { Wallet, Experiment } from "../types";
|
|
|
16
16
|
import { BUTTON_LAYOUT, BUTTON_FLOW } from "../constants";
|
|
17
17
|
|
|
18
18
|
import { getFundingConfig } from "./config";
|
|
19
|
+
import { supportsVenmoPopups, isSupportedNativeVenmoBrowser } from "./util";
|
|
19
20
|
|
|
20
21
|
type IsFundingEligibleOptions = {|
|
|
21
22
|
layout?: $Values<typeof BUTTON_LAYOUT>,
|
|
@@ -35,6 +36,7 @@ type IsFundingEligibleOptions = {|
|
|
|
35
36
|
supportedNativeBrowser: boolean,
|
|
36
37
|
experiment?: Experiment,
|
|
37
38
|
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
39
|
+
userAgent?: string,
|
|
38
40
|
|};
|
|
39
41
|
|
|
40
42
|
function isFundingVaultable({
|
|
@@ -84,6 +86,7 @@ export function isFundingEligible(
|
|
|
84
86
|
supportedNativeBrowser,
|
|
85
87
|
experiment,
|
|
86
88
|
displayOnly,
|
|
89
|
+
userAgent,
|
|
87
90
|
}: IsFundingEligibleOptions
|
|
88
91
|
): boolean {
|
|
89
92
|
if (!fundingEligibility[source] || !fundingEligibility[source].eligible) {
|
|
@@ -156,10 +159,17 @@ export function isFundingEligible(
|
|
|
156
159
|
return false;
|
|
157
160
|
}
|
|
158
161
|
|
|
159
|
-
if (fundingConfig.requires) {
|
|
162
|
+
if (fundingConfig.requires && userAgent) {
|
|
160
163
|
const required = fundingConfig.requires({ experiment, platform });
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
const popupSupport =
|
|
165
|
+
source === FUNDING.VENMO
|
|
166
|
+
? supportsVenmoPopups(experiment, supportsPopups, userAgent)
|
|
167
|
+
: supportsPopups;
|
|
168
|
+
const nativeBrowserSupport =
|
|
169
|
+
source === FUNDING.VENMO
|
|
170
|
+
? isSupportedNativeVenmoBrowser(experiment, userAgent)
|
|
171
|
+
: supportedNativeBrowser;
|
|
172
|
+
if (required.popup === true && popupSupport === false) {
|
|
163
173
|
return false;
|
|
164
174
|
}
|
|
165
175
|
|
|
@@ -167,7 +177,7 @@ export function isFundingEligible(
|
|
|
167
177
|
return false;
|
|
168
178
|
}
|
|
169
179
|
|
|
170
|
-
if (required.native === true &&
|
|
180
|
+
if (required.native === true && nativeBrowserSupport === false) {
|
|
171
181
|
return false;
|
|
172
182
|
}
|
|
173
183
|
}
|
|
@@ -204,6 +214,7 @@ export function determineEligibleFunding({
|
|
|
204
214
|
supportedNativeBrowser,
|
|
205
215
|
experiment,
|
|
206
216
|
displayOnly = [],
|
|
217
|
+
userAgent = "",
|
|
207
218
|
}: {|
|
|
208
219
|
fundingSource: ?$Values<typeof FUNDING>,
|
|
209
220
|
remembered: $ReadOnlyArray<$Values<typeof FUNDING>>,
|
|
@@ -223,6 +234,7 @@ export function determineEligibleFunding({
|
|
|
223
234
|
supportedNativeBrowser: boolean,
|
|
224
235
|
experiment: Experiment,
|
|
225
236
|
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
237
|
+
userAgent?: string,
|
|
226
238
|
|}): $ReadOnlyArray<$Values<typeof FUNDING>> {
|
|
227
239
|
if (fundingSource) {
|
|
228
240
|
return [fundingSource];
|
|
@@ -247,6 +259,7 @@ export function determineEligibleFunding({
|
|
|
247
259
|
supportedNativeBrowser,
|
|
248
260
|
experiment,
|
|
249
261
|
displayOnly,
|
|
262
|
+
userAgent,
|
|
250
263
|
})
|
|
251
264
|
);
|
|
252
265
|
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
-
import { COMPONENTS, FUNDING
|
|
3
|
-
import { describe, expect } from "vitest";
|
|
2
|
+
import { COMPONENTS, FUNDING } from "@paypal/sdk-constants/src";
|
|
3
|
+
import { describe, expect, vi, beforeEach, afterEach } from "vitest";
|
|
4
4
|
|
|
5
5
|
import { BUTTON_FLOW } from "../constants";
|
|
6
6
|
|
|
7
7
|
import { isFundingEligible, isWalletFundingEligible } from "./funding";
|
|
8
|
+
import { supportsVenmoPopups, isSupportedNativeVenmoBrowser } from "./util";
|
|
9
|
+
import { getFundingConfig } from "./config";
|
|
10
|
+
|
|
11
|
+
// Mock the venmo utility functions
|
|
12
|
+
vi.mock("./util", () => ({
|
|
13
|
+
supportsVenmoPopups: vi.fn(),
|
|
14
|
+
isSupportedNativeVenmoBrowser: vi.fn(),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
// Mock getFundingConfig to control funding config behavior
|
|
18
|
+
vi.mock("./config", () => ({
|
|
19
|
+
getFundingConfig: vi.fn(),
|
|
20
|
+
}));
|
|
8
21
|
|
|
9
22
|
const defaultMockFundingOptions = {
|
|
10
23
|
platform: "desktop",
|
|
@@ -55,9 +68,41 @@ const defaultMockFundingOptions = {
|
|
|
55
68
|
onShippingChange: null,
|
|
56
69
|
onShippingAddressChange: null,
|
|
57
70
|
onShippingOptionsChange: null,
|
|
71
|
+
userAgent:
|
|
72
|
+
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1",
|
|
58
73
|
};
|
|
59
74
|
|
|
60
75
|
describe("Funding eligibility", () => {
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
// Mock getFundingConfig with basic configs for all funding sources
|
|
78
|
+
vi.mocked(getFundingConfig).mockReturnValue({
|
|
79
|
+
[FUNDING.PAYLATER]: {
|
|
80
|
+
enabled: true,
|
|
81
|
+
automatic: true,
|
|
82
|
+
},
|
|
83
|
+
[FUNDING.CARD]: {
|
|
84
|
+
enabled: true,
|
|
85
|
+
automatic: true,
|
|
86
|
+
},
|
|
87
|
+
[FUNDING.SEPA]: {
|
|
88
|
+
enabled: false,
|
|
89
|
+
automatic: false,
|
|
90
|
+
},
|
|
91
|
+
[FUNDING.OXXO]: {
|
|
92
|
+
enabled: false,
|
|
93
|
+
automatic: false,
|
|
94
|
+
},
|
|
95
|
+
[FUNDING.VENMO]: {
|
|
96
|
+
enabled: true,
|
|
97
|
+
automatic: true,
|
|
98
|
+
},
|
|
99
|
+
[FUNDING.PAYPAL]: {
|
|
100
|
+
enabled: true,
|
|
101
|
+
automatic: true,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
61
106
|
describe("Desktop", () => {
|
|
62
107
|
test("should not be eligible if funding source is missing from fundingEligibility", () => {
|
|
63
108
|
const fundingEligible = isFundingEligible(
|
|
@@ -173,29 +218,272 @@ describe("Funding eligibility", () => {
|
|
|
173
218
|
});
|
|
174
219
|
});
|
|
175
220
|
|
|
176
|
-
describe("
|
|
177
|
-
|
|
178
|
-
|
|
221
|
+
describe("Venmo-specific funding requirements", () => {
|
|
222
|
+
beforeEach(() => {
|
|
223
|
+
// Reset all mocks before each test
|
|
224
|
+
vi.clearAllMocks();
|
|
179
225
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
226
|
+
// Mock getFundingConfig to return configs with venmo requirements
|
|
227
|
+
vi.mocked(getFundingConfig).mockReturnValue({
|
|
228
|
+
[FUNDING.PAYLATER]: {
|
|
229
|
+
enabled: true,
|
|
230
|
+
automatic: true,
|
|
231
|
+
},
|
|
232
|
+
[FUNDING.CARD]: {
|
|
233
|
+
enabled: true,
|
|
234
|
+
automatic: true,
|
|
235
|
+
},
|
|
236
|
+
[FUNDING.SEPA]: {
|
|
237
|
+
enabled: false,
|
|
238
|
+
automatic: false,
|
|
239
|
+
},
|
|
240
|
+
[FUNDING.OXXO]: {
|
|
241
|
+
enabled: false,
|
|
242
|
+
automatic: false,
|
|
243
|
+
},
|
|
244
|
+
[FUNDING.VENMO]: {
|
|
245
|
+
enabled: true,
|
|
246
|
+
automatic: true,
|
|
247
|
+
requires: () => ({
|
|
248
|
+
popup: true,
|
|
249
|
+
native: true,
|
|
250
|
+
}),
|
|
251
|
+
},
|
|
252
|
+
[FUNDING.PAYPAL]: {
|
|
253
|
+
enabled: true,
|
|
254
|
+
automatic: true,
|
|
255
|
+
requires: () => ({
|
|
256
|
+
popup: true,
|
|
257
|
+
native: true,
|
|
258
|
+
}),
|
|
259
|
+
},
|
|
184
260
|
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
afterEach(() => {
|
|
264
|
+
vi.resetAllMocks();
|
|
265
|
+
});
|
|
185
266
|
|
|
186
|
-
|
|
267
|
+
test("should use supportsVenmoPopups for venmo funding source when popup is required", () => {
|
|
268
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
269
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
187
270
|
|
|
188
|
-
|
|
271
|
+
const options = {
|
|
272
|
+
...defaultMockFundingOptions,
|
|
273
|
+
fundingSource: FUNDING.VENMO,
|
|
274
|
+
platform: "mobile",
|
|
275
|
+
experiment: { venmoEnableWebOnNonNativeBrowser: true },
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
279
|
+
|
|
280
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
281
|
+
options.experiment,
|
|
282
|
+
true,
|
|
283
|
+
options.userAgent
|
|
284
|
+
);
|
|
285
|
+
expect(result).toBe(true);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
test("should use isSupportedNativeVenmoBrowser for venmo funding source when native is required", () => {
|
|
289
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
290
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
291
|
+
|
|
292
|
+
const options = {
|
|
293
|
+
...defaultMockFundingOptions,
|
|
294
|
+
fundingSource: FUNDING.VENMO,
|
|
295
|
+
platform: "mobile",
|
|
296
|
+
experiment: { venmoEnableWebOnNonNativeBrowser: true },
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
300
|
+
|
|
301
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
302
|
+
options.experiment,
|
|
303
|
+
options.userAgent
|
|
304
|
+
);
|
|
305
|
+
expect(result).toBe(true);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test("should return false when venmo popup support is required but supportsVenmoPopups returns false", () => {
|
|
309
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(false);
|
|
310
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
311
|
+
|
|
312
|
+
const options = {
|
|
313
|
+
...defaultMockFundingOptions,
|
|
314
|
+
fundingSource: FUNDING.VENMO,
|
|
315
|
+
platform: "mobile",
|
|
316
|
+
experiment: {},
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
320
|
+
|
|
321
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
322
|
+
options.experiment,
|
|
323
|
+
true,
|
|
324
|
+
options.userAgent
|
|
325
|
+
);
|
|
326
|
+
expect(result).toBe(false);
|
|
189
327
|
});
|
|
190
328
|
|
|
191
|
-
test("should
|
|
192
|
-
|
|
329
|
+
test("should return false when venmo native support is required but isSupportedNativeVenmoBrowser returns false", () => {
|
|
330
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
331
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
332
|
+
|
|
333
|
+
const options = {
|
|
193
334
|
...defaultMockFundingOptions,
|
|
194
|
-
|
|
195
|
-
|
|
335
|
+
fundingSource: FUNDING.VENMO,
|
|
336
|
+
platform: "mobile",
|
|
337
|
+
experiment: {},
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
341
|
+
|
|
342
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
343
|
+
options.experiment,
|
|
344
|
+
options.userAgent
|
|
345
|
+
);
|
|
346
|
+
expect(result).toBe(false);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
test("should use standard supportsPopups for non-venmo funding sources", () => {
|
|
350
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(false);
|
|
351
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
352
|
+
|
|
353
|
+
// Update the mock to not require popup and native for PayPal to isolate the test
|
|
354
|
+
vi.mocked(getFundingConfig).mockReturnValue({
|
|
355
|
+
[FUNDING.PAYLATER]: {
|
|
356
|
+
enabled: true,
|
|
357
|
+
automatic: true,
|
|
358
|
+
},
|
|
359
|
+
[FUNDING.CARD]: {
|
|
360
|
+
enabled: true,
|
|
361
|
+
automatic: true,
|
|
362
|
+
},
|
|
363
|
+
[FUNDING.SEPA]: {
|
|
364
|
+
enabled: false,
|
|
365
|
+
automatic: false,
|
|
366
|
+
},
|
|
367
|
+
[FUNDING.OXXO]: {
|
|
368
|
+
enabled: false,
|
|
369
|
+
automatic: false,
|
|
370
|
+
},
|
|
371
|
+
[FUNDING.VENMO]: {
|
|
372
|
+
enabled: true,
|
|
373
|
+
automatic: true,
|
|
374
|
+
requires: () => ({
|
|
375
|
+
popup: true,
|
|
376
|
+
native: true,
|
|
377
|
+
}),
|
|
378
|
+
},
|
|
379
|
+
[FUNDING.PAYPAL]: {
|
|
380
|
+
enabled: true,
|
|
381
|
+
automatic: true,
|
|
382
|
+
// No requires function for PayPal to test standard behavior
|
|
383
|
+
},
|
|
196
384
|
});
|
|
197
385
|
|
|
198
|
-
|
|
386
|
+
const options = {
|
|
387
|
+
...defaultMockFundingOptions,
|
|
388
|
+
fundingSource: FUNDING.PAYPAL,
|
|
389
|
+
platform: "mobile",
|
|
390
|
+
supportsPopups: true,
|
|
391
|
+
supportedNativeBrowser: true,
|
|
392
|
+
experiment: {},
|
|
393
|
+
fundingEligibility: {
|
|
394
|
+
...defaultMockFundingOptions.fundingEligibility,
|
|
395
|
+
paypal: {
|
|
396
|
+
eligible: true,
|
|
397
|
+
vaultable: false,
|
|
398
|
+
branded: false,
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const result = isFundingEligible(FUNDING.PAYPAL, options);
|
|
404
|
+
|
|
405
|
+
// Venmo functions should not be called for non-venmo sources
|
|
406
|
+
expect(supportsVenmoPopups).not.toHaveBeenCalled();
|
|
407
|
+
expect(isSupportedNativeVenmoBrowser).not.toHaveBeenCalled();
|
|
408
|
+
expect(result).toBe(true);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test("should handle undefined experiment parameter for venmo", () => {
|
|
412
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
413
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
414
|
+
|
|
415
|
+
const options = {
|
|
416
|
+
...defaultMockFundingOptions,
|
|
417
|
+
fundingSource: FUNDING.VENMO,
|
|
418
|
+
platform: "mobile",
|
|
419
|
+
experiment: undefined,
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
423
|
+
|
|
424
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
425
|
+
undefined,
|
|
426
|
+
true,
|
|
427
|
+
options.userAgent
|
|
428
|
+
);
|
|
429
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
430
|
+
undefined,
|
|
431
|
+
options.userAgent
|
|
432
|
+
);
|
|
433
|
+
expect(result).toBe(true);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test("should pass through experiment flags to venmo utility functions", () => {
|
|
437
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
438
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
439
|
+
|
|
440
|
+
const experimentFlags = {
|
|
441
|
+
venmoEnableWebOnNonNativeBrowser: true,
|
|
442
|
+
venmoVaultWithoutPurchase: false,
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const options = {
|
|
446
|
+
...defaultMockFundingOptions,
|
|
447
|
+
fundingSource: FUNDING.VENMO,
|
|
448
|
+
platform: "mobile",
|
|
449
|
+
experiment: experimentFlags,
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
453
|
+
|
|
454
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
455
|
+
experimentFlags,
|
|
456
|
+
true,
|
|
457
|
+
options.userAgent
|
|
458
|
+
);
|
|
459
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
460
|
+
experimentFlags,
|
|
461
|
+
options.userAgent
|
|
462
|
+
);
|
|
463
|
+
expect(result).toBe(true);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test("should respect combination of venmo popup and native requirements", () => {
|
|
467
|
+
// Test case where popup succeeds but native fails
|
|
468
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
469
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
470
|
+
|
|
471
|
+
const options = {
|
|
472
|
+
...defaultMockFundingOptions,
|
|
473
|
+
fundingSource: FUNDING.VENMO,
|
|
474
|
+
platform: "mobile",
|
|
475
|
+
experiment: {},
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
479
|
+
|
|
480
|
+
expect(result).toBe(false);
|
|
481
|
+
|
|
482
|
+
// Test case where both succeed
|
|
483
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
484
|
+
|
|
485
|
+
const result2 = isFundingEligible(FUNDING.VENMO, options);
|
|
486
|
+
expect(result2).toBe(true);
|
|
199
487
|
});
|
|
200
488
|
});
|
|
201
489
|
});
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
PaylaterMarkRebrandExternalImage,
|
|
14
14
|
} from "@paypal/sdk-logos/src";
|
|
15
15
|
|
|
16
|
-
import { Logo } from "../paypal/template";
|
|
16
|
+
import { Logo as PayPalRebrandLogo } from "../paypal/template";
|
|
17
17
|
import { BUTTON_COLOR, BUTTON_LAYOUT, DEFAULT } from "../../constants";
|
|
18
18
|
import { DEFAULT_FUNDING_CONFIG, type FundingSourceConfig } from "../common";
|
|
19
19
|
import { Text } from "../../ui/text";
|
|
@@ -111,7 +111,7 @@ export function getPaylaterConfig(): FundingSourceConfig {
|
|
|
111
111
|
|
|
112
112
|
return (
|
|
113
113
|
<Style css={css} nonce={nonce}>
|
|
114
|
-
<
|
|
114
|
+
<PayPalRebrandLogo
|
|
115
115
|
logoColor={logoColor}
|
|
116
116
|
shouldApplyRebrandedStyles={shouldApplyRebrandedStyles}
|
|
117
117
|
env={env}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
isWebView,
|
|
5
|
+
isIosWebview,
|
|
6
|
+
isAndroidWebview,
|
|
7
|
+
isFacebookWebView,
|
|
8
|
+
isOperaMini,
|
|
9
|
+
isFirefoxIOS,
|
|
10
|
+
isEdgeIOS,
|
|
11
|
+
isQQBrowser,
|
|
12
|
+
isElectron,
|
|
13
|
+
isTablet,
|
|
14
|
+
isIos,
|
|
15
|
+
isSafari,
|
|
16
|
+
isAndroid,
|
|
17
|
+
isChrome,
|
|
18
|
+
isFirefox,
|
|
19
|
+
} from "@krakenjs/belter/src";
|
|
20
|
+
|
|
21
|
+
import type { Experiment } from "../types";
|
|
22
|
+
|
|
23
|
+
const isMacOsCna = (userAgent: string): boolean => {
|
|
24
|
+
return /Macintosh.*AppleWebKit(?!.*Safari)/i.test(userAgent);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const isVenmoSupportedWebView = (userAgent: string): boolean => {
|
|
28
|
+
return (
|
|
29
|
+
isWebView(userAgent) ||
|
|
30
|
+
isIosWebview(userAgent) ||
|
|
31
|
+
isAndroidWebview(userAgent) ||
|
|
32
|
+
isFacebookWebView(userAgent)
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const venmoUserAgentSupportsPopups = (userAgent: string): boolean => {
|
|
37
|
+
return !(
|
|
38
|
+
isVenmoSupportedWebView(userAgent) ||
|
|
39
|
+
isOperaMini(userAgent) ||
|
|
40
|
+
isFirefoxIOS(userAgent) ||
|
|
41
|
+
isEdgeIOS(userAgent) ||
|
|
42
|
+
isQQBrowser(userAgent) ||
|
|
43
|
+
isMacOsCna(userAgent) ||
|
|
44
|
+
isElectron()
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export function supportsVenmoPopups(
|
|
49
|
+
experiment?: Experiment,
|
|
50
|
+
supportsPopups: boolean,
|
|
51
|
+
userAgent: string
|
|
52
|
+
): boolean {
|
|
53
|
+
if (isVenmoSupportedWebView(userAgent)) {
|
|
54
|
+
if (typeof window !== "undefined" && window.popupBridge) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (experiment?.venmoEnableWebOnNonNativeBrowser === true) {
|
|
61
|
+
return venmoUserAgentSupportsPopups(userAgent);
|
|
62
|
+
}
|
|
63
|
+
return supportsPopups;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function isSupportedNativeVenmoBrowser(
|
|
67
|
+
experiment?: Experiment,
|
|
68
|
+
userAgent: string
|
|
69
|
+
): boolean {
|
|
70
|
+
if (isVenmoSupportedWebView(userAgent)) {
|
|
71
|
+
if (typeof window !== "undefined" && window.popupBridge) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isTablet(userAgent)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Default supported browsers for Venmo
|
|
82
|
+
if (
|
|
83
|
+
(isIos(userAgent) && isSafari(userAgent)) ||
|
|
84
|
+
(isAndroid(userAgent) && isChrome(userAgent))
|
|
85
|
+
) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Additional browsers enabled by experiment
|
|
90
|
+
if (
|
|
91
|
+
experiment?.venmoEnableWebOnNonNativeBrowser === true &&
|
|
92
|
+
((isIos(userAgent) && isChrome(userAgent)) ||
|
|
93
|
+
(isAndroid(userAgent) && isFirefox(userAgent)))
|
|
94
|
+
) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return false;
|
|
99
|
+
}
|