@paypal/checkout-components 5.0.383 → 5.0.385
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 +3 -2
- package/src/funding/bancontact/config.jsx +4 -0
- package/src/funding/common.jsx +1 -0
- package/src/funding/credit/config.jsx +4 -0
- package/src/funding/funding.js +17 -4
- package/src/funding/funding.test.js +300 -16
- package/src/funding/paylater/config.jsx +4 -0
- package/src/funding/util.js +99 -0
- package/src/funding/util.test.js +264 -0
- package/src/funding/venmo/config.jsx +7 -8
- package/src/funding/venmo/config.test.js +17 -37
- package/src/marks/component.jsx +28 -9
- package/src/marks/template.jsx +3 -8
- package/src/marks/templateRebrand.jsx +177 -0
- package/src/ui/buttons/buttons.jsx +2 -0
- package/src/ui/buttons/props.js +6 -0
- package/src/zoid/buttons/component.jsx +33 -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.385",
|
|
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",
|
|
@@ -122,7 +123,7 @@
|
|
|
122
123
|
"@paypal/funding-components": "^1.0.31",
|
|
123
124
|
"@paypal/sdk-client": "^4.0.199",
|
|
124
125
|
"@paypal/sdk-constants": "^1.0.156",
|
|
125
|
-
"@paypal/sdk-logos": "^2.3.
|
|
126
|
+
"@paypal/sdk-logos": "^2.3.2"
|
|
126
127
|
},
|
|
127
128
|
"lint-staged": {
|
|
128
129
|
"**/*": "prettier --write --ignore-unknown"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import {
|
|
5
5
|
BancontactLogoInlineSVG,
|
|
6
6
|
BancontactLogoExternalImage,
|
|
7
|
+
BancontactMarkRebrandExternalImage,
|
|
7
8
|
} from "@paypal/sdk-logos/src";
|
|
8
9
|
import { Fragment, node } from "@krakenjs/jsx-pragmatic/src";
|
|
9
10
|
|
|
@@ -47,5 +48,8 @@ export function getBancontactConfig(): FundingSourceConfig {
|
|
|
47
48
|
|
|
48
49
|
return <BasicLabel {...opts} logo={apmLogo} />;
|
|
49
50
|
},
|
|
51
|
+
|
|
52
|
+
Mark: () => <BancontactMarkRebrandExternalImage />,
|
|
53
|
+
shouldUseMarkForRebrandOnly: true,
|
|
50
54
|
};
|
|
51
55
|
}
|
package/src/funding/common.jsx
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
LOGO_COLOR,
|
|
14
14
|
PPRebrandLogoInlineSVG,
|
|
15
15
|
PPRebrandLogoExternalImage,
|
|
16
|
+
CreditMarkRebrandExternalImage,
|
|
16
17
|
} from "@paypal/sdk-logos/src";
|
|
17
18
|
|
|
18
19
|
import {
|
|
@@ -93,6 +94,9 @@ export function getCreditConfig(): FundingSourceConfig {
|
|
|
93
94
|
);
|
|
94
95
|
},
|
|
95
96
|
|
|
97
|
+
Mark: () => <CreditMarkRebrandExternalImage />,
|
|
98
|
+
shouldUseMarkForRebrandOnly: true,
|
|
99
|
+
|
|
96
100
|
WalletLabel,
|
|
97
101
|
|
|
98
102
|
colors: [
|
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, 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,268 @@ 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
|
+
options.userAgent
|
|
283
|
+
);
|
|
284
|
+
expect(result).toBe(true);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test("should use isSupportedNativeVenmoBrowser for venmo funding source when native is required", () => {
|
|
288
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
289
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
290
|
+
|
|
291
|
+
const options = {
|
|
292
|
+
...defaultMockFundingOptions,
|
|
293
|
+
fundingSource: FUNDING.VENMO,
|
|
294
|
+
platform: "mobile",
|
|
295
|
+
experiment: { venmoEnableWebOnNonNativeBrowser: true },
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
299
|
+
|
|
300
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
301
|
+
options.experiment,
|
|
302
|
+
options.userAgent
|
|
303
|
+
);
|
|
304
|
+
expect(result).toBe(true);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test("should return false when venmo popup support is required but supportsVenmoPopups returns false", () => {
|
|
308
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(false);
|
|
309
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
310
|
+
|
|
311
|
+
const options = {
|
|
312
|
+
...defaultMockFundingOptions,
|
|
313
|
+
fundingSource: FUNDING.VENMO,
|
|
314
|
+
platform: "mobile",
|
|
315
|
+
experiment: {},
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
319
|
+
|
|
320
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
321
|
+
options.experiment,
|
|
322
|
+
options.userAgent
|
|
323
|
+
);
|
|
324
|
+
expect(result).toBe(false);
|
|
189
325
|
});
|
|
190
326
|
|
|
191
|
-
test("should
|
|
192
|
-
|
|
327
|
+
test("should return false when venmo native support is required but isSupportedNativeVenmoBrowser returns false", () => {
|
|
328
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
329
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
330
|
+
|
|
331
|
+
const options = {
|
|
193
332
|
...defaultMockFundingOptions,
|
|
194
|
-
|
|
195
|
-
|
|
333
|
+
fundingSource: FUNDING.VENMO,
|
|
334
|
+
platform: "mobile",
|
|
335
|
+
experiment: {},
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
339
|
+
|
|
340
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
341
|
+
options.experiment,
|
|
342
|
+
options.userAgent
|
|
343
|
+
);
|
|
344
|
+
expect(result).toBe(false);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
test("should use standard supportsPopups for non-venmo funding sources", () => {
|
|
348
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(false);
|
|
349
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
350
|
+
|
|
351
|
+
// Update the mock to not require popup and native for PayPal to isolate the test
|
|
352
|
+
vi.mocked(getFundingConfig).mockReturnValue({
|
|
353
|
+
[FUNDING.PAYLATER]: {
|
|
354
|
+
enabled: true,
|
|
355
|
+
automatic: true,
|
|
356
|
+
},
|
|
357
|
+
[FUNDING.CARD]: {
|
|
358
|
+
enabled: true,
|
|
359
|
+
automatic: true,
|
|
360
|
+
},
|
|
361
|
+
[FUNDING.SEPA]: {
|
|
362
|
+
enabled: false,
|
|
363
|
+
automatic: false,
|
|
364
|
+
},
|
|
365
|
+
[FUNDING.OXXO]: {
|
|
366
|
+
enabled: false,
|
|
367
|
+
automatic: false,
|
|
368
|
+
},
|
|
369
|
+
[FUNDING.VENMO]: {
|
|
370
|
+
enabled: true,
|
|
371
|
+
automatic: true,
|
|
372
|
+
requires: () => ({
|
|
373
|
+
popup: true,
|
|
374
|
+
native: true,
|
|
375
|
+
}),
|
|
376
|
+
},
|
|
377
|
+
[FUNDING.PAYPAL]: {
|
|
378
|
+
enabled: true,
|
|
379
|
+
automatic: true,
|
|
380
|
+
// No requires function for PayPal to test standard behavior
|
|
381
|
+
},
|
|
196
382
|
});
|
|
197
383
|
|
|
198
|
-
|
|
384
|
+
const options = {
|
|
385
|
+
...defaultMockFundingOptions,
|
|
386
|
+
fundingSource: FUNDING.PAYPAL,
|
|
387
|
+
platform: "mobile",
|
|
388
|
+
supportsPopups: true,
|
|
389
|
+
supportedNativeBrowser: true,
|
|
390
|
+
experiment: {},
|
|
391
|
+
fundingEligibility: {
|
|
392
|
+
...defaultMockFundingOptions.fundingEligibility,
|
|
393
|
+
paypal: {
|
|
394
|
+
eligible: true,
|
|
395
|
+
vaultable: false,
|
|
396
|
+
branded: false,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const result = isFundingEligible(FUNDING.PAYPAL, options);
|
|
402
|
+
|
|
403
|
+
// Venmo functions should not be called for non-venmo sources
|
|
404
|
+
expect(supportsVenmoPopups).not.toHaveBeenCalled();
|
|
405
|
+
expect(isSupportedNativeVenmoBrowser).not.toHaveBeenCalled();
|
|
406
|
+
expect(result).toBe(true);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
test("should handle undefined experiment parameter for venmo", () => {
|
|
410
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
411
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
412
|
+
|
|
413
|
+
const options = {
|
|
414
|
+
...defaultMockFundingOptions,
|
|
415
|
+
fundingSource: FUNDING.VENMO,
|
|
416
|
+
platform: "mobile",
|
|
417
|
+
experiment: undefined,
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
421
|
+
|
|
422
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
423
|
+
undefined,
|
|
424
|
+
options.userAgent
|
|
425
|
+
);
|
|
426
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
427
|
+
undefined,
|
|
428
|
+
options.userAgent
|
|
429
|
+
);
|
|
430
|
+
expect(result).toBe(true);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test("should pass through experiment flags to venmo utility functions", () => {
|
|
434
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
435
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
436
|
+
|
|
437
|
+
const experimentFlags = {
|
|
438
|
+
venmoEnableWebOnNonNativeBrowser: true,
|
|
439
|
+
venmoVaultWithoutPurchase: false,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const options = {
|
|
443
|
+
...defaultMockFundingOptions,
|
|
444
|
+
fundingSource: FUNDING.VENMO,
|
|
445
|
+
platform: "mobile",
|
|
446
|
+
experiment: experimentFlags,
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
450
|
+
|
|
451
|
+
expect(supportsVenmoPopups).toHaveBeenCalledWith(
|
|
452
|
+
experimentFlags,
|
|
453
|
+
options.userAgent
|
|
454
|
+
);
|
|
455
|
+
expect(isSupportedNativeVenmoBrowser).toHaveBeenCalledWith(
|
|
456
|
+
experimentFlags,
|
|
457
|
+
options.userAgent
|
|
458
|
+
);
|
|
459
|
+
expect(result).toBe(true);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test("should respect combination of venmo popup and native requirements", () => {
|
|
463
|
+
// Test case where popup succeeds but native fails
|
|
464
|
+
vi.mocked(supportsVenmoPopups).mockReturnValue(true);
|
|
465
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(false);
|
|
466
|
+
|
|
467
|
+
const options = {
|
|
468
|
+
...defaultMockFundingOptions,
|
|
469
|
+
fundingSource: FUNDING.VENMO,
|
|
470
|
+
platform: "mobile",
|
|
471
|
+
experiment: {},
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
const result = isFundingEligible(FUNDING.VENMO, options);
|
|
475
|
+
|
|
476
|
+
expect(result).toBe(false);
|
|
477
|
+
|
|
478
|
+
// Test case where both succeed
|
|
479
|
+
vi.mocked(isSupportedNativeVenmoBrowser).mockReturnValue(true);
|
|
480
|
+
|
|
481
|
+
const result2 = isFundingEligible(FUNDING.VENMO, options);
|
|
482
|
+
expect(result2).toBe(true);
|
|
199
483
|
});
|
|
200
484
|
});
|
|
201
485
|
});
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
LOGO_COLOR,
|
|
11
11
|
PPRebrandLogoInlineSVG,
|
|
12
12
|
PPRebrandLogoExternalImage,
|
|
13
|
+
PaylaterMarkRebrandExternalImage,
|
|
13
14
|
} from "@paypal/sdk-logos/src";
|
|
14
15
|
|
|
15
16
|
import { Logo } from "../paypal/template";
|
|
@@ -131,6 +132,9 @@ export function getPaylaterConfig(): FundingSourceConfig {
|
|
|
131
132
|
);
|
|
132
133
|
},
|
|
133
134
|
|
|
135
|
+
Mark: () => <PaylaterMarkRebrandExternalImage />,
|
|
136
|
+
shouldUseMarkForRebrandOnly: true,
|
|
137
|
+
|
|
134
138
|
colors: [
|
|
135
139
|
BUTTON_COLOR.WHITE,
|
|
136
140
|
BUTTON_COLOR.BLACK,
|
|
@@ -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
|
+
supportsPopups,
|
|
14
|
+
isTablet,
|
|
15
|
+
isIos,
|
|
16
|
+
isSafari,
|
|
17
|
+
isAndroid,
|
|
18
|
+
isChrome,
|
|
19
|
+
isFirefox,
|
|
20
|
+
} from "@krakenjs/belter/src";
|
|
21
|
+
|
|
22
|
+
import type { Experiment } from "../types";
|
|
23
|
+
|
|
24
|
+
const isMacOsCna = (userAgent: string): boolean => {
|
|
25
|
+
return /Macintosh.*AppleWebKit(?!.*Safari)/i.test(userAgent);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const isVenmoSupportedWebView = (userAgent: string): boolean => {
|
|
29
|
+
return (
|
|
30
|
+
isWebView(userAgent) ||
|
|
31
|
+
isIosWebview(userAgent) ||
|
|
32
|
+
isAndroidWebview(userAgent) ||
|
|
33
|
+
isFacebookWebView(userAgent)
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const venmoUserAgentSupportsPopups = (userAgent: string): boolean => {
|
|
38
|
+
return !(
|
|
39
|
+
isVenmoSupportedWebView(userAgent) ||
|
|
40
|
+
isOperaMini(userAgent) ||
|
|
41
|
+
isFirefoxIOS(userAgent) ||
|
|
42
|
+
isEdgeIOS(userAgent) ||
|
|
43
|
+
isQQBrowser(userAgent) ||
|
|
44
|
+
isMacOsCna(userAgent) ||
|
|
45
|
+
isElectron()
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export function supportsVenmoPopups(
|
|
50
|
+
experiment?: Experiment,
|
|
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
|
+
}
|