@lookiero/checkout 10.1.0 → 11.0.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.
Files changed (74) hide show
  1. package/cypress/integration/checkout.spec.ts +0 -3
  2. package/dist/fake-dependencies/@lookiero/payments-front/index.d.ts +8 -7
  3. package/dist/fake-dependencies/@lookiero/payments-front/index.js +11 -3
  4. package/dist/index.d.ts +3 -3
  5. package/dist/src/ExpoRoot.js +17 -12
  6. package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.d.ts +1 -1
  7. package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.js +2 -0
  8. package/dist/src/infrastructure/projection/checkout/checkout.mock.d.ts +1 -0
  9. package/dist/src/infrastructure/projection/checkout/checkout.mock.js +3 -3
  10. package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.d.ts +1 -1
  11. package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.js +2 -1
  12. package/dist/src/infrastructure/tracking/tracking.d.ts +2 -2
  13. package/dist/src/infrastructure/tracking/useTrackCheckout.d.ts +10 -17
  14. package/dist/src/infrastructure/tracking/useTrackCheckout.js +27 -12
  15. package/dist/src/infrastructure/ui/Root.d.ts +6 -6
  16. package/dist/src/infrastructure/ui/Root.js +2 -3
  17. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.d.ts +26 -0
  18. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.js +127 -0
  19. package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.d.ts +3 -2
  20. package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.js +17 -26
  21. package/dist/src/infrastructure/ui/i18n/i18n.d.ts +1 -0
  22. package/dist/src/infrastructure/ui/i18n/i18n.js +1 -0
  23. package/dist/src/infrastructure/ui/routing/CheckoutMiddleware.js +1 -12
  24. package/dist/src/infrastructure/ui/routing/Routing.d.ts +5 -5
  25. package/dist/src/infrastructure/ui/routing/Routing.js +2 -10
  26. package/dist/src/infrastructure/ui/routing/routes.d.ts +0 -1
  27. package/dist/src/infrastructure/ui/routing/routes.js +0 -1
  28. package/dist/src/infrastructure/ui/views/App.js +5 -6
  29. package/dist/src/infrastructure/ui/views/checkout/Checkout.d.ts +7 -2
  30. package/dist/src/infrastructure/ui/views/checkout/Checkout.js +20 -9
  31. package/dist/src/infrastructure/ui/views/checkout/Checkout.style.d.ts +3 -0
  32. package/dist/src/infrastructure/ui/views/checkout/Checkout.style.js +3 -0
  33. package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.js +7 -7
  34. package/dist/src/projection/customer/customer.d.ts +2 -0
  35. package/dist/src/projection/order/order.d.ts +1 -1
  36. package/dist/src/projection/subscription/subscription.d.ts +1 -1
  37. package/dist/src/version.d.ts +1 -1
  38. package/dist/src/version.js +1 -1
  39. package/fake-dependencies/@lookiero/payments-front/index.tsx +36 -8
  40. package/index.ts +10 -3
  41. package/package.json +3 -3
  42. package/src/ExpoRoot.tsx +43 -36
  43. package/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.ts +4 -1
  44. package/src/infrastructure/projection/checkout/checkout.mock.ts +8 -3
  45. package/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.ts +3 -2
  46. package/src/infrastructure/tracking/tracking.ts +2 -2
  47. package/src/infrastructure/tracking/useTrackCheckout.test.tsx +51 -24
  48. package/src/infrastructure/tracking/useTrackCheckout.ts +66 -56
  49. package/src/infrastructure/ui/Root.tsx +9 -9
  50. package/src/infrastructure/ui/components/templates/header/itemHeader/ItemHeader.tsx +1 -0
  51. package/src/infrastructure/ui/hooks/useCheckoutFlow.test.tsx +302 -0
  52. package/src/infrastructure/ui/hooks/useCheckoutFlow.tsx +203 -0
  53. package/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.ts +18 -60
  54. package/src/infrastructure/ui/i18n/i18n.ts +1 -0
  55. package/src/infrastructure/ui/routing/CheckoutMiddleware.test.tsx +0 -11
  56. package/src/infrastructure/ui/routing/CheckoutMiddleware.tsx +1 -15
  57. package/src/infrastructure/ui/routing/Routing.tsx +14 -25
  58. package/src/infrastructure/ui/routing/routes.ts +0 -1
  59. package/src/infrastructure/ui/views/App.tsx +5 -13
  60. package/src/infrastructure/ui/views/checkout/Checkout.style.ts +3 -0
  61. package/src/infrastructure/ui/views/checkout/Checkout.test.tsx +51 -43
  62. package/src/infrastructure/ui/views/checkout/Checkout.tsx +51 -13
  63. package/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.tsx +8 -8
  64. package/src/projection/customer/customer.ts +2 -0
  65. package/src/projection/order/order.ts +1 -1
  66. package/src/projection/subscription/subscription.ts +1 -1
  67. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.d.ts +0 -27
  68. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.js +0 -97
  69. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.d.ts +0 -12
  70. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.js +0 -88
  71. package/src/infrastructure/ui/hooks/useSubmitCheckout.test.ts +0 -297
  72. package/src/infrastructure/ui/hooks/useSubmitCheckout.ts +0 -169
  73. package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.test.tsx +0 -134
  74. package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.tsx +0 -124
