@paypal/checkout-components 5.0.381 → 5.0.383-alpha-0983e51.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/dist/button.js +1 -1
- package/dist/test/button.js +1 -1
- package/package.json +2 -1
- package/src/funding/funding.js +17 -4
- package/src/funding/funding.test.js +300 -16
- 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 +5 -0
- package/src/ui/buttons/buttons.jsx +2 -0
- package/src/ui/buttons/props.js +6 -0
- package/src/ui/buttons/styles/button.js +1 -1
- package/src/zoid/buttons/component.jsx +33 -2
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
import { vi, describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
4
|
+
import {
|
|
5
|
+
isWebView,
|
|
6
|
+
isIosWebview,
|
|
7
|
+
isAndroidWebview,
|
|
8
|
+
isFacebookWebView,
|
|
9
|
+
isOperaMini,
|
|
10
|
+
isFirefoxIOS,
|
|
11
|
+
isEdgeIOS,
|
|
12
|
+
isQQBrowser,
|
|
13
|
+
isElectron,
|
|
14
|
+
supportsPopups,
|
|
15
|
+
isTablet,
|
|
16
|
+
isIos,
|
|
17
|
+
isSafari,
|
|
18
|
+
isAndroid,
|
|
19
|
+
isChrome,
|
|
20
|
+
isFirefox,
|
|
21
|
+
} from "@krakenjs/belter/src";
|
|
22
|
+
|
|
23
|
+
import { supportsVenmoPopups, isSupportedNativeVenmoBrowser } from "./util";
|
|
24
|
+
|
|
25
|
+
// Mock all the browser detection functions from belter
|
|
26
|
+
vi.mock("@krakenjs/belter/src", () => ({
|
|
27
|
+
isWebView: vi.fn(),
|
|
28
|
+
isIosWebview: vi.fn(),
|
|
29
|
+
isAndroidWebview: vi.fn(),
|
|
30
|
+
isFacebookWebView: vi.fn(),
|
|
31
|
+
isOperaMini: vi.fn(),
|
|
32
|
+
isFirefoxIOS: vi.fn(),
|
|
33
|
+
isEdgeIOS: vi.fn(),
|
|
34
|
+
isQQBrowser: vi.fn(),
|
|
35
|
+
isElectron: vi.fn(),
|
|
36
|
+
supportsPopups: vi.fn(),
|
|
37
|
+
isTablet: vi.fn(),
|
|
38
|
+
isIos: vi.fn(),
|
|
39
|
+
isSafari: vi.fn(),
|
|
40
|
+
isAndroid: vi.fn(),
|
|
41
|
+
isChrome: vi.fn(),
|
|
42
|
+
isFirefox: vi.fn(),
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
describe("funding/util", () => {
|
|
46
|
+
const defaultUserAgent =
|
|
47
|
+
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
|
|
48
|
+
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
// Reset all mocks before each test
|
|
51
|
+
vi.clearAllMocks();
|
|
52
|
+
|
|
53
|
+
// Reset window.popupBridge
|
|
54
|
+
delete window.popupBridge;
|
|
55
|
+
|
|
56
|
+
// Set default mock return values
|
|
57
|
+
vi.mocked(isWebView).mockReturnValue(false);
|
|
58
|
+
vi.mocked(isIosWebview).mockReturnValue(false);
|
|
59
|
+
vi.mocked(isAndroidWebview).mockReturnValue(false);
|
|
60
|
+
vi.mocked(isFacebookWebView).mockReturnValue(false);
|
|
61
|
+
vi.mocked(isOperaMini).mockReturnValue(false);
|
|
62
|
+
vi.mocked(isFirefoxIOS).mockReturnValue(false);
|
|
63
|
+
vi.mocked(isEdgeIOS).mockReturnValue(false);
|
|
64
|
+
vi.mocked(isQQBrowser).mockReturnValue(false);
|
|
65
|
+
vi.mocked(isElectron).mockReturnValue(false);
|
|
66
|
+
vi.mocked(supportsPopups).mockReturnValue(true);
|
|
67
|
+
vi.mocked(isTablet).mockReturnValue(false);
|
|
68
|
+
vi.mocked(isIos).mockReturnValue(false);
|
|
69
|
+
vi.mocked(isSafari).mockReturnValue(false);
|
|
70
|
+
vi.mocked(isAndroid).mockReturnValue(false);
|
|
71
|
+
vi.mocked(isChrome).mockReturnValue(false);
|
|
72
|
+
vi.mocked(isFirefox).mockReturnValue(false);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
afterEach(() => {
|
|
76
|
+
vi.resetAllMocks();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("supportsVenmoPopups", () => {
|
|
80
|
+
describe("when in supported webview", () => {
|
|
81
|
+
beforeEach(() => {
|
|
82
|
+
vi.mocked(isWebView).mockReturnValue(true);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should return true when popupBridge is available", () => {
|
|
86
|
+
window.popupBridge = {};
|
|
87
|
+
|
|
88
|
+
expect(supportsVenmoPopups({}, defaultUserAgent)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should return false when popupBridge is not available", () => {
|
|
92
|
+
expect(supportsVenmoPopups({}, defaultUserAgent)).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("when not in supported webview", () => {
|
|
97
|
+
it("should return true when experiment flag is enabled and user agent supports popups", () => {
|
|
98
|
+
vi.mocked(supportsPopups).mockReturnValue(true);
|
|
99
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
100
|
+
|
|
101
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should return false when experiment flag is enabled but user agent doesn't support popups due to isOperaMini", () => {
|
|
105
|
+
vi.mocked(isOperaMini).mockReturnValue(true);
|
|
106
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
107
|
+
|
|
108
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should return false when experiment flag is enabled but user agent doesn't support popups due to isFirefoxIOS", () => {
|
|
112
|
+
vi.mocked(isFirefoxIOS).mockReturnValue(true);
|
|
113
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
114
|
+
|
|
115
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("should return false when experiment flag is enabled but user agent doesn't support popups due to isEdgeIOS", () => {
|
|
119
|
+
vi.mocked(isEdgeIOS).mockReturnValue(true);
|
|
120
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
121
|
+
|
|
122
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("should return false when experiment flag is enabled but user agent doesn't support popups due to isQQBrowser", () => {
|
|
126
|
+
vi.mocked(isQQBrowser).mockReturnValue(true);
|
|
127
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
128
|
+
|
|
129
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should return false when experiment flag is enabled but user agent doesn't support popups due to isElectron", () => {
|
|
133
|
+
vi.mocked(isElectron).mockReturnValue(true);
|
|
134
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
135
|
+
|
|
136
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should fall back to supportsPopups when experiment flag is not enabled", () => {
|
|
140
|
+
vi.mocked(supportsPopups).mockReturnValue(true);
|
|
141
|
+
const experiment = {};
|
|
142
|
+
|
|
143
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should fall back to supportsPopups when experiment flag is false", () => {
|
|
147
|
+
vi.mocked(supportsPopups).mockReturnValue(false);
|
|
148
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: false };
|
|
149
|
+
|
|
150
|
+
expect(supportsVenmoPopups(experiment, defaultUserAgent)).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("should handle undefined experiment", () => {
|
|
154
|
+
vi.mocked(supportsPopups).mockReturnValue(true);
|
|
155
|
+
|
|
156
|
+
expect(supportsVenmoPopups(undefined, defaultUserAgent)).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("isSupportedNativeVenmoBrowser", () => {
|
|
162
|
+
describe("when in supported webview", () => {
|
|
163
|
+
beforeEach(() => {
|
|
164
|
+
vi.mocked(isWebView).mockReturnValue(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should return true when popupBridge is available", () => {
|
|
168
|
+
window.popupBridge = {};
|
|
169
|
+
|
|
170
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("should return false when popupBridge is not available", () => {
|
|
174
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("when not in supported webview", () => {
|
|
179
|
+
it("should return false when on tablet", () => {
|
|
180
|
+
vi.mocked(isTablet).mockReturnValue(true);
|
|
181
|
+
|
|
182
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("should return true for iOS Safari by default", () => {
|
|
186
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
187
|
+
vi.mocked(isSafari).mockReturnValue(true);
|
|
188
|
+
|
|
189
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(true);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("should return true for Android Chrome by default", () => {
|
|
193
|
+
vi.mocked(isAndroid).mockReturnValue(true);
|
|
194
|
+
vi.mocked(isChrome).mockReturnValue(true);
|
|
195
|
+
|
|
196
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should return false for iOS Chrome without experiment flag", () => {
|
|
200
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
201
|
+
vi.mocked(isChrome).mockReturnValue(true);
|
|
202
|
+
|
|
203
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("should return true for iOS Chrome with experiment flag", () => {
|
|
207
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
208
|
+
vi.mocked(isChrome).mockReturnValue(true);
|
|
209
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
210
|
+
|
|
211
|
+
expect(
|
|
212
|
+
isSupportedNativeVenmoBrowser(experiment, defaultUserAgent)
|
|
213
|
+
).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("should return false for Android Firefox without experiment flag", () => {
|
|
217
|
+
vi.mocked(isAndroid).mockReturnValue(true);
|
|
218
|
+
vi.mocked(isFirefox).mockReturnValue(true);
|
|
219
|
+
|
|
220
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("should return true for Android Firefox with experiment flag", () => {
|
|
224
|
+
vi.mocked(isAndroid).mockReturnValue(true);
|
|
225
|
+
vi.mocked(isFirefox).mockReturnValue(true);
|
|
226
|
+
const experiment = { venmoEnableWebOnNonNativeBrowser: true };
|
|
227
|
+
|
|
228
|
+
expect(
|
|
229
|
+
isSupportedNativeVenmoBrowser(experiment, defaultUserAgent)
|
|
230
|
+
).toBe(true);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("should return false for unsupported browser combinations", () => {
|
|
234
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
235
|
+
vi.mocked(isFirefox).mockReturnValue(true); // iOS Firefox (not Chrome)
|
|
236
|
+
|
|
237
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("should return false for desktop browsers", () => {
|
|
241
|
+
// No mobile flags set, simulating desktop
|
|
242
|
+
|
|
243
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it("should handle undefined experiment", () => {
|
|
247
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
248
|
+
vi.mocked(isSafari).mockReturnValue(true);
|
|
249
|
+
|
|
250
|
+
expect(isSupportedNativeVenmoBrowser(undefined, defaultUserAgent)).toBe(
|
|
251
|
+
true
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("should prioritize tablet check over browser checks", () => {
|
|
256
|
+
vi.mocked(isTablet).mockReturnValue(true);
|
|
257
|
+
vi.mocked(isIos).mockReturnValue(true);
|
|
258
|
+
vi.mocked(isSafari).mockReturnValue(true);
|
|
259
|
+
|
|
260
|
+
expect(isSupportedNativeVenmoBrowser({}, defaultUserAgent)).toBe(false);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
});
|
|
@@ -48,19 +48,18 @@ export function getVenmoConfig(): FundingSourceConfig {
|
|
|
48
48
|
return true;
|
|
49
49
|
},
|
|
50
50
|
|
|
51
|
-
requires: ({
|
|
52
|
-
const isNonNativeSupported =
|
|
53
|
-
experiment?.venmoEnableWebOnNonNativeBrowser === true ||
|
|
54
|
-
(__WEB__ && window.popupBridge);
|
|
55
|
-
|
|
51
|
+
requires: ({ platform }) => {
|
|
56
52
|
if (platform === PLATFORM.MOBILE) {
|
|
57
53
|
return {
|
|
58
|
-
native:
|
|
59
|
-
popup:
|
|
54
|
+
native: true,
|
|
55
|
+
popup: true,
|
|
60
56
|
};
|
|
61
57
|
}
|
|
62
58
|
|
|
63
|
-
return {
|
|
59
|
+
return {
|
|
60
|
+
native: false,
|
|
61
|
+
popup: false,
|
|
62
|
+
};
|
|
64
63
|
},
|
|
65
64
|
|
|
66
65
|
Logo: ({ logoColor, optional, shouldApplyRebrandedStyles }) => {
|
|
@@ -8,6 +8,9 @@ import { BUTTON_FLOW } from "../../constants";
|
|
|
8
8
|
import { getVenmoConfig } from "./config";
|
|
9
9
|
|
|
10
10
|
describe("Venmo eligibility", () => {
|
|
11
|
+
window.navigator.mockUserAgent =
|
|
12
|
+
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
|
|
13
|
+
|
|
11
14
|
const baseEligibilityProps = {
|
|
12
15
|
fundingSource: undefined,
|
|
13
16
|
components: ["buttons"],
|
|
@@ -102,58 +105,35 @@ describe("Venmo eligibility", () => {
|
|
|
102
105
|
});
|
|
103
106
|
|
|
104
107
|
describe("requires", () => {
|
|
105
|
-
test("should
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const isVenmoEligible = venmoConfig.requires?.({
|
|
109
|
-
experiment: {
|
|
110
|
-
venmoEnableWebOnNonNativeBrowser: true,
|
|
111
|
-
},
|
|
108
|
+
test("should require native and popup support when platform is mobile", () => {
|
|
109
|
+
const venmoRequires = venmoConfig.requires?.({
|
|
112
110
|
platform: PLATFORM.MOBILE,
|
|
113
111
|
});
|
|
114
112
|
|
|
115
|
-
expect(
|
|
116
|
-
native:
|
|
117
|
-
popup:
|
|
113
|
+
expect(venmoRequires).toEqual({
|
|
114
|
+
native: true,
|
|
115
|
+
popup: true,
|
|
118
116
|
});
|
|
119
|
-
|
|
120
|
-
window.popupBridge = undefined;
|
|
121
117
|
});
|
|
122
118
|
|
|
123
|
-
test("should not
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
venmoEnableWebOnNonNativeBrowser: true,
|
|
127
|
-
},
|
|
128
|
-
platform: PLATFORM.MOBILE,
|
|
119
|
+
test("should not require native or popup support when platform is desktop", () => {
|
|
120
|
+
const venmoRequires = venmoConfig.requires?.({
|
|
121
|
+
platform: PLATFORM.DESKTOP,
|
|
129
122
|
});
|
|
130
123
|
|
|
131
|
-
expect(
|
|
124
|
+
expect(venmoRequires).toEqual({
|
|
132
125
|
native: false,
|
|
133
126
|
popup: false,
|
|
134
127
|
});
|
|
135
128
|
});
|
|
136
129
|
|
|
137
|
-
test("should
|
|
138
|
-
const
|
|
139
|
-
experiment: {
|
|
140
|
-
venmoEnableWebOnNonNativeBrowser: false,
|
|
141
|
-
},
|
|
142
|
-
platform: PLATFORM.MOBILE,
|
|
143
|
-
});
|
|
130
|
+
test("should not require native or popup support when platform is not specified", () => {
|
|
131
|
+
const venmoRequires = venmoConfig.requires?.({});
|
|
144
132
|
|
|
145
|
-
expect(
|
|
146
|
-
native:
|
|
147
|
-
popup:
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
test("should not check for native and popup eligibility if platform is not mobile", () => {
|
|
152
|
-
const isVenmoEligible = venmoConfig.requires?.({
|
|
153
|
-
platform: PLATFORM.DESKTOP,
|
|
133
|
+
expect(venmoRequires).toEqual({
|
|
134
|
+
native: false,
|
|
135
|
+
popup: false,
|
|
154
136
|
});
|
|
155
|
-
|
|
156
|
-
expect(isVenmoEligible).toEqual({});
|
|
157
137
|
});
|
|
158
138
|
});
|
|
159
139
|
});
|
package/src/marks/component.jsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
memoize,
|
|
10
10
|
isApplePaySupported,
|
|
11
11
|
supportsPopups as userAgentSupportsPopups,
|
|
12
|
+
getUserAgent,
|
|
12
13
|
} from "@krakenjs/belter/src";
|
|
13
14
|
import {
|
|
14
15
|
PLATFORM,
|
|
@@ -50,6 +51,7 @@ type MarksProps = {|
|
|
|
50
51
|
onShippingAddressChange?: OnShippingAddressChange,
|
|
51
52
|
onShippingOptionsChange?: OnShippingOptionsChange,
|
|
52
53
|
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
54
|
+
userAgent: string,
|
|
53
55
|
|};
|
|
54
56
|
|
|
55
57
|
export type MarksComponent = (MarksProps) => MarksInstance;
|
|
@@ -61,6 +63,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
|
|
|
61
63
|
onShippingAddressChange,
|
|
62
64
|
onShippingOptionsChange,
|
|
63
65
|
displayOnly,
|
|
66
|
+
userAgent = getUserAgent(),
|
|
64
67
|
}: MarksProps = {}): MarksInstance {
|
|
65
68
|
const height = DEFAULT_HEIGHT;
|
|
66
69
|
const fundingEligibility = getFundingEligibility();
|
|
@@ -97,6 +100,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
|
|
|
97
100
|
supportedNativeBrowser,
|
|
98
101
|
experiment,
|
|
99
102
|
displayOnly,
|
|
103
|
+
userAgent,
|
|
100
104
|
});
|
|
101
105
|
const env = getEnv();
|
|
102
106
|
|
|
@@ -121,6 +125,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
|
|
|
121
125
|
supportedNativeBrowser,
|
|
122
126
|
experiment,
|
|
123
127
|
displayOnly,
|
|
128
|
+
userAgent,
|
|
124
129
|
});
|
|
125
130
|
};
|
|
126
131
|
|
|
@@ -168,6 +168,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
|
|
|
168
168
|
userIDToken,
|
|
169
169
|
vault,
|
|
170
170
|
wallet,
|
|
171
|
+
userAgent,
|
|
171
172
|
} = normalizeButtonProps(props);
|
|
172
173
|
const { layout, shape, tagline } = style;
|
|
173
174
|
|
|
@@ -190,6 +191,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
|
|
|
190
191
|
supportedNativeBrowser,
|
|
191
192
|
experiment,
|
|
192
193
|
displayOnly,
|
|
194
|
+
userAgent,
|
|
193
195
|
});
|
|
194
196
|
const multiple = fundingSources.length > 1;
|
|
195
197
|
|
package/src/ui/buttons/props.js
CHANGED
|
@@ -491,6 +491,7 @@ export type RenderButtonProps = {|
|
|
|
491
491
|
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
492
492
|
message?: ButtonMessage,
|
|
493
493
|
messageMarkup?: string,
|
|
494
|
+
userAgent: string,
|
|
494
495
|
|};
|
|
495
496
|
|
|
496
497
|
export type PrerenderDetails = {|
|
|
@@ -633,6 +634,7 @@ export type ButtonProps = {|
|
|
|
633
634
|
message?: ButtonMessage,
|
|
634
635
|
messageMarkup?: string,
|
|
635
636
|
hideSubmitButtonForCardForm?: boolean,
|
|
637
|
+
userAgent: string,
|
|
636
638
|
|};
|
|
637
639
|
|
|
638
640
|
// eslint-disable-next-line flowtype/require-exact-type
|
|
@@ -683,6 +685,7 @@ export type ButtonPropsInputs = {
|
|
|
683
685
|
messageMarkup?: string | void,
|
|
684
686
|
renderedButtons: $ReadOnlyArray<$Values<typeof FUNDING>>,
|
|
685
687
|
buttonColor: ButtonColor,
|
|
688
|
+
userAgent: string,
|
|
686
689
|
};
|
|
687
690
|
|
|
688
691
|
export const DEFAULT_STYLE = {
|
|
@@ -1262,6 +1265,7 @@ export function normalizeButtonProps(
|
|
|
1262
1265
|
messageMarkup,
|
|
1263
1266
|
renderedButtons,
|
|
1264
1267
|
shopperSessionId,
|
|
1268
|
+
userAgent,
|
|
1265
1269
|
} = props;
|
|
1266
1270
|
|
|
1267
1271
|
const { country, lang } = locale;
|
|
@@ -1315,6 +1319,7 @@ export function normalizeButtonProps(
|
|
|
1315
1319
|
supportsPopups,
|
|
1316
1320
|
supportedNativeBrowser,
|
|
1317
1321
|
displayOnly,
|
|
1322
|
+
userAgent,
|
|
1318
1323
|
})
|
|
1319
1324
|
) {
|
|
1320
1325
|
throw new Error(`Funding Source not eligible: ${fundingSource}`);
|
|
@@ -1366,5 +1371,6 @@ export function normalizeButtonProps(
|
|
|
1366
1371
|
displayOnly,
|
|
1367
1372
|
message,
|
|
1368
1373
|
messageMarkup,
|
|
1374
|
+
userAgent,
|
|
1369
1375
|
};
|
|
1370
1376
|
}
|
|
@@ -211,7 +211,7 @@ export const buttonRebrandStyle = `
|
|
|
211
211
|
width: auto;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
/* Hide/show credit/paylater logos based on button width */
|
|
215
215
|
@media only screen and (min-width: 0px) and (max-width: 150px) {
|
|
216
216
|
[${ATTRIBUTE.FUNDING_SOURCE}="credit"].${CLASS.BUTTON_REBRAND} .${CLASS.BUTTON_LABEL} .${CLASS.LOGO_REBRAND},
|
|
217
217
|
[${ATTRIBUTE.FUNDING_SOURCE}="paylater"].${CLASS.BUTTON_REBRAND} .${CLASS.BUTTON_LABEL} .${CLASS.LOGO_REBRAND} {
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
isApplePaySupported,
|
|
62
62
|
supportsPopups as userAgentSupportsPopups,
|
|
63
63
|
noop,
|
|
64
|
+
getUserAgent,
|
|
64
65
|
} from "@krakenjs/belter/src";
|
|
65
66
|
import {
|
|
66
67
|
FUNDING,
|
|
@@ -89,6 +90,10 @@ import {
|
|
|
89
90
|
type ButtonExtensions,
|
|
90
91
|
} from "../../ui/buttons/props";
|
|
91
92
|
import { isFundingEligible } from "../../funding";
|
|
93
|
+
import {
|
|
94
|
+
supportsVenmoPopups,
|
|
95
|
+
isSupportedNativeVenmoBrowser,
|
|
96
|
+
} from "../../funding/util";
|
|
92
97
|
import { getPixelComponent } from "../pixel";
|
|
93
98
|
import { CLASS } from "../../constants";
|
|
94
99
|
import { PayPalAppSwitchOverlay } from "../../ui/overlay/paypal-app-switch/overlay";
|
|
@@ -251,6 +256,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
251
256
|
createSubscription,
|
|
252
257
|
createVaultSetupToken,
|
|
253
258
|
displayOnly,
|
|
259
|
+
userAgent,
|
|
254
260
|
} = props;
|
|
255
261
|
|
|
256
262
|
const flow = determineFlow({
|
|
@@ -294,6 +300,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
294
300
|
supportedNativeBrowser,
|
|
295
301
|
experiment,
|
|
296
302
|
displayOnly,
|
|
303
|
+
userAgent,
|
|
297
304
|
})
|
|
298
305
|
) {
|
|
299
306
|
return {
|
|
@@ -714,6 +721,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
714
721
|
createSubscription,
|
|
715
722
|
createVaultSetupToken,
|
|
716
723
|
displayOnly,
|
|
724
|
+
userAgent = getUserAgent(),
|
|
717
725
|
} = props;
|
|
718
726
|
|
|
719
727
|
const flow = determineFlow({
|
|
@@ -744,6 +752,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
744
752
|
supportsPopups,
|
|
745
753
|
supportedNativeBrowser,
|
|
746
754
|
displayOnly,
|
|
755
|
+
userAgent,
|
|
747
756
|
})
|
|
748
757
|
) {
|
|
749
758
|
throw new Error(`${fundingSource} is not eligible`);
|
|
@@ -1266,13 +1275,28 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
1266
1275
|
|
|
1267
1276
|
supportedNativeBrowser: {
|
|
1268
1277
|
type: "boolean",
|
|
1269
|
-
value:
|
|
1278
|
+
value: ({ props }) => {
|
|
1279
|
+
if (props.fundingSource === FUNDING.VENMO) {
|
|
1280
|
+
return isSupportedNativeVenmoBrowser(
|
|
1281
|
+
props.experiment,
|
|
1282
|
+
props.userAgent
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
return isSupportedNativeBrowser();
|
|
1287
|
+
},
|
|
1270
1288
|
queryParam: true,
|
|
1271
1289
|
},
|
|
1272
1290
|
|
|
1273
1291
|
supportsPopups: {
|
|
1274
1292
|
type: "boolean",
|
|
1275
|
-
value: () =>
|
|
1293
|
+
value: ({ props }) => {
|
|
1294
|
+
if (props.fundingSource === FUNDING.VENMO) {
|
|
1295
|
+
return supportsVenmoPopups(props.experiment, props.userAgent);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
return userAgentSupportsPopups();
|
|
1299
|
+
},
|
|
1276
1300
|
queryParam: true,
|
|
1277
1301
|
},
|
|
1278
1302
|
|
|
@@ -1316,6 +1340,13 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
1316
1340
|
required: false,
|
|
1317
1341
|
queryParam: true,
|
|
1318
1342
|
},
|
|
1343
|
+
|
|
1344
|
+
userAgent: {
|
|
1345
|
+
type: "string",
|
|
1346
|
+
required: false,
|
|
1347
|
+
queryParam: true,
|
|
1348
|
+
value: getUserAgent,
|
|
1349
|
+
},
|
|
1319
1350
|
},
|
|
1320
1351
|
|
|
1321
1352
|
exports: {
|