@lookiero/checkout 10.1.0 → 11.1.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 (80) 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/Expo.js +8 -2
  6. package/dist/src/ExpoRoot.d.ts +5 -1
  7. package/dist/src/ExpoRoot.js +26 -17
  8. package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.d.ts +1 -1
  9. package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.js +2 -0
  10. package/dist/src/infrastructure/projection/checkout/checkout.mock.d.ts +1 -0
  11. package/dist/src/infrastructure/projection/checkout/checkout.mock.js +3 -3
  12. package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.d.ts +1 -1
  13. package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.js +2 -1
  14. package/dist/src/infrastructure/tracking/tracking.d.ts +2 -2
  15. package/dist/src/infrastructure/tracking/useTrackCheckout.d.ts +10 -17
  16. package/dist/src/infrastructure/tracking/useTrackCheckout.js +27 -12
  17. package/dist/src/infrastructure/ui/Root.d.ts +6 -6
  18. package/dist/src/infrastructure/ui/Root.js +2 -3
  19. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.d.ts +26 -0
  20. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.js +127 -0
  21. package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.d.ts +3 -2
  22. package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.js +17 -26
  23. package/dist/src/infrastructure/ui/i18n/i18n.d.ts +1 -0
  24. package/dist/src/infrastructure/ui/i18n/i18n.js +1 -0
  25. package/dist/src/infrastructure/ui/routing/CheckoutMiddleware.js +1 -12
  26. package/dist/src/infrastructure/ui/routing/Routing.d.ts +5 -5
  27. package/dist/src/infrastructure/ui/routing/Routing.js +2 -10
  28. package/dist/src/infrastructure/ui/routing/routes.d.ts +0 -1
  29. package/dist/src/infrastructure/ui/routing/routes.js +0 -1
  30. package/dist/src/infrastructure/ui/views/App.js +5 -6
  31. package/dist/src/infrastructure/ui/views/checkout/Checkout.d.ts +7 -2
  32. package/dist/src/infrastructure/ui/views/checkout/Checkout.js +20 -9
  33. package/dist/src/infrastructure/ui/views/checkout/Checkout.style.d.ts +3 -0
  34. package/dist/src/infrastructure/ui/views/checkout/Checkout.style.js +3 -0
  35. package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.js +7 -7
  36. package/dist/src/projection/customer/customer.d.ts +2 -0
  37. package/dist/src/projection/order/order.d.ts +1 -1
  38. package/dist/src/projection/subscription/subscription.d.ts +1 -1
  39. package/dist/src/version.d.ts +1 -1
  40. package/dist/src/version.js +1 -1
  41. package/fake-dependencies/@lookiero/payments-front/index.tsx +36 -8
  42. package/index.ts +10 -3
  43. package/package.json +3 -4
  44. package/src/Expo.tsx +10 -2
  45. package/src/ExpoRoot.tsx +58 -43
  46. package/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.ts +4 -1
  47. package/src/infrastructure/projection/checkout/checkout.mock.ts +8 -3
  48. package/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.ts +3 -2
  49. package/src/infrastructure/tracking/tracking.ts +2 -2
  50. package/src/infrastructure/tracking/useTrackCheckout.test.tsx +51 -24
  51. package/src/infrastructure/tracking/useTrackCheckout.ts +66 -56
  52. package/src/infrastructure/ui/Root.tsx +9 -9
  53. package/src/infrastructure/ui/components/templates/header/itemHeader/ItemHeader.tsx +1 -0
  54. package/src/infrastructure/ui/hooks/useCheckoutFlow.test.tsx +302 -0
  55. package/src/infrastructure/ui/hooks/useCheckoutFlow.tsx +203 -0
  56. package/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.ts +18 -60
  57. package/src/infrastructure/ui/i18n/i18n.ts +1 -0
  58. package/src/infrastructure/ui/routing/CheckoutMiddleware.test.tsx +0 -11
  59. package/src/infrastructure/ui/routing/CheckoutMiddleware.tsx +1 -15
  60. package/src/infrastructure/ui/routing/Routing.tsx +14 -25
  61. package/src/infrastructure/ui/routing/routes.ts +0 -1
  62. package/src/infrastructure/ui/views/App.tsx +5 -13
  63. package/src/infrastructure/ui/views/checkout/Checkout.style.ts +3 -0
  64. package/src/infrastructure/ui/views/checkout/Checkout.test.tsx +51 -43
  65. package/src/infrastructure/ui/views/checkout/Checkout.tsx +51 -13
  66. package/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.tsx +8 -8
  67. package/src/infrastructure/ui/views/item/components/itemActions/__snapshots__/ItemActions.test.tsx.snap +8 -0
  68. package/src/infrastructure/ui/views/item/components/selectModal/__snapshots__/SelecModal.test.tsx.snap +8 -0
  69. package/src/infrastructure/ui/views/item/components/sizeWithoutStockModal/__snapshots__/SizeWithoutStockModal.test.tsx.snap +8 -0
  70. package/src/projection/customer/customer.ts +2 -0
  71. package/src/projection/order/order.ts +1 -1
  72. package/src/projection/subscription/subscription.ts +1 -1
  73. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.d.ts +0 -27
  74. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.js +0 -97
  75. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.d.ts +0 -12
  76. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.js +0 -88
  77. package/src/infrastructure/ui/hooks/useSubmitCheckout.test.ts +0 -297
  78. package/src/infrastructure/ui/hooks/useSubmitCheckout.ts +0 -169
  79. package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.test.tsx +0 -134
  80. package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.tsx +0 -124
