@lookiero/checkout 12.1.2 → 12.2.0-beta.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 (32) hide show
  1. package/dist/public/public/assets/adaptive-icon.png +0 -0
  2. package/dist/public/public/assets/favicon.png +0 -0
  3. package/dist/public/public/assets/icon.png +0 -0
  4. package/dist/public/public/assets/splash.png +0 -0
  5. package/dist/public/public/images/not-found.png +0 -0
  6. package/dist/src/infrastructure/integration/useRedirect.d.ts +7 -0
  7. package/dist/src/infrastructure/integration/useRedirect.js +1 -0
  8. package/dist/src/infrastructure/ui/Root.d.ts +2 -1
  9. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.d.ts +2 -0
  10. package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.js +5 -5
  11. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.d.ts +27 -0
  12. package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.js +97 -0
  13. package/dist/src/infrastructure/ui/routing/Routing.d.ts +2 -1
  14. package/dist/src/infrastructure/ui/routing/useBasePath.d.ts +8 -0
  15. package/dist/src/infrastructure/ui/routing/useBasePath.js +9 -0
  16. package/dist/src/infrastructure/ui/views/checkout/Checkout.d.ts +2 -1
  17. package/dist/src/infrastructure/ui/views/checkout/Checkout.js +1 -0
  18. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.d.ts +12 -0
  19. package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.js +90 -0
  20. package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.d.ts +2 -1
  21. package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.js +1 -1
  22. package/dist/src/version.d.ts +1 -1
  23. package/dist/src/version.js +1 -1
  24. package/package.json +1 -1
  25. package/src/ExpoRoot.tsx +2 -1
  26. package/src/infrastructure/integration/useRedirect.ts +9 -0
  27. package/src/infrastructure/ui/Root.tsx +2 -1
  28. package/src/infrastructure/ui/hooks/useCheckoutFlow.test.tsx +12 -7
  29. package/src/infrastructure/ui/hooks/useCheckoutFlow.tsx +6 -4
  30. package/src/infrastructure/ui/routing/Routing.tsx +2 -1
  31. package/src/infrastructure/ui/views/checkout/Checkout.tsx +3 -1
  32. package/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.tsx +3 -2
@@ -0,0 +1,7 @@
1
+ interface UseRedirectFunctionReturn {
2
+ readonly returnUrl: string;
3
+ }
4
+ interface UseRedirectFunction {
5
+ (): UseRedirectFunctionReturn;
6
+ }
7
+ export type { UseRedirectFunction };
@@ -0,0 +1 @@
1
+ export {};
@@ -11,6 +11,7 @@ import { Customer } from "../../projection/customer/customer";
11
11
  import { OrderProjection } from "../../projection/order/order";
12
12
  import { SubscriptionProjection } from "../../projection/subscription/subscription";
13
13
  import { KameleoonEnvironment } from "../ab-testing/kameleoonEnvironment";
