@paypal/checkout-components 5.0.282 → 5.0.283
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paypal/checkout-components",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.283",
|
|
4
4
|
"description": "PayPal Checkout components, for integrating checkout products.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"@paypal/common-components": "^1.0.35",
|
|
111
111
|
"@paypal/funding-components": "^1.0.31",
|
|
112
112
|
"@paypal/sdk-client": "^4.0.176",
|
|
113
|
-
"@paypal/sdk-constants": "^1.0.
|
|
113
|
+
"@paypal/sdk-constants": "^1.0.133",
|
|
114
114
|
"@paypal/sdk-logos": "^2.2.6"
|
|
115
115
|
},
|
|
116
116
|
"lint-staged": {
|
package/src/funding/funding.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type {
|
|
4
|
+
FundingEligibilityType,
|
|
5
|
+
CardEligibility,
|
|
6
|
+
} from "@paypal/sdk-client/src";
|
|
7
|
+
import {
|
|
8
|
+
PLATFORM,
|
|
9
|
+
FUNDING,
|
|
10
|
+
COMPONENTS,
|
|
11
|
+
DISPLAY_ONLY_VALUES,
|
|
12
|
+
} from "@paypal/sdk-constants/src";
|
|
5
13
|
import { SUPPORTED_FUNDING_SOURCES } from "@paypal/funding-components/src";
|
|
6
14
|
|
|
7
15
|
import type { Wallet, Experiment } from "../types";
|
|
@@ -30,8 +38,36 @@ type IsFundingEligibleOptions = {|
|
|
|
30
38
|
supportsPopups: boolean,
|
|
31
39
|
supportedNativeBrowser: boolean,
|
|
32
40
|
experiment?: Experiment,
|
|
41
|
+
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
33
42
|
|};
|
|
34
43
|
|
|
44
|
+
function isFundingVaultable({
|
|
45
|
+
fundingEligibility,
|
|
46
|
+
fundingSource,
|
|
47
|
+
}: {|
|
|
48
|
+
fundingEligibility: FundingEligibilityType,
|
|
49
|
+
fundingSource: $Values<typeof FUNDING>,
|
|
50
|
+
|}): boolean {
|
|
51
|
+
// fundingEligibility.card doesn't give vaultable property like other funding sources
|
|
52
|
+
if (
|
|
53
|
+
fundingSource === FUNDING.CARD &&
|
|
54
|
+
fundingEligibility[fundingSource]?.vendors
|
|
55
|
+
) {
|
|
56
|
+
const { vendors } = (fundingEligibility[fundingSource]: CardEligibility);
|
|
57
|
+
|
|
58
|
+
// If any vendors are both eligible & vaultable, card is vaultable
|
|
59
|
+
return Object.keys(vendors).some(
|
|
60
|
+
(vendor) => vendors[vendor]?.eligible && vendors[vendor]?.vaultable
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!fundingEligibility[fundingSource]?.vaultable) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
35
71
|
export function isFundingEligible(
|
|
36
72
|
source: $Values<typeof FUNDING>,
|
|
37
73
|
{
|
|
@@ -50,6 +86,7 @@ export function isFundingEligible(
|
|
|
50
86
|
supportsPopups,
|
|
51
87
|
supportedNativeBrowser,
|
|
52
88
|
experiment,
|
|
89
|
+
displayOnly,
|
|
53
90
|
}: IsFundingEligibleOptions
|
|
54
91
|
): boolean {
|
|
55
92
|
if (!fundingEligibility[source] || !fundingEligibility[source].eligible) {
|
|
@@ -70,6 +107,16 @@ export function isFundingEligible(
|
|
|
70
107
|
return false;
|
|
71
108
|
}
|
|
72
109
|
|
|
110
|
+
const shouldDisplayOnlyVaultableButtons =
|
|
111
|
+
displayOnly && displayOnly.includes("vaultable");
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
shouldDisplayOnlyVaultableButtons &&
|
|
115
|
+
!isFundingVaultable({ fundingEligibility, fundingSource: source })
|
|
116
|
+
) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
73
120
|
if (
|
|
74
121
|
fundingConfig.eligible &&
|
|
75
122
|
!fundingConfig.eligible({
|
|
@@ -152,6 +199,7 @@ export function determineEligibleFunding({
|
|
|
152
199
|
supportsPopups,
|
|
153
200
|
supportedNativeBrowser,
|
|
154
201
|
experiment,
|
|
202
|
+
displayOnly = [],
|
|
155
203
|
}: {|
|
|
156
204
|
fundingSource: ?$Values<typeof FUNDING>,
|
|
157
205
|
remembered: $ReadOnlyArray<$Values<typeof FUNDING>>,
|
|
@@ -169,6 +217,7 @@ export function determineEligibleFunding({
|
|
|
169
217
|
supportsPopups: boolean,
|
|
170
218
|
supportedNativeBrowser: boolean,
|
|
171
219
|
experiment: Experiment,
|
|
220
|
+
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
172
221
|
|}): $ReadOnlyArray<$Values<typeof FUNDING>> {
|
|
173
222
|
if (fundingSource) {
|
|
174
223
|
return [fundingSource];
|
|
@@ -191,6 +240,7 @@ export function determineEligibleFunding({
|
|
|
191
240
|
supportsPopups,
|
|
192
241
|
supportedNativeBrowser,
|
|
193
242
|
experiment,
|
|
243
|
+
displayOnly,
|
|
194
244
|
})
|
|
195
245
|
);
|
|
196
246
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import { COMPONENTS, FUNDING } from "@paypal/sdk-constants/src";
|
|
3
|
+
import { describe, expect } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { BUTTON_FLOW } from "../constants";
|
|
6
|
+
|
|
7
|
+
import { isFundingEligible } from "./funding";
|
|
8
|
+
|
|
9
|
+
const defaultMockFundingOptions = {
|
|
10
|
+
platform: "desktop",
|
|
11
|
+
components: [COMPONENTS.BUTTONS],
|
|
12
|
+
flow: BUTTON_FLOW.PURCHASE,
|
|
13
|
+
fundingSource: FUNDING.SEPA,
|
|
14
|
+
fundingEligibility: {
|
|
15
|
+
paylater: {
|
|
16
|
+
eligible: true,
|
|
17
|
+
vaultable: false,
|
|
18
|
+
},
|
|
19
|
+
venmo: {
|
|
20
|
+
eligible: true,
|
|
21
|
+
vaultable: true,
|
|
22
|
+
branded: false,
|
|
23
|
+
},
|
|
24
|
+
sepa: {
|
|
25
|
+
eligible: false,
|
|
26
|
+
branded: false,
|
|
27
|
+
},
|
|
28
|
+
oxxo: {
|
|
29
|
+
eligible: false,
|
|
30
|
+
vaultable: true,
|
|
31
|
+
branded: false,
|
|
32
|
+
},
|
|
33
|
+
card: {
|
|
34
|
+
eligible: true,
|
|
35
|
+
branded: false,
|
|
36
|
+
vendors: {
|
|
37
|
+
visa: {
|
|
38
|
+
eligible: true,
|
|
39
|
+
vaultable: false,
|
|
40
|
+
},
|
|
41
|
+
mastercard: {
|
|
42
|
+
eligible: true,
|
|
43
|
+
vaultable: false,
|
|
44
|
+
},
|
|
45
|
+
amex: {
|
|
46
|
+
eligible: true,
|
|
47
|
+
vaultable: false,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
applePaySupport: false,
|
|
53
|
+
supportsPopups: true,
|
|
54
|
+
supportedNativeBrowser: true,
|
|
55
|
+
onShippingChange: null,
|
|
56
|
+
onShippingAddressChange: null,
|
|
57
|
+
onShippingOptionsChange: null,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
describe("Funding eligibility", () => {
|
|
61
|
+
test("should not be eligible if funding source is missing from fundingEligibility", () => {
|
|
62
|
+
const fundingEligible = isFundingEligible(
|
|
63
|
+
FUNDING.WECHATPAY,
|
|
64
|
+
defaultMockFundingOptions
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(fundingEligible).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("should not be eligible if displayOnly includes 'vaultable' and vaultable is false", () => {
|
|
71
|
+
const options = {
|
|
72
|
+
...defaultMockFundingOptions,
|
|
73
|
+
displayOnly: ["vaultable"],
|
|
74
|
+
fundingSource: FUNDING.PAYLATER,
|
|
75
|
+
};
|
|
76
|
+
const fundingEligible = isFundingEligible(FUNDING.PAYLATER, options);
|
|
77
|
+
|
|
78
|
+
expect(fundingEligible).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("card should not be eligible if displayOnly includes 'vaultable' and no vendors are vaultable", () => {
|
|
82
|
+
const options = {
|
|
83
|
+
...defaultMockFundingOptions,
|
|
84
|
+
displayOnly: ["vaultable"],
|
|
85
|
+
components: [COMPONENTS.BUTTONS],
|
|
86
|
+
fundingSource: FUNDING.CARD,
|
|
87
|
+
};
|
|
88
|
+
const fundingEligible = isFundingEligible(FUNDING.CARD, options);
|
|
89
|
+
|
|
90
|
+
expect(fundingEligible).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("card should be eligible if displayOnly includes 'vaultable' and any vendor is vaultable", () => {
|
|
94
|
+
const options = {
|
|
95
|
+
...defaultMockFundingOptions,
|
|
96
|
+
displayOnly: ["vaultable"],
|
|
97
|
+
fundingSource: FUNDING.CARD,
|
|
98
|
+
components: [COMPONENTS.BUTTONS],
|
|
99
|
+
platform: "desktop",
|
|
100
|
+
fundingEligibility: {
|
|
101
|
+
card: {
|
|
102
|
+
eligible: true,
|
|
103
|
+
branded: false,
|
|
104
|
+
vendors: {
|
|
105
|
+
visa: {
|
|
106
|
+
eligible: true,
|
|
107
|
+
vaultable: true,
|
|
108
|
+
},
|
|
109
|
+
mastercard: {
|
|
110
|
+
eligible: true,
|
|
111
|
+
vaultable: false,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const fundingEligible = isFundingEligible(FUNDING.CARD, options);
|
|
119
|
+
|
|
120
|
+
expect(fundingEligible).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("should not be eligible if fundingSource.eligible is false", () => {
|
|
124
|
+
const fundingEligible = isFundingEligible(
|
|
125
|
+
FUNDING.SEPA,
|
|
126
|
+
defaultMockFundingOptions
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
expect(fundingEligible).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("should not be eligible if fundingSource.eligible is false and fundingSource.vaultable is true", () => {
|
|
133
|
+
const fundingEligible = isFundingEligible(
|
|
134
|
+
FUNDING.OXXO,
|
|
135
|
+
defaultMockFundingOptions
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
expect(fundingEligible).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -178,6 +178,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
|
|
|
178
178
|
supportsPopups,
|
|
179
179
|
supportedNativeBrowser,
|
|
180
180
|
showPayLabel,
|
|
181
|
+
displayOnly,
|
|
181
182
|
} = normalizeButtonProps(props);
|
|
182
183
|
const { layout, shape, tagline } = style;
|
|
183
184
|
|
|
@@ -196,6 +197,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
|
|
|
196
197
|
supportsPopups,
|
|
197
198
|
supportedNativeBrowser,
|
|
198
199
|
experiment,
|
|
200
|
+
displayOnly,
|
|
199
201
|
});
|
|
200
202
|
const multiple = fundingSources.length > 1;
|
|
201
203
|
|
package/src/ui/buttons/props.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
type LocaleType,
|
|
25
25
|
CARD,
|
|
26
26
|
COMPONENTS,
|
|
27
|
+
DISPLAY_ONLY_VALUES,
|
|
27
28
|
} from "@paypal/sdk-constants/src";
|
|
28
29
|
import { type CrossDomainWindowType } from "@krakenjs/cross-domain-utils/src";
|
|
29
30
|
import { LOGO_COLOR } from "@paypal/sdk-logos/src";
|
|
@@ -461,6 +462,7 @@ export type RenderButtonProps = {|
|
|
|
461
462
|
supportsPopups: boolean,
|
|
462
463
|
supportedNativeBrowser: boolean,
|
|
463
464
|
showPayLabel: boolean,
|
|
465
|
+
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
464
466
|
|};
|
|
465
467
|
|
|
466
468
|
export type PrerenderDetails = {|
|
|
@@ -518,6 +520,7 @@ export type ButtonProps = {|
|
|
|
518
520
|
meta: {||},
|
|
519
521
|
renderedButtons: $ReadOnlyArray<$Values<typeof FUNDING>>,
|
|
520
522
|
createVaultSetupToken: CreateVaultSetupToken,
|
|
523
|
+
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
521
524
|
|};
|
|
522
525
|
|
|
523
526
|
// eslint-disable-next-line flowtype/require-exact-type
|
|
@@ -559,6 +562,7 @@ export type ButtonPropsInputs = {
|
|
|
559
562
|
supportsPopups: boolean,
|
|
560
563
|
supportedNativeBrowser: boolean,
|
|
561
564
|
showPayLabel: boolean,
|
|
565
|
+
displayOnly: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
562
566
|
};
|
|
563
567
|
|
|
564
568
|
export const DEFAULT_STYLE = {
|
|
@@ -744,6 +748,7 @@ export function normalizeButtonProps(
|
|
|
744
748
|
supportsPopups = false,
|
|
745
749
|
supportedNativeBrowser = false,
|
|
746
750
|
showPayLabel = true,
|
|
751
|
+
displayOnly = [],
|
|
747
752
|
} = props;
|
|
748
753
|
|
|
749
754
|
const { country, lang } = locale;
|
|
@@ -794,6 +799,7 @@ export function normalizeButtonProps(
|
|
|
794
799
|
applePaySupport,
|
|
795
800
|
supportsPopups,
|
|
796
801
|
supportedNativeBrowser,
|
|
802
|
+
displayOnly,
|
|
797
803
|
})
|
|
798
804
|
) {
|
|
799
805
|
throw new Error(`Funding Source not eligible: ${fundingSource}`);
|
|
@@ -833,5 +839,6 @@ export function normalizeButtonProps(
|
|
|
833
839
|
supportsPopups,
|
|
834
840
|
supportedNativeBrowser,
|
|
835
841
|
showPayLabel,
|
|
842
|
+
displayOnly,
|
|
836
843
|
};
|
|
837
844
|
}
|
|
@@ -833,6 +833,15 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
833
833
|
required: false,
|
|
834
834
|
value: getExperimentation,
|
|
835
835
|
},
|
|
836
|
+
|
|
837
|
+
displayOnly: {
|
|
838
|
+
type: "array",
|
|
839
|
+
queryParam: true,
|
|
840
|
+
required: false,
|
|
841
|
+
value: ({ props }) => {
|
|
842
|
+
return props?.displayOnly || [];
|
|
843
|
+
},
|
|
844
|
+
},
|
|
836
845
|
},
|
|
837
846
|
});
|
|
838
847
|
});
|