@@ -1,29 +1,20 @@
1
- import { useCallback, useEffect } from "react";
2
- import { useEvent } from "@lookiero/event";
3
- import { NotificationLevel, useCreateToastNotification } from "@lookiero/sty-psp-notifications";
4
- import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
5
- import { I18nMessages } from "../i18n/i18n";
6
- const PAYMENT_ERROR = "ERROR";
7
- const PAYMENT_SUCCESS = "PAYMENT_INSTRUMENT_UPDATED";
8
- const usePaymentInstrumentEvents = ({ logger }) => {
9
- const { subscribe, unsubscribe } = useEvent();
10
- const [createNotification] = useCreateToastNotification({ contextId: MESSAGING_CONTEXT_ID, logger });
11
- const onSuccess = useCallback(({ message }) => createNotification({ bodyI18nKey: message.id, level: NotificationLevel.SUCCESS }), [createNotification]);
12
- const onError = useCallback(({ error }) => {
13
- if (error.toaster) {
14
- createNotification({
15
- bodyI18nKey: error.toaster.id || I18nMessages.CHECKOUT_TOAST_PAYMENT_ERROR,
16
- level: NotificationLevel.ERROR,
17
- });
18
- }
19
- }, [createNotification]);
1
+ import { useEffect } from "react";
2
+ import { Section, usePaymentStatusManager } from "@lookiero/payments-front";
3
+ const usePaymentInstrumentEvents = ({ onSuccess, onError }) => {
4
+ const refreshStatus = usePaymentStatusManager(Section.BOX_CHECKOUT);
20
5
  useEffect(() => {
21
- subscribe({ event: PAYMENT_ERROR }, onError);
22
- subscribe({ event: PAYMENT_SUCCESS }, onSuccess);
23
- return () => {
24
- unsubscribe({ event: PAYMENT_ERROR }, onError);
25
- unsubscribe({ event: PAYMENT_SUCCESS }, onSuccess);
26
- };
27
- }, [subscribe, unsubscribe, createNotification, onError, onSuccess]);
6
+ const { isLoading, consumePayload } = refreshStatus;
7
+ if (isLoading) {
8
+ return;
9
+ }
10
+ consumePayload((payload) => {
11
+ if (payload.success) {
12
+ onSuccess(payload);
13
+ }
14
+ else {
15
+ onError(payload);
16
+ }
17
+ });
18
+ }, [onError, onSuccess, refreshStatus]);
28
19
  };
29
20
  export { usePaymentInstrumentEvents };
