@paypal/checkout-components 5.0.329 → 5.0.331
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 +1 -1
- package/src/funding/common.jsx +1 -0
- package/src/funding/paypal/config.jsx +7 -4
- package/src/ui/buttons/button.jsx +29 -19
- package/src/ui/buttons/buttons.jsx +25 -23
- package/src/ui/buttons/props.js +10 -3
- package/src/ui/buttons/util.js +22 -5
- package/src/zoid/buttons/component.jsx +7 -4
- package/src/zoid/buttons/util.js +17 -3
- package/src/zoid/card-fields/component.jsx +5 -3
- package/src/zoid/venmo/component.jsx +6 -0
package/package.json
CHANGED
package/src/funding/common.jsx
CHANGED
|
@@ -45,18 +45,21 @@ export function getPayPalConfig(): FundingSourceConfig {
|
|
|
45
45
|
|
|
46
46
|
labelText: ({ content, label, period }) => {
|
|
47
47
|
let text = `${FUNDING_BRAND_LABEL.PAYPAL}`;
|
|
48
|
+
|
|
48
49
|
if (content && label === BUTTON_LABEL.INSTALLMENT) {
|
|
49
50
|
if (period) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const rawLabel = content["label.installment.withPeriod"];
|
|
52
|
+
|
|
53
|
+
if (typeof rawLabel === "string") {
|
|
54
|
+
text = rawLabel.replace("{period}", String(period));
|
|
55
|
+
}
|
|
54
56
|
} else {
|
|
55
57
|
text = content["label.installment.withoutPeriod"];
|
|
56
58
|
}
|
|
57
59
|
} else if (content && label && content[`label.${label}`]) {
|
|
58
60
|
text = content[`label.${label}`];
|
|
59
61
|
}
|
|
62
|
+
|
|
60
63
|
return text;
|
|
61
64
|
},
|
|
62
65
|
Logo,
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
/** @jsx node */
|
|
3
3
|
|
|
4
4
|
import type { FundingEligibilityType } from "@paypal/sdk-client/src";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
COUNTRY,
|
|
7
|
+
FUNDING,
|
|
8
|
+
ENV,
|
|
9
|
+
type LocaleType,
|
|
10
|
+
} from "@paypal/sdk-constants/src";
|
|
6
11
|
import { node, type ElementNode } from "@krakenjs/jsx-pragmatic/src";
|
|
7
12
|
import { LOGO_COLOR, LOGO_CLASS } from "@paypal/sdk-logos/src";
|
|
8
13
|
import {
|
|
@@ -37,12 +42,13 @@ import type {
|
|
|
37
42
|
} from "./props";
|
|
38
43
|
import { Spinner } from "./spinner";
|
|
39
44
|
import { MenuButton } from "./menu-button";
|
|
40
|
-
import { isBorderRadiusNumber } from "./util";
|
|
45
|
+
import { isBorderRadiusNumber, checkLabelEligibility } from "./util";
|
|
41
46
|
|
|
42
47
|
type IndividualButtonProps = {|
|
|
43
48
|
style: ButtonStyle,
|
|
44
49
|
fundingSource: $Values<typeof FUNDING>,
|
|
45
50
|
multiple: boolean,
|
|
51
|
+
buyerCountry: $Values<typeof COUNTRY>,
|
|
46
52
|
locale: LocaleType,
|
|
47
53
|
onClick?: Function,
|
|
48
54
|
env: $Values<typeof ENV>,
|
|
@@ -68,26 +74,27 @@ type IndividualButtonProps = {|
|
|
|
68
74
|
|};
|
|
69
75
|
|
|
70
76
|
export function Button({
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
buyerCountry,
|
|
78
|
+
commit,
|
|
79
|
+
content,
|
|
80
|
+
customerId,
|
|
75
81
|
env,
|
|
82
|
+
experiment,
|
|
83
|
+
flow,
|
|
76
84
|
fundingEligibility,
|
|
85
|
+
fundingSource,
|
|
77
86
|
i,
|
|
87
|
+
instrument,
|
|
88
|
+
locale,
|
|
89
|
+
multiple,
|
|
78
90
|
nonce,
|
|
79
|
-
flow,
|
|
80
|
-
vault,
|
|
81
|
-
userIDToken,
|
|
82
|
-
customerId,
|
|
83
|
-
personalization,
|
|
84
91
|
onClick = noop,
|
|
85
|
-
|
|
86
|
-
tagline,
|
|
87
|
-
commit,
|
|
88
|
-
experiment,
|
|
89
|
-
instrument,
|
|
92
|
+
personalization,
|
|
90
93
|
showPayLabel,
|
|
94
|
+
style,
|
|
95
|
+
tagline,
|
|
96
|
+
userIDToken,
|
|
97
|
+
vault,
|
|
91
98
|
}: IndividualButtonProps): ElementNode {
|
|
92
99
|
const { layout, shape, borderRadius } = style;
|
|
93
100
|
|
|
@@ -142,13 +149,16 @@ export function Button({
|
|
|
142
149
|
}
|
|
143
150
|
};
|
|
144
151
|
|
|
152
|
+
const eligibleLabel = checkLabelEligibility(label, buyerCountry);
|
|
153
|
+
|
|
145
154
|
function getAriaLabel(): string {
|
|
146
155
|
let labelText =
|
|
147
156
|
typeof fundingConfig.labelText === "function"
|
|
148
157
|
? fundingConfig.labelText({
|
|
158
|
+
buyerCountry,
|
|
149
159
|
content,
|
|
150
160
|
fundingEligibility,
|
|
151
|
-
label,
|
|
161
|
+
label: eligibleLabel,
|
|
152
162
|
period,
|
|
153
163
|
})
|
|
154
164
|
: fundingConfig.labelText || fundingSource;
|
|
@@ -166,7 +176,7 @@ export function Button({
|
|
|
166
176
|
|
|
167
177
|
const logoNode = (
|
|
168
178
|
<Logo
|
|
169
|
-
label={
|
|
179
|
+
label={eligibleLabel}
|
|
170
180
|
locale={locale}
|
|
171
181
|
logoColor={logoColor}
|
|
172
182
|
fundingEligibility={fundingEligibility}
|
|
@@ -182,7 +192,7 @@ export function Button({
|
|
|
182
192
|
<Label
|
|
183
193
|
i={i}
|
|
184
194
|
logo={logoNode}
|
|
185
|
-
label={
|
|
195
|
+
label={eligibleLabel}
|
|
186
196
|
nonce={nonce}
|
|
187
197
|
locale={locale}
|
|
188
198
|
logoColor={logoColor}
|
|
@@ -136,36 +136,37 @@ export function validateButtonProps(props: ButtonPropsInputs) {
|
|
|
136
136
|
export function Buttons(props: ButtonsProps): ElementNode {
|
|
137
137
|
const { onClick = noop } = props;
|
|
138
138
|
const {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
applePaySupport,
|
|
140
|
+
buyerCountry,
|
|
141
|
+
commit,
|
|
142
|
+
components,
|
|
143
|
+
content,
|
|
144
|
+
customerId,
|
|
145
|
+
displayOnly,
|
|
146
|
+
enableFunding,
|
|
144
147
|
env,
|
|
148
|
+
experiment,
|
|
149
|
+
flow,
|
|
145
150
|
fundingEligibility,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
fundingSource,
|
|
152
|
+
hasShippingCallback,
|
|
153
|
+
locale,
|
|
154
|
+
message,
|
|
155
|
+
messageMarkup,
|
|
149
156
|
nonce,
|
|
150
|
-
enableFunding,
|
|
151
|
-
components,
|
|
152
|
-
onShippingChange,
|
|
153
157
|
onShippingAddressChange,
|
|
158
|
+
onShippingChange,
|
|
154
159
|
onShippingOptionsChange,
|
|
155
|
-
hasShippingCallback,
|
|
156
160
|
personalization,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
content,
|
|
160
|
-
flow,
|
|
161
|
-
experiment,
|
|
162
|
-
applePaySupport,
|
|
163
|
-
supportsPopups,
|
|
164
|
-
supportedNativeBrowser,
|
|
161
|
+
platform,
|
|
162
|
+
remembered,
|
|
165
163
|
showPayLabel,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
style,
|
|
165
|
+
supportedNativeBrowser,
|
|
166
|
+
supportsPopups,
|
|
167
|
+
userIDToken,
|
|
168
|
+
vault,
|
|
169
|
+
wallet,
|
|
169
170
|
} = normalizeButtonProps(props);
|
|
170
171
|
const { layout, shape, tagline } = style;
|
|
171
172
|
|
|
@@ -268,6 +269,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
|
|
|
268
269
|
fundingSource={source}
|
|
269
270
|
multiple={multiple}
|
|
270
271
|
env={env}
|
|
272
|
+
buyerCountry={buyerCountry}
|
|
271
273
|
locale={locale}
|
|
272
274
|
nonce={nonce}
|
|
273
275
|
fundingEligibility={fundingEligibility}
|
package/src/ui/buttons/props.js
CHANGED
|
@@ -433,7 +433,7 @@ export type ApplePaySessionConfigRequest = (
|
|
|
433
433
|
|
|
434
434
|
export type ButtonMessage = {|
|
|
435
435
|
amount?: number,
|
|
436
|
-
offer?:
|
|
436
|
+
offer?: string,
|
|
437
437
|
color: $Values<typeof MESSAGE_COLOR>,
|
|
438
438
|
position: $Values<typeof MESSAGE_POSITION>,
|
|
439
439
|
align: $Values<typeof MESSAGE_ALIGN>,
|
|
@@ -450,6 +450,7 @@ export type ButtonMessageInputs = {|
|
|
|
450
450
|
export type RenderButtonProps = {|
|
|
451
451
|
style: ButtonStyle,
|
|
452
452
|
locale: LocaleType,
|
|
453
|
+
buyerCountry: $Values<typeof COUNTRY>,
|
|
453
454
|
commit: boolean,
|
|
454
455
|
fundingSource: ?$Values<typeof FUNDING>,
|
|
455
456
|
env: $Values<typeof ENV>,
|
|
@@ -555,6 +556,7 @@ export type ButtonPropsInputs = {
|
|
|
555
556
|
clientID: string,
|
|
556
557
|
fundingSource?: ?$Values<typeof FUNDING>,
|
|
557
558
|
style?: ButtonStyleInputs | void,
|
|
559
|
+
buyerCountry: $Values<typeof COUNTRY>,
|
|
558
560
|
locale?: $PropertyType<ButtonProps, "locale"> | void,
|
|
559
561
|
commit?: $PropertyType<ButtonProps, "commit"> | void,
|
|
560
562
|
env?: $PropertyType<ButtonProps, "env"> | void,
|
|
@@ -780,12 +782,11 @@ export function normalizeButtonMessage(
|
|
|
780
782
|
): ButtonMessage {
|
|
781
783
|
const {
|
|
782
784
|
amount,
|
|
783
|
-
offer,
|
|
784
785
|
color = MESSAGE_COLOR.BLACK,
|
|
785
786
|
position,
|
|
786
787
|
align = MESSAGE_ALIGN.CENTER,
|
|
787
788
|
} = message;
|
|
788
|
-
|
|
789
|
+
let offer = message.offer;
|
|
789
790
|
if (typeof amount !== "undefined") {
|
|
790
791
|
if (typeof amount !== "number") {
|
|
791
792
|
throw new TypeError(
|
|
@@ -800,6 +801,9 @@ export function normalizeButtonMessage(
|
|
|
800
801
|
}
|
|
801
802
|
|
|
802
803
|
if (typeof offer !== "undefined") {
|
|
804
|
+
if (typeof offer === "string") {
|
|
805
|
+
offer = offer.split(",");
|
|
806
|
+
}
|
|
803
807
|
if (!Array.isArray(offer)) {
|
|
804
808
|
throw new TypeError(
|
|
805
809
|
`Expected message.offer to be an array of strings, got: ${String(
|
|
@@ -813,6 +817,7 @@ export function normalizeButtonMessage(
|
|
|
813
817
|
if (invalidOffers.length > 0) {
|
|
814
818
|
throw new Error(`Invalid offer(s): ${invalidOffers.join(",")}`);
|
|
815
819
|
}
|
|
820
|
+
offer = offer.join(",");
|
|
816
821
|
}
|
|
817
822
|
|
|
818
823
|
if (typeof color !== "undefined" && !values(MESSAGE_COLOR).includes(color)) {
|
|
@@ -868,6 +873,7 @@ export function normalizeButtonProps(
|
|
|
868
873
|
);
|
|
869
874
|
|
|
870
875
|
let {
|
|
876
|
+
buyerCountry,
|
|
871
877
|
clientID,
|
|
872
878
|
fundingSource,
|
|
873
879
|
style = getDefaultStyle(),
|
|
@@ -970,6 +976,7 @@ export function normalizeButtonProps(
|
|
|
970
976
|
: undefined;
|
|
971
977
|
|
|
972
978
|
return {
|
|
979
|
+
buyerCountry,
|
|
973
980
|
clientID,
|
|
974
981
|
fundingSource,
|
|
975
982
|
style,
|
package/src/ui/buttons/util.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
-
import { FUNDING } from "@paypal/sdk-constants/src";
|
|
2
|
+
import { COUNTRY, FUNDING } from "@paypal/sdk-constants/src";
|
|
3
3
|
|
|
4
|
-
import { BUTTON_LAYOUT, MESSAGE_POSITION } from "../../constants";
|
|
5
|
-
import { ValidationError } from "../../lib";
|
|
4
|
+
import { BUTTON_LABEL, BUTTON_LAYOUT, MESSAGE_POSITION } from "../../constants";
|
|
6
5
|
|
|
7
6
|
export function isBorderRadiusNumber(borderRadius?: number): boolean {
|
|
8
7
|
return typeof borderRadius === "number";
|
|
@@ -25,8 +24,9 @@ export function calculateMessagePosition(
|
|
|
25
24
|
const showPoweredBy = calculateShowPoweredBy(layout, fundingSources);
|
|
26
25
|
|
|
27
26
|
if (showPoweredBy && position === MESSAGE_POSITION.BOTTOM) {
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.warn(
|
|
29
|
+
"PayPal Button Message cannot be positioned at bottom when displaying the Debit or Credit Card button."
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -39,3 +39,20 @@ export function calculateMessagePosition(
|
|
|
39
39
|
}
|
|
40
40
|
return MESSAGE_POSITION.BOTTOM;
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
export function checkLabelEligibility(
|
|
44
|
+
label?: $Values<typeof BUTTON_LABEL>,
|
|
45
|
+
buyerCountry: $Values<typeof COUNTRY>
|
|
46
|
+
): $Values<typeof BUTTON_LABEL> | typeof undefined {
|
|
47
|
+
const eligibleCountriesForInstallmentLabel = ["BR", "MX"];
|
|
48
|
+
|
|
49
|
+
// Don't render the installment label if buyerCountry is not eligible for installment product
|
|
50
|
+
if (
|
|
51
|
+
label === BUTTON_LABEL.INSTALLMENT &&
|
|
52
|
+
!eligibleCountriesForInstallmentLabel.includes(buyerCountry)
|
|
53
|
+
) {
|
|
54
|
+
return BUTTON_LABEL.PAYPAL;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return label;
|
|
58
|
+
}
|
|
@@ -743,7 +743,11 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
743
743
|
})
|
|
744
744
|
.flush();
|
|
745
745
|
|
|
746
|
-
const modalInstance = await getModal(
|
|
746
|
+
const modalInstance = await getModal(
|
|
747
|
+
clientID,
|
|
748
|
+
merchantID,
|
|
749
|
+
buttonSessionID
|
|
750
|
+
);
|
|
747
751
|
return modalInstance?.show({
|
|
748
752
|
amount,
|
|
749
753
|
offer: offerType,
|
|
@@ -758,11 +762,10 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
758
762
|
required: false,
|
|
759
763
|
value: ({ props }) => {
|
|
760
764
|
return () => {
|
|
761
|
-
const { clientID, merchantID } = props;
|
|
762
765
|
// offerType, messageType, offerCountryCode, and creditProductIdentifier are passed in and may be used in an upcoming message hover logging feature
|
|
763
|
-
|
|
764
766
|
// lazy loads the modal, to be memoized and executed onMessageClick
|
|
765
|
-
|
|
767
|
+
const { buttonSessionID, clientID, merchantID } = props;
|
|
768
|
+
return getModal(clientID, merchantID, buttonSessionID);
|
|
766
769
|
};
|
|
767
770
|
},
|
|
768
771
|
},
|
package/src/zoid/buttons/util.js
CHANGED
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
once,
|
|
15
15
|
memoize,
|
|
16
16
|
} from "@krakenjs/belter/src";
|
|
17
|
-
import { FUNDING } from "@paypal/sdk-constants/src";
|
|
18
17
|
import {
|
|
19
18
|
getEnableFunding,
|
|
20
19
|
getLogger,
|
|
@@ -25,6 +24,7 @@ import {
|
|
|
25
24
|
getEnv,
|
|
26
25
|
getNamespace,
|
|
27
26
|
} from "@paypal/sdk-client/src";
|
|
27
|
+
import { FUNDING, FPTI_KEY } from "@paypal/sdk-constants/src";
|
|
28
28
|
import { getRefinedFundingEligibility } from "@paypal/funding-components/src";
|
|
29
29
|
|
|
30
30
|
import type { Experiment as EligibilityExperiment } from "../../types";
|
|
@@ -371,8 +371,9 @@ function buildModalBundleUrl(): string {
|
|
|
371
371
|
|
|
372
372
|
export const getModal: (
|
|
373
373
|
clientID: string,
|
|
374
|
-
merchantID
|
|
375
|
-
|
|
374
|
+
merchantID: $ReadOnlyArray<string> | void,
|
|
375
|
+
buttonSessionID: string
|
|
376
|
+
) => Object = memoize(async (clientID, merchantID, buttonSessionID) => {
|
|
376
377
|
try {
|
|
377
378
|
const namespace = getNamespace();
|
|
378
379
|
if (!window[namespace].MessagesModal) {
|
|
@@ -393,6 +394,19 @@ export const getModal: (
|
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
return window[namespace].MessagesModal({
|
|
397
|
+
buttonSessionId: buttonSessionID,
|
|
398
|
+
onApply: () =>
|
|
399
|
+
getLogger()
|
|
400
|
+
.info("button_message_modal_apply")
|
|
401
|
+
.track({
|
|
402
|
+
[FPTI_KEY.TRANSITION]: "button_message_modal_apply",
|
|
403
|
+
[FPTI_KEY.STATE]: "BUTTON_MESSAGE",
|
|
404
|
+
[FPTI_KEY.BUTTON_SESSION_UID]: buttonSessionID,
|
|
405
|
+
[FPTI_KEY.CONTEXT_ID]: buttonSessionID,
|
|
406
|
+
[FPTI_KEY.CONTEXT_TYPE]: "button_session_id",
|
|
407
|
+
[FPTI_KEY.EVENT_NAME]: "modal_apply",
|
|
408
|
+
})
|
|
409
|
+
.flush(),
|
|
396
410
|
account: `client-id:${clientID}`,
|
|
397
411
|
merchantId: merchantID?.join(",") || undefined,
|
|
398
412
|
});
|
|
@@ -50,6 +50,7 @@ type CardFieldsProps = {|
|
|
|
50
50
|
clientID: string,
|
|
51
51
|
style?: {|
|
|
52
52
|
height: number,
|
|
53
|
+
input: {| height: number |},
|
|
53
54
|
|},
|
|
54
55
|
env?: string,
|
|
55
56
|
locale?: string,
|
|
@@ -128,9 +129,10 @@ const url = () =>
|
|
|
128
129
|
`${getPayPalDomain()}${__PAYPAL_CHECKOUT__.__URI__.__CARD_FIELD__}`;
|
|
129
130
|
|
|
130
131
|
const prerenderTemplate = ({ props, doc }) => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
const height = props.style?.height ?? props.style?.input?.height ?? null;
|
|
133
|
+
return (<CardPrerender nonce={props.nonce} height={height} />).render(
|
|
134
|
+
dom({ doc })
|
|
135
|
+
);
|
|
134
136
|
};
|
|
135
137
|
|
|
136
138
|
export type CardFieldsComponent = ZoidComponent<
|
|
@@ -295,6 +295,12 @@ export function getVenmoCheckoutComponent(): VenmoCheckoutComponent {
|
|
|
295
295
|
queryParam: true,
|
|
296
296
|
required: false,
|
|
297
297
|
},
|
|
298
|
+
|
|
299
|
+
venmoVaultEnabled: {
|
|
300
|
+
type: "boolean",
|
|
301
|
+
queryParam: true,
|
|
302
|
+
required: false,
|
|
303
|
+
},
|
|
298
304
|
},
|
|
299
305
|
|
|
300
306
|
dimensions: ({ props }) => {
|