@blocklet/payment-react 1.13.113

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 (173) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +29 -0
  3. package/babel.config.es.js +8 -0
  4. package/build.config.ts +29 -0
  5. package/es/api.d.ts +2 -0
  6. package/es/api.js +18 -0
  7. package/es/checkout/index.d.ts +15 -0
  8. package/es/checkout/index.js +61 -0
  9. package/es/components/input.d.ts +23 -0
  10. package/es/components/input.js +44 -0
  11. package/es/components/livemode.d.ts +2 -0
  12. package/es/components/livemode.js +24 -0
  13. package/es/components/pricing-table.d.ts +18 -0
  14. package/es/components/pricing-table.js +175 -0
  15. package/es/components/status.d.ts +3 -0
  16. package/es/components/status.js +20 -0
  17. package/es/components/switch.d.ts +6 -0
  18. package/es/components/switch.js +42 -0
  19. package/es/contexts/payment.d.ts +29 -0
  20. package/es/contexts/payment.js +45 -0
  21. package/es/dayjs.d.ts +2 -0
  22. package/es/dayjs.js +14 -0
  23. package/es/index.d.ts +16 -0
  24. package/es/index.js +29 -0
  25. package/es/locales/en.d.ts +2 -0
  26. package/es/locales/en.js +213 -0
  27. package/es/locales/index.d.ts +10 -0
  28. package/es/locales/index.js +20 -0
  29. package/es/locales/zh.d.ts +2 -0
  30. package/es/locales/zh.js +213 -0
  31. package/es/payment/amount.d.ts +12 -0
  32. package/es/payment/amount.js +22 -0
  33. package/es/payment/error.d.ts +13 -0
  34. package/es/payment/error.js +12 -0
  35. package/es/payment/footer.d.ts +4 -0
  36. package/es/payment/footer.js +9 -0
  37. package/es/payment/form/addon.d.ts +2 -0
  38. package/es/payment/form/addon.js +14 -0
  39. package/es/payment/form/address.d.ts +7 -0
  40. package/es/payment/form/address.js +119 -0
  41. package/es/payment/form/index.d.ts +9 -0
  42. package/es/payment/form/index.js +337 -0
  43. package/es/payment/form/phone.d.ts +4 -0
  44. package/es/payment/form/phone.js +97 -0
  45. package/es/payment/form/stripe.d.ts +13 -0
  46. package/es/payment/form/stripe.js +158 -0
  47. package/es/payment/header.d.ts +7 -0
  48. package/es/payment/header.js +29 -0
  49. package/es/payment/index.d.ts +28 -0
  50. package/es/payment/index.js +327 -0
  51. package/es/payment/product-card.d.ts +21 -0
  52. package/es/payment/product-card.js +34 -0
  53. package/es/payment/product-item.d.ts +19 -0
  54. package/es/payment/product-item.js +107 -0
  55. package/es/payment/product-skeleton.d.ts +4 -0
  56. package/es/payment/product-skeleton.js +34 -0
  57. package/es/payment/skeleton/overview.d.ts +2 -0
  58. package/es/payment/skeleton/overview.js +13 -0
  59. package/es/payment/skeleton/payment.d.ts +2 -0
  60. package/es/payment/skeleton/payment.js +19 -0
  61. package/es/payment/success.d.ts +8 -0
  62. package/es/payment/success.js +164 -0
  63. package/es/payment/summary.d.ts +12 -0
  64. package/es/payment/summary.js +178 -0
  65. package/es/theme.d.ts +1 -0
  66. package/es/theme.js +17 -0
  67. package/es/types/index.d.ts +19 -0
  68. package/es/types/index.js +0 -0
  69. package/es/types/shims.d.ts +18 -0
  70. package/es/util.d.ts +52 -0
  71. package/es/util.js +390 -0
  72. package/lib/api.d.ts +2 -0
  73. package/lib/api.js +26 -0
  74. package/lib/checkout/index.d.ts +15 -0
  75. package/lib/checkout/index.js +83 -0
  76. package/lib/components/input.d.ts +23 -0
  77. package/lib/components/input.js +72 -0
  78. package/lib/components/livemode.d.ts +2 -0
  79. package/lib/components/livemode.js +29 -0
  80. package/lib/components/pricing-table.d.ts +18 -0
  81. package/lib/components/pricing-table.js +232 -0
  82. package/lib/components/status.d.ts +3 -0
  83. package/lib/components/status.js +23 -0
  84. package/lib/components/switch.d.ts +6 -0
  85. package/lib/components/switch.js +51 -0
  86. package/lib/contexts/payment.d.ts +29 -0
  87. package/lib/contexts/payment.js +73 -0
  88. package/lib/dayjs.d.ts +2 -0
  89. package/lib/dayjs.js +21 -0
  90. package/lib/index.d.ts +16 -0
  91. package/lib/index.js +143 -0
  92. package/lib/locales/en.d.ts +2 -0
  93. package/lib/locales/en.js +220 -0
  94. package/lib/locales/index.d.ts +10 -0
  95. package/lib/locales/index.js +33 -0
  96. package/lib/locales/zh.d.ts +2 -0
  97. package/lib/locales/zh.js +220 -0
  98. package/lib/payment/amount.d.ts +12 -0
  99. package/lib/payment/amount.js +28 -0
  100. package/lib/payment/error.d.ts +13 -0
  101. package/lib/payment/error.js +52 -0
  102. package/lib/payment/footer.d.ts +4 -0
  103. package/lib/payment/footer.js +25 -0
  104. package/lib/payment/form/addon.d.ts +2 -0
  105. package/lib/payment/form/addon.js +37 -0
  106. package/lib/payment/form/address.d.ts +7 -0
  107. package/lib/payment/form/address.js +152 -0
  108. package/lib/payment/form/index.d.ts +9 -0
  109. package/lib/payment/form/index.js +464 -0
  110. package/lib/payment/form/phone.d.ts +4 -0
  111. package/lib/payment/form/phone.js +133 -0
  112. package/lib/payment/form/stripe.d.ts +13 -0
  113. package/lib/payment/form/stripe.js +213 -0
  114. package/lib/payment/header.d.ts +7 -0
  115. package/lib/payment/header.js +58 -0
  116. package/lib/payment/index.d.ts +28 -0
  117. package/lib/payment/index.js +382 -0
  118. package/lib/payment/product-card.d.ts +21 -0
  119. package/lib/payment/product-card.js +81 -0
  120. package/lib/payment/product-item.d.ts +19 -0
  121. package/lib/payment/product-item.js +160 -0
  122. package/lib/payment/product-skeleton.d.ts +4 -0
  123. package/lib/payment/product-skeleton.js +71 -0
  124. package/lib/payment/skeleton/overview.d.ts +2 -0
  125. package/lib/payment/skeleton/overview.js +48 -0
  126. package/lib/payment/skeleton/payment.d.ts +2 -0
  127. package/lib/payment/skeleton/payment.js +54 -0
  128. package/lib/payment/success.d.ts +8 -0
  129. package/lib/payment/success.js +215 -0
  130. package/lib/payment/summary.d.ts +12 -0
  131. package/lib/payment/summary.js +225 -0
  132. package/lib/theme.d.ts +1 -0
  133. package/lib/theme.js +19 -0
  134. package/lib/types/index.d.ts +19 -0
  135. package/lib/types/index.js +1 -0
  136. package/lib/types/shims.d.ts +18 -0
  137. package/lib/util.d.ts +52 -0
  138. package/lib/util.js +487 -0
  139. package/package.json +104 -0
  140. package/src/api.ts +24 -0
  141. package/src/checkout/index.tsx +74 -0
  142. package/src/components/input.tsx +58 -0
  143. package/src/components/livemode.tsx +23 -0
  144. package/src/components/pricing-table.tsx +207 -0
  145. package/src/components/status.tsx +19 -0
  146. package/src/components/switch.tsx +48 -0
  147. package/src/contexts/payment.tsx +74 -0
  148. package/src/dayjs.ts +17 -0
  149. package/src/index.ts +32 -0
  150. package/src/locales/en.tsx +218 -0
  151. package/src/locales/index.tsx +30 -0
  152. package/src/locales/zh.tsx +214 -0
  153. package/src/payment/amount.tsx +24 -0
  154. package/src/payment/error.tsx +29 -0
  155. package/src/payment/footer.tsx +12 -0
  156. package/src/payment/form/addon.tsx +24 -0
  157. package/src/payment/form/address.tsx +119 -0
  158. package/src/payment/form/index.tsx +401 -0
  159. package/src/payment/form/phone.tsx +103 -0
  160. package/src/payment/form/stripe.tsx +195 -0
  161. package/src/payment/header.tsx +40 -0
  162. package/src/payment/index.tsx +367 -0
  163. package/src/payment/product-card.tsx +55 -0
  164. package/src/payment/product-item.tsx +121 -0
  165. package/src/payment/product-skeleton.tsx +39 -0
  166. package/src/payment/skeleton/overview.tsx +21 -0
  167. package/src/payment/skeleton/payment.tsx +35 -0
  168. package/src/payment/success.tsx +186 -0
  169. package/src/payment/summary.tsx +198 -0
  170. package/src/theme.ts +18 -0
  171. package/src/types/index.ts +29 -0
  172. package/src/types/shims.d.ts +18 -0
  173. package/src/util.ts +543 -0