@@ -1,11 +1,14 @@
1
- import React, { FC, ReactNode, useCallback, useMemo, useState } from "react";
1
+ import React, { FC, useCallback, useMemo, useState } from "react";
2
2
  import { LayoutRectangle, Platform, ScrollView, View } from "react-native";
3
3
  import { useNavigate } from "react-router-native";
4
4
  import { Box, Button, Layout as AuroraLayout, Spinner, Text, useDevice } from "@lookiero/aurora";
5
5
  import { useI18nMessage } from "@lookiero/i18n-react";
6
6
  import { QueryStatus } from "@lookiero/messaging-react";
7
+ import { Country } from "@lookiero/sty-psp-locale";
7
8
  import { Layout as UiLayout, Sticky } from "@lookiero/sty-psp-ui";
8
9
  import { CheckoutItemStatus } from "../../../../domain/checkoutItem/model/checkoutItem";
10
+ import { OrderProjection } from "../../../../projection/order/order";
11
+ import { SubscriptionProjection } from "../../../../projection/subscription/subscription";
9
12
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
10
13
  import { useViewPricingByCheckoutId } from "../../../projection/pricing/react/useViewPricingByCheckoutId";
11
14
  import { TrackingPage } from "../../../tracking/tracking";
@@ -14,6 +17,7 @@ import { useTrackPressBack } from "../../../tracking/useTrackPressBack";
14
17
  import { useTrackPressContinue } from "../../../tracking/useTrackPressContinue";
15
18
  import { Body } from "../../components/layouts/body/Body";
16
19
  import { CheckoutHeader } from "../../components/templates/header/checkoutHeader/CheckoutHeader";
20
+ import { useCheckoutFlow } from "../../hooks/useCheckoutFlow";
17
21
  import { useStaticInfo } from "../../hooks/useStaticInfo";
18
22
  import { DOMAIN, I18nMessages } from "../../i18n/i18n";
19
23
  import { Routes } from "../../routing/routes";
@@ -24,12 +28,22 @@ import { DeliveryBanner } from "./components/deliveryBanner/DeliveryBanner";
24
28
  import { PaymentInstrument } from "./components/paymentInstrument/PaymentInstrument";
25
29
 
26
30
  interface CheckoutProps {
27
- readonly children?: ReactNode;
28
31
  readonly layout: UiLayout;
32
+ readonly order: OrderProjection;
33
+ readonly subscription: SubscriptionProjection;
34
+ readonly getAuthToken: () => Promise<string>;
35
+ readonly onCheckoutFlowSuccess: () => void;
29
36
  readonly useRedirect: () => Record<string, string>;
30
37
  }