14
+ import { UseRedirectFunction } from "../integration/useRedirect";
14
15
  interface RootFunctionArgs {
15
16
  readonly Messaging: MessagingRoot;
16
17
  readonly I18n: I18n;
@@ -33,7 +34,7 @@ interface RootProps {
33
34
  readonly tradename: Tradename;
34
35
  readonly onNotAccessible: () => void;
35
36
  readonly onCheckoutFlowSuccess: () => void;
36
- readonly useRedirect: () => Record<string, string>;
37
+ readonly useRedirect: UseRedirectFunction;
37
38
  readonly useRoutes?: typeof reactRouterUseRoutes;
38
39
  }
39
40
  declare const root: RootFunction;
@@ -2,6 +2,7 @@ import { ReactNode } from "react";
2
2
  import { CheckoutProjection } from "../../../projection/checkout/checkout";
3
3
  import { OrderProjection } from "../../../projection/order/order";
4
4
  import { SubscriptionProjection } from "../../../projection/subscription/subscription";
5
+ import { UseRedirectFunction } from "../../integration/useRedirect";
5
6
  type CheckoutFlowStatus = "idle" | "loading" | "success" | "error";
6
7
  interface CheckoutFlowFunction {
7
8
  (): Promise<void>;
@@ -17,6 +18,7 @@ interface UseCheckoutFlowArgs {
17
18
  readonly subscription: SubscriptionProjection;
18
19
  readonly getAuthToken: () => Promise<string>;
19
20
  readonly onSuccess: () => void;
21
+ readonly useRedirect: UseRedirectFunction;
20
22
  }
21
23
  interface UseCheckoutFlowFunction {
22
24
  (args: UseCheckoutFlowArgs): CheckoutFlowReturn;
@@ -12,14 +12,14 @@ import { useViewPaymentFlowPayloadByCheckoutId } from "../../projection/payment/
12
12
  import { useViewPricingByCheckoutId } from "../../projection/pricing/react/useViewPricingByCheckoutId";
13
13
  import { useTrackCheckout } from "../../tracking/useTrackCheckout";
14
14
  import { I18nMessages } from "../i18n/i18n";
15
- import { Routes } from "../routing/routes";
16
15
  import { usePaymentInstrumentEvents } from "./usePaymentInstrumentEvents";
17
16
  import { useQueryBus } from "./useQueryBus";
18
17
  import { useStaticInfo } from "./useStaticInfo";
19
- const useCheckoutFlow = ({ checkout: checkoutProjection, order: orderProjection, subscription: subscriptionProjection, getAuthToken, onSuccess, }) => {
18
+ const useCheckoutFlow = ({ checkout: checkoutProjection, order: orderProjection, subscription: subscriptionProjection, getAuthToken, onSuccess, useRedirect, }) => {
20
19
  const logger = useLogger();
21
20
  const queryBus = useQueryBus();
22
- const { customer: { customerId, country, segment, name, email }, basePath, tradename, } = useStaticInfo();
21
+ const { customer: { customerId, country, segment, name, email }, tradename, } = useStaticInfo();
22
+ const { returnUrl } = useRedirect();
23
23
  const paymentFlowRef = useRef(null);
24
24
  const [paymentFlowPayload] = useViewPaymentFlowPayloadByCheckoutId({
25
25
  checkoutId: checkoutProjection?.id,
@@ -73,14 +73,14 @@ const useCheckoutFlow = ({ checkout: checkoutProjection, order: orderProjection,
73
73
  paymentFlowRef.current?.startLegacyBoxCheckout({
74
74
  ...paymentFlowPayload,
75
75
  userInformation: { email, name },
76
- returnUrl: `${basePath}/${Routes.CHECKOUT}`,
76
+ returnUrl,
77
77
  });
78
78
  }, [
79
79
  checkoutProjection?.checkoutBookingId,
80
80
  paymentFlowPayload,
81
81
  email,
82
82
  name,
83
- basePath,
83
+ returnUrl,
84
84
  sizeChangeEnabled,
85
85
  blockCheckoutBooking,
86
86
  queryBus,
@@ -0,0 +1,27 @@
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 };
@@ -0,0 +1,97 @@
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 };
@@ -8,6 +8,7 @@ import { Customer } from "../../../projection/customer/customer";
8
8
  import { OrderProjection } from "../../../projection/order/order";
9
9
  import { SubscriptionProjection } from "../../../projection/subscription/subscription";
10
10
  import { KameleoonEnvironment } from "../../ab-testing/kameleoonEnvironment";
11
+ import { UseRedirectFunction } from "../../integration/useRedirect";
11
12
  interface RoutingProps {
12
13
  readonly basePath?: string;
13
14
  readonly customer: Customer;
@@ -22,7 +23,7 @@ interface RoutingProps {
22
23
  readonly onNotAccessible: () => void;
23
24
  readonly onCheckoutFlowSuccess: () => void;
24
25
  readonly onI18nError?: (err: Error) => void;
25
- readonly useRedirect: () => Record<string, string>;
26
+ readonly useRedirect: UseRedirectFunction;
26
27
  readonly useRoutes: typeof reactRouterUseRoutes;
27
28
  }
28
29
  /**
@@ -0,0 +1,8 @@
1
+ import { FC } from "react";
2
+ interface BasePathProviderProps {
3
+ readonly children: JSX.Element;
4
+ readonly basePath: string;
5
+ }
6
+ export declare const BasePathProvider: FC<BasePathProviderProps>;
7
+ export declare const useBasePath: () => string;
8
+ export {};
@@ -0,0 +1,9 @@
1
+ import React, { createContext, useContext } from "react";
2
+ import invariant from "tiny-invariant";
3
+ const BasePathContext = createContext(null);
4
+ export const BasePathProvider = ({ basePath, children }) => (React.createElement(BasePathContext.Provider, { value: basePath }, children));
5
+ export const useBasePath = () => {
6
+ const basePath = useContext(BasePathContext);
7
+ invariant(basePath !== null, "Your are trying to use the useBasePath hook without wrapping your app with the <BasePathProvider>.");
8
+ return basePath;
9
+ };
@@ -2,13 +2,14 @@ import { FC } from "react";
2
2
  import { Layout as UiLayout } from "@lookiero/sty-psp-ui";
3
3
  import { OrderProjection } from "../../../../projection/order/order";
4
4
  import { SubscriptionProjection } from "../../../../projection/subscription/subscription";
5
+ import { UseRedirectFunction } from "../../../integration/useRedirect";
5
6
  interface CheckoutProps {
6
7
  readonly layout: UiLayout;
7
8
  readonly order: OrderProjection;
8
9
  readonly subscription: SubscriptionProjection;
9
10
  readonly getAuthToken: () => Promise<string>;
10
11
  readonly onCheckoutFlowSuccess: () => void;
11
- readonly useRedirect: () => Record<string, string>;
12
+ readonly useRedirect: UseRedirectFunction;
12
13
  }
13
14
  declare const Checkout: FC<CheckoutProps>;
14
15
  export { Checkout };
@@ -41,6 +41,7 @@ const Checkout = ({ layout: Layout, order, subscription, getAuthToken, useRedire
41
41
  subscription,
42
42
  getAuthToken,
43
43
  onSuccess: onCheckoutFlowSuccess,
44
+ useRedirect,
44
45
  });
45
46
  useTrackPageView({
46
47
  page: TrackingPage.CHECKOUT,
@@ -0,0 +1,12 @@
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 };
@@ -0,0 +1,90 @@
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
+ import { useBasePath } from "../../../../routing/useBasePath";
17
+ const CheckoutPaymentModal = ({ coupon, isFirstOrder, subscription, orderNumber, getAuthToken, onCheckoutSubmitted, }) => {
18
+ const paymentFlowRef = useRef(null);
19
+ const logger = useLogger();
20
+ const { customer: { customerId, country, segment }, } = useStaticInfo();
21
+ const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
22
+ const [paymentFlowPayload] = useViewPaymentFlowPayloadByCheckoutId({
23
+ checkoutId: checkout?.id,
24
+ });
25
+ const [sizeChangeEnabled] = useViewIsSizeChangeEnabledByCheckoutId({ checkoutId: checkout?.id });
26
+ const [pricing] = useViewPricingByCheckoutId({
27
+ checkoutId: checkout?.id,
28
+ queryOptions: { refetchOnMount: true },
29
+ });
30
+ const [authToken, setAuthToken] = useState();
31
+ useEffect(() => {
32
+ const loadAuthToken = async () => setAuthToken(await getAuthToken());
33
+ loadAuthToken();
34
+ }, [getAuthToken]);
35
+ const basePath = useBasePath();
36
+ const navigate = useNavigate();
37
+ const trackCheckout = useTrackCheckout({
38
+ page: TrackingPage.CHECKOUT,
39
+ checkoutId: checkout?.id,
40
+ country,
41
+ segment,
42
+ });
43
+ const handleOnSubmitCheckoutError = useCallback(() => navigate(`${basePath}/${Routes.CHECKOUT}`, { replace: true }), [basePath, navigate]);
44
+ const handleOnSubmitCheckoutSuccess = useCallback(() => {
45
+ const checkoutItemsKept = checkout?.items.filter((checkoutItem) => checkoutItem.status === CheckoutItemStatus.KEPT || checkoutItem.status === CheckoutItemStatus.REPLACED);
46
+ const totalReplacedFor = checkoutItemsKept?.filter(({ replacedFor }) => Boolean(replacedFor)).length || 0;
47
+ trackCheckout({
48
+ totalCheckoutItemsKept: checkoutItemsKept?.length || 0,
49
+ pendingToPay: pricing?.pendingToPay.amount / 100,
50
+ coupon,
51
+ currencyCode: pricing?.pendingToPay.currency,
52
+ isFirstOrder,
53
+ orderNumber,
54
+ totalReplacedFor,
55
+ subscription,
56
+ userId: customerId,
57
+ });
58
+ onCheckoutSubmitted?.();
59
+ }, [
60
+ checkout?.items,
61
+ coupon,
62
+ customerId,
63
+ isFirstOrder,
64
+ onCheckoutSubmitted,
65
+ orderNumber,
66
+ pricing?.pendingToPay.amount,
67
+ pricing?.pendingToPay.currency,
68
+ subscription,
69
+ trackCheckout,
70
+ ]);
71
+ const [submitCheckout] = useSubmitCheckout({
72
+ checkoutId: checkout?.id,
73
+ checkoutBookingId: checkout?.checkoutBookingId,
74
+ paymentFlowRef,
75
+ onError: handleOnSubmitCheckoutError,
76
+ onSuccess: handleOnSubmitCheckoutSuccess,
77
+ logger,
78
+ });
79
+ useEffect(() => {
80
+ if (paymentFlowPayload && sizeChangeEnabled !== undefined && pricing !== undefined) {
81
+ submitCheckout({ paymentFlowPayload, sizeChangeEnabled });
82
+ }
83
+ }, [paymentFlowPayload, pricing, sizeChangeEnabled, submitCheckout]);
84
+ const dependenciesLoadedStatuses = [QueryStatus.ERROR, QueryStatus.SUCCESS];
85
+ const dependenciesLoaded = (dependenciesLoadedStatuses.includes(checkoutStatus) || checkout) && authToken;
86
+ if (!dependenciesLoaded)
87
+ return null;
88
+ return React.createElement(PaymentFlow, { ref: paymentFlowRef, token: authToken });
89
+ };
90
+ export { CheckoutPaymentModal };
@@ -1,6 +1,7 @@
1
1
  import { FC } from "react";
2
+ import { UseRedirectFunction } from "../../../../../integration/useRedirect";
2
3
  interface PaymentInstrumentProps {
3
- readonly useRedirect: () => Record<string, string>;
4
+ readonly useRedirect: UseRedirectFunction;
4
5
  }
5
6
  declare const PaymentInstrument: FC<PaymentInstrumentProps>;
6
7
  export { PaymentInstrument };
@@ -4,7 +4,7 @@ import { useStaticInfo } from "../../../../hooks/useStaticInfo";
4
4
  const PaymentInstrument = ({ useRedirect }) => {
5
5
  const { returnUrl } = useRedirect();
6
6
  const { customer } = useStaticInfo();
7
- return (React.createElement(PaymentInstrumentSelect, { beforeRedirect: returnUrl ? () => Promise.resolve(returnUrl) : undefined, hasError: false, section: Section.BOX_CHECKOUT, userInformation: {
7
+ return (React.createElement(PaymentInstrumentSelect, { beforeRedirect: () => Promise.resolve(returnUrl), hasError: false, section: Section.BOX_CHECKOUT, userInformation: {
8
8
  email: customer.email,
9
9
  name: customer.name,
10
10
  }, showSingleUsePaymentMethods: true }));
@@ -1 +1 @@
1
- export declare const VERSION = "12.1.2";
1
+ export declare const VERSION = "12.2.0-beta.0";
@@ -1 +1 @@
1
- export const VERSION = "12.1.2";
1
+ export const VERSION = "12.2.0-beta.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "12.1.2",
3
+ "version": "12.2.0-beta.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": "false",
package/src/ExpoRoot.tsx CHANGED
@@ -17,6 +17,7 @@ import { Tradename } from "@lookiero/sty-sp-tradename";
17
17
  import { KameleoonEnvironment } from "./infrastructure/ab-testing/kameleoonEnvironment";
18
18
  import { bootstrap as checkoutBootstrap } from "./infrastructure/delivery/bootstrap";
19
19
  import { bootstrap as checkoutMockBootstrap } from "./infrastructure/delivery/bootstrap.mock";
20
+ import { UseRedirectFunction } from "./infrastructure/integration/useRedirect";
20
21
  import { root } from "./infrastructure/ui/Root";
21
22
  import { DOMAIN } from "./infrastructure/ui/i18n/i18n";
22
23
  import { Router } from "./infrastructure/ui/routing/router/Router";
@@ -79,7 +80,7 @@ const translations: EndpointFunction[] = [
79
80
  })(locale),
80
81
  ];
81
82
 
82
- const useRedirect: () => Record<string, string> = () => ({
83
+ const useRedirect: UseRedirectFunction = () => ({
83
84
  returnUrl: "https://web2.dev.aws.lookiero.es/user/",
84
85
  });
85
86
 
@@ -0,0 +1,9 @@
1
+ interface UseRedirectFunctionReturn {
2
+ readonly returnUrl: string;
3
+ }
4
+
5
+ interface UseRedirectFunction {
6
+ (): UseRedirectFunctionReturn;
7
+ }
8
+
9
+ export type { UseRedirectFunction };
@@ -13,6 +13,7 @@ import { Customer } from "../../projection/customer/customer";
13
13
  import { OrderProjection } from "../../projection/order/order";
14
14
  import { SubscriptionProjection } from "../../projection/subscription/subscription";
15
15
  import { KameleoonEnvironment } from "../ab-testing/kameleoonEnvironment";
16
+ import { UseRedirectFunction } from "../integration/useRedirect";
16
17
  import { QueryBusProvider } from "./hooks/useQueryBus";
17
18
  import { Routing } from "./routing/Routing";
18
19
 
@@ -40,7 +41,7 @@ interface RootProps {
40
41
  readonly tradename: Tradename;
41
42
  readonly onNotAccessible: () => void;
42
43
  readonly onCheckoutFlowSuccess: () => void;
43
- readonly useRedirect: () => Record<string, string>;
44
+ readonly useRedirect: UseRedirectFunction;
44
45
  readonly useRoutes?: typeof reactRouterUseRoutes;
45
46
  }
46
47
 
@@ -11,6 +11,7 @@ import { OrderProjection } from "../../../projection/order/order";
11
11
  import { SubscriptionProjection } from "../../../projection/subscription/subscription";
12
12
  import { useSubmitCheckout } from "../../domain/checkout/react/useSubmitCheckout";
13
13
  import { useBlockCheckoutBooking } from "../../domain/checkoutBooking/react/useBlockCheckoutBooking";
14
+ import { UseRedirectFunction } from "../../integration/useRedirect";
14
15
  import { checkout } from "../../projection/checkout/checkout.mock";
15
16
  import { useViewIsSizeChangeEnabledByCheckoutId } from "../../projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId";
16
17
  import { paymentFlowPayload as mockPaymentFlowPayload } from "../../projection/payment/paymentFlowPayload.mock";
@@ -18,11 +19,15 @@ import { useViewPaymentFlowPayloadByCheckoutId } from "../../projection/payment/
18
19
  import { pricing } from "../../projection/pricing/pricing.mock";
19
20
  import { useViewPricingByCheckoutId } from "../../projection/pricing/react/useViewPricingByCheckoutId";
20
21
  import { I18nMessages } from "../i18n/i18n";
21
- import { Routes } from "../routing/routes";
22
22
  import { useCheckoutFlow as sut } from "./useCheckoutFlow";
23
23
  import { usePaymentInstrumentEvents } from "./usePaymentInstrumentEvents";
24
24
  import { useQueryBus } from "./useQueryBus";
25
25
 
26
+ const returnUrl = "/checkout";
27
+ const useRedirect: UseRedirectFunction = () => ({
28
+ returnUrl,
29
+ });
30
+
26
31
  const getAuthToken = () => Promise.resolve("token");
27
32
  const mockCheckout = checkout({
28
33
  items: [
@@ -119,7 +124,7 @@ describe("useCheckoutFlow custom hook", () => {
119
124
  });
120
125
 
121
126
  const { result } = renderHook(() =>
122
- sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess }),
127
+ sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess, useRedirect }),
123
128
  );
124
129
 
125
130
  let checkoutFlow: () => void, status, paymentFlowComponent;
@@ -145,7 +150,7 @@ describe("useCheckoutFlow custom hook", () => {
145
150
  expect.objectContaining({
146
151
  ...mockPaymentFlowPayload,
147
152
  userInformation: { email, name },
148
- returnUrl: `${basePath}/${Routes.CHECKOUT}`,
153
+ returnUrl,
149
154
  }),
150
155
  );
151
156
  expect(mockSubmitCheckout).toHaveBeenCalled();
@@ -175,7 +180,7 @@ describe("useCheckoutFlow custom hook", () => {
175
180
  });
176
181
 
177
182
  const { result } = renderHook(() =>
178
- sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess }),
183
+ sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess, useRedirect }),
179
184
  );
180
185
 
181
186
  let checkoutFlow: () => void, status, paymentFlowComponent;
@@ -201,7 +206,7 @@ describe("useCheckoutFlow custom hook", () => {
201
206
  expect.objectContaining({
202
207
  ...mockPaymentFlowPayload,
203
208
  userInformation: { email, name },
204
- returnUrl: `${basePath}/${Routes.CHECKOUT}`,
209
+ returnUrl,
205
210
  }),
206
211
  );
207
212
  expect(mockSubmitCheckout).toHaveBeenCalled();
@@ -231,7 +236,7 @@ describe("useCheckoutFlow custom hook", () => {
231
236
  });
232
237
 
233
238
  const { result } = renderHook(() =>
234
- sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess }),
239
+ sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess, useRedirect }),
235
240
  );
236
241
 
237
242
  let checkoutFlow: () => void, status, paymentFlowComponent;
@@ -278,7 +283,7 @@ describe("useCheckoutFlow custom hook", () => {
278
283
  });
279
284
 
280
285
  const { result } = renderHook(() =>
281
- sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess }),
286
+ sut({ checkout: mockCheckout, order, subscription, getAuthToken, onSuccess: mockOnSuccess, useRedirect }),
282
287
  );
283
288
 
284
289
  let checkoutFlow: () => void, status, paymentFlowComponent;
@@ -15,12 +15,12 @@ import { SubscriptionProjection } from "../../../projection/subscription/subscri
15
15
  import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
16
16
  import { useSubmitCheckout } from "../../domain/checkout/react/useSubmitCheckout";
17
17
  import { useBlockCheckoutBooking } from "../../domain/checkoutBooking/react/useBlockCheckoutBooking";
18
+ import { UseRedirectFunction } from "../../integration/useRedirect";
18
19
  import { useViewIsSizeChangeEnabledByCheckoutId } from "../../projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId";
19
20
  import { useViewPaymentFlowPayloadByCheckoutId } from "../../projection/payment/react/useViewPaymentFlowPayloadByCheckoutId";
20
21
  import { useViewPricingByCheckoutId } from "../../projection/pricing/react/useViewPricingByCheckoutId";
21
22
  import { useTrackCheckout } from "../../tracking/useTrackCheckout";
22
23
  import { I18nMessages } from "../i18n/i18n";
23
- import { Routes } from "../routing/routes";
24
24
  import { usePaymentInstrumentEvents } from "./usePaymentInstrumentEvents";
25
25
  import { useQueryBus } from "./useQueryBus";
26
26
  import { useStaticInfo } from "./useStaticInfo";
@@ -43,6 +43,7 @@ interface UseCheckoutFlowArgs {
43
43
  readonly subscription: SubscriptionProjection;
44
44
  readonly getAuthToken: () => Promise<string>;
45
45
  readonly onSuccess: () => void;
46
+ readonly useRedirect: UseRedirectFunction;
46
47
  }
47
48
 
48
49
  interface UseCheckoutFlowFunction {
@@ -55,14 +56,15 @@ const useCheckoutFlow: UseCheckoutFlowFunction = ({
55
56
  subscription: subscriptionProjection,
56
57
  getAuthToken,
57
58
  onSuccess,
59
+ useRedirect,
58
60
  }) => {
59
61
  const logger = useLogger();
60
62
  const queryBus = useQueryBus();
61
63
  const {
62
64
  customer: { customerId, country, segment, name, email },
63
- basePath,
64
65
  tradename,
65
66
  } = useStaticInfo();
67
+ const { returnUrl } = useRedirect();
66
68
  const paymentFlowRef = useRef<PaymentFlowRef>(null);
67
69
  const [paymentFlowPayload] = useViewPaymentFlowPayloadByCheckoutId({
68
70
  checkoutId: checkoutProjection?.id as string,
@@ -122,14 +124,14 @@ const useCheckoutFlow: UseCheckoutFlowFunction = ({
122
124
  paymentFlowRef.current?.startLegacyBoxCheckout({
123
125
  ...paymentFlowPayload,
124
126
  userInformation: { email, name },
125
- returnUrl: `${basePath}/${Routes.CHECKOUT}`,
127
+ returnUrl,
126
128
  } as unknown as LegacyBoxCheckoutStrategyPayload);
127
129
  }, [
128
130
  checkoutProjection?.checkoutBookingId,
129
131
  paymentFlowPayload,
130
132
  email,
131
133
  name,
132
- basePath,
134
+ returnUrl,
133
135
  sizeChangeEnabled,
134
136
  blockCheckoutBooking,
135
137
  queryBus,
@@ -10,6 +10,7 @@ import { Customer } from "../../../projection/customer/customer";
10
10
  import { OrderProjection } from "../../../projection/order/order";
11
11
  import { SubscriptionProjection } from "../../../projection/subscription/subscription";
12
12
  import { KameleoonEnvironment } from "../../ab-testing/kameleoonEnvironment";
13
+ import { UseRedirectFunction } from "../../integration/useRedirect";
13
14
  import { StaticInfoProvider } from "../hooks/useStaticInfo";
14
15
  import { App } from "../views/App";
15
16
  import { Checkout } from "../views/checkout/Checkout";
@@ -35,7 +36,7 @@ interface RoutingProps {
35
36
  readonly onNotAccessible: () => void;
36
37
  readonly onCheckoutFlowSuccess: () => void;
37
38
  readonly onI18nError?: (err: Error) => void;
38
- readonly useRedirect: () => Record<string, string>;
39
+ readonly useRedirect: UseRedirectFunction;
39
40
  readonly useRoutes: typeof reactRouterUseRoutes;
40
41
  }
41
42
 
@@ -9,6 +9,7 @@ import { Layout as UiLayout, Sticky, useScreenSize } from "@lookiero/sty-psp-ui"
9
9
  import { CheckoutItemStatus } from "../../../../domain/checkoutItem/model/checkoutItem";
10
10
  import { OrderProjection } from "../../../../projection/order/order";
11
11
  import { SubscriptionProjection } from "../../../../projection/subscription/subscription";
12
+ import { UseRedirectFunction } from "../../../integration/useRedirect";
12
13
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
13
14
  import { useViewPricingByCheckoutId } from "../../../projection/pricing/react/useViewPricingByCheckoutId";
14
15
  import { TrackingPage } from "../../../tracking/tracking";
@@ -33,7 +34,7 @@ interface CheckoutProps {
33
34
  readonly subscription: SubscriptionProjection;
34
35
  readonly getAuthToken: () => Promise<string>;
35
36
  readonly onCheckoutFlowSuccess: () => void;
36
- readonly useRedirect: () => Record<string, string>;
37
+ readonly useRedirect: UseRedirectFunction;
37
38
  }
38
39
 
39
40
  const Checkout: FC<CheckoutProps> = ({
@@ -68,6 +69,7 @@ const Checkout: FC<CheckoutProps> = ({
68
69
  subscription,
69
70
  getAuthToken,
70
71
  onSuccess: onCheckoutFlowSuccess,
72
+ useRedirect,
71
73
  });
72
74
 
73
75
  useTrackPageView({
@@ -1,9 +1,10 @@
1
1
  import React, { FC } from "react";
2
2
  import { PaymentInstrumentSelect, Section } from "@lookiero/payments-front";
3
+ import { UseRedirectFunction } from "../../../../../integration/useRedirect";
3
4
  import { useStaticInfo } from "../../../../hooks/useStaticInfo";
4
5
 
5
6
  interface PaymentInstrumentProps {
6
- readonly useRedirect: () => Record<string, string>;
7
+ readonly useRedirect: UseRedirectFunction;
7
8
  }
8
9
  const PaymentInstrument: FC<PaymentInstrumentProps> = ({ useRedirect }) => {
9
10
  const { returnUrl } = useRedirect();
@@ -11,7 +12,7 @@ const PaymentInstrument: FC<PaymentInstrumentProps> = ({ useRedirect }) => {
11
12
 
12
13
  return (
13
14
  <PaymentInstrumentSelect
14
- beforeRedirect={returnUrl ? () => Promise.resolve(returnUrl) : undefined}
15
+ beforeRedirect={() => Promise.resolve(returnUrl)}
15
16
  hasError={false}
16
17
  section={Section.BOX_CHECKOUT}
17
18
  userInformation={{