UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

128 lines (127 loc) 4.75 kB
import { fromUnitToToken } from "@ocap/util"; export { primaryContrastColor } from "../../libs/util.js"; export const INTERVAL_LOCALE_KEY = { day: "common.daily", week: "common.weekly", month: "common.monthly", year: "common.yearly" }; export function countryCodeToFlag(code) { if (!code || code.length !== 2) return ""; return String.fromCodePoint( ...code.toUpperCase().split("").map((c) => 127397 + c.charCodeAt(0)) ); } export function formatTokenAmount(unitAmount, currency) { if (!unitAmount || !currency) return "0"; try { const tokenAmount = fromUnitToToken(String(unitAmount), currency.decimal || 0); const num = Number(tokenAmount); if (!Number.isFinite(num)) return "0"; const abs = Math.abs(num); const precision = abs > 0 && abs < 0.01 ? 6 : 2; const formatted = num.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: precision }); return formatted.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "") || "0"; } catch { return "0"; } } export function getUnitAmountForCurrency(price, currency) { if (!price || !currency) return "0"; const options = price.price_currency_options || price.currency_options || []; const option = options.find((x) => x.currency_id === currency.id); if (option) { if (option.custom_unit_amount) { return option.custom_unit_amount.preset || option.custom_unit_amount.presets?.[0] || option.unit_amount; } return option.unit_amount; } if (price.currency_id === currency.id) { return price.unit_amount || "0"; } return "0"; } export function formatDynamicUnitPrice(price, currency, exchangeRate) { if (!price || !currency) return null; const isDynamic = price.pricing_type === "dynamic"; if (isDynamic && exchangeRate && price.base_amount) { const rate = Number(exchangeRate); if (rate > 0 && Number.isFinite(rate)) { const baseUsd = Number(price.base_amount); if (baseUsd > 0 && Number.isFinite(baseUsd)) { const tokenAmount = baseUsd / rate; const abs = Math.abs(tokenAmount); const precision = abs > 0 && abs < 0.01 ? 6 : 2; return tokenAmount.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: precision }).replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "") || "0"; } } } if (!exchangeRate && price.base_amount != null) { const baseUsd = Number(price.base_amount); if (baseUsd >= 0 && Number.isFinite(baseUsd)) { return baseUsd.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } } return formatTokenAmount(getUnitAmountForCurrency(price, currency), currency); } export function tSafe(t, key, fallback) { const v = t(key); return v && !v.includes(".") ? v : fallback; } export const whiteTooltipSx = { "& .MuiTooltip-tooltip": { bgcolor: "background.paper", color: "text.primary", border: "1px solid", borderColor: "divider", borderRadius: "10px", boxShadow: "0 8px 24px rgba(0,0,0,0.12)", p: 1.5, maxWidth: 280, fontSize: 12 }, "& .MuiTooltip-arrow": { color: "background.paper", "&::before": { border: "1px solid", borderColor: "divider" } } }; export function formatTrialText(t, days, interval) { const key = interval || "day"; const intervalKey = days > 1 ? `common.${key}s` : `common.${key}`; return t("payment.checkout.free", { count: days, interval: t(intervalKey) }); } export function getSessionHeaderMeta(t, session, product, items) { const mode = session?.mode || "payment"; const isSubscription = ["subscription", "setup"].includes(mode); const isCreditTopup = items.length === 1 && mode === "payment" && items[0]?.price?.product?.type === "credit" && items[0]?.price?.metadata?.credit_config; let badge; if (isCreditTopup) { badge = "topup"; } else if (isSubscription) { badge = "subscription"; } else { badge = "oneTime"; } const badgeLabel = t(`payment.checkout.typeBadge.${badge}`); const productName = product?.name || items[0]?.price?.product?.name || ""; let title = productName; if (productName) { if (isSubscription) { title = t("payment.checkout.headerTitle.subscribe", { name: productName }); } else if (!isCreditTopup) { title = t("payment.checkout.headerTitle.purchase", { name: productName }); } } let subtitle = ""; if (isCreditTopup) { subtitle = t("payment.checkout.subtitle.creditsTopup"); } else if (isSubscription) { const planName = product?.metadata?.plan_name || product?.metadata?.plan_display_name; if (planName) { subtitle = planName; } } else { subtitle = t("payment.checkout.subtitle.oneTime"); } return { badge, badgeLabel, title, subtitle }; }