31
38
 
32
- const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect }) => {
39
+ const Checkout: FC<CheckoutProps> = ({
40
+ layout: Layout,
41
+ order,
42
+ subscription,
43
+ getAuthToken,
44
+ useRedirect,
45
+ onCheckoutFlowSuccess,
46
+ }) => {
33
47
  const {
34
48
  customer: { customerId, country, segment },
35
49
  basePath,
@@ -43,6 +57,14 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
43
57
  const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
44
58
  const [pricing, pricingStatus] = useViewPricingByCheckoutId({ checkoutId: checkout?.id as string });
45
59
 
60
+ const [checkoutFlow, checkoutFlowStatus, paymentFlowComponent] = useCheckoutFlow({
61
+ checkout,
62
+ order,
63
+ subscription,
64
+ getAuthToken,
65
+ onSuccess: onCheckoutFlowSuccess,
66
+ });
67
+
46
68
  useTrackPageView({
47
69
  page: TrackingPage.CHECKOUT,
48
70
  country,
@@ -51,17 +73,16 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
51
73
  });
52
74
 
53
75
  const navigate = useNavigate();
54
-
55
76
  const trackPressContinue = useTrackPressContinue({
56
77
  page: TrackingPage.CHECKOUT,
57
78
  country,
58
79
  segment,
59
80
  checkoutId: checkout?.id,
60
81
  });
61
- const handleOnSubmit = useCallback(() => {
82
+ const handleOnSubmit = useCallback(async () => {
62
83
  trackPressContinue();
63
- navigate(`${basePath}/${Routes.CHECKOUT}/${Routes.CHECKOUT_PAYMENT}`, { replace: true });
64
- }, [basePath, navigate, trackPressContinue]);
84
+ await checkoutFlow();
85
+ }, [checkoutFlow, trackPressContinue]);
65
86
 
66
87
  const checkoutItemsKept = useMemo(
67
88
  () =>
@@ -115,6 +136,12 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
115
136
  >
116
137
  <Box size={{ L: "2/3" }} style={screen.L && style.desktopListSpacing}>
117
138
  <View style={[style.contentWrapper, screen.L && style.desktopContentWrapper]}>
139
+ {country === Country.NL && (
140
+ <View style={style.paymentSelectorNL}>
141
+ <PaymentInstrument useRedirect={useRedirect} />
142
+ </View>
143
+ )}
144
+
118
145
  <Text level={3} style={style.title} heading>
119
146
  {titleText}
120
147
  </Text>
@@ -138,9 +165,11 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
138
165
  </View>
139
166
  ))}
140
167
 
141
- <View style={style.paymentSelector}>
142
- <PaymentInstrument useRedirect={useRedirect} />
143
- </View>
168
+ {country !== Country.NL && (
169
+ <View style={style.paymentSelector}>
170
+ <PaymentInstrument useRedirect={useRedirect} />
171
+ </View>
172
+ )}
144
173
  </View>
145
174
  </Box>
146
175
 
@@ -150,7 +179,11 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
150
179
  <Pricing pricing={pricing} totalCheckoutItemsKept={checkoutItemsKept?.length || 0} />
151
180
 
152
181
  {screen.L ? (
153
- <Button testID="confirm-checkout-button" onPress={handleOnSubmit}>
182
+ <Button
183
+ busy={checkoutFlowStatus === "loading"}
184
+ testID="confirm-checkout-button"
185
+ onPress={handleOnSubmit}
186
+ >
154
187
  {submitButtonText}
155
188
  </Button>
156
189
  ) : null}
@@ -163,14 +196,19 @@ const Checkout: FC<CheckoutProps> = ({ children, layout: Layout, useRedirect })
163
196
  {pricing && !screen.L ? (
164
197
  <Sticky style={style.sticky} onLayout={Platform.OS !== "web" ? handleOnPricingLayout : undefined}>
165
198
  <Body>
166
- <Button testID="confirm-checkout-button" small onPress={handleOnSubmit}>
199
+ <Button
200
+ busy={checkoutFlowStatus === "loading"}
201
+ testID="confirm-checkout-button"
202
+ small
203
+ onPress={handleOnSubmit}
204
+ >
167
205
  {submitButtonText}
168
206
  </Button>
169
207
  </Body>
170
208
  </Sticky>
171
209
  ) : null}
172
210
 
173
- {children}
211
+ {paymentFlowComponent}
174
212
  </Layout>
175
213
  );
