@
统一月付价格为 10 USDC 并清理所有 trial 文案 - 默认月付 fallback 从 5U 改为 10U(contract_checkout.py、AccountCenter.tsx) - 移除 LoginClient / HeaderBar / AccountCenter / UnlockProOverlay 中的试用推广文案 - VPS 同步: PLAN_CATALOG_JSON、GROUP_MEMBER_PRICE_USDC 更新为 10 - SIGNUP_TRIAL_ENABLED=false 保持关闭 @
This commit is contained in:
@@ -819,14 +819,6 @@ export function AccountCenter() {
|
||||
freeTier: "FREE TIER",
|
||||
proPendingSync: isEn ? "Activated (pending sync)" : "已开通(待同步)",
|
||||
noProSubscription: isEn ? "No Pro subscription" : "暂无 Pro 订阅",
|
||||
trialEndsSoonTitle: isEn ? "Trial ending soon" : "试用即将结束",
|
||||
trialEndsSoonBody: isEn
|
||||
? "Your 3-day trial is almost over. Upgrade to Pro to keep full intraday analysis and decision cards."
|
||||
: "你的 3 天试用即将结束。升级 Pro 后可继续使用完整日内分析和城市决策卡。",
|
||||
trialExpiredTitle: isEn ? "Trial ended" : "试用已结束",
|
||||
trialExpiredBody: isEn
|
||||
? "Your trial access has ended. Renew with Pro to restore full access."
|
||||
: "试用权限已结束。开通 Pro 后可恢复完整权限。",
|
||||
proEndsSoonTitle: isEn ? "Pro renewal due soon" : "Pro 即将到期",
|
||||
proEndsSoonBody: isEn
|
||||
? "Your Pro membership will expire soon. Renew now to avoid interruption."
|
||||
@@ -836,7 +828,6 @@ export function AccountCenter() {
|
||||
? "Your Pro membership has expired. Renew now to restore premium access."
|
||||
: "你的 Pro 会员已到期。立即续费可恢复高级权限。",
|
||||
renewNow: isEn ? "Renew Now" : "立即续费",
|
||||
trialBadge: isEn ? "TRIAL" : "试用中",
|
||||
daysLeft: isEn ? "{days} days left" : "剩余 {days} 天",
|
||||
queuedExtensionSummary: isEn
|
||||
? "Current plan until {current}. Queued extension: +{days} days. Total access until {total}."
|
||||
@@ -1513,7 +1504,7 @@ export function AccountCenter() {
|
||||
telegram_pricing?: TelegramPricing | null;
|
||||
};
|
||||
if (data.telegram_pricing?.is_group_member) {
|
||||
const amount = data.telegram_pricing.amount_usdc || "5";
|
||||
const amount = data.telegram_pricing.amount_usdc || "10";
|
||||
setPaymentInfo(`Telegram 群成员验证成功,当前会员价 ${amount}U。`);
|
||||
}
|
||||
await loadSnapshot();
|
||||
@@ -1576,25 +1567,17 @@ export function AccountCenter() {
|
||||
const paymentFeatureReady = paymentReadyForRecovery;
|
||||
const canOpenCheckoutOverlay = Boolean(
|
||||
paymentFeatureReady &&
|
||||
(!isSubscribed || isTrialPlan || showExpiringSoon || showExpiredReminder),
|
||||
(!isSubscribed || showExpiringSoon || showExpiredReminder),
|
||||
);
|
||||
const subscriptionStatusTitle = showExpiredReminder
|
||||
? isTrialPlan
|
||||
? copy.trialExpiredTitle
|
||||
: copy.proExpiredTitle
|
||||
? copy.proExpiredTitle
|
||||
: showExpiringSoon
|
||||
? isTrialPlan
|
||||
? copy.trialEndsSoonTitle
|
||||
: copy.proEndsSoonTitle
|
||||
? copy.proEndsSoonTitle
|
||||
: "";
|
||||
const subscriptionStatusBody = showExpiredReminder
|
||||
? isTrialPlan
|
||||
? copy.trialExpiredBody
|
||||
: copy.proExpiredBody
|
||||
? copy.proExpiredBody
|
||||
: showExpiringSoon
|
||||
? isTrialPlan
|
||||
? copy.trialEndsSoonBody
|
||||
: copy.proEndsSoonBody
|
||||
? copy.proEndsSoonBody
|
||||
: "";
|
||||
const subscriptionStatusMeta =
|
||||
expiryInfo && (showExpiringSoon || showExpiredReminder)
|
||||
@@ -1738,7 +1721,7 @@ export function AccountCenter() {
|
||||
|
||||
const billing = useMemo(() => {
|
||||
const parsedPlanAmount = Number(
|
||||
backend?.telegram_pricing?.amount_usdc ?? selectedPlan?.amount_usdc ?? 5,
|
||||
backend?.telegram_pricing?.amount_usdc ?? selectedPlan?.amount_usdc ?? 10,
|
||||
);
|
||||
const planAmount =
|
||||
Number.isFinite(parsedPlanAmount) && parsedPlanAmount > 0
|
||||
@@ -2778,9 +2761,7 @@ export function AccountCenter() {
|
||||
className={`px-2 py-0.5 rounded-full text-[10px] font-black uppercase tracking-tighter border ${isSubscribed ? "bg-blue-500/20 border-blue-500/40 text-blue-400" : "bg-slate-700/50 border-white/10 text-slate-500"}`}
|
||||
>
|
||||
{isSubscribed
|
||||
? isTrialPlan
|
||||
? copy.trialBadge
|
||||
: copy.proMember
|
||||
? copy.proMember
|
||||
: copy.freeTier}
|
||||
</span>
|
||||
</div>
|
||||
@@ -2861,7 +2842,7 @@ export function AccountCenter() {
|
||||
Top 2-3
|
||||
</span>
|
||||
<span className="text-xs font-bold text-slate-300">
|
||||
+100 积分 & 3天Pro
|
||||
+100 积分
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
|
||||
|
||||
@@ -72,9 +72,6 @@ export function LoginClient({ nextPath }: LoginClientProps) {
|
||||
signupCheckEmail: isEn
|
||||
? "Sign-up successful. Please verify your email before signing in."
|
||||
: "注册成功,请检查邮箱并完成验证后登录。",
|
||||
trialPromo: isEn
|
||||
? "New users unlock a free 3-day Pro trial after sign-up."
|
||||
: "新用户注册后可免费体验 3 天 Pro。",
|
||||
reset: isEn ? "Forgot password?" : "忘记密码?",
|
||||
resetSent: isEn
|
||||
? "Reset link sent. Check your inbox."
|
||||
@@ -231,9 +228,6 @@ export function LoginClient({ nextPath }: LoginClientProps) {
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-white">PolyWeather</h1>
|
||||
<p className="mt-2 text-sm text-slate-400">{copy.subtitle}</p>
|
||||
<div className="mt-4 inline-flex items-center rounded-full border border-cyan-400/30 bg-cyan-400/10 px-4 py-1.5 text-xs font-semibold text-cyan-200 shadow-[0_0_20px_rgba(34,211,238,0.08)]">
|
||||
{copy.trialPromo}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
|
||||
@@ -76,9 +76,6 @@ export function HeaderBar({
|
||||
proAccess.subscriptionActive &&
|
||||
proAccess.subscriptionQueuedDays > 0,
|
||||
);
|
||||
const isTrialPlan = /trial/i.test(
|
||||
String(proAccess.subscriptionPlanCode || ""),
|
||||
);
|
||||
const showRenewReminder =
|
||||
isAuthenticated &&
|
||||
!proAccess.loading &&
|
||||
@@ -90,20 +87,12 @@ export function HeaderBar({
|
||||
const renewReminderLabel = !showRenewReminder
|
||||
? ""
|
||||
: !proAccess.subscriptionActive
|
||||
? isTrialPlan
|
||||
? locale === "en-US"
|
||||
? "Trial ended"
|
||||
: "试用已结束"
|
||||
: locale === "en-US"
|
||||
? "Pro expired"
|
||||
: "Pro 已到期"
|
||||
: isTrialPlan
|
||||
? locale === "en-US"
|
||||
? `Trial ${Math.max(expiryInfo?.daysLeft || 0, 0)}d left`
|
||||
: `试用剩余 ${Math.max(expiryInfo?.daysLeft || 0, 0)} 天`
|
||||
: locale === "en-US"
|
||||
? `Pro ${Math.max(expiryInfo?.daysLeft || 0, 0)}d left`
|
||||
: `Pro 还剩 ${Math.max(expiryInfo?.daysLeft || 0, 0)} 天`;
|
||||
? locale === "en-US"
|
||||
? "Pro expired"
|
||||
: "Pro 已到期"
|
||||
: locale === "en-US"
|
||||
? `Pro ${Math.max(expiryInfo?.daysLeft || 0, 0)}d left`
|
||||
: `Pro 还剩 ${Math.max(expiryInfo?.daysLeft || 0, 0)} 天`;
|
||||
|
||||
useEffect(() => {
|
||||
const savedTheme =
|
||||
|
||||
@@ -147,11 +147,6 @@ export function UnlockProOverlay({
|
||||
? "High-precision weather intelligence, delivered everywhere."
|
||||
: "全球最精准的高精度气象推送,全平台覆盖"}
|
||||
</p>
|
||||
<div className={s.trialPromo}>
|
||||
{isEn
|
||||
? "New users get a free 3-day Pro trial before billing."
|
||||
: "新用户可先免费体验 3 天 Pro,再决定是否付费。"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Cards ── */}
|
||||
|
||||
@@ -21,6 +21,8 @@ from src.database.db_manager import DBManager
|
||||
DEFAULT_POLYGON_CHAIN_ID = 137
|
||||
DEFAULT_USDC_E_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
|
||||
DEFAULT_NATIVE_USDC_ADDRESS = "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359"
|
||||
DEFAULT_USDT_ADDRESS = "0xc2132d05d31c914a87c6611c10748aeb04b58e8f"
|
||||
DEFAULT_PUSD_ADDRESS = "0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb"
|
||||
|
||||
PAYMENT_CONTRACT_ABI = [
|
||||
{
|
||||
@@ -86,7 +88,7 @@ ERC20_TRANSFER_EVENT_ABI = {
|
||||
}
|
||||
|
||||
DEFAULT_PLAN_CATALOG: Dict[str, Dict[str, Any]] = {
|
||||
"pro_monthly": {"plan_id": 101, "amount_usdc": "5", "duration_days": 30},
|
||||
"pro_monthly": {"plan_id": 101, "amount_usdc": "10", "duration_days": 30},
|
||||
"pro_quarterly": {"plan_id": 102, "amount_usdc": "79", "duration_days": 90},
|
||||
"pro_yearly": {"plan_id": 103, "amount_usdc": "279", "duration_days": 365},
|
||||
}
|
||||
@@ -266,8 +268,8 @@ class PaymentContractCheckoutService:
|
||||
legacy_receiver_contract = _normalize_address(
|
||||
os.getenv("POLYWEATHER_PAYMENT_RECEIVER_CONTRACT") or ""
|
||||
)
|
||||
legacy_token_address = _normalize_address(
|
||||
os.getenv("POLYWEATHER_PAYMENT_TOKEN_ADDRESS") or DEFAULT_USDC_E_ADDRESS
|
||||
legacy_token_address = (
|
||||
os.getenv("POLYWEATHER_PAYMENT_TOKEN_ADDRESS") or DEFAULT_NATIVE_USDC_ADDRESS
|
||||
)
|
||||
self.supported_tokens = self._load_supported_tokens(
|
||||
os.getenv("POLYWEATHER_PAYMENT_ACCEPTED_TOKENS_JSON") or "",
|
||||
@@ -381,6 +383,10 @@ class PaymentContractCheckoutService:
|
||||
normalized = _normalize_address(address)
|
||||
if normalized == _normalize_address(DEFAULT_NATIVE_USDC_ADDRESS):
|
||||
return {"code": "usdc", "symbol": "USDC", "name": "Native USDC"}
|
||||
if normalized == _normalize_address(DEFAULT_USDT_ADDRESS):
|
||||
return {"code": "usdt", "symbol": "USDT", "name": "USDT"}
|
||||
if normalized == _normalize_address(DEFAULT_PUSD_ADDRESS):
|
||||
return {"code": "pusd", "symbol": "pUSD", "name": "Polymarket pUSD"}
|
||||
if normalized == _normalize_address(DEFAULT_USDC_E_ADDRESS):
|
||||
return {"code": "usdc_e", "symbol": "USDC.e", "name": "USDC.e (PoS)"}
|
||||
return {"code": "usdc_token", "symbol": "USDC", "name": "USDC"}
|
||||
|
||||
Reference in New Issue
Block a user