Updated ABACATEPAY_SETUP.md with comprehensive setup guide, including environment variables, API key instructions, webhook configuration, donation flow, and field details for better integration clarity. Added required fields (phone, CPF/CNPJ) to the donation form in app/[locale]/apoiar/page.tsx to collect essential donor information and improve compliance. This ensures smoother setup and more robust donation processing.
70 lines
2.2 KiB
TypeScript
70 lines
2.2 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
||
import { abacatePay } from "@/lib/abacatepay";
|
||
|
||
export async function POST(request: NextRequest) {
|
||
try {
|
||
const payload = await request.text();
|
||
const signature = request.headers.get("x-abacatepay-signature");
|
||
|
||
if (!signature || !abacatePay.verifyWebhookSignature(payload, signature)) {
|
||
return NextResponse.json(
|
||
{ error: "Assinatura inválida" },
|
||
{ status: 401 }
|
||
);
|
||
}
|
||
|
||
const event = JSON.parse(payload);
|
||
|
||
console.log("🔔 Webhook recebido:", JSON.stringify(event, null, 2));
|
||
|
||
// Capturar todos os tipos de eventos de pagamento
|
||
const isPaidEvent =
|
||
event.type === "pix.paid" ||
|
||
event.type === "billing.paid" ||
|
||
event.type === "payment.paid" ||
|
||
event.data?.status === "PAID";
|
||
|
||
if (isPaidEvent) {
|
||
console.log("✅ Doação confirmada via webhook:", event.data.id);
|
||
|
||
// Log estruturado para futura persistência em banco de dados
|
||
const donationRecord = {
|
||
type: "donation_paid",
|
||
pixId: event.data.id,
|
||
amount: event.data.amount,
|
||
customer: event.data.customer,
|
||
paidAt: event.data.paidAt || new Date().toISOString(),
|
||
createdAt: new Date().toISOString(),
|
||
metadata: event.data.metadata,
|
||
};
|
||
|
||
console.log("📝 Registro de pagamento:", donationRecord);
|
||
|
||
// TODO: Quando implementar banco de dados, salvar aqui:
|
||
// await db.donations.create(donationRecord);
|
||
|
||
// TODO: Quando implementar email, enviar aqui:
|
||
// if (event.data.customer?.email) {
|
||
// await sendThankYouEmail({
|
||
// to: event.data.customer.email,
|
||
// donorName: event.data.customer.name,
|
||
// amount: event.data.amount,
|
||
// });
|
||
// }
|
||
|
||
// TODO: Atualizar estatísticas
|
||
// await updateDonationStats(event.data.amount);
|
||
} else {
|
||
console.log("ℹ️ Evento de webhook (não é pagamento):", event.type);
|
||
}
|
||
|
||
return NextResponse.json({ success: true });
|
||
} catch (error) {
|
||
console.error("Webhook error:", error);
|
||
return NextResponse.json(
|
||
{ error: "Erro ao processar webhook" },
|
||
{ status: 500 }
|
||
);
|
||
}
|
||
}
|