import { NextRequest, NextResponse } from "next/server"; import { abacatePay } from "@/lib/abacatepay"; import { DONATION_PRODUCTS, DonorData } from "@/types/donation"; export async function POST(request: NextRequest) { try { const body = await request.json(); // Validar tier const validTiers: Array = [ "coffee", "snack", "lunch", "custom", ]; if (!body.tier || !validTiers.includes(body.tier)) { return NextResponse.json( { success: false, error: "Tier de doação inválido" }, { status: 400 } ); } const product = DONATION_PRODUCTS[body.tier as keyof typeof DONATION_PRODUCTS]; // Se for custom, validar valor enviado let finalAmount: number; let finalDescription: string; if (body.tier === "custom") { if (!body.customAmount || typeof body.customAmount !== "number") { return NextResponse.json( { success: false, error: "Valor customizado inválido" }, { status: 400 } ); } const minAmount = DONATION_PRODUCTS.custom.minAmount; const maxAmount = DONATION_PRODUCTS.custom.maxAmount; if (body.customAmount < minAmount || body.customAmount > maxAmount) { return NextResponse.json( { success: false, error: `Valor deve estar entre R$ ${minAmount} e R$ ${maxAmount}`, }, { status: 400 } ); } // Converter para centavos finalAmount = Math.round(body.customAmount * 100); finalDescription = `Doação Personalizada - R$ ${body.customAmount.toFixed( 2 )}`; } else { finalAmount = product.price; finalDescription = product.name; } let pixData; // Fluxo: Anônimo ou Identificado if (body.anonymous === true) { // Doação anônima - sem customer pixData = await abacatePay.createPixQrCode({ amount: finalAmount, description: finalDescription, expiresIn: 600, }); console.log("🔍 PIX criado (anônimo):", pixData); console.log("📝 Registro de doação anônima:", { type: "donation_created", pixId: pixData.id, amount: finalAmount, tier: body.tier, customAmount: body.tier === "custom" ? body.customAmount : undefined, anonymous: true, createdAt: new Date().toISOString(), }); } else { // Doação identificada - validar campos obrigatórios if (!body.donorName || body.donorName.trim().length < 3) { return NextResponse.json( { success: false, error: "Nome é obrigatório (mínimo 3 caracteres)" }, { status: 400 } ); } if (!body.donorPhone || body.donorPhone.trim().length === 0) { return NextResponse.json( { success: false, error: "Telefone é obrigatório" }, { status: 400 } ); } if (!body.donorEmail) { return NextResponse.json( { success: false, error: "Email é obrigatório para doação identificada", }, { status: 400 } ); } if (!body.donorTaxId || body.donorTaxId.trim().length === 0) { return NextResponse.json( { success: false, error: "CPF/CNPJ é obrigatório" }, { status: 400 } ); } if (body.donorMessage && body.donorMessage.length > 280) { return NextResponse.json( { success: false, error: "Mensagem deve ter no máximo 280 caracteres", }, { status: 400 } ); } pixData = await abacatePay.createPixQrCode({ amount: finalAmount, description: finalDescription, expiresIn: 600, customer: { name: body.donorName.trim(), email: body.donorEmail.trim(), cellphone: body.donorPhone.trim(), taxId: body.donorTaxId.trim(), }, }); console.log("🔍 PIX criado (identificado):", pixData); console.log("📝 Registro de doação identificada:", { type: "donation_created", pixId: pixData.id, amount: finalAmount, tier: body.tier, customAmount: body.tier === "custom" ? body.customAmount : undefined, anonymous: false, donor: { name: body.donorName, email: body.donorEmail, phone: body.donorPhone, taxId: body.donorTaxId, message: body.donorMessage, }, createdAt: new Date().toISOString(), }); } return NextResponse.json({ success: true, pixId: pixData.id, brCode: pixData.brCode, brCodeBase64: pixData.brCodeBase64, expiresAt: pixData.expiresAt, }); } catch (error) { console.error("Donation creation error:", error); return NextResponse.json( { success: false, error: error instanceof Error ? error.message : "Erro interno", }, { status: 500 } ); } }