import { NextResponse } from "next/server"; import { createBtcPayInvoice, isBtcPayConfigured } from "@/lib/btcpay"; import { registerInvoice } from "@/lib/serverLedger"; export async function POST(req: Request) { if (!isBtcPayConfigured()) { return NextResponse.json( { ok: false, error: "BTCPay not configured — set BTCPAY_URL, BTCPAY_API_KEY, BTCPAY_STORE_ID in .env.local" }, { status: 503 }, ); } let body: unknown; try { body = await req.json(); } catch { return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 }); } const { usdAmount, handle } = (body as Record) ?? {}; if (typeof usdAmount !== "number" || usdAmount <= 0 || !Number.isFinite(usdAmount)) { return NextResponse.json({ ok: false, error: "usdAmount must be a positive number" }, { status: 400 }); } if (typeof handle !== "string" || !handle.trim()) { return NextResponse.json({ ok: false, error: "handle is required" }, { status: 400 }); } if (usdAmount < 0.5) { return NextResponse.json({ ok: false, error: "Minimum deposit is $0.50" }, { status: 400 }); } if (usdAmount > 50000) { return NextResponse.json({ ok: false, error: "Maximum single deposit is $50,000" }, { status: 400 }); } const result = await createBtcPayInvoice(usdAmount, handle.trim()); if (!result.ok) { return NextResponse.json({ ok: false, error: result.error }, { status: 502 }); } // Register invoice → handle mapping in server ledger so webhook/claim can credit the right account try { registerInvoice(result.invoice.id, handle.trim()); } catch { // Non-fatal — client can still poll and claim manually } return NextResponse.json({ ok: true, invoiceId: result.invoice.id, checkoutLink: result.invoice.checkoutLink, status: result.invoice.status, expiresAt: result.invoice.expirationTime, }); }