@@ -47,6 +47,7 @@ declare enum I18nMessages {
47
47
  CHECKOUT_TITLE = "checkout.title",
48
48
  CHECKOUT_PAY_BUTTON = "checkout.pay_button",
49
49
  CHECKOUT_TOAST_PAYMENT_ERROR = "checkout.toast_payment_error",
50
+ CHECKOUT_TOAST_PAYMENT_SUCCESS = "checkout.toast_payment_success",
50
51
  CHECKOUT_SUCCESS_MODAL_TITLE = "checkout.success_modal_title",
51
52
  CHECKOUT_SUCCESS_MODAL_DESCRIPTION = "checkout.success_modal_description",
52
53
  CHECKOUT_SUCCESS_MODAL_BUTTON = "checkout.success_modal_button",
@@ -49,6 +49,7 @@ var I18nMessages;
49
49
  I18nMessages["CHECKOUT_TITLE"] = "checkout.title";
50
50
  I18nMessages["CHECKOUT_PAY_BUTTON"] = "checkout.pay_button";
51
51
  I18nMessages["CHECKOUT_TOAST_PAYMENT_ERROR"] = "checkout.toast_payment_error";
52
+ I18nMessages["CHECKOUT_TOAST_PAYMENT_SUCCESS"] = "checkout.toast_payment_success";
52
53
  I18nMessages["CHECKOUT_SUCCESS_MODAL_TITLE"] = "checkout.success_modal_title";
53
54
  I18nMessages["CHECKOUT_SUCCESS_MODAL_DESCRIPTION"] = "checkout.success_modal_description";
54
55
  I18nMessages["CHECKOUT_SUCCESS_MODAL_BUTTON"] = "checkout.success_modal_button";
@@ -33,11 +33,6 @@ const CheckoutMiddleware = ({ customerId, onNotAccessible, loader = React.create
33
33
  const feedbackRouteMatch = useMatch(`${basePath}/${Routes.FEEDBACK}`);
34
34
  const feedbackRouteMatchRef = useRef(feedbackRouteMatch);
35
35
  feedbackRouteMatchRef.current = feedbackRouteMatch;
36
- const checkoutPaymentRouteMatch = useMatch(`${basePath}/${Routes.CHECKOUT}/${Routes.CHECKOUT_PAYMENT}`);
37
- const checkoutPaymentRouteMatchRef = useRef(checkoutPaymentRouteMatch);
38
- checkoutPaymentRouteMatchRef.current = checkoutPaymentRouteMatch;
39
- const checkoutShown = useRef(false);
40
- checkoutShown.current = checkoutShown.current || (Boolean(checkoutRouteMatch) && !Boolean(checkoutPaymentRouteMatch));
41
36
  const [checkout] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
42
37
  const checkoutItemsRef = useRef();
43
38
  /* This hook is mounted at this level, although not being used directly, for optimization (regarding cache) */
@@ -66,8 +61,7 @@ const CheckoutMiddleware = ({ customerId, onNotAccessible, loader = React.create
66
61
  !(summaryRouteMatchRef.current ||
67
62
  summaryTabsRouteMatchRef.current ||
68
63
  itemDetailRouteMatchRef.current ||
69
- checkoutRouteMatchRef.current ||
70
- checkoutPaymentRouteMatchRef.current)) {
64
+ checkoutRouteMatchRef.current)) {
71
65
  navigateRef.current(`${basePath}/${Routes.SUMMARY}`, { replace: true });
72
66
  }
73
67
  if (itemWithoutCustomerDecision &&
@@ -85,11 +79,6 @@ const CheckoutMiddleware = ({ customerId, onNotAccessible, loader = React.create
85
79
  onNotAccessible();
86
80
  return null;
87
81
  }
88
- /* Prevent direct payment access */
89
- if (checkoutPaymentRouteMatch && !checkoutShown.current) {
90
- onNotAccessible();
91
- return null;
92
- }
93
82
  return children;
94
83
  };
95
84
  export { CheckoutMiddleware };
@@ -5,14 +5,14 @@ import { Locale } from "@lookiero/sty-psp-locale";
5
5
  import { Layout } from "@lookiero/sty-psp-ui";
6
6
  import { Tradename } from "@lookiero/sty-sp-tradename";
7
7
  import { Customer } from "../../../projection/customer/customer";
8
- import { Order } from "../../../projection/order/order";
9
- import { Subscription } from "../../../projection/subscription/subscription";
8
+ import { OrderProjection } from "../../../projection/order/order";
9
+ import { SubscriptionProjection } from "../../../projection/subscription/subscription";
10
10
  import { KameleoonEnvironment } from "../../ab-testing/kameleoonEnvironment";
11
11
  interface RoutingProps {
12
12
  readonly basePath?: string;
13
13
  readonly customer: Customer;
14
- readonly order: Order | undefined;
15
- readonly subscription: Subscription | undefined;
14
+ readonly order: OrderProjection;
15
+ readonly subscription: SubscriptionProjection;
16
16
  readonly locale: Locale;
17
17
  readonly I18n: I18n;
18
18
  readonly kameleoon: KameleoonEnvironment;
@@ -20,7 +20,7 @@ interface RoutingProps {
20
20
  readonly tradename: Tradename;
21
21
  readonly getAuthToken: () => Promise<string>;
22
22
  readonly onNotAccessible: () => void;
23
- readonly onCheckoutSubmitted?: () => void;
23
+ readonly onCheckoutFlowSuccess: () => void;
24
24
  readonly onI18nError?: (err: Error) => void;
25
25
  readonly useRedirect: () => Record<string, string>;
26
26
  readonly useRoutes: typeof reactRouterUseRoutes;
@@ -5,7 +5,6 @@ import { Kameleoon } from "@lookiero/sty-psp-ab-testing";
5
5
  import { StaticInfoProvider } from "../hooks/useStaticInfo";
6
6
  import { App } from "../views/App";
7
7
  import { Checkout } from "../views/checkout/Checkout";
8
- import { CheckoutPaymentModal } from "../views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal";
9
8
  import { Feedback } from "../views/feedback/Feedback";
10
9
  import { Item } from "../views/item/Item";
11
10
  import { Return } from "../views/return/Return";
@@ -13,7 +12,7 @@ import { Summary } from "../views/summary/Summary";
13
12
  import { SummaryTabs } from "../views/summaryTabs/SummaryTabs";
14
13
  import { CheckoutMiddleware } from "./CheckoutMiddleware";
15
14
  import { Routes } from "./routes";
16
- const Routing = ({ basePath = "", customer, order, subscription, locale, I18n, kameleoon, layout, tradename, getAuthToken, onI18nError, onNotAccessible, onCheckoutSubmitted, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
15
+ const Routing = ({ basePath = "", customer, order, subscription, locale, I18n, kameleoon, layout, tradename, getAuthToken, onI18nError, onNotAccessible, onCheckoutFlowSuccess, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
17
16
  return useRoutes([
18
17
  {
19
18
  path: "",
@@ -50,14 +49,7 @@ const Routing = ({ basePath = "", customer, order, subscription, locale, I18n, k
50
49
  {
51
50
  path: Routes.CHECKOUT,
52
51
  element: (React.createElement(Suspense, { fallback: React.createElement(Spinner, null) },
53
- React.createElement(Checkout, { layout: layout, useRedirect: useRedirect },
54
- React.createElement(Outlet, null)))),
55
- children: [
56
- {
57
- path: Routes.CHECKOUT_PAYMENT,
58
- element: (React.createElement(CheckoutPaymentModal, { coupon: order?.coupon || null, getAuthToken: getAuthToken, isFirstOrder: order?.isFirstOrder, orderNumber: order?.orderNumber, subscription: subscription, onCheckoutSubmitted: onCheckoutSubmitted })),
59
- },
60
- ],
52
+ React.createElement(Checkout, { getAuthToken: getAuthToken, layout: layout, order: order, subscription: subscription, useRedirect: useRedirect, onCheckoutFlowSuccess: onCheckoutFlowSuccess }))),
61
53
  },
62
54
  {
63
55
  path: Routes.FEEDBACK,
@@ -5,7 +5,6 @@ export declare enum Routes {
5
5
  SUMMARY = "summary",
6
6
  SUMMARY_TABS = "tabs/:tab",
7
7
  CHECKOUT = "checkout",
8
- CHECKOUT_PAYMENT = "payment",
9
8
  FEEDBACK = "feedback",
10
9
  RETURN = "return/:id"
11
10
  }
@@ -6,7 +6,6 @@ export var Routes;
6
6
  Routes["SUMMARY"] = "summary";
7
7
  Routes["SUMMARY_TABS"] = "tabs/:tab";
8
8
  Routes["CHECKOUT"] = "checkout";
9
- Routes["CHECKOUT_PAYMENT"] = "payment";
10
9
  Routes["FEEDBACK"] = "feedback";
11
10
  Routes["RETURN"] = "return/:id";
12
11
  })(Routes || (Routes = {}));
@@ -1,16 +1,15 @@
1
- import { PortalProvider } from "@gorhom/portal";
1
+ import { PortalHost } from "@gorhom/portal";
2
2
  import React from "react";
3
3
  import { StatusBar } from "react-native";
4
4
  import { SafeAreaProvider } from "react-native-safe-area-context";
5
- import { PortalProvider as AuroraPortalProvider } from "@lookiero/aurora";
6
5
  import { Notifications } from "@lookiero/sty-psp-notifications";
7
6
  import { theme } from "@lookiero/sty-psp-ui";
8
7
  import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
9
8
  import { DOMAIN } from "../i18n/i18n";
10
9
  const { colorBgBase } = theme();
11
10
  const App = ({ children }) => (React.createElement(SafeAreaProvider, null,
12
- React.createElement(PortalProvider, { rootHostName: "Checkout" },
13
- React.createElement(StatusBar, { backgroundColor: colorBgBase, barStyle: "dark-content", translucent: true }),
14
- React.createElement(Notifications, { contextId: MESSAGING_CONTEXT_ID, domain: DOMAIN, portalHostName: "Checkout" }),
15
- React.createElement(AuroraPortalProvider, null, children))));
11
+ React.createElement(StatusBar, { backgroundColor: colorBgBase, barStyle: "dark-content", translucent: true }),
12
+ React.createElement(Notifications, { contextId: MESSAGING_CONTEXT_ID, domain: DOMAIN, portalHostName: "Checkout" }),
13
+ React.createElement(PortalHost, { name: "Checkout" }),
14
+ children));
16
15
  export { App };
@@ -1,8 +1,13 @@
1
- import { FC, ReactNode } from "react";
1
+ import { FC } from "react";
2
2
  import { Layout as UiLayout } from "@lookiero/sty-psp-ui";
3
+ import { OrderProjection } from "../../../../projection/order/order";
4
+ import { SubscriptionProjection } from "../../../../projection/subscription/subscription";
3
5
  interface CheckoutProps {
4
- readonly children?: ReactNode;
5
6
  readonly layout: UiLayout;
7
+ readonly order: OrderProjection;
8
+ readonly subscription: SubscriptionProjection;
9
+ readonly getAuthToken: () => Promise<string>;
10
+ readonly onCheckoutFlowSuccess: () => void;
6
11
  readonly useRedirect: () => Record<string, string>;
7
12
  }
8
13
  declare const Checkout: FC<CheckoutProps>;
@@ -4,6 +4,7 @@ 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 { Sticky } from "@lookiero/sty-psp-ui";
8
9
  import { CheckoutItemStatus } from "../../../../domain/checkoutItem/model/checkoutItem";
9
10
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
@@ -14,6 +15,7 @@ import { useTrackPressBack } from "../../../tracking/useTrackPressBack";
14
15
  import { useTrackPressContinue } from "../../../tracking/useTrackPressContinue";
15
16
  import { Body } from "../../components/layouts/body/Body";
16
17
  import { CheckoutHeader } from "../../components/templates/header/checkoutHeader/CheckoutHeader";
18
+ import { useCheckoutFlow } from "../../hooks/useCheckoutFlow";
17
19
  import { useStaticInfo } from "../../hooks/useStaticInfo";
18
20
  import { DOMAIN, I18nMessages } from "../../i18n/i18n";
19
21
  import { Routes } from "../../routing/routes";
@@ -22,7 +24,7 @@ import { Pricing } from "../summary/components/pricing/Pricing";
22
24
  import { style } from "./Checkout.style";
23
25
  import { DeliveryBanner } from "./components/deliveryBanner/DeliveryBanner";
24
26
  import { PaymentInstrument } from "./components/paymentInstrument/PaymentInstrument";
25
- const Checkout = ({ children, layout: Layout, useRedirect }) => {
27
+ const Checkout = ({ layout: Layout, order, subscription, getAuthToken, useRedirect, onCheckoutFlowSuccess, }) => {
26
28
  const { customer: { customerId, country, segment }, basePath, } = useStaticInfo();
27
29
  const titleText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.CHECKOUT_TITLE });
28
30
  const submitButtonText = useI18nMessage({ domain: DOMAIN, id: I18nMessages.CHECKOUT_PAY_BUTTON });
@@ -31,6 +33,13 @@ const Checkout = ({ children, layout: Layout, useRedirect }) => {
31
33
  const handleOnPricingLayout = useCallback(({ height }) => setPricingHeight(height), []);
32
34
  const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
33
35
  const [pricing, pricingStatus] = useViewPricingByCheckoutId({ checkoutId: checkout?.id });
36
+ const [checkoutFlow, checkoutFlowStatus, paymentFlowComponent] = useCheckoutFlow({
37
+ checkout,
38
+ order,
39
+ subscription,
40
+ getAuthToken,
41
+ onSuccess: onCheckoutFlowSuccess,
42
+ });
34
43
  useTrackPageView({
35
44
  page: TrackingPage.CHECKOUT,
36
45
  country,
@@ -44,10 +53,10 @@ const Checkout = ({ children, layout: Layout, useRedirect }) => {
44
53
  segment,
45
54
  checkoutId: checkout?.id,
46
55
  });
47
- const handleOnSubmit = useCallback(() => {
56
+ const handleOnSubmit = useCallback(async () => {
48
57
  trackPressContinue();
49
- navigate(`${basePath}/${Routes.CHECKOUT}/${Routes.CHECKOUT_PAYMENT}`, { replace: true });
50
- }, [basePath, navigate, trackPressContinue]);
58
+ await checkoutFlow();
59
+ }, [checkoutFlow, trackPressContinue]);
51
60
  const checkoutItemsKept = useMemo(() => checkout?.items.filter((checkoutItem) => checkoutItem.status === CheckoutItemStatus.KEPT || checkoutItem.status === CheckoutItemStatus.REPLACED), [checkout?.items]);
52
61
  const hasReplacedCheckoutItem = useMemo(() => checkout?.items.some((checkoutItem) => checkoutItem.status === CheckoutItemStatus.REPLACED), [checkout?.items]);
53
62
  const trackPressBack = useTrackPressBack({
@@ -75,19 +84,21 @@ const Checkout = ({ children, layout: Layout, useRedirect }) => {
75
84
  React.createElement(AuroraLayout, { fullWidth: !screen.L, style: [screen.L && style.desktopLayoutSpacing, !screen.L && { paddingBottom: pricingHeight }] },
76
85
  React.createElement(Box, { size: { L: "2/3" }, style: screen.L && style.desktopListSpacing },
77
86
  React.createElement(View, { style: [style.contentWrapper, screen.L && style.desktopContentWrapper] },
87
+ country === Country.NL && (React.createElement(View, { style: style.paymentSelectorNL },
88
+ React.createElement(PaymentInstrument, { useRedirect: useRedirect }))),
78
89
  React.createElement(Text, { level: 3, style: style.title, heading: true }, titleText),
79
90
  checkoutItemsKept?.map((checkoutItem) => (React.createElement(View, { key: checkoutItem.id, testID: "checkout-items-kept" },
80
91
  React.createElement(ProductVariant, { brand: checkoutItem.productVariant.brand, color: checkoutItem.productVariant.color, country: country, media: checkoutItem.productVariant.media, name: checkoutItem.productVariant.name, price: checkoutItem.price, status: checkoutItem.status, size: checkoutItem.status === CheckoutItemStatus.REPLACED && checkoutItem.replacedFor
81
92
  ? checkoutItem.replacedFor.size
82
93
  : checkoutItem.productVariant.size })))),
83
- React.createElement(View, { style: style.paymentSelector },
84
- React.createElement(PaymentInstrument, { useRedirect: useRedirect })))),
94
+ country !== Country.NL && (React.createElement(View, { style: style.paymentSelector },
95
+ React.createElement(PaymentInstrument, { useRedirect: useRedirect }))))),
85
96
  React.createElement(Box, { size: { L: "1/3" }, style: [style.resume, screen.L && style.desktopResume] }, pricing ? (React.createElement(View, { style: [style.princingWrapper, !screen.L && style.princingWrapperSmall] },
86
97
  React.createElement(Pricing, { pricing: pricing, totalCheckoutItemsKept: checkoutItemsKept?.length || 0 }),
87
- screen.L ? (React.createElement(Button, { testID: "confirm-checkout-button", onPress: handleOnSubmit }, submitButtonText)) : null)) : null))),
98
+ screen.L ? (React.createElement(Button, { busy: checkoutFlowStatus === "loading", testID: "confirm-checkout-button", onPress: handleOnSubmit }, submitButtonText)) : null)) : null))),
88
99
  pricing && !screen.L ? (React.createElement(Sticky, { style: style.sticky, onLayout: Platform.OS !== "web" ? handleOnPricingLayout : undefined },
89
100
  React.createElement(Body, null,
90
- React.createElement(Button, { testID: "confirm-checkout-button", small: true, onPress: handleOnSubmit }, submitButtonText)))) : null,
91
- children));
101
+ React.createElement(Button, { busy: checkoutFlowStatus === "loading", testID: "confirm-checkout-button", small: true, onPress: handleOnSubmit }, submitButtonText)))) : null,
102
+ paymentFlowComponent));
92
103
  };
