UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

1,088 lines (1,075 loc) 34.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Root = void 0; module.exports = Payment; var _jsxRuntime = require("react/jsx-runtime"); var _context = require("@arcblock/ux/lib/Locale/context"); var _Toast = _interopRequireDefault(require("@arcblock/ux/lib/Toast")); var _Header = _interopRequireDefault(require("@blocklet/ui-react/lib/Header")); var _iconsMaterial = require("@mui/icons-material"); var _material = require("@mui/material"); var _system = require("@mui/system"); var _util = require("@ocap/util"); var _ahooks = require("ahooks"); var _react = require("react"); var _reactHookForm = require("react-hook-form"); var _trim = _interopRequireDefault(require("lodash/trim")); var _payment = require("../contexts/payment"); var _api = _interopRequireDefault(require("../libs/api")); var _util2 = require("../libs/util"); var _error = _interopRequireDefault(require("./error")); var _footer = _interopRequireDefault(require("./footer")); var _form = _interopRequireWildcard(require("./form")); var _overview = _interopRequireDefault(require("./skeleton/overview")); var _payment2 = _interopRequireDefault(require("./skeleton/payment")); var _success = _interopRequireDefault(require("./success")); var _summary = _interopRequireDefault(require("./summary")); var _mobile = require("../hooks/mobile"); var _phoneValidator = require("../libs/phone-validator"); var _currency = require("../libs/currency"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function PaymentInner({ checkoutSession, paymentMethods, paymentLink, paymentIntent, customer, completed = false, mode, onPaid, onError, onChange, action, showCheckoutSummary = true, quotes, rateUnavailable, rateError }) { const { t } = (0, _context.useLocaleContext)(); const { settings, session } = (0, _payment.usePaymentContext)(); const { isMobile } = (0, _mobile.useMobile)(); const [state, setState] = (0, _ahooks.useSetState)({ checkoutSession, quotes, rateUnavailable, rateError, paymentIntent, liveRateInfo: void 0, liveQuoteSnapshot: void 0, liveRateUnavailable: false, liveRateError: void 0, isRateLoading: false }); const isCurrencySwitchRef = (0, _react.useRef)(false); const prevCurrencyIdRef = (0, _react.useRef)(null); const query = (0, _util2.getQueryParams)(window.location.href); const availableCurrencyIds = (0, _react.useMemo)(() => { const currencyIds = /* @__PURE__ */new Set(); paymentMethods.forEach(method2 => { method2.payment_currencies.forEach(currency2 => { if (currency2.active) { currencyIds.add(currency2.id); } }); }); return Array.from(currencyIds); }, [paymentMethods]); const defaultCurrencyId = (0, _react.useMemo)(() => { const hasAppliedDiscount = Boolean(state.checkoutSession?.discounts?.length); if (hasAppliedDiscount && state.checkoutSession.currency_id && availableCurrencyIds.includes(state.checkoutSession.currency_id)) { return state.checkoutSession.currency_id; } if (query.currencyId && availableCurrencyIds.includes(query.currencyId)) { return query.currencyId; } if (session?.user && !(0, _form.hasDidWallet)(session.user)) { const stripeCurrencyId = paymentMethods.find(m => m.type === "stripe")?.payment_currencies.find(c => c.active)?.id; if (stripeCurrencyId) { return stripeCurrencyId; } } const savedPreference = (0, _currency.getCurrencyPreference)(session?.user?.did, availableCurrencyIds); if (savedPreference) { return savedPreference; } if (state.checkoutSession.currency_id && availableCurrencyIds.includes(state.checkoutSession.currency_id)) { return state.checkoutSession.currency_id; } return availableCurrencyIds?.[0]; }, [query.currencyId, availableCurrencyIds, session?.user, state.checkoutSession, paymentMethods]); const defaultMethodId = paymentMethods.find(m => m.payment_currencies.some(c => c.id === defaultCurrencyId))?.id; const hideSummaryCard = mode.endsWith("-minimal") || !showCheckoutSummary; const methods = (0, _reactHookForm.useForm)({ defaultValues: { customer_name: customer?.name || session?.user?.fullName || "", customer_email: customer?.email || session?.user?.email || "", customer_phone: (0, _phoneValidator.formatPhone)(customer?.phone || session?.user?.phone || ""), payment_method: defaultMethodId, payment_currency: defaultCurrencyId, billing_address: Object.assign({ country: session?.user?.address?.country || "", state: session?.user?.address?.province || "", city: session?.user?.address?.city || "", line1: session?.user?.address?.line1 || "", line2: session?.user?.address?.line2 || "", postal_code: session?.user?.address?.postalCode || "" }, customer?.address || {}, { country: (0, _util2.isValidCountry)(customer?.address?.country || session?.user?.address?.country || "") ? customer?.address?.country : "us" }) } }); (0, _react.useEffect)(() => { const hasAppliedDiscount = Boolean(state.checkoutSession?.discounts?.length); const currentCurrency = methods.getValues("payment_currency"); const currentMethod = methods.getValues("payment_method"); if (defaultCurrencyId) { if (!hasAppliedDiscount || !currentCurrency) { methods.setValue("payment_currency", defaultCurrencyId); } } if (defaultMethodId) { if (!hasAppliedDiscount || !currentMethod) { methods.setValue("payment_method", defaultMethodId); } } }, [defaultCurrencyId, defaultMethodId, state.checkoutSession.discounts]); (0, _react.useEffect)(() => { if (!(0, _util2.isMobileSafari)()) { return () => {}; } let scrollTop = 0; const focusinHandler = () => { scrollTop = window.scrollY; }; const focusoutHandler = () => { window.scrollTo(0, scrollTop); }; document.body.addEventListener("focusin", focusinHandler); document.body.addEventListener("focusout", focusoutHandler); return () => { document.body.removeEventListener("focusin", focusinHandler); document.body.removeEventListener("focusout", focusoutHandler); }; }, []); const currencyId = (0, _reactHookForm.useWatch)({ control: methods.control, name: "payment_currency", defaultValue: defaultCurrencyId }); const currency = (0, _util2.findCurrency)(paymentMethods, currencyId) || settings.baseCurrency; const method = paymentMethods.find(x => x.id === currency.payment_method_id); const hasDynamicPricing = (0, _react.useMemo)(() => state.checkoutSession.line_items.some(item => (item.upsell_price || item.price)?.pricing_type === "dynamic"), [state.checkoutSession.line_items]); const isStripePayment = method?.type === "stripe"; const needsExchangeRate = hasDynamicPricing && !isStripePayment; const effectiveRateUnavailable = needsExchangeRate && (state.rateUnavailable || state.liveRateUnavailable); if (state.liveRateError || state.rateError) { console.error("[Rate Error]", { liveRateError: state.liveRateError, rateError: state.rateError }); } const refreshRateRef = (0, _react.useRef)(null); (0, _react.useEffect)(() => { if (!currencyId) { return; } const isCurrencySwitch = prevCurrencyIdRef.current !== null && prevCurrencyIdRef.current !== currencyId; prevCurrencyIdRef.current = currencyId; if (isCurrencySwitch) { isCurrencySwitchRef.current = true; setState({ isRateLoading: true }); } if (needsExchangeRate) { setState({ liveRateInfo: void 0, liveQuoteSnapshot: void 0, liveRateUnavailable: false, liveRateError: void 0 }); liveRateRefreshRef.current = false; refreshRateRef.current?.(); } else { setState({ liveRateInfo: void 0, liveQuoteSnapshot: void 0, liveRateUnavailable: false, liveRateError: void 0 }); liveRateRefreshRef.current = false; if (isCurrencySwitch && !state.checkoutSession?.discounts?.length) { setState({ isRateLoading: false }); isCurrencySwitchRef.current = false; } } }, [currencyId, needsExchangeRate]); (0, _react.useEffect)(() => { if (!state.checkoutSession?.id || completed || !needsExchangeRate) { return void 0; } let cancelled = false; let consecutiveFailures = 0; const baseInterval = 3e4; const MAX_INTERVAL = 5 * 60 * 1e3; const QUICK_RETRY_DELAY = 1e3; const MAX_QUICK_RETRIES = 2; let currentInterval = baseInterval; let timer = null; const scheduleNext = () => { if (timer) { clearInterval(timer); } timer = window.setInterval(() => { fetchRate(false); }, currentInterval); }; const fetchRate = async (isManualRetry = false) => { if (document.hidden && !isManualRetry) { return; } if (typeof navigator !== "undefined" && !navigator.onLine) { return; } if (liveRateRefreshRef.current) { return; } liveRateRefreshRef.current = true; let quickRetryCount = 0; let lastError = null; try { while (quickRetryCount <= MAX_QUICK_RETRIES) { try { const { data } = await _api.default.get(`/api/checkout-sessions/${state.checkoutSession.id}/exchange-rate`, { params: currencyId ? { currency_id: currencyId } : void 0 }); if (cancelled) { return; } consecutiveFailures = 0; currentInterval = baseInterval; setState({ liveRateInfo: data, liveQuoteSnapshot: void 0, // Quote is created at submit time only liveRateUnavailable: false, liveRateError: void 0 }); if (isCurrencySwitchRef.current && !state.checkoutSession?.discounts?.length) { setState({ isRateLoading: false }); isCurrencySwitchRef.current = false; } scheduleNext(); return; } catch (err) { lastError = err; quickRetryCount++; if (quickRetryCount <= MAX_QUICK_RETRIES && !cancelled) { console.log(`[Exchange Rate] Quick retry ${quickRetryCount}/${MAX_QUICK_RETRIES} after ${QUICK_RETRY_DELAY}ms`); await new Promise(resolve => { setTimeout(resolve, QUICK_RETRY_DELAY); }); } } } if (cancelled) { return; } consecutiveFailures++; const technicalError = lastError?.response?.data?.error || (0, _util2.formatError)(lastError); console.error("[Exchange Rate Fetch Error]", { error: technicalError, consecutiveFailures, sessionId: state.checkoutSession?.id, currencyId }); setState({ liveRateUnavailable: true, liveRateError: void 0 }); if (consecutiveFailures >= 3) { console.warn("Exchange rate fetch failed multiple times", { consecutiveFailures, technicalError }); } const nextInterval = Math.min(baseInterval * 2 ** (consecutiveFailures - 1), MAX_INTERVAL); currentInterval = nextInterval; scheduleNext(); } finally { liveRateRefreshRef.current = false; } }; refreshRateRef.current = async () => { liveRateRefreshRef.current = false; await fetchRate(true); }; fetchRate(false); const handleVisibilityChange = () => { if (!document.hidden) { fetchRate(false); } }; document.addEventListener("visibilitychange", handleVisibilityChange); return () => { cancelled = true; refreshRateRef.current = null; if (timer) { clearInterval(timer); } document.removeEventListener("visibilitychange", handleVisibilityChange); }; }, [state.checkoutSession?.id, currencyId, completed, needsExchangeRate]); const recalculatePromotion = async () => { if (state.checkoutSession?.discounts?.length) { try { await _api.default.post(`/api/checkout-sessions/${state.checkoutSession.id}/recalculate-promotion`, { currency_id: currencyId }); await onPromotionUpdate(); } catch (err) { console.error("[recalculatePromotion] Error:", err); } finally { if (isCurrencySwitchRef.current) { setState({ isRateLoading: false }); isCurrencySwitchRef.current = false; } } } else if (isCurrencySwitchRef.current) { setState({ isRateLoading: false }); isCurrencySwitchRef.current = false; } }; (0, _react.useEffect)(() => { if (onChange) { onChange(methods.getValues()); } recalculatePromotion(); }, [currencyId]); const onUpsell = async (from, to) => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/upsell`, { from, to }); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onDownsell = async from => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/downsell`, { from }); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onApplyCrossSell = async to => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`, { to }); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onQuantityChange = async (itemId, quantity) => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/adjust-quantity`, { itemId, quantity, currency_id: currencyId }); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data, ...(data.rateUnavailable !== void 0 && { rateUnavailable: data.rateUnavailable }), ...(data.rateError !== void 0 && { rateError: data.rateError }), ...(data.quotes !== void 0 && { quotes: data.quotes }) }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onCancelCrossSell = async () => { try { const { data } = await _api.default.delete(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onChangeAmount = async ({ priceId, amount }) => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/amount`, { priceId, amount: (0, _util.fromTokenToUnit)(amount, currency.decimal).toString() }); if (data.discounts?.length) { recalculatePromotion(); return; } setState({ checkoutSession: data }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const onPromotionUpdate = async () => { try { const { data } = await _api.default.get(`/api/checkout-sessions/retrieve/${state.checkoutSession.id}`); setState({ checkoutSession: data.checkoutSession }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } }; const handlePaid = result => { setState({ checkoutSession: result.checkoutSession }); onPaid(result); }; const handleQuoteUpdated = payload => { setState({ checkoutSession: payload.checkoutSession, ...(payload.quotes !== void 0 && { quotes: payload.quotes }), ...(payload.rateUnavailable !== void 0 && { rateUnavailable: payload.rateUnavailable }), ...(payload.rateError !== void 0 && { rateError: payload.rateError }), ...(payload.paymentIntent !== void 0 && { paymentIntent: payload.paymentIntent }) }); }; const handlePaymentIntentUpdate = intent => { setState({ paymentIntent: intent }); }; const quoteRefreshRef = (0, _react.useRef)(false); const liveRateRefreshRef = (0, _react.useRef)(false); const handleQuoteExpired = async (forceRefresh = false) => { if (quoteRefreshRef.current) { return; } quoteRefreshRef.current = true; try { const { data } = await _api.default.get(`/api/checkout-sessions/retrieve/${state.checkoutSession.id}`, { params: forceRefresh ? { forceRefresh: "1" } : void 0 }); handleQuoteUpdated({ checkoutSession: data.checkoutSession, quotes: data.quotes, rateUnavailable: data.rateUnavailable, rateError: data.rateError, paymentIntent: data.paymentIntent }); } catch (err) { console.error(err); _Toast.default.error((0, _util2.formatError)(err)); } finally { quoteRefreshRef.current = false; } }; let trialInDays = Number(state.checkoutSession?.subscription_data?.trial_period_days || 0); let trialEnd = Number(state.checkoutSession?.subscription_data?.trial_end || 0); const trialCurrencyIds = (state.checkoutSession?.subscription_data?.trial_currency || "").split(",").map(_trim.default).filter(Boolean); if (trialCurrencyIds.length > 0 && trialCurrencyIds.includes(currencyId) === false) { trialInDays = 0; trialEnd = 0; } const showFeatures = `${paymentLink?.metadata?.show_product_features}` === "true"; return /* @__PURE__ */(0, _jsxRuntime.jsx)(_reactHookForm.FormProvider, { ...methods, children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { className: "cko-container", sx: { gap: { sm: mode === "standalone" ? 0 : mode === "inline" ? 4 : 8 } }, children: [!hideSummaryCard && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Fade, { in: true, children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { className: "base-card cko-overview", direction: "column", children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_summary.default, { items: state.checkoutSession.line_items, trialInDays, trialEnd, billingThreshold: Math.max(state.checkoutSession.subscription_data?.billing_threshold_amount || 0, // @ts-ignore state.checkoutSession.subscription_data?.min_stake_amount || 0), showStaking: (0, _util2.showStaking)(method, currency, !!state.checkoutSession.subscription_data?.no_stake), currency, paymentIntent: state.paymentIntent || paymentIntent, onUpsell, onDownsell, onQuantityChange, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId: state.checkoutSession.id, crossSellBehavior: state.checkoutSession.cross_sell_behavior, donationSettings: paymentLink?.donation_settings, action, completed, checkoutSession: state.checkoutSession, onPromotionUpdate, paymentMethods, showFeatures, rateUnavailable: effectiveRateUnavailable, isRateLoading: state.isRateLoading, liveRate: state.liveRateInfo, liveQuoteSnapshot: state.liveQuoteSnapshot, onQuoteExpired: handleQuoteExpired, onRefreshRate: refreshRateRef.current || void 0, isStripePayment, onSlippageChange: async slippageConfig => { try { const { data } = await _api.default.put(`/api/checkout-sessions/${state.checkoutSession.id}/slippage`, { slippage_config: slippageConfig }); handleQuoteUpdated({ checkoutSession: data.checkoutSession || state.checkoutSession, quotes: data.quotes, rateUnavailable: data.rateUnavailable, rateError: data.rateError }); } catch (err) { console.error("Failed to update slippage", err); } } }), mode === "standalone" && !isMobile && /* @__PURE__ */(0, _jsxRuntime.jsx)(_footer.default, { className: "cko-footer", sx: { color: "text.lighter" } })] }) }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { className: "base-card cko-payment", direction: "column", spacing: { xs: 2, sm: 3 }, children: [completed && /* @__PURE__ */(0, _jsxRuntime.jsx)(_success.default, { mode, pageInfo: state.checkoutSession.metadata?.page_info, vendorCount: state.checkoutSession.line_items.reduce((total, item) => { return total + (item.price?.product?.vendor_config?.length || 0); }, 0), sessionId: state.checkoutSession.id, payee: (0, _util2.getStatementDescriptor)(state.checkoutSession.line_items), action: state.checkoutSession.mode, invoiceId: state.checkoutSession.invoice_id, subscriptionId: state.checkoutSession.subscription_id, subscriptions: state.checkoutSession.subscriptions, message: paymentLink?.after_completion?.hosted_confirmation?.custom_message || t(`payment.checkout.completed.${state.checkoutSession.submit_type === "donate" ? "donate" : state.checkoutSession.mode}`) }), !completed && /* @__PURE__ */(0, _jsxRuntime.jsx)(_form.default, { currencyId, checkoutSession: state.checkoutSession, paymentMethods, paymentIntent: state.paymentIntent || paymentIntent, paymentLink, customer, onPaid: handlePaid, onError, onQuoteUpdated: handleQuoteUpdated, onPaymentIntentUpdate: handlePaymentIntentUpdate, mode, action, rateUnavailable: effectiveRateUnavailable })] }), mode === "standalone" && isMobile && /* @__PURE__ */(0, _jsxRuntime.jsx)(_footer.default, { className: "cko-footer", sx: { color: "text.lighter" } })] }) }); } function Payment({ checkoutSession, paymentMethods, paymentIntent, paymentLink, customer, completed = false, error = null, mode, onPaid, onError, onChange, goBack, action, showCheckoutSummary = true, quotes, rateUnavailable, rateError }) { const { t } = (0, _context.useLocaleContext)(); const { refresh, livemode, setLivemode } = (0, _payment.usePaymentContext)(); const [delay, setDelay] = (0, _react.useState)(false); const { isMobile } = (0, _mobile.useMobile)(); const hideSummaryCard = mode.endsWith("-minimal") || !showCheckoutSummary; const isMobileSafariEnv = (0, _util2.isMobileSafari)(); (0, _react.useEffect)(() => { setTimeout(() => { setDelay(true); }, 500); }, []); (0, _react.useEffect)(() => { if (checkoutSession) { if (livemode !== checkoutSession.livemode) { setLivemode(checkoutSession.livemode); } } }, [checkoutSession, livemode, setLivemode, refresh]); const renderContent = () => { if (error) { return /* @__PURE__ */(0, _jsxRuntime.jsx)(_error.default, { mode, title: "Oops", description: (0, _util2.formatError)(error) }); } if (!checkoutSession || !delay) { return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { className: "cko-container", sx: { gap: { sm: mode === "standalone" ? 0 : mode === "inline" ? 4 : 8 } }, children: [!hideSummaryCard && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, { className: "base-card cko-overview", children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, { className: "cko-product", children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_overview.default, {}) }) }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, { className: "base-card cko-payment", children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_payment2.default, {}) })] }); } if (checkoutSession.expires_at <= Math.round(Date.now() / 1e3)) { return /* @__PURE__ */(0, _jsxRuntime.jsx)(_error.default, { mode, title: t("payment.checkout.expired.title"), description: t("payment.checkout.expired.description") }); } if (!checkoutSession.line_items.length) { return /* @__PURE__ */(0, _jsxRuntime.jsx)(_error.default, { mode, title: t("payment.checkout.emptyItems.title"), description: t("payment.checkout.emptyItems.description") }); } return /* @__PURE__ */(0, _jsxRuntime.jsx)(PaymentInner, { checkoutSession, paymentMethods, paymentLink, paymentIntent, completed: completed || checkoutSession.status === "complete", customer, onPaid, onError, onChange, goBack, mode, action, showCheckoutSummary, quotes, rateUnavailable, rateError }); }; return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { sx: { display: "flex", flexDirection: "column", height: mode === "standalone" ? "100vh" : "auto", overflow: isMobileSafariEnv ? "visible" : "hidden" }, children: [mode === "standalone" ? /* @__PURE__ */(0, _jsxRuntime.jsx)(_Header.default, { meta: void 0, addons: void 0, sessionManagerProps: void 0, homeLink: void 0, theme: void 0, hideNavMenu: void 0, maxWidth: false, sx: { borderBottom: "1px solid", borderColor: "divider" } }) : null, /* @__PURE__ */(0, _jsxRuntime.jsxs)(Root, { mode, sx: { flex: 1, overflow: { xs: isMobileSafariEnv ? "visible" : "auto", md: "hidden" }, ...(isMobile && mode === "standalone" ? { ".cko-payment-submit-btn": { position: "fixed", bottom: 20, left: 0, right: 0, zIndex: 999, backgroundColor: "background.paper", padding: "10px", textAlign: "center", button: { maxWidth: 542 } }, ".cko-footer": { position: "fixed", bottom: 0, left: 0, right: 0, zIndex: 999, backgroundColor: "background.paper", marginBottom: 0 }, ".cko-payment": { paddingBottom: "100px" } } : {}) }, children: [goBack && /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.ArrowBackOutlined, { sx: { mr: 0.5, color: "text.secondary", alignSelf: "flex-start", margin: "16px 0", cursor: "pointer" }, onClick: goBack, fontSize: "medium" }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, { className: "cko-container", sx: { gap: { sm: mode === "standalone" ? 0 : mode === "inline" ? 4 : 8 } }, children: renderContent() })] })] }); } const Root = exports.Root = (0, _system.styled)(_material.Box)` box-sizing: border-box; display: flex; flex-direction: column; align-items: center; overflow: hidden; position: relative; .cko-container { overflow: hidden; width: 100%; display: flex; flex-direction: row; justify-content: center; position: relative; flex: 1; padding: 1px; } .base-card { border: none; border-radius: 0; padding: ${props => props.mode === "standalone" ? "100px 40px 20px" : "20px 0"}; box-shadow: none; flex: 1; max-width: 582px; } .cko-overview { position: relative; flex-direction: column; display: ${props => props.mode.endsWith("-minimal") ? "none" : "flex"}; background: ${({ theme }) => theme.palette.background.default}; min-height: 'auto'; } .cko-header { left: 0; margin-bottom: 0; position: absolute; right: 0; top: 0; transition: background-color 0.15s ease, box-shadow 0.15s ease-out; } .cko-product { flex: 1; overflow: hidden; } .cko-product-summary { width: 100%; } .cko-ellipsis { width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .cko-payment { width: 502px; padding-left: ${props => props.mode === "standalone" ? "40px" : "20px"}; position: relative; &:before { -webkit-animation-fill-mode: both; content: ''; height: 100%; position: absolute; left: 0px; top: 0px; transform-origin: left center; width: 8px; box-shadow: -4px 0px 8px 0px rgba(2, 7, 19, 0.04); } } .cko-payment-contact { overflow: hidden; } .cko-footer { display: ${props => props.mode.endsWith("-minimal") ? "none" : "block"}; text-align: center; margin-top: 20px; } .cko-payment-form { .MuiFormLabel-root { color: ${({ theme }) => theme.palette.grey.A700}; font-weight: 500; margin-top: 12px; margin-bottom: 4px; } .MuiBox-root { margin: 0; } .MuiFormHelperText-root { margin-left: 14px; } } .cko-payment-methods { } .cko-payment-submit { .MuiButtonBase-root { font-size: 1.3rem; position: relative; } .cko-submit-progress { position: absolute; top: 0; width: 100%; height: 100%; opacity: 0.3; } } .cko-header { } .product-item { border-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; border: 1px solid; border-color: ${({ theme }) => theme.palette.divider}; .product-item-content { padding: 16px; background: ${({ theme }) => theme.palette.grey[50]}; border-top-left-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; border-top-right-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; } .product-item-upsell { margin-top: 0; padding: 16px; background: ${({ theme }) => theme.palette.grey[100]}; border-bottom-left-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; border-bottom-right-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; } .product-item-content:only-child { border-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`}; } } @media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) { padding-top: 0; overflow: auto; &:before { display: none; } .cko-container { flex-direction: column; align-items: center; justify-content: flex-start; gap: 0; overflow: visible; min-width: 200px; } .cko-overview { width: 100%; min-height: auto; flex: none; } .cko-payment { width: 100%; height: fit-content; flex: none; border-top: 1px solid; border-color: ${({ theme }) => theme.palette.divider}; &:before { display: none; } } .cko-footer { position: relative; margin-bottom: 4px; margin-top: 0; bottom: 0; left: 0; transform: translateX(0); } .base-card { box-shadow: none; border-radius: 0; padding: 20px; } } `;