45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { writerDb } from "@/drizzle/db";
|
|
import { tenants } from "@/drizzle/schema";
|
|
import { eq } from 'drizzle-orm';
|
|
|
|
/**
|
|
* XENDIT WEBHOOK HANDLER (QUANTUM SYNC)
|
|
*
|
|
* Menerima callback dari Xendit saat pembayaran Lunas (PAID).
|
|
* Langsung mengupdate status tenant secara reaktif.
|
|
*/
|
|
|
|
export async function POST(req: Request) {
|
|
try {
|
|
// Keamanan: Validasi Xendit Callback Token (WAJIB di Production)
|
|
const callbackToken = req.headers.get('x-callback-token');
|
|
if (callbackToken !== process.env.XENDIT_CALLBACK_TOKEN) {
|
|
console.error('[XENDIT WEBHOOK] REJECTED: Invalid callback token');
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const body = await req.json();
|
|
const { status, external_id, amount, payment_method } = body;
|
|
|
|
if (status === 'PAID') {
|
|
const parts = external_id.split('-');
|
|
const tenantId = parts[1]; // We should use full ID or mapping table
|
|
|
|
console.log(`[XENDIT WEBHOOK] PAID: ${amount} via ${payment_method} for Tenant: ${tenantId}`);
|
|
|
|
// Aktifkan Tenant secara otomatis (WAJIB writerDb untuk mutasi)
|
|
await writerDb.update(tenants)
|
|
.set({ isActive: true })
|
|
.where(eq(tenants.id, tenantId));
|
|
|
|
console.log(`[SYSTEM] Tenant ${tenantId} has been reactivated via Quantum Billing.`);
|
|
}
|
|
|
|
return NextResponse.json({ success: true });
|
|
} catch (error) {
|
|
console.error("[WEBHOOK ERROR]", error);
|
|
return NextResponse.json({ error: "Webhook Processing Failed" }, { status: 500 });
|
|
}
|
|
}
|