52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { z } from "zod";
|
|
import { getSessionUser } from "@/lib/session";
|
|
import { setAutoChargeEnabled } from "@/lib/db";
|
|
import { safeError } from "@/lib/errors";
|
|
|
|
/**
|
|
* POST /api/billing/auto-charge
|
|
*
|
|
* Phase 9. Toggle the auto_charge_enabled flag on the caller's
|
|
* org. The body is `{ enabled: boolean }`.
|
|
*
|
|
* When OFF: invoices issued for this org won't trigger an
|
|
* auto-charge against the saved card. The customer pays
|
|
* manually (or admin marks paid) — same flow as a bank-transfer
|
|
* customer.
|
|
*
|
|
* When ON: future invoice issuance attempts the auto-charge.
|
|
* No effect if there's no saved card on file.
|
|
*
|
|
* Idempotent: setting OFF on an already-OFF flag is a no-op
|
|
* (same outcome).
|
|
*/
|
|
|
|
const bodySchema = z.object({
|
|
enabled: z.boolean(),
|
|
});
|
|
|
|
export async function POST(request: Request) {
|
|
const user = await getSessionUser();
|
|
if (!user) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
const body = await request.json().catch(() => ({}));
|
|
const parsed = bodySchema.safeParse(body);
|
|
if (!parsed.success) {
|
|
return NextResponse.json(
|
|
{ error: "Invalid request", details: parsed.error.flatten() },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
try {
|
|
await setAutoChargeEnabled(user.orgId, parsed.data.enabled);
|
|
return NextResponse.json({ enabled: parsed.data.enabled });
|
|
} catch (e) {
|
|
return NextResponse.json(
|
|
{ error: safeError(e, "Failed to update auto-charge setting") },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|