@lookiero/checkout 10.0.1 → 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.
- package/cypress/integration/checkout.spec.ts +0 -3
- package/dist/fake-dependencies/@lookiero/payments-front/index.d.ts +8 -7
- package/dist/fake-dependencies/@lookiero/payments-front/index.js +11 -3
- package/dist/index.d.ts +3 -3
- package/dist/src/ExpoRoot.js +17 -12
- package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.d.ts +1 -1
- package/dist/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.js +2 -0
- package/dist/src/infrastructure/projection/checkout/checkout.mock.d.ts +1 -0
- package/dist/src/infrastructure/projection/checkout/checkout.mock.js +3 -3
- package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.d.ts +1 -1
- package/dist/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.js +2 -1
- package/dist/src/infrastructure/tracking/tracking.d.ts +2 -2
- package/dist/src/infrastructure/tracking/useTrackCheckout.d.ts +10 -17
- package/dist/src/infrastructure/tracking/useTrackCheckout.js +27 -12
- package/dist/src/infrastructure/ui/Root.d.ts +6 -6
- package/dist/src/infrastructure/ui/Root.js +2 -3
- package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.d.ts +26 -0
- package/dist/src/infrastructure/ui/hooks/useCheckoutFlow.js +127 -0
- package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.d.ts +3 -2
- package/dist/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.js +17 -26
- package/dist/src/infrastructure/ui/i18n/i18n.d.ts +1 -0
- package/dist/src/infrastructure/ui/i18n/i18n.js +1 -0
- package/dist/src/infrastructure/ui/routing/CheckoutMiddleware.js +1 -12
- package/dist/src/infrastructure/ui/routing/Routing.d.ts +5 -5
- package/dist/src/infrastructure/ui/routing/Routing.js +2 -10
- package/dist/src/infrastructure/ui/routing/routes.d.ts +0 -1
- package/dist/src/infrastructure/ui/routing/routes.js +0 -1
- package/dist/src/infrastructure/ui/views/App.js +5 -6
- package/dist/src/infrastructure/ui/views/checkout/Checkout.d.ts +7 -2
- package/dist/src/infrastructure/ui/views/checkout/Checkout.js +20 -9
- package/dist/src/infrastructure/ui/views/checkout/Checkout.style.d.ts +3 -0
- package/dist/src/infrastructure/ui/views/checkout/Checkout.style.js +3 -0
- package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.js +7 -7
- package/dist/src/projection/customer/customer.d.ts +2 -0
- package/dist/src/projection/order/order.d.ts +1 -1
- package/dist/src/projection/subscription/subscription.d.ts +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/fake-dependencies/@lookiero/payments-front/index.tsx +36 -8
- package/index.ts +10 -3
- package/package.json +4 -4
- package/src/ExpoRoot.tsx +43 -36
- package/src/infrastructure/domain/checkoutBooking/react/useBlockCheckoutBooking.ts +4 -1
- package/src/infrastructure/projection/checkout/checkout.mock.ts +8 -3
- package/src/infrastructure/projection/pricing/react/useViewPricingByCheckoutId.ts +3 -2
- package/src/infrastructure/tracking/tracking.ts +2 -2
- package/src/infrastructure/tracking/useTrackCheckout.test.tsx +51 -24
- package/src/infrastructure/tracking/useTrackCheckout.ts +66 -56
- package/src/infrastructure/ui/Root.tsx +9 -9
- package/src/infrastructure/ui/components/templates/header/itemHeader/ItemHeader.tsx +1 -0
- package/src/infrastructure/ui/hooks/useCheckoutFlow.test.tsx +302 -0
- package/src/infrastructure/ui/hooks/useCheckoutFlow.tsx +203 -0
- package/src/infrastructure/ui/hooks/usePaymentInstrumentEvents.ts +18 -60
- package/src/infrastructure/ui/i18n/i18n.ts +1 -0
- package/src/infrastructure/ui/routing/CheckoutMiddleware.test.tsx +0 -11
- package/src/infrastructure/ui/routing/CheckoutMiddleware.tsx +1 -15
- package/src/infrastructure/ui/routing/Routing.tsx +14 -25
- package/src/infrastructure/ui/routing/routes.ts +0 -1
- package/src/infrastructure/ui/views/App.tsx +5 -13
- package/src/infrastructure/ui/views/checkout/Checkout.style.ts +3 -0
- package/src/infrastructure/ui/views/checkout/Checkout.test.tsx +51 -43
- package/src/infrastructure/ui/views/checkout/Checkout.tsx +51 -13
- package/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.tsx +8 -8
- package/src/projection/customer/customer.ts +2 -0
- package/src/projection/order/order.ts +1 -1
- package/src/projection/subscription/subscription.ts +1 -1
- package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.d.ts +0 -27
- package/dist/src/infrastructure/ui/hooks/useSubmitCheckout.js +0 -97
- package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.d.ts +0 -12
- package/dist/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.js +0 -88
- package/src/infrastructure/ui/hooks/useSubmitCheckout.test.ts +0 -297
- package/src/infrastructure/ui/hooks/useSubmitCheckout.ts +0 -169
- package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.test.tsx +0 -134
- package/src/infrastructure/ui/views/checkout/components/checkoutPaymentModal/CheckoutPaymentModal.tsx +0 -124
|
@@ -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 {
|
|
9
|
-
import {
|
|
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:
|
|
15
|
-
readonly subscription:
|
|
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
|
|
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,
|
|
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,
|
|
@@ -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 {
|
|
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(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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 = ({
|
|
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
|
-
|
|
50
|
-
}, [
|
|
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
|
-
|
|
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 };
|
package/dist/src/infrastructure/ui/views/checkout/components/paymentInstrument/PaymentInstrument.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { PaymentInstrumentSelect, Section } from "@lookiero/payments-front";
|
|
3
|
-
import {
|
|
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
|
|
9
|
-
|
|
10
|
-
|
|
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 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
type Subscription = "o" | "m" | "b" | "q";
|
|
2
|
-
export type { Subscription };
|
|
2
|
+
export type { Subscription as SubscriptionProjection };
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "
|
|
1
|
+
export declare const VERSION = "11.0.0";
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "
|
|
1
|
+
export const VERSION = "11.0.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
|
-
|
|
15
|
-
readonly status: string;
|
|
16
|
-
readonly final: boolean;
|
|
17
|
-
}
|
|
17
|
+
|
|
18
18
|
interface StartLegacyBoxCheckoutFunction {
|
|
19
|
-
(paymentFlowPayload: unknown
|
|
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 (
|
|
26
|
-
|
|
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
|
-
|
|
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 {
|
|
18
|
-
import {
|
|
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 {
|
|
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": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"sideEffects": "false",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@lookiero/sty-psp-segment": "^0.1",
|
|
33
33
|
"@lookiero/sty-psp-storage": "^0.2",
|
|
34
34
|
"@lookiero/sty-psp-tracking": "^0.2",
|
|
35
|
-
"@lookiero/sty-sp-tradename": "^0
|
|
35
|
+
"@lookiero/sty-sp-tradename": "^1.0",
|
|
36
36
|
"@lookiero/sty-psp-ui": "^0.7",
|
|
37
37
|
"@lookiero/sty-psp-ui-settings": "^0.2",
|
|
38
38
|
"@lookiero/sty-psp-units": "^0.1",
|
|
@@ -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": "
|
|
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": "*",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@lookiero/event": "^0.3",
|
|
77
77
|
"@lookiero/i18n": ">=2",
|
|
78
78
|
"@lookiero/i18n-react": ">=2",
|
|
79
|
-
"@lookiero/payments-front": "
|
|
79
|
+
"@lookiero/payments-front": ">=7",
|
|
80
80
|
"apollo-boost": "0.4.4",
|
|
81
81
|
"expo": ">=51",
|
|
82
82
|
"expo-font": ">=12",
|
package/src/ExpoRoot.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PortalProvider } from "@gorhom/portal";
|
|
1
2
|
import { useFonts } from "expo-font";
|
|
2
3
|
import "expo/build/Expo.fx";
|
|
3
4
|
import React, { FC, useCallback, useState } from "react";
|
|
@@ -21,22 +22,24 @@ 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";
|
|
23
24
|
import { Customer } from "./projection/customer/customer";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
25
|
+
import { OrderProjection } from "./projection/order/order";
|
|
26
|
+
import { SubscriptionProjection } from "./projection/subscription/subscription";
|
|
26
27
|
import { VERSION } from "./version";
|
|
27
28
|
|
|
28
|
-
const locale: Locale = Locale.
|
|
29
|
-
const subscription:
|
|
30
|
-
const order:
|
|
29
|
+
const locale: Locale = Locale.es_ES;
|
|
30
|
+
const subscription: SubscriptionProjection = "b";
|
|
31
|
+
const order: OrderProjection = {
|
|
31
32
|
isFirstOrder: false,
|
|
32
33
|
orderNumber: 3687582,
|
|
33
34
|
coupon: "MYLOOKIERO",
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
const customer: Customer = {
|
|
37
|
-
customerId: "
|
|
38
|
-
country: Country.
|
|
38
|
+
customerId: "9cfb056e-6008-44b1-9075-320479bf92ac",
|
|
39
|
+
country: Country.NL,
|
|
39
40
|
segment: Segment.WOMEN,
|
|
41
|
+
email: "email@example.com",
|
|
42
|
+
name: "Adèle Léonce Émilie",
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
const sentryConfig: SentryEnvironment = {
|
|
@@ -53,7 +56,7 @@ const apiUrl =
|
|
|
53
56
|
? "/local-to-dev"
|
|
54
57
|
: "/checkout/api";
|
|
55
58
|
const authToken =
|
|
56
|
-
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
|
|
59
|
+
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjU2NDk0NjYsImV4cCI6MTc0MjQ3MDI5OSwiZGlzcGxheU5hbWUiOiJNaWtlbCIsImNvdW50cnlfY29kZSI6IkVTIiwiYWNjZXNzVmlhIjoiZW1haWwiLCJzdWJzY3JpcHRpb25TdGFydGluZ0RhdGUiOiIyMDI0LTExLTExIiwiaW1wZXJzb25hdGVkIjpmYWxzZSwidXVpZCI6ImQzYzIzNTRiLTk4MTEtNDZkNC1iMmJhLTVmYmEwMTJlZDk0ZCIsImlhdCI6MTc0MDA1MTA5OX0.AkuUZTsn9mgplQwatg0dPKyv1Hsc6r267UMahxMH19g";
|
|
57
60
|
const getAuthToken = () => Promise.resolve(authToken);
|
|
58
61
|
|
|
59
62
|
const externalTranslationsUrl =
|
|
@@ -94,6 +97,7 @@ setPaymentsBridge({
|
|
|
94
97
|
useFeatureFlags: () => ({}),
|
|
95
98
|
locale: () => Promise.resolve("es-ES"),
|
|
96
99
|
scrollView: ScrollView,
|
|
100
|
+
hostUrl: "",
|
|
97
101
|
});
|
|
98
102
|
|
|
99
103
|
const kameleoonConfig: KameleoonEnvironment = {
|
|
@@ -131,36 +135,39 @@ const ExpoRoot: FC = () => {
|
|
|
131
135
|
const onNotAccessible = useCallback(() => setIsAccessible(false), []);
|
|
132
136
|
|
|
133
137
|
return fontsLoaded ? (
|
|
134
|
-
<
|
|
135
|
-
<
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
+
<PortalProvider>
|
|
139
|
+
<PaymentsQueryProvider>
|
|
140
|
+
<EventProvider>
|
|
141
|
+
<Aurora>
|
|
142
|
+
{isAccessible === false && <Text heading={true}>Checkout is not accessible!</Text>}
|
|
138
143
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
<Router>
|
|
145
|
+
<Routes>
|
|
146
|
+
<Route
|
|
147
|
+
path="/checkout/*"
|
|
148
|
+
element={
|
|
149
|
+
<Root
|
|
150
|
+
basePath="/checkout"
|
|
151
|
+
customer={customer}
|
|
152
|
+
layout={DummyLayout}
|
|
153
|
+
locale={locale}
|
|
154
|
+
order={order}
|
|
155
|
+
subscription={subscription}
|
|
156
|
+
tradename={Tradename.LOOKIERO}
|
|
157
|
+
useRedirect={useRedirect}
|
|
158
|
+
onCheckoutFlowSuccess={() => console.log("Checkout flow success!")}
|
|
159
|
+
onNotAccessible={onNotAccessible}
|
|
160
|
+
/>
|
|
161
|
+
}
|
|
162
|
+
/>
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
<Route element={<Navigate to="/checkout" replace />} path="*" />
|
|
165
|
+
</Routes>
|
|
166
|
+
</Router>
|
|
167
|
+
</Aurora>
|
|
168
|
+
</EventProvider>
|
|
169
|
+
</PaymentsQueryProvider>
|
|
170
|
+
</PortalProvider>
|
|
164
171
|
) : null;
|
|
165
172
|
};
|
|
166
173
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
|
+
import invariant from "tiny-invariant";
|
|
2
3
|
import { CommandStatus, useCommand } from "@lookiero/messaging-react";
|
|
3
4
|
import { Logger } from "@lookiero/sty-psp-logging";
|
|
4
5
|
import { NotificationLevel, useCreateToastNotification } from "@lookiero/sty-psp-notifications";
|
|
@@ -13,7 +14,7 @@ interface BlockCheckoutBookingFunction {
|
|
|
13
14
|
type UseBlockCheckoutBooking = [blockCheckoutBooking: BlockCheckoutBookingFunction, status: CommandStatus];
|
|
14
15
|
|
|
15
16
|
interface UseBlockCheckoutBookingFunctionArgs {
|
|
16
|
-
readonly checkoutBookingId: string;
|
|
17
|
+
readonly checkoutBookingId: string | undefined;
|
|
17
18
|
readonly logger: Logger;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -26,6 +27,8 @@ const useBlockCheckoutBooking: UseBlockCheckoutBookingFunction = ({ checkoutBook
|
|
|
26
27
|
const [createNotification] = useCreateToastNotification({ contextId: MESSAGING_CONTEXT_ID, logger });
|
|
27
28
|
|
|
28
29
|
const blockCheckoutBooking = useCallback(async () => {
|
|
30
|
+
invariant(checkoutBookingId, "checkoutBookingId is required");
|
|
31
|
+
|
|
29
32
|
try {
|
|
30
33
|
await commandBus(
|
|
31
34
|
blockCheckoutBookingCommand({
|
|
@@ -11,6 +11,7 @@ const itemIds = [
|
|
|
11
11
|
"8890e00b-d4ed-4220-ae13-52cd88ae8ed5",
|
|
12
12
|
];
|
|
13
13
|
interface CheckoutDtoFunctionArgs {
|
|
14
|
+
readonly id?: string;
|
|
14
15
|
readonly status?: CheckoutStatus;
|
|
15
16
|
readonly items: CheckoutItemFunctionArgs[];
|
|
16
17
|
}
|
|
@@ -19,8 +20,12 @@ interface CheckoutDtoFunction {
|
|
|
19
20
|
(args: CheckoutDtoFunctionArgs): CheckoutDto;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
const checkoutDto: CheckoutDtoFunction = ({
|
|
23
|
-
id
|
|
23
|
+
const checkoutDto: CheckoutDtoFunction = ({
|
|
24
|
+
id = "9c450400-0cd7-44a4-b0e3-e0002a9bf8df",
|
|
25
|
+
status = CheckoutStatus.STARTED,
|
|
26
|
+
items,
|
|
27
|
+
}) => ({
|
|
28
|
+
id,
|
|
24
29
|
status,
|
|
25
30
|
customerId: "0df61ca7-7e4d-462b-a422-a57de0d116b4",
|
|
26
31
|
boxId: "9c406e57-100a-4aa6-83c5-016e7c2970e7",
|
|
@@ -37,6 +42,6 @@ interface CheckoutFunction {
|
|
|
37
42
|
(args: CheckoutFunctionArgs): CheckoutProjection;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
const checkout: CheckoutFunction = ({ status, items }) => toCheckoutProjection(checkoutDto({ status, items }));
|
|
45
|
+
const checkout: CheckoutFunction = ({ id, status, items }) => toCheckoutProjection(checkoutDto({ id, status, items }));
|
|
41
46
|
|
|
42
47
|
export { checkout, checkoutDto };
|