176
214
  };
@@ -1,24 +1,24 @@
1
- import React, { FC, useRef } from "react";
1
+ import React, { FC } from "react";
2
2
  import { PaymentInstrumentSelect, Section } from "@lookiero/payments-front";
3
- import { useLogger } from "@lookiero/sty-psp-logging";
4
- import { usePaymentInstrumentEvents } from "../../../../hooks/usePaymentInstrumentEvents";
3
+ import { useStaticInfo } from "../../../../hooks/useStaticInfo";
5
4
 
6
5
  interface PaymentInstrumentProps {
7
6
  readonly useRedirect: () => Record<string, string>;
8
7
  }
9
8
  const PaymentInstrument: FC<PaymentInstrumentProps> = ({ useRedirect }) => {
10
- const paymentInstrumentSelectRef = useRef(null);
11
9
  const { returnUrl } = useRedirect();
12
- const logger = useLogger();
13
-
14
- usePaymentInstrumentEvents({ logger });
10
+ const { customer } = useStaticInfo();
15
11
 
16
12
  return (
17
13
  <PaymentInstrumentSelect
18
- ref={paymentInstrumentSelectRef}
19
14
  beforeRedirect={returnUrl ? () => Promise.resolve(returnUrl) : undefined}
20
15
  hasError={false}
21
16
  section={Section.BOX_CHECKOUT}
17
+ userInformation={{
18
+ email: customer.email,
19
+ name: customer.name,
20
+ }}
21
+ showSingleUsePaymentMethods
22
22
  />
23
23
  );
24
24
  };
@@ -5,6 +5,8 @@ interface Customer {
5
5
  readonly customerId: string;
6
6
  readonly country: Country;
7
7
  readonly segment: Segment;
8
+ readonly name: string;
9
+ readonly email: string;
8
10
  }
9
11
 
10
12
  export type { Customer };
@@ -4,4 +4,4 @@ interface Order {
4
4
  readonly coupon: string | null;
5
5
  }
6
6
 
7
- export type { Order };
7
+ export type { Order as OrderProjection };
@@ -1,3 +1,3 @@
1
1
  type Subscription = "o" | "m" | "b" | "q";
2
2
 
