Simplify account payment flow and harden direct transfers

This commit is contained in:
2569718930@qq.com
2026-06-14 06:58:45 +08:00
parent 715d79c9b5
commit 0f497ab822
15 changed files with 310 additions and 167 deletions
@@ -27,10 +27,6 @@ export function runTests() {
path.join(projectRoot, "components", "account", "useBilling.ts"),
"utf8",
);
const unlockProOverlay = fs.readFileSync(
path.join(projectRoot, "components", "subscription", "UnlockProOverlay.tsx"),
"utf8",
);
const telegramPricing = fs.readFileSync(
path.join(projectRoot, "components", "account", "telegram-pricing.ts"),
"utf8",
@@ -93,17 +89,16 @@ export function runTests() {
!accountCenter.includes(["private", "Group", "Monthly", "Plan"].join("")) &&
!accountCopy.includes(["Private", "group", "monthly"].join(" ")) &&
!accountCopy.includes(["私", "密", "群", "月", "付"].join("")),
"account plan card and checkout overlay should not expose a separate discounted monthly label",
"account plan card should not expose a separate discounted monthly label",
);
assert(
accountCenter.includes("overlayPlanLabel") &&
accountCenter.includes("overlayPeriodLabel") &&
accountCenter.includes("displayPlanList.map") &&
accountCenter.includes("plan.amount_usdc") &&
accountCenter.includes("USDC") &&
!accountCenter.includes(`copy.${["private", "Group", "Monthly", "Plan"].join("")}`) &&
unlockProOverlay.includes("planLabel") &&
unlockProOverlay.includes("USDC") &&
!unlockProOverlay.includes("<span className={s.price}>${planPriceUsd.toFixed(2)}</span>") &&
!unlockProOverlay.includes('<span className={s.summaryUnit}>USD</span>'),
"checkout overlay must display payment amounts as USDC without exposing the discounted-price source label",
!accountCenter.includes("overlayPlanLabel") &&
!accountCenter.includes("overlayPeriodLabel"),
"payment management must display payment amounts as USDC without relying on the removed checkout overlay",
);
assert(
types.includes("ReferralSummary") &&
@@ -80,10 +80,14 @@ export function runTests() {
"AccountCenter must validate backend-returned manual payment receiver before displaying it",
);
assert(
/!\(\s*txValidation\.checked\s*&&\s*txValidation\.valid === true\s*\)/.test(
accountCenterSource,
),
"manual payment submit button must require checked && valid === true",
accountCenterSource.includes("manualTxHashReady") &&
accountCenterSource.includes("/^0x[a-fA-F0-9]{64}$/") &&
!/!\(\s*txValidation\.checked\s*&&\s*txValidation\.valid === true\s*\)/.test(
accountCenterSource,
) &&
paymentFlowSource.includes("const submitRes = await fetch(`/api/payments/intents/${intentIdVal}/submit`") &&
paymentFlowSource.includes("const confirmRes = await fetch(`/api/payments/intents/${intentIdVal}/confirm`"),
"manual payment submit button may proceed with a well-formed tx hash, but backend submit/confirm must remain the authority",
);
assert(
paymentFlowSource.includes("validateTxHash") &&
@@ -152,14 +152,10 @@ export function runTests() {
);
assert(
accountCenterSource.includes(
'import { UnlockProOverlay } from "@/components/subscription/UnlockProOverlay";',
),
"checkout overlay must be in the account bundle, not lazy-loaded after the user clicks pay",
);
assert(
!/const\s+UnlockProOverlay\s*=\s*dynamic\s*\(/.test(accountCenterSource),
"checkout overlay must not be dynamically imported; stale deployments can make the lazy chunk fail at pay time",
!accountCenterSource.includes("UnlockProOverlay") &&
!accountCenterSource.includes("showOverlay") &&
accountCenterSource.includes("focusPaymentManagement"),
"account page must use the payment management section as the only checkout surface instead of a fixed Pro overlay",
);
assert(
!/STATIC_ASSETS\s*=\s*\[[^\]]*["']\/_next\//s.test(serviceWorkerSource),
@@ -416,6 +412,12 @@ export function runTests() {
.length >= 3,
"manual payment mutations must require a valid Supabase bearer token instead of forwarding unauthenticated requests that surface raw backend JSON",
);
assert(
accountCenterSource.includes("manualTxHashReady") &&
accountCenterSource.includes("/^0x[a-fA-F0-9]{64}$/") &&
!accountCenterSource.includes("txValidation.valid === true)"),
"manual transfer submit button must allow a well-formed tx hash even when advisory pre-validation is unavailable",
);
assert(
paymentFlowSource.includes("verifyPaymentAuthReady") &&
paymentFlowSource.indexOf("await verifyPaymentAuthReady()") <
@@ -28,14 +28,14 @@ export function runTests() {
accountCenter.includes("canTrialUpgrade") &&
accountCenter.includes("isTrialSubscription") &&
accountCenter.includes("canTrialUpgrade || !isSubscribed"),
"trial subscribers must be allowed to open the Pro checkout before expiry",
"trial subscribers must be allowed to enter payment management before expiry",
);
assert(
accountCenter.includes("useSearchParams") &&
accountCenter.includes('searchParams.get("checkout") === "1"') &&
accountCenter.includes("setShowOverlay(true)"),
"account page must support /account?checkout=1 for direct upgrade entry",
accountCenter.includes("focusPaymentManagement"),
"account page must support /account?checkout=1 by focusing payment management",
);
assert(