import { NextRequest, NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; import { requireAuth } from "@/lib/auth"; const TOP_UP_AMOUNTS = { 500: { usd: 0.99, bonus: 0, priceEnv: "POLAR_FLH_500" }, 1000: { usd: 0.99, bonus: 0, priceEnv: "POLAR_FLH_1000" }, 5000: { usd: 4.99, bonus: 500, priceEnv: "POLAR_FLH_5000" }, 10000: { usd: 9.99, bonus: 2000, priceEnv: "POLAR_FLH_10000" }, 50000: { usd: 49.99, bonus: 15000, priceEnv: "POLAR_FLH_50000" }, } as const; export async function POST(req: NextRequest) { const jwtPayload = await requireAuth(req); if (!jwtPayload) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } try { const body = await req.json(); const { amount } = body; if (!amount || !(amount in TOP_UP_AMOUNTS)) { return NextResponse.json( { error: "Invalid amount. Choose 500, 1000, 5000, 10000, or 50000 FLH." }, { status: 400 } ); } const pricing = TOP_UP_AMOUNTS[amount as keyof typeof TOP_UP_AMOUNTS]; const totalFlh = amount + (pricing.bonus || 0); // Mock mode: use when POLAR_ACCESS_TOKEN is not configured (dev only) if (!process.env.POLAR_ACCESS_TOKEN) { // Production guard: never allow mock top-ups in production if (process.env.NODE_ENV === "production") { return NextResponse.json( { error: "Payment service not configured" }, { status: 500 } ); } await prisma.user.update({ where: { id: jwtPayload.userId }, data: { flhBalance: { increment: totalFlh } }, }); return NextResponse.json({ success: true, url: "/wallet?topup=success", mock: true, amount, bonus: pricing.bonus || 0, amountUsd: pricing.usd, }); } // Production — Polar.sh checkout session const productPriceId = process.env[pricing.priceEnv]; if (!productPriceId) { return NextResponse.json( { error: `Polar price not configured for ${amount} FLH. Set ${pricing.priceEnv} env var.` }, { status: 500 } ); } const origin = req.headers.get("origin") || req.headers.get("host") || ""; const baseUrl = origin.startsWith("http") ? origin : `https://${origin}`; const polarResponse = await fetch("https://api.polar.sh/v1/checkouts/", { method: "POST", headers: { Authorization: `Bearer ${process.env.POLAR_ACCESS_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ product_price_id: productPriceId, success_url: `${baseUrl}/wallet?topup=success&amount=${amount}`, customer_email: jwtPayload.email, return_url: `${baseUrl}/wallet`, metadata: { type: "flh_purchase", flh_amount: totalFlh, user_id: jwtPayload.userId, user_email: jwtPayload.email, }, allow_trial: false, }), }); if (!polarResponse.ok) { const errorBody = await polarResponse.text(); console.error("Polar API error:", polarResponse.status, errorBody); return NextResponse.json( { error: `Checkout creation failed (HTTP ${polarResponse.status})` }, { status: 502 } ); } const polarData = await polarResponse.json(); return NextResponse.json({ success: true, url: polarData.url, checkout_id: polarData.id, amount, amountUsd: pricing.usd, bonus: pricing.bonus || 0, }); } catch (error) { console.error("Top-up checkout error:", error); return NextResponse.json( { error: error instanceof Error ? error.message : "Failed to create checkout" }, { status: 500 } ); } }