update: plans

This commit is contained in:
2026-03-22 05:46:41 +04:00
parent 2d0f1ce302
commit d159d1b17a
7 changed files with 128 additions and 77 deletions
+1 -1
View File
@@ -231,7 +231,7 @@ async function applyPlan(payment: any) {
export async function expireProPlans() {
const result = await sql`
UPDATE accounts SET plan = 'free', plan_expires_at = NULL
WHERE plan = 'pro' AND plan_expires_at IS NOT NULL AND plan_expires_at < now()
WHERE plan IN ('pro', 'pro2x', 'pro4x') AND plan_expires_at IS NOT NULL AND plan_expires_at < now()
`;
if (result.count > 0) console.log(`Downgraded ${result.count} expired pro accounts`);
}
+10 -14
View File
@@ -1,17 +1,13 @@
export const PLANS = {
pro: {
label: "Pro",
monthlyUsd: 12,
},
pro4x: {
label: "Pro 4x",
monthlyUsd: 48,
},
lifetime: {
label: "Lifetime",
priceUsd: 140,
},
} as const;
// Pro pricing — base $12/mo, multiplied for 2x/4x
export const PRO_MONTHLY_USD = 12;
export const LIFETIME_USD = 140;
export const PLANS: Record<string, { label: string; monthlyUsd?: number; priceUsd?: number }> = {
pro: { label: "Pro", monthlyUsd: PRO_MONTHLY_USD },
pro2x: { label: "Pro 2x", monthlyUsd: PRO_MONTHLY_USD * 2 },
pro4x: { label: "Pro 4x", monthlyUsd: PRO_MONTHLY_USD * 4 },
lifetime: { label: "Lifetime", priceUsd: LIFETIME_USD },
};
export const COINS: Record<string, { label: string; ticker: string; confirmations: number; uri: string }> = {
btc: { label: "Bitcoin", ticker: "BTC", confirmations: 1, uri: "bitcoin" },
+3 -1
View File
@@ -19,9 +19,11 @@ export async function generateReceipt(paymentId: number): Promise<string> {
? new Date(payment.paid_at).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })
: "—";
const createdDate = new Date(payment.created_at).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
const planNames: Record<string, string> = { pro: "Pro", pro2x: "Pro 2x", pro4x: "Pro 4x", lifetime: "Lifetime" };
const planName = planNames[payment.plan] || payment.plan;
const planLabel = payment.plan === "lifetime"
? "Lifetime"
: `Pro × ${payment.months} month${payment.months > 1 ? "s" : ""}`;
: `${planName} × ${payment.months} month${payment.months > 1 ? "s" : ""}`;
const txRows = txs.map((tx: any) => {
const date = new Date(tx.detected_at).toLocaleDateString("en-US", {
+3 -2
View File
@@ -72,8 +72,9 @@ export const routes = new Elysia()
if (!available.includes(coin)) { set.status = 400; return { error: `${coin} is temporarily unavailable` }; }
// Calculate amount
const planPricing = plan === "lifetime" ? null : (plan === "pro4x" ? PLANS.pro4x : PLANS.pro);
const amountUsd = plan === "lifetime" ? PLANS.lifetime.priceUsd : planPricing!.monthlyUsd * (months ?? 1);
const planDef = PLANS[plan];
if (!planDef) { set.status = 400; return { error: `Unknown plan: ${plan}` }; }
const amountUsd = planDef.priceUsd ?? (planDef.monthlyUsd! * (months ?? 1));
const rates = await getExchangeRates();
const rate = rates[coin];
if (!rate) { set.status = 500; return { error: "Could not fetch exchange rate" }; }