93
104
  export { Checkout };
@@ -24,6 +24,9 @@ declare const style: {
24
24
  paymentSelector: {
25
25
  marginTop: number;
26
26
  };
27
+ paymentSelectorNL: {
28
+ marginBottom: number;
29
+ };
27
30
  princingWrapper: {
28
31
  padding: number;
29
32
  };
@@ -28,6 +28,9 @@ const style = StyleSheet.create({
28
28
  paymentSelector: {
29
29
  marginTop: space6,
30
30
  },
31
+ paymentSelectorNL: {
32
+ marginBottom: space6,
33
+ },
31
34
  princingWrapper: {
32
35
  padding: space6,
33
36
  },
@@ -1,12 +1,12 @@
1
- import React, { useRef } from "react";
1
+ import React 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
  const PaymentInstrument = ({ useRedirect }) => {
6
- const paymentInstrumentSelectRef = useRef(null);
7
5
  const { returnUrl } = useRedirect();
8
- const logger = useLogger();
9
- usePaymentInstrumentEvents({ logger });
10
- return (React.createElement(PaymentInstrumentSelect, { ref: paymentInstrumentSelectRef, beforeRedirect: returnUrl ? () => Promise.resolve(returnUrl) : undefined, hasError: false, section: Section.BOX_CHECKOUT }));
6
+ const { customer } = useStaticInfo();
7
+ return (React.createElement(PaymentInstrumentSelect, { beforeRedirect: returnUrl ? () => Promise.resolve(returnUrl) : undefined, hasError: false, section: Section.BOX_CHECKOUT, userInformation: {
8
+ email: customer.email,
9
+ name: customer.name,
10
+ }, showSingleUsePaymentMethods: true }));
11
11
  };
12
12
  export { PaymentInstrument };
@@ -4,5 +4,7 @@ interface Customer {
4
4
  readonly customerId: string;
5
5
  readonly country: Country;
6
6
  readonly segment: Segment;
7
+ readonly name: string;
8
+ readonly email: string;
7
9
  }
8
10
  export type { Customer };
@@ -3,4 +3,4 @@ interface Order {
3
3
  readonly isFirstOrder: boolean;
4
4
  readonly coupon: string | null;
5
5
  }
6
- export type { Order };
6
+ export type { Order as OrderProjection };
@@ -1,2 +1,2 @@
1
1
  type Subscription = "o" | "m" | "b" | "q";
2
- export type { Subscription };
2
+ export type { Subscription as SubscriptionProjection };
@@ -1 +1 @@
1
- export declare const VERSION = "10.1.0";
1
+ export declare const VERSION = "11.1.0";
@@ -1 +1 @@
1
- export const VERSION = "10.1.0";
1
+ export const VERSION = "11.1.0";
@@ -7,34 +7,62 @@ import {
7
7
  RefAttributes,
8
8
  useImperativeHandle,
9
9
  } from "react";
10
+ import { PaymentPayload } from "@lookiero/payments-front";
11
+
12
+ let startLegacyBoxCheckoutListener: ({ success }: { success: boolean }) => void;
10
13
 
11
14
  const setPaymentsBridge = () => void 0;
12
15
  const PaymentsQueryProvider: FC<PropsWithChildren> = ({ children }) => children;
13
16
  const PaymentInstrumentSelect: FC = () => null;
14
- interface StartLegacyBoxCheckoutCallbackArgs {
15
- readonly status: string;
16
- readonly final: boolean;
17
- }
17
+
18
18
  interface StartLegacyBoxCheckoutFunction {
19
- (paymentFlowPayload: unknown, callback: (params: StartLegacyBoxCheckoutCallbackArgs) => Promise<void>): void;
19
+ (paymentFlowPayload: unknown): void;
20
20
  }
21
+
21
22
  interface PaymentFlowRef {
22
23
  readonly startLegacyBoxCheckout: StartLegacyBoxCheckoutFunction;
23
24
  }
25
+
24
26
  const paymentFlowRef: PaymentFlowRef = {
25
- startLegacyBoxCheckout: async (_paymentFlowPayload, callback) => {
26
- await callback({ status: "EXECUTED", final: true });
27
+ startLegacyBoxCheckout: async () => {
28
+ startLegacyBoxCheckoutListener?.({ success: true });
27
29
  },
28
30
  };
31
+
29
32
  const PaymentFlow: ForwardRefExoticComponent<RefAttributes<PaymentFlowRef>> = forwardRef<PaymentFlowRef, unknown>(
30
33
  (_props, ref) => {
31
34
  useImperativeHandle(ref, () => paymentFlowRef, []);
32
35
  return null;
33
36
  },
34
37
  );
38
+
35
39
  PaymentFlow.displayName = "PaymentFlow";
40
+
41
+ interface UsePaymentStatusManagerResult {
42
+ isLoading: boolean;
43
+ consumePayload: (callback: (payload: PaymentPayload) => void) => void;
44
+ }
45
+
46
+ const paymentStatusManagerResult: UsePaymentStatusManagerResult = {
47
+ isLoading: false,
48
+ consumePayload: (callback) => {
49
+ startLegacyBoxCheckoutListener = () => callback({ success: true } as PaymentPayload);
50
+ },
51
+ };
52
+
53
+ const usePaymentStatusManager: (section: Section) => UsePaymentStatusManagerResult = () => paymentStatusManagerResult;
54
+
36
55
  enum Section {
37
56
  BOX_CHECKOUT = "box-checkout",
38
57
  }
58
+
39
59
  export type { PaymentFlowRef };
40
- export { PaymentsQueryProvider, PaymentInstrumentSelect, PaymentFlow, Section, setPaymentsBridge, paymentFlowRef };
60
+
61
+ export {
62
+ PaymentsQueryProvider,
63
+ PaymentInstrumentSelect,
64
+ PaymentFlow,
65
+ Section,
66
+ setPaymentsBridge,
67
+ usePaymentStatusManager,
68
+ };
package/index.ts CHANGED
@@ -14,8 +14,8 @@ import { DOMAIN } from "./src/infrastructure/ui/i18n/i18n";
14
14
  import { CheckoutProjection } from "./src/projection/checkout/checkout";
15
15
  import { viewFirstAvailableCheckoutByCustomerId } from "./src/projection/checkout/viewFirstAvailableCheckoutByCustomerId";
16
16
  import { Customer } from "./src/projection/customer/customer";
17
- import { Order } from "./src/projection/order/order";
18
- import { Subscription } from "./src/projection/subscription/subscription";
17
+ import { OrderProjection } from "./src/projection/order/order";
18
+ import { SubscriptionProjection } from "./src/projection/subscription/subscription";
19
19
 
20
20
  interface FirstAvailableCheckoutByCustomerIdFunctionArgs {
21
21
  readonly customerId: string | undefined;
@@ -59,4 +59,11 @@ const bootstrap: BootstrapFunction = ({ apiUrl, getAuthToken, translations, sent
59
59
  };
60
60
 
61
61
  export { bootstrap, translationEndpoint, translationExternalEndpoint, Country, Segment, CheckoutStatus, Tradename };
62
- export type { SentryEnvironment, KameleoonEnvironment, Customer, Subscription, Order, Locale };
62
+ export type {
63
+ SentryEnvironment,
64
+ KameleoonEnvironment,
65
+ Customer,
66
+ SubscriptionProjection as Subscription,
67
+ OrderProjection as Order,
68
+ Locale,
69
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "10.1.0",
3
+ "version": "11.1.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": "false",
@@ -46,7 +46,7 @@
46
46
  "@cypress/webpack-preprocessor": "^6.0.2",
47
47
  "@lookiero/eslint-config-sty-psp": "*",
48
48
  "@lookiero/event": "^0.3",
49
- "@lookiero/payments-front": "6.0.3",
49
+ "@lookiero/payments-front": "^7.0.0",
50
50
  "@lookiero/sty-psp-jest-config": "*",
51
51
  "@lookiero/sty-psp-prettier-config": "*",
52
52
  "@lookiero/sty-psp-scripts": "*",
@@ -71,12 +71,11 @@
71
71
  "peerDependencies": {
72
72
  "@gorhom/portal": ">=1.0",
73
73
  "@lookiero/aurora": ">=6",
74
- "@lookiero/aurora-fonts": ">=2",
75
74
  "@lookiero/aurora-iconfont": ">=3",
76
75
  "@lookiero/event": "^0.3",
77
76
  "@lookiero/i18n": ">=2",
78
77
  "@lookiero/i18n-react": ">=2",
79
- "@lookiero/payments-front": "6.0.3",
78
+ "@lookiero/payments-front": ">=7",
80
79
  "apollo-boost": "0.4.4",
81
80
  "expo": ">=51",
82
81
  "expo-font": ">=12",
package/src/Expo.tsx CHANGED
@@ -1,8 +1,16 @@
1
1
  import { registerRootComponent } from "expo";
2
+ import React from "react";
2
3
  import { enableLegacyWebImplementation } from "react-native-gesture-handler";
3
4
  import "react-native-get-random-values";
4
- import { ExpoRoot } from "./ExpoRoot";
5
+ import { setTheme } from "@lookiero/sty-psp-ui";
6
+ import { Tradename } from "@lookiero/sty-sp-tradename";
5
7
 
6
8
  enableLegacyWebImplementation(true);
7
9
 
8
- registerRootComponent(ExpoRoot);
10
+ const tradename = Tradename.LOOKIERO;
11
+ setTheme({ tradename });
12
+
13
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
14
+ const { ExpoRoot } = require("./ExpoRoot");
15
+
16
+ registerRootComponent(() => <ExpoRoot tradename={tradename} />);