@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paypal/checkout-components",
3
- "version": "5.0.373-alpha-bd1c80d.0",
3
+ "version": "5.0.373",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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 = {
@@ -132,6 +132,7 @@ export type GetCallbackProps = {|
132
132
  hostedButtonId: string,
133
133
  merchantId?: string,
134
134
  shouldIncludeShippingCallbacks?: boolean,
135
+ trackingId?: string,
135
136
  |};
136
137
 
137
138
  export type HostedButtonsInstance = {|
@@ -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,3 +0,0 @@
1
- /* @flow */
2
-
3
- export * from "./overlay";
@@ -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
- }