@@ -0,0 +1,158 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import Center from "@arcblock/ux/lib/Center";
3
+ import Dialog from "@arcblock/ux/lib/Dialog";
4
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
5
+ import { LoadingButton } from "@mui/lab";
6
+ import { CircularProgress, Typography } from "@mui/material";
7
+ import { styled } from "@mui/system";
8
+ import { Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
9
+ import { loadStripe } from "@stripe/stripe-js";
10
+ import { useSetState } from "ahooks";
11
+ import { useEffect } from "react";
12
+ function StripeCheckoutForm({ clientSecret, intentType, customer, mode, onConfirm }) {
13
+ const stripe = useStripe();
14
+ const elements = useElements();
15
+ const { t } = useLocaleContext();
16
+ const [state, setState] = useSetState({
17
+ message: "",
18
+ confirming: false,
19
+ loaded: false
20
+ });
21
+ useEffect(() => {
22
+ if (!stripe) {
23
+ return;
24
+ }
25
+ if (!clientSecret) {
26
+ return;
27
+ }
28
+ const method = intentType === "payment_intent" ? "retrievePaymentIntent" : "retrieveSetupIntent";
29
+ stripe[method](clientSecret).then(({ paymentIntent, setupIntent }) => {
30
+ const intent = paymentIntent || setupIntent;
31
+ switch (intent?.status) {
32
+ case "succeeded":
33
+ setState({ message: t("paymentCredit.preparePayMessage.succeeded") });
34
+ break;
35
+ case "processing":
36
+ setState({ message: t("paymentCredit.preparePayMessage.processing") });
37
+ break;
38
+ case "requires_payment_method":
39
+ default:
40
+ break;
41
+ }
42
+ });
43
+ }, [stripe, clientSecret]);
44
+ const handleSubmit = async (e) => {
45
+ e.preventDefault();
46
+ if (!stripe || !elements) {
47
+ return;
48
+ }
49
+ try {
50
+ setState({ confirming: true });
51
+ const method = intentType === "payment_intent" ? "confirmPayment" : "confirmSetup";
52
+ const { error } = await stripe[method]({
53
+ elements,
54
+ redirect: "if_required",
55
+ confirmParams: {
56
+ payment_method_data: {
57
+ billing_details: {
58
+ name: customer.name,
59
+ phone: customer.phone,
60
+ email: customer.email,
61
+ address: customer.address
62
+ }
63
+ }
64
+ }
65
+ });
66
+ setState({ confirming: false });
67
+ if (error) {
68
+ if (error.type === "validation_error") {
69
+ return;
70
+ }
71
+ setState({ message: error.message });
72
+ return;
73
+ }
74
+ onConfirm();
75
+ } catch (err) {
76
+ console.error(err);
77
+ setState({ confirming: false, message: err.message });
78
+ }
79
+ };
80
+ return /* @__PURE__ */ jsxs(Content, { onSubmit: handleSubmit, children: [
81
+ /* @__PURE__ */ jsx(
82
+ PaymentElement,
83
+ {
84
+ options: { layout: "auto", fields: { billingDetails: "never" }, readOnly: state.confirming },
85
+ onReady: () => setState({ loaded: true })
86
+ }
87
+ ),
88
+ (!stripe || !elements || !state.loaded) && /* @__PURE__ */ jsx(Center, { relative: "parent", children: /* @__PURE__ */ jsx(CircularProgress, {}) }),
89
+ stripe && elements && state.loaded && /* @__PURE__ */ jsx(
90
+ LoadingButton,
91
+ {
92
+ fullWidth: true,
93
+ sx: { mt: 2, mb: 1, borderRadius: 0, fontSize: "1.1rem" },
94
+ type: "submit",
95
+ disabled: state.confirming || !state.loaded,
96
+ loading: state.confirming,
97
+ loadingPosition: "end",
98
+ variant: "contained",
99
+ color: "primary",
100
+ size: "large",
101
+ children: t("payment.checkout.continue", { action: mode })
102
+ }
103
+ ),
104
+ state.message && /* @__PURE__ */ jsx(Typography, { sx: { mt: 1, color: "error.main" }, children: state.message })
105
+ ] });
106
+ }
107
+ const Content = styled("form")`
108
+ display: flex;
109
+ flex-direction: column;
110
+ justify-content: center;
111
+ align-items: center;
112
+ width: 100%;
113
+ height: 100%;
114
+ min-height: 320px;
115
+ `;
116
+ export default function StripeCheckout({
117
+ clientSecret,
118
+ intentType,
119
+ publicKey,
120
+ mode,
121
+ customer,
122
+ onConfirm,
123
+ onCancel
124
+ }) {
125
+ const stripePromise = loadStripe(publicKey);
126
+ const { t } = useLocaleContext();
127
+ const [state, setState] = useSetState({
128
+ open: true,
129
+ closable: true
130
+ });
131
+ const handleClose = (_, reason) => {
132
+ if (reason === "backdropClick") {
133
+ return;
134
+ }
135
+ setState({ open: false });
136
+ onCancel();
137
+ };
138
+ return /* @__PURE__ */ jsx(
139
+ Dialog,
140
+ {
141
+ title: t("payment.checkout.cardPay", { action: t(`payment.checkout.${mode}`) }),
142
+ showCloseButton: state.closable,
143
+ open: state.open,
144
+ onClose: handleClose,
145
+ disableEscapeKeyDown: true,
146
+ children: /* @__PURE__ */ jsx(Elements, { options: { clientSecret }, stripe: stripePromise, children: /* @__PURE__ */ jsx(
147
+ StripeCheckoutForm,
148
+ {
149
+ clientSecret,
150
+ intentType,
151
+ mode,
152
+ customer,
153
+ onConfirm
154
+ }
155
+ ) })
156
+ }
157
+ );
158
+ }
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import type { TCheckoutSessionExpanded } from '@blocklet/payment-types';
3
+ type Props = {
4
+ checkoutSession: TCheckoutSessionExpanded;
5
+ };
6
+ export default function PaymentHeader({ checkoutSession }: Props): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,29 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useTheme } from "@arcblock/ux/lib/Theme";
3
+ import { Avatar, Stack, Typography } from "@mui/material";
4
+ import { useCreation, useLocalStorageState, useSize } from "ahooks";
5
+ import Livemode from "../components/livemode.js";
6
+ import { getStatementDescriptor } from "../util.js";
7
+ import UserButtons from "./form/addon.js";
8
+ export default function PaymentHeader({ checkoutSession }) {
9
+ const [livemode] = useLocalStorageState("livemode", { defaultValue: true });
10
+ const brand = getStatementDescriptor(checkoutSession.line_items);
11
+ const theme = useTheme();
12
+ const domSize = useSize(document.body);
13
+ const isColumnLayout = useCreation(() => {
14
+ if (domSize) {
15
+ if (domSize?.width <= theme.breakpoints.values.md) {
16
+ return true;
17
+ }
18
+ }
19
+ return false;
20
+ }, [domSize, theme]);
21
+ return /* @__PURE__ */ jsxs(Stack, { className: "cko-header", direction: "row", spacing: 1, alignItems: "center", justifyContent: "space-between", children: [
22
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", children: [
23
+ /* @__PURE__ */ jsx(Avatar, { variant: "square", src: window.blocklet.appLogo, sx: { width: 32, height: 32 } }),
24
+ /* @__PURE__ */ jsx(Typography, { sx: { color: "text.primary", fontWeight: 600 }, children: brand }),
25
+ !livemode && /* @__PURE__ */ jsx(Livemode, {})
26
+ ] }),
27
+ isColumnLayout ? /* @__PURE__ */ jsx(UserButtons, {}) : null
28
+ ] });
29
+ }
@@ -0,0 +1,28 @@
1
+ /// <reference types="react" />
2
+ import { CheckoutCallbacks, CheckoutContext } from '../types';
3
+ type Props = CheckoutContext & CheckoutCallbacks & {
4
+ completed?: boolean;
5
+ error?: any;
6
+ };
7
+ declare function Payment({ checkoutSession, paymentMethods, paymentIntent, paymentLink, customer, completed, error, mode, onPaid, onError, }: Props): import("react").JSX.Element;
8
+ declare namespace Payment {
9
+ var defaultProps: {
10
+ completed: boolean;
11
+ error: null;
12
+ };
13
+ }
14
+ export default Payment;
15
+ type MainProps = CheckoutContext & CheckoutCallbacks & {
16
+ completed?: boolean;
17
+ };
18
+ export declare function PaymentInner({ checkoutSession, paymentMethods, paymentLink, paymentIntent, customer, completed, mode, onPaid, onError, }: MainProps): import("react").JSX.Element;
19
+ export declare namespace PaymentInner {
20
+ var defaultProps: {
21
+ completed: boolean;
22
+ };
23
+ }
24
+ export declare const Root: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
25
+ ref?: ((instance: HTMLDivElement | null) => void) | import("react").RefObject<HTMLDivElement> | null | undefined;
26
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/system").Theme> & {
27
+ mode: string;
28
+ }, {}, {}>;
@@ -0,0 +1,327 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
3
+ import Toast from "@arcblock/ux/lib/Toast";
4
+ import { Box, Fade, Stack } from "@mui/material";
5
+ import { styled } from "@mui/system";
6
+ import { useSetState } from "ahooks";
7
+ import { useEffect } from "react";
8
+ import { FormProvider, useForm } from "react-hook-form";
9
+ import api from "../api.js";
10
+ import { usePaymentContext } from "../contexts/payment.js";
11
+ import { findCurrency, formatError, getStatementDescriptor, isValidCountry } from "../util.js";
12
+ import PaymentError from "./error.js";
13
+ import CheckoutFooter from "./footer.js";
14
+ import PaymentForm from "./form/index.js";
15
+ import PaymentHeader from "./header.js";
16
+ import OverviewSkeleton from "./skeleton/overview.js";
17
+ import PaymentSkeleton from "./skeleton/payment.js";
18
+ import PaymentSuccess from "./success.js";
19
+ import PaymentSummary from "./summary.js";
20
+ Payment.defaultProps = {
21
+ completed: false,
22
+ error: null
23
+ };
24
+ export default function Payment({
25
+ checkoutSession,
26
+ paymentMethods,
27
+ paymentIntent,
28
+ paymentLink,
29
+ customer,
30
+ completed,
31
+ error,
32
+ mode,
33
+ onPaid,
34
+ onError
35
+ }) {
36
+ const { t } = useLocaleContext();
37
+ const { refresh, livemode, setLivemode } = usePaymentContext();
38
+ useEffect(() => {
39
+ if (checkoutSession) {
40
+ if (livemode !== checkoutSession.livemode) {
41
+ setLivemode(checkoutSession.livemode);
42
+ setTimeout(() => {
43
+ refresh();
44
+ }, 10);
45
+ }
46
+ }
47
+ }, [checkoutSession, livemode, setLivemode, refresh]);
48
+ if (error) {
49
+ return /* @__PURE__ */ jsx(PaymentError, { title: "Oops", description: formatError(error) });
50
+ }
51
+ if (!checkoutSession) {
52
+ return /* @__PURE__ */ jsx(Root, { mode, children: /* @__PURE__ */ jsxs(Stack, { className: "cko-container", children: [
53
+ /* @__PURE__ */ jsx(Stack, { className: "cko-overview", children: /* @__PURE__ */ jsx(OverviewSkeleton, {}) }),
54
+ /* @__PURE__ */ jsx(Stack, { className: "cko-payment", children: /* @__PURE__ */ jsx(PaymentSkeleton, {}) }),
55
+ /* @__PURE__ */ jsx(CheckoutFooter, { className: "cko-footer" })
56
+ ] }) });
57
+ }
58
+ if (checkoutSession.expires_at <= Math.round(Date.now() / 1e3)) {
59
+ return /* @__PURE__ */ jsx(
60
+ PaymentError,
61
+ {
62
+ title: t("payment.checkout.expired.title"),
63
+ description: t("payment.checkout.expired.description")
64
+ }
65
+ );
66
+ }
67
+ if (checkoutSession.status === "complete") {
68
+ return /* @__PURE__ */ jsx(
69
+ PaymentError,
70
+ {
71
+ title: t("payment.checkout.complete.title"),
72
+ description: t("payment.checkout.complete.description")
73
+ }
74
+ );
75
+ }
76
+ return /* @__PURE__ */ jsx(
77
+ PaymentInner,
78
+ {
79
+ checkoutSession,
80
+ paymentMethods,
81
+ paymentLink,
82
+ paymentIntent,
83
+ completed,
84
+ customer,
85
+ onPaid,
86
+ onError,
87
+ mode
88
+ }
89
+ );
90
+ }
91
+ PaymentInner.defaultProps = {
92
+ completed: false
93
+ };
94
+ export function PaymentInner({
95
+ checkoutSession,
96
+ paymentMethods,
97
+ paymentLink,
98
+ paymentIntent,
99
+ customer,
100
+ completed,
101
+ mode,
102
+ onPaid,
103
+ onError
104
+ }) {
105
+ const { t } = useLocaleContext();
106
+ const { settings, session } = usePaymentContext();
107
+ const [state, setState] = useSetState({ checkoutSession });
108
+ const defaultCurrencyId = state.checkoutSession.currency_id || state.checkoutSession.line_items[0]?.price.currency_id;
109
+ const defaultMethodId = paymentMethods.find((m) => m.payment_currencies.some((c) => c.id === defaultCurrencyId))?.id;
110
+ const methods = useForm({
111
+ defaultValues: {
112
+ customer_name: customer?.name || session.user?.fullName || "",
113
+ customer_email: customer?.email || session.user?.email || "",
114
+ customer_phone: customer?.phone || session.user?.phone || "",
115
+ payment_method: defaultMethodId,
116
+ payment_currency: defaultCurrencyId,
117
+ billing_address: Object.assign(
118
+ {
119
+ country: "",
120
+ state: "",
121
+ city: "",
122
+ line1: "",
123
+ line2: "",
124
+ postal_code: ""
125
+ },
126
+ customer?.address || {},
127
+ { country: isValidCountry(customer?.address?.country || "") ? customer?.address?.country : "us" }
128
+ )
129
+ }
130
+ });
131
+ const currencyId = methods.watch("payment_currency");
132
+ const currency = findCurrency(paymentMethods, currencyId) || settings.baseCurrency;
133
+ const onUpsell = async (from, to) => {
134
+ try {
135
+ const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/upsell`, { from, to });
136
+ setState({ checkoutSession: data });
137
+ } catch (err) {
138
+ console.error(err);
139
+ Toast.error(formatError(err));
140
+ }
141
+ };
142
+ const onDownsell = async (from) => {
143
+ try {
144
+ const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/downsell`, { from });
145
+ setState({ checkoutSession: data });
146
+ } catch (err) {
147
+ console.error(err);
148
+ Toast.error(formatError(err));
149
+ }
150
+ };
151
+ const onApplyCrossSell = async (to) => {
152
+ try {
153
+ const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`, { to });
154
+ setState({ checkoutSession: data });
155
+ } catch (err) {
156
+ console.error(err);
157
+ Toast.error(formatError(err));
158
+ }
159
+ };
160
+ const onCancelCrossSell = async () => {
161
+ try {
162
+ const { data } = await api.delete(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`);
163
+ setState({ checkoutSession: data });
164
+ } catch (err) {
165
+ console.error(err);
166
+ Toast.error(formatError(err));
167
+ }
168
+ };
169
+ return /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx(Root, { mode, children: /* @__PURE__ */ jsxs(Stack, { className: "cko-container", children: [
170
+ /* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(Stack, { className: "cko-overview", direction: "column", children: [
171
+ /* @__PURE__ */ jsx(PaymentHeader, { checkoutSession: state.checkoutSession }),
172
+ /* @__PURE__ */ jsx(
173
+ PaymentSummary,
174
+ {
175
+ checkoutSession: state.checkoutSession,
176
+ currency,
177
+ onUpsell,
178
+ onDownsell,
179
+ onApplyCrossSell,
180
+ onCancelCrossSell
181
+ }
182
+ )
183
+ ] }) }),
184
+ /* @__PURE__ */ jsxs(Stack, { className: "cko-payment", direction: "column", spacing: 4, children: [
185
+ completed && /* @__PURE__ */ jsx(
186
+ PaymentSuccess,
187
+ {
188
+ payee: getStatementDescriptor(state.checkoutSession.line_items),
189
+ action: state.checkoutSession.mode,
190
+ message: paymentLink?.after_completion?.hosted_confirmation?.custom_message || t(`payment.checkout.completed.${state.checkoutSession.mode}`)
191
+ }
192
+ ),
193
+ !completed && /* @__PURE__ */ jsx(
194
+ PaymentForm,
195
+ {
196
+ checkoutSession: state.checkoutSession,
197
+ paymentMethods,
198
+ paymentIntent,
199
+ customer,
200
+ onPaid,
201
+ onError,
202
+ mode
203
+ }
204
+ )
205
+ ] }),
206
+ /* @__PURE__ */ jsx(CheckoutFooter, { className: "cko-footer" })
207
+ ] }) }) });
208
+ }
209
+ export const Root = styled(Box)`
210
+ box-sizing: border-box;
211
+ display: flex;
212
+ flex-direction: column;
213
+ justify-content: center;
214
+ align-items: center;
215
+ min-height: 100vh;
216
+ position: relative;
217
+
218
+ &:before {
219
+ animation-fill-mode: both;
220
+ background: #ffffff;
221
+ content: '';
222
+ height: 100%;
223
+ position: fixed;
224
+ right: 0;
225
+ top: 0;
226
+ transform-origin: right;
227
+ width: 50%;
228
+ box-shadow: 15px 0 30px 0 rgba(0, 0, 0, 0.18);
229
+ }
230
+
231
+ .cko-container {
232
+ width: 100%;
233
+ max-width: 1000px;
234
+ display: flex;
235
+ flex-direction: row;
236
+ justify-content: space-between;
237
+ position: relative;
238
+ padding: 0 16px;
239
+ }
240
+
241
+ .cko-overview {
242
+ width: 400px;
243
+ min-height: 540px;
244
+ position: relative;
245
+ }
246
+ .cko-header {
247
+ left: 0;
248
+ margin-bottom: 0;
249
+ position: absolute;
250
+ right: 0;
251
+ top: 0;
252
+ transition: background-color 0.15s ease, box-shadow 0.15s ease-out;
253
+ }
254
+ .cko-product-summary {
255
+ }
256
+
257
+ .cko-payment {
258
+ width: 400px;
259
+ .MuiInputBase-root {
260
+ border-radius: 0;
261
+ }
262
+ }
263
+
264
+ .cko-payment-form {
265
+ .MuiInputAdornment-positionStart {
266
+ width: 50px;
267
+ }
268
+
269
+ .MuiBox-root {
270
+ border: 1px solid #ccc;
271
+ margin: -1px 0 0 -1px;
272
+ }
273
+
274
+ .MuiFormHelperText-root {
275
+ margin-left: 14px;
276
+ }
277
+
278
+ .MuiOutlinedInput-notchedOutline {
279
+ border: none;
280
+ }
281
+ }
282
+
283
+ .cko-payment-methods {
284
+ }
285
+
286
+ .cko-payment-submit {
287
+ .MuiButtonBase-root {
288
+ border-radius: 0;
289
+ font-size: 1.3rem;
290
+ }
291
+ }
292
+
293
+ .cko-header {
294
+ }
295
+
296
+ .cko-footer {
297
+ position: absolute;
298
+ bottom: 0;
299
+ left: 12px;
300
+ margin: 12px 0;
301
+ }
302
+
303
+ @media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
304
+ &:before {
305
+ display: none;
306
+ }
307
+ .cko-container {
308
+ flex-direction: column;
309
+ align-items: center;
310
+ gap: 24px;
311
+ min-width: 350px;
312
+ max-width: 400px;
313
+ }
314
+ .cko-overview {
315
+ width: 100%;
316
+ min-height: auto;
317
+ }
318
+ .cko-payment {
319
+ width: 100%;
320
+ }
321
+
322
+ .cko-footer {
323
+ position: static;
324
+ margin-top: 0;
325
+ }
326
+ }
327
+ `;
@@ -0,0 +1,21 @@
1
+ /// <reference types="react" />
2
+ import type { LiteralUnion } from 'type-fest';
3
+ type Props = {
4
+ name: string;
5
+ description?: string;
6
+ logo?: string;
7
+ size?: number;
8
+ extra?: React.ReactNode;
9
+ variant?: LiteralUnion<'square' | 'rounded' | 'circular', string>;
10
+ };
11
+ declare function ProductCard({ size, variant, name, logo, description, extra }: Props): import("react").JSX.Element;
12
+ declare namespace ProductCard {
13
+ var defaultProps: {
14
+ logo: string;
15
+ size: number;
16
+ description: string;
17
+ variant: string;
18
+ extra: undefined;
19
+ };
20
+ }
21
+ export default ProductCard;
@@ -0,0 +1,34 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Avatar, Stack, Typography } from "@mui/material";
3
+ export default function ProductCard({ size, variant, name, logo, description, extra }) {
4
+ const s = { width: size, height: size };
5
+ return /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "flex-start", spacing: 1, flex: 2, children: [
6
+ logo ? (
7
+ // @ts-ignore
8
+ /* @__PURE__ */ jsx(Avatar, { src: logo, alt: name, variant, sx: s })
9
+ ) : (
10
+ // @ts-ignore
11
+ /* @__PURE__ */ jsx(Avatar, { variant, sx: s, children: name.slice(0, 1) })
12
+ ),
13
+ /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", justifyContent: "space-around", children: [
14
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontWeight: 500, mb: 0.5, lineHeight: 1 }, color: "text.primary", children: name }),
15
+ description && /* @__PURE__ */ jsx(
16
+ Typography,
17
+ {
18
+ variant: "body1",
19
+ sx: { fontSize: "0.85rem", mb: 0.5, lineHeight: 1, textAlign: "left" },
20
+ color: "text.secondary",
21
+ children: description
22
+ }
23
+ ),
24
+ extra && /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontSize: "0.85rem" }, color: "text.secondary", children: extra })
25
+ ] })
26
+ ] });
27
+ }
28
+ ProductCard.defaultProps = {
29
+ logo: "",
30
+ size: 48,
31
+ description: "",
32
+ variant: "rounded",
33
+ extra: void 0
34
+ };
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import type { TCheckoutSessionExpanded, TLineItemExpanded, TPaymentCurrency } from '@blocklet/payment-types';
3
+ type Props = {
4
+ item: TLineItemExpanded;
5
+ session: TCheckoutSessionExpanded;
6
+ currency: TPaymentCurrency;
7
+ onUpsell: Function;
8
+ onDownsell: Function;
9
+ mode?: 'normal' | 'cross-sell';
10
+ children?: React.ReactNode;
11
+ };
12
+ declare function ProductItem({ item, session, currency, mode, children, onUpsell, onDownsell }: Props): import("react").JSX.Element;
13
+ declare namespace ProductItem {
14
+ var defaultProps: {
15
+ mode: string;
16
+ children: null;
17
+ };
18
+ }
19
+ export default ProductItem;