3
- export type { Subscription };
3
+ export type { Subscription as SubscriptionProjection };
@@ -1,27 +0,0 @@
1
- import { RefObject } from "react";
2
- import { PaymentFlowRef } from "@lookiero/payments-front";
3
- import { Logger } from "@lookiero/sty-psp-logging";
4
- import { PaymentFlowPayloadProjection } from "../../../projection/payment/paymentFlowPayload";
5
- type Status = "idle" | "loading" | "success" | "error";
6
- interface SubmitCheckoutFunctionArgs {
7
- readonly paymentFlowPayload: PaymentFlowPayloadProjection;
8
- readonly sizeChangeEnabled: boolean;
9
- }
10
- interface SubmitCheckoutFunction {
11
- (args: SubmitCheckoutFunctionArgs): Promise<void>;
12
- }
13
- type UseSubmitCheckoutResult = [submitCheckout: SubmitCheckoutFunction, status: Status];
14
- interface UseSubmitCheckoutFunctionArgs {
15
- readonly checkoutId: string;
16
- readonly checkoutBookingId: string;
17
- readonly paymentFlowRef: RefObject<PaymentFlowRef>;
18
- readonly onError: () => void;
19
- readonly onSuccess?: () => void;
20
- readonly logger: Logger;
21
- }
22
- interface UseSubmitCheckoutFunction {
23
- (args: UseSubmitCheckoutFunctionArgs): UseSubmitCheckoutResult;
24
- }
25
- declare const useSubmitCheckout: UseSubmitCheckoutFunction;
26
- export type { Status, SubmitCheckoutFunction };
27
- export { useSubmitCheckout };
@@ -1,97 +0,0 @@
1
- import { useCallback, useMemo, useState } from "react";
2
- import { CommandStatus } from "@lookiero/messaging-react";
3
- import { NotificationLevel, useCreateToastNotification } from "@lookiero/sty-psp-notifications";
4
- import { viewCheckoutBookingById, } from "../../../projection/checkoutBooking/viewCheckoutBookingById";
5
- import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
6
- import { useSubmitCheckout as useSubmitCheckoutCommand } from "../../domain/checkout/react/useSubmitCheckout";
7
- import { useBlockCheckoutBooking } from "../../domain/checkoutBooking/react/useBlockCheckoutBooking";
8
- import { I18nMessages } from "../i18n/i18n";
9
- import { useQueryBus } from "./useQueryBus";
10
- var ChargeStatus;
11
- (function (ChargeStatus) {
12
- ChargeStatus["EXECUTED"] = "EXECUTED";
13
- ChargeStatus["REQUIRES_ACTION"] = "REQUIRES_ACTION";
14
- ChargeStatus["REQUIRED_ACTION_CANCELLED"] = "REQUIRED_ACTION_CANCELLED";
15
- ChargeStatus["REJECTED"] = "REJECTED";
16
- ChargeStatus["CANCELLED"] = "CANCELLED";
17
- ChargeStatus["TO_CONFIRM"] = "TO_CONFIRM";
18
- ChargeStatus["ERROR"] = "ERROR";
19
- ChargeStatus["UNKNOWN"] = "UNKNOWN";
20
- })(ChargeStatus || (ChargeStatus = {}));
21
- const useSubmitCheckout = ({ checkoutId, checkoutBookingId, paymentFlowRef, onError, onSuccess, logger, }) => {
22
- const queryBus = useQueryBus();
23
- const [submitCheckoutCommand, submitCheckoutCommandStatus] = useSubmitCheckoutCommand({ checkoutId, logger });
24
- const [blockCheckoutBooking, blockCheckoutBookingStatus] = useBlockCheckoutBooking({ checkoutBookingId, logger });
25
- const [createNotification] = useCreateToastNotification({ contextId: MESSAGING_CONTEXT_ID, logger });
26
- const [checkoutBookingExpired, setCheckoutBookingExpired] = useState(false);
27
- const [startLegacyBoxCheckoutStatus, setStartLegacyBoxCheckoutStatus] = useState("idle");
28
- const submitCheckout = useCallback(async ({ paymentFlowPayload, sizeChangeEnabled }) => {
29
- try {
30
- sizeChangeEnabled && (await blockCheckoutBooking());
31
- }
32
- catch (error) {
33
- return;
34
- }
35
- const checkoutBooking = await queryBus(viewCheckoutBookingById({ checkoutBookingId }));
36
- if (checkoutBooking?.isExpired) {
37
- setCheckoutBookingExpired(true);
38
- return;
39
- }
40
- paymentFlowRef.current?.startLegacyBoxCheckout(
41
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
- // @ts-ignore
43
- paymentFlowPayload, async ({ status, toaster, final }) => {
44
- setStartLegacyBoxCheckoutStatus("loading");
45
- if (final) {
46
- if (status === ChargeStatus.EXECUTED) {
47
- setStartLegacyBoxCheckoutStatus("success");
48
- await submitCheckoutCommand();
49
- onSuccess?.();
50
- }
51
- else {
52
- createNotification({
53
- level: NotificationLevel.ERROR,
54
- bodyI18nKey: toaster?.id || I18nMessages.CHECKOUT_TOAST_PAYMENT_ERROR,
55
- });
56
- setStartLegacyBoxCheckoutStatus("error");
57
- }
58
- }
59
- });
60
- }, [
61
- queryBus,
62
- checkoutBookingId,
63
- paymentFlowRef,
64
- blockCheckoutBooking,
65
- submitCheckoutCommand,
66
- onSuccess,
67
- createNotification,
68
- ]);
69
- const status = useMemo(() => {
70
- if (blockCheckoutBookingStatus === CommandStatus.LOADING ||
71
- startLegacyBoxCheckoutStatus === "loading" ||
72
- submitCheckoutCommandStatus === CommandStatus.LOADING) {
73
- return "loading";
74
- }
75
- if (blockCheckoutBookingStatus === CommandStatus.SUCCESS &&
76
- startLegacyBoxCheckoutStatus === "success" &&
77
- submitCheckoutCommandStatus === CommandStatus.SUCCESS) {
78
- return "success";
79
- }
80
- if (blockCheckoutBookingStatus === CommandStatus.ERROR ||
81
- startLegacyBoxCheckoutStatus === "error" ||
82
- submitCheckoutCommandStatus === CommandStatus.ERROR ||
83
- checkoutBookingExpired) {
84
- onError();
85
- return "error";
86
- }
87
- return "idle";
88
- }, [
89
- blockCheckoutBookingStatus,
90
- startLegacyBoxCheckoutStatus,
91
- submitCheckoutCommandStatus,
92
- checkoutBookingExpired,
93
- onError,
94
- ]);
95
- return [submitCheckout, status];
96
- };
97
- export { useSubmitCheckout };
@@ -1,12 +0,0 @@
1
- import { FC } from "react";
2
- import { Subscription } from "../../../../../../projection/subscription/subscription";
3
- interface CheckoutPaymentModalProps {
4
- readonly coupon: string | null;
5
- readonly orderNumber: number;
6
- readonly isFirstOrder: boolean;
7
- readonly subscription: Subscription;
8
- readonly getAuthToken: () => Promise<string>;
9
- readonly onCheckoutSubmitted?: () => void;
10
- }
11
- declare const CheckoutPaymentModal: FC<CheckoutPaymentModalProps>;
12
- export { CheckoutPaymentModal };
@@ -1,88 +0,0 @@
1
- import React, { useCallback, useEffect, useRef, useState } from "react";
2
- import { useNavigate } from "react-router-native";
3
- import { QueryStatus } from "@lookiero/messaging-react";
4
- import { PaymentFlow } from "@lookiero/payments-front";
5
- import { useLogger } from "@lookiero/sty-psp-logging";
6
- import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
7
- import { useViewFirstAvailableCheckoutByCustomerId } from "../../../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
8
- import { useViewIsSizeChangeEnabledByCheckoutId } from "../../../../../projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId";
9
- import { useViewPaymentFlowPayloadByCheckoutId } from "../../../../../projection/payment/react/useViewPaymentFlowPayloadByCheckoutId";
10
- import { useViewPricingByCheckoutId } from "../../../../../projection/pricing/react/useViewPricingByCheckoutId";
11
- import { TrackingPage } from "../../../../../tracking/tracking";
12
- import { useTrackCheckout } from "../../../../../tracking/useTrackCheckout";
13
- import { useStaticInfo } from "../../../../hooks/useStaticInfo";
14
- import { useSubmitCheckout } from "../../../../hooks/useSubmitCheckout";
15
- import { Routes } from "../../../../routing/routes";
16
- const CheckoutPaymentModal = ({ coupon, isFirstOrder, subscription, orderNumber, getAuthToken, onCheckoutSubmitted, }) => {
17
- const paymentFlowRef = useRef(null);
18
- const logger = useLogger();
19
- const { customer: { customerId, country, segment }, basePath, } = useStaticInfo();
20
- const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
21
- const [paymentFlowPayload] = useViewPaymentFlowPayloadByCheckoutId({
22
- checkoutId: checkout?.id,
23
- });
24
- const [sizeChangeEnabled] = useViewIsSizeChangeEnabledByCheckoutId({ checkoutId: checkout?.id });
25
- const [pricing] = useViewPricingByCheckoutId({
26
- checkoutId: checkout?.id,
27
- queryOptions: { refetchOnMount: true },
28
- });
29
- const [authToken, setAuthToken] = useState();
30
- useEffect(() => {
31
- const loadAuthToken = async () => setAuthToken(await getAuthToken());
32
- loadAuthToken();
33
- }, [getAuthToken]);
34
- const navigate = useNavigate();
35
- const trackCheckout = useTrackCheckout({
36
- page: TrackingPage.CHECKOUT,
37
- checkoutId: checkout?.id,
38
- country,
39
- segment,
40
- });
41
- const handleOnSubmitCheckoutError = useCallback(() => navigate(`${basePath}/${Routes.CHECKOUT}`, { replace: true }), [basePath, navigate]);
42
- const handleOnSubmitCheckoutSuccess = useCallback(() => {
43
- const checkoutItemsKept = checkout?.items.filter((checkoutItem) => checkoutItem.status === CheckoutItemStatus.KEPT || checkoutItem.status === CheckoutItemStatus.REPLACED);
44
- const totalReplacedFor = checkoutItemsKept?.filter(({ replacedFor }) => Boolean(replacedFor)).length || 0;
45
- trackCheckout({
46
- totalCheckoutItemsKept: checkoutItemsKept?.length || 0,
47
- pendingToPay: pricing?.pendingToPay.amount / 100,
48
- coupon,
49
- currencyCode: pricing?.pendingToPay.currency,
50
- isFirstOrder,
51
- orderNumber,
52
- totalReplacedFor,
53
- subscription,
54
- userId: customerId,
55
- });
56
- onCheckoutSubmitted?.();
57
- }, [
58
- checkout?.items,
59
- coupon,
60
- customerId,
61
- isFirstOrder,
62
- onCheckoutSubmitted,
63
- orderNumber,
64
- pricing?.pendingToPay.amount,
65
- pricing?.pendingToPay.currency,
66
- subscription,
67
- trackCheckout,
68
- ]);
69
- const [submitCheckout] = useSubmitCheckout({
70
- checkoutId: checkout?.id,
71
- checkoutBookingId: checkout?.checkoutBookingId,
72
- paymentFlowRef,
73
- onError: handleOnSubmitCheckoutError,
74
- onSuccess: handleOnSubmitCheckoutSuccess,
75
- logger,
76
- });
77
- useEffect(() => {
78
- if (paymentFlowPayload && sizeChangeEnabled !== undefined && pricing !== undefined) {
79
- submitCheckout({ paymentFlowPayload, sizeChangeEnabled });
80
- }
81
- }, [paymentFlowPayload, pricing, sizeChangeEnabled, submitCheckout]);
82
- const dependenciesLoadedStatuses = [QueryStatus.ERROR, QueryStatus.SUCCESS];
83
- const dependenciesLoaded = (dependenciesLoadedStatuses.includes(checkoutStatus) || checkout) && authToken;
84
- if (!dependenciesLoaded)
85
- return null;
86
- return React.createElement(PaymentFlow, { ref: paymentFlowRef, token: authToken });
87
- };
88
- export { CheckoutPaymentModal };