@paypal/checkout-components 5.0.373-alpha-bd1c80d.0 → 5.0.373
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/hosted-buttons/index.js +7 -0
- package/src/hosted-buttons/types.js +1 -0
- package/src/hosted-buttons/utils.js +48 -1
- package/src/hosted-buttons/utils.test.js +34 -0
- package/src/zoid/buttons/component.jsx +0 -33
- package/src/ui/overlay/paypal-on-approve-processing-overlay/index.jsx +0 -3
- package/src/ui/overlay/paypal-on-approve-processing-overlay/overlay.jsx +0 -82
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
renderDefaultButton,
|
|
15
15
|
renderForm,
|
|
16
16
|
renderStandaloneButton,
|
|
17
|
+
getTrackingId,
|
|
17
18
|
} from "./utils";
|
|
18
19
|
import type {
|
|
19
20
|
HostedButtonsComponent,
|
|
@@ -49,28 +50,34 @@ export const getHostedButtonsComponent = (): HostedButtonsComponent => {
|
|
|
49
50
|
selector,
|
|
50
51
|
});
|
|
51
52
|
|
|
53
|
+
const trackingId = getTrackingId(selector);
|
|
54
|
+
|
|
52
55
|
const createOrder = buildHostedButtonCreateOrder({
|
|
53
56
|
enableDPoP,
|
|
54
57
|
hostedButtonId,
|
|
55
58
|
merchantId,
|
|
59
|
+
trackingId,
|
|
56
60
|
});
|
|
57
61
|
|
|
58
62
|
const onApprove = buildHostedButtonOnApprove({
|
|
59
63
|
enableDPoP,
|
|
60
64
|
hostedButtonId,
|
|
61
65
|
merchantId,
|
|
66
|
+
trackingId,
|
|
62
67
|
});
|
|
63
68
|
|
|
64
69
|
const onShippingAddressChange = buildHostedButtonOnShippingAddressChange({
|
|
65
70
|
enableDPoP,
|
|
66
71
|
hostedButtonId,
|
|
67
72
|
shouldIncludeShippingCallbacks,
|
|
73
|
+
trackingId,
|
|
68
74
|
});
|
|
69
75
|
|
|
70
76
|
const onShippingOptionsChange = buildHostedButtonOnShippingOptionsChange({
|
|
71
77
|
enableDPoP,
|
|
72
78
|
hostedButtonId,
|
|
73
79
|
shouldIncludeShippingCallbacks,
|
|
80
|
+
trackingId,
|
|
74
81
|
});
|
|
75
82
|
|
|
76
83
|
const buttonOptions: HostedButtonOptions = {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
getLocale,
|
|
10
10
|
getMerchantID as getSDKMerchantID,
|
|
11
11
|
} from "@paypal/sdk-client/src";
|
|
12
|
-
import { FUNDING } from "@paypal/sdk-constants/src";
|
|
12
|
+
import { FUNDING, FPTI_KEY } from "@paypal/sdk-constants/src";
|
|
13
13
|
import { SUPPORTED_FUNDING_SOURCES } from "@paypal/funding-components/src";
|
|
14
14
|
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
15
15
|
|
|
@@ -214,6 +214,18 @@ export function getElementFromSelector(
|
|
|
214
214
|
: selector;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
export function getTrackingId(
|
|
218
|
+
HostedButtonSelector: string | HTMLElement
|
|
219
|
+
): string {
|
|
220
|
+
if (typeof HostedButtonSelector !== "string") {
|
|
221
|
+
return "";
|
|
222
|
+
}
|
|
223
|
+
const ele = document.querySelector(
|
|
224
|
+
`${HostedButtonSelector} input[name="uuid"]`
|
|
225
|
+
);
|
|
226
|
+
return ele ? ele.getAttribute("value") || "" : "";
|
|
227
|
+
}
|
|
228
|
+
|
|
217
229
|
/**
|
|
218
230
|
* Attaches form fields (html) to the given selector, and
|
|
219
231
|
* initializes window.__pp_form_fields (htmlScript).
|
|
@@ -246,6 +258,7 @@ export const buildHostedButtonCreateOrder = ({
|
|
|
246
258
|
enableDPoP,
|
|
247
259
|
hostedButtonId,
|
|
248
260
|
merchantId,
|
|
261
|
+
trackingId,
|
|
249
262
|
}: GetCallbackProps): CreateOrder => {
|
|
250
263
|
return async (data) => {
|
|
251
264
|
const userInputs =
|
|
@@ -271,6 +284,13 @@ export const buildHostedButtonCreateOrder = ({
|
|
|
271
284
|
});
|
|
272
285
|
// $FlowIssue request returns ZalgoPromise
|
|
273
286
|
const { body } = response;
|
|
287
|
+
getLogger()
|
|
288
|
+
.track({
|
|
289
|
+
[FPTI_KEY.CONTEXT_ID]: body.context_id,
|
|
290
|
+
[FPTI_KEY.EVENT_NAME]: "ncps_create_order",
|
|
291
|
+
tracking_id: trackingId,
|
|
292
|
+
})
|
|
293
|
+
.flush();
|
|
274
294
|
return body.context_id || onError(body.name);
|
|
275
295
|
} catch (e) {
|
|
276
296
|
return onError("REQUEST_FAILED");
|
|
@@ -282,6 +302,7 @@ export const buildHostedButtonOnApprove = ({
|
|
|
282
302
|
enableDPoP,
|
|
283
303
|
hostedButtonId,
|
|
284
304
|
merchantId,
|
|
305
|
+
trackingId,
|
|
285
306
|
}: GetCallbackProps): OnApprove => {
|
|
286
307
|
return async (data) => {
|
|
287
308
|
const url = `${apiUrl}/v1/checkout/links/${hostedButtonId}/pay`;
|
|
@@ -299,6 +320,14 @@ export const buildHostedButtonOnApprove = ({
|
|
|
299
320
|
context_id: data.orderID,
|
|
300
321
|
}),
|
|
301
322
|
}).then((response) => {
|
|
323
|
+
getLogger()
|
|
324
|
+
.track({
|
|
325
|
+
[FPTI_KEY.CONTEXT_ID]: data.orderID,
|
|
326
|
+
[FPTI_KEY.EVENT_NAME]: "ncps_onapprove_order",
|
|
327
|
+
tracking_id: trackingId,
|
|
328
|
+
})
|
|
329
|
+
.flush();
|
|
330
|
+
|
|
302
331
|
// The "Debit or Credit Card" button does not open a popup
|
|
303
332
|
// so we need to redirect to the thank you page for buyers who complete
|
|
304
333
|
// a checkout via "Debit or Credit Card".
|
|
@@ -319,6 +348,7 @@ export const buildHostedButtonOnShippingAddressChange = ({
|
|
|
319
348
|
enableDPoP,
|
|
320
349
|
hostedButtonId,
|
|
321
350
|
shouldIncludeShippingCallbacks,
|
|
351
|
+
trackingId,
|
|
322
352
|
}: GetCallbackProps): OnShippingAddressChange | typeof undefined => {
|
|
323
353
|
if (shouldIncludeShippingCallbacks) {
|
|
324
354
|
return async (data, actions) => {
|
|
@@ -354,6 +384,14 @@ export const buildHostedButtonOnShippingAddressChange = ({
|
|
|
354
384
|
if (response.status !== 200) {
|
|
355
385
|
return actions.reject(errors?.ADDRESS_ERROR);
|
|
356
386
|
}
|
|
387
|
+
|
|
388
|
+
getLogger()
|
|
389
|
+
.track({
|
|
390
|
+
[FPTI_KEY.CONTEXT_ID]: orderID,
|
|
391
|
+
[FPTI_KEY.EVENT_NAME]: "ncps_shipping_address_change",
|
|
392
|
+
tracking_id: trackingId,
|
|
393
|
+
})
|
|
394
|
+
.flush();
|
|
357
395
|
};
|
|
358
396
|
}
|
|
359
397
|
};
|
|
@@ -362,6 +400,7 @@ export const buildHostedButtonOnShippingOptionsChange = ({
|
|
|
362
400
|
enableDPoP,
|
|
363
401
|
hostedButtonId,
|
|
364
402
|
shouldIncludeShippingCallbacks,
|
|
403
|
+
trackingId,
|
|
365
404
|
}: GetCallbackProps): OnShippingOptionsChange | typeof undefined => {
|
|
366
405
|
if (shouldIncludeShippingCallbacks) {
|
|
367
406
|
return async (data, actions) => {
|
|
@@ -386,6 +425,14 @@ export const buildHostedButtonOnShippingOptionsChange = ({
|
|
|
386
425
|
if (response.status !== 200) {
|
|
387
426
|
return actions.reject(errors?.METHOD_UNAVAILABLE);
|
|
388
427
|
}
|
|
428
|
+
|
|
429
|
+
getLogger()
|
|
430
|
+
.track({
|
|
431
|
+
[FPTI_KEY.CONTEXT_ID]: orderID,
|
|
432
|
+
[FPTI_KEY.EVENT_NAME]: "ncps_shipping_options_change",
|
|
433
|
+
tracking_id: trackingId,
|
|
434
|
+
})
|
|
435
|
+
.flush();
|
|
389
436
|
};
|
|
390
437
|
}
|
|
391
438
|
};
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
renderStandaloneButton,
|
|
22
22
|
applyContainerStyles,
|
|
23
23
|
renderDefaultButton,
|
|
24
|
+
getTrackingId,
|
|
24
25
|
} from "./utils";
|
|
25
26
|
|
|
26
27
|
vi.mock("@krakenjs/belter/src", async () => {
|
|
@@ -39,6 +40,10 @@ vi.mock("@paypal/sdk-client/src", async () => {
|
|
|
39
40
|
getLocale: () => ({ lang: "en", country: "US" }),
|
|
40
41
|
getLogger: vi.fn(() => ({
|
|
41
42
|
error: vi.fn(),
|
|
43
|
+
track: vi.fn().mockImplementation(() => ({
|
|
44
|
+
flush: vi.fn(),
|
|
45
|
+
})),
|
|
46
|
+
flush: vi.fn(),
|
|
42
47
|
})),
|
|
43
48
|
};
|
|
44
49
|
});
|
|
@@ -803,6 +808,35 @@ test("getElementFromSelector", () => {
|
|
|
803
808
|
expect(mockQuerySelector).toHaveBeenCalledWith(containerId);
|
|
804
809
|
});
|
|
805
810
|
|
|
811
|
+
describe("getTrackingId", () => {
|
|
812
|
+
const containerId = "#container-id";
|
|
813
|
+
|
|
814
|
+
test("returns uuid value when input element exists and has a value", () => {
|
|
815
|
+
const inputElement = document.createElement("input");
|
|
816
|
+
inputElement.setAttribute("name", "uuid");
|
|
817
|
+
inputElement.setAttribute("value", "test-uuid-123");
|
|
818
|
+
|
|
819
|
+
const containerElement = document.createElement("div");
|
|
820
|
+
containerElement.appendChild(inputElement);
|
|
821
|
+
|
|
822
|
+
vi.spyOn(document, "querySelector").mockImplementationOnce(
|
|
823
|
+
() => inputElement
|
|
824
|
+
);
|
|
825
|
+
|
|
826
|
+
const result = getTrackingId(containerId);
|
|
827
|
+
|
|
828
|
+
expect(result).toBe("test-uuid-123");
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
test("returns empty string when input element doesn't exist", () => {
|
|
832
|
+
vi.spyOn(document, "querySelector").mockImplementationOnce(() => null);
|
|
833
|
+
|
|
834
|
+
const result = getTrackingId(containerId);
|
|
835
|
+
|
|
836
|
+
expect(result).toBe("");
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
|
|
806
840
|
describe("getButtonPreferences", () => {
|
|
807
841
|
test("returns all button preferences if all are eligible", () => {
|
|
808
842
|
const params = {
|
|
@@ -105,7 +105,6 @@ import {
|
|
|
105
105
|
sendPostRobotMessageToButtonIframe,
|
|
106
106
|
isEagerOrderCreationEnabled,
|
|
107
107
|
} from "./util";
|
|
108
|
-
import { PayPalOnApproveOverlay } from "../../ui/overlay/paypal-on-approve-processing-overlay";
|
|
109
108
|
|
|
110
109
|
export type ButtonsComponent = ZoidComponent<
|
|
111
110
|
ButtonProps,
|
|
@@ -342,38 +341,6 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
342
341
|
},
|
|
343
342
|
},
|
|
344
343
|
|
|
345
|
-
showOnApproveOverlay: {
|
|
346
|
-
type: "function",
|
|
347
|
-
queryParam: false,
|
|
348
|
-
value:
|
|
349
|
-
({ props: { buttonSessionID } }) =>
|
|
350
|
-
() => {
|
|
351
|
-
const overlay = (
|
|
352
|
-
<PayPalOnApproveOverlay
|
|
353
|
-
buttonSessionID={buttonSessionID}
|
|
354
|
-
/>
|
|
355
|
-
).render(dom({ doc: document }));
|
|
356
|
-
|
|
357
|
-
document.body?.appendChild(overlay);
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
|
|
361
|
-
hideOnApproveOverlay: {
|
|
362
|
-
type: "function",
|
|
363
|
-
queryParam: false,
|
|
364
|
-
value:
|
|
365
|
-
({ props: { buttonSessionID } }) =>
|
|
366
|
-
() => {
|
|
367
|
-
const overlay = document.getElementsByName(
|
|
368
|
-
`paypal-onapprove-overlay-${buttonSessionID}`
|
|
369
|
-
)?.[0];
|
|
370
|
-
|
|
371
|
-
if (overlay) {
|
|
372
|
-
overlay.remove();
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
},
|
|
376
|
-
|
|
377
344
|
redirect: {
|
|
378
345
|
type: "function",
|
|
379
346
|
sendToChild: true,
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
/** @jsx node */
|
|
3
|
-
|
|
4
|
-
import { animate, noop } from "@krakenjs/belter/src";
|
|
5
|
-
import { node, type ElementNode } from "@krakenjs/jsx-pragmatic/src";
|
|
6
|
-
import { LOGO_COLOR, PayPalRebrandLogo } from "@paypal/sdk-logos/src";
|
|
7
|
-
import { type ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
8
|
-
|
|
9
|
-
import { getContainerStyle, getSandboxStyle } from "../paypal-app-switch/style";
|
|
10
|
-
|
|
11
|
-
type OverlayProps = {|
|
|
12
|
-
buttonSessionID: string,
|
|
13
|
-
close: () => ZalgoPromise<void>,
|
|
14
|
-
focus: () => ZalgoPromise<void>,
|
|
15
|
-
|};
|
|
16
|
-
|
|
17
|
-
export function PayPalOnApproveOverlay({
|
|
18
|
-
buttonSessionID,
|
|
19
|
-
}: OverlayProps): ElementNode {
|
|
20
|
-
const uid = `paypal-onapprove-overlay-${buttonSessionID}`;
|
|
21
|
-
const overlayIframeName = `__paypal_checkout_sandbox_${uid}__`;
|
|
22
|
-
const nonce = "";
|
|
23
|
-
function closeOverlay(e) {
|
|
24
|
-
e.preventDefault();
|
|
25
|
-
e.stopPropagation();
|
|
26
|
-
const overlay = document.getElementsByName(uid)?.[0];
|
|
27
|
-
|
|
28
|
-
animate(overlay, "hide-container", noop);
|
|
29
|
-
|
|
30
|
-
if (overlay) {
|
|
31
|
-
// the delay is to allow the animation time to run
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
overlay.remove();
|
|
34
|
-
}, 300);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const setupShowAnimation = () => (el) => {
|
|
39
|
-
animate(el, "show-container", noop);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<div
|
|
44
|
-
id={uid}
|
|
45
|
-
name={uid}
|
|
46
|
-
onRender={setupShowAnimation()}
|
|
47
|
-
class="paypal-checkout-sandbox"
|
|
48
|
-
>
|
|
49
|
-
<style nonce={nonce}>{getSandboxStyle({ uid })}</style>
|
|
50
|
-
<iframe
|
|
51
|
-
title="PayPal Checkout On Approve Overlay"
|
|
52
|
-
name={overlayIframeName}
|
|
53
|
-
scrolling="no"
|
|
54
|
-
class="paypal-checkout-sandbox-iframe"
|
|
55
|
-
>
|
|
56
|
-
<html>
|
|
57
|
-
<body>
|
|
58
|
-
<div
|
|
59
|
-
dir="auto"
|
|
60
|
-
id={uid}
|
|
61
|
-
class="paypal-overlay-context-popup paypal-checkout-overlay"
|
|
62
|
-
>
|
|
63
|
-
<a
|
|
64
|
-
href="#"
|
|
65
|
-
class="paypal-checkout-close"
|
|
66
|
-
onClick={closeOverlay}
|
|
67
|
-
aria-label="close"
|
|
68
|
-
role="button"
|
|
69
|
-
/>
|
|
70
|
-
<div class="paypal-checkout-modal">
|
|
71
|
-
<div class="paypal-checkout-logo" dir="ltr">
|
|
72
|
-
<PayPalRebrandLogo logoColor={LOGO_COLOR.WHITE} />
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
<style nonce={nonce}>{getContainerStyle({ uid })}</style>
|
|
76
|
-
</div>
|
|
77
|
-
</body>
|
|
78
|
-
</html>
|
|
79
|
-
</iframe>
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
}
|