This commit is contained in:
51
src/app/api/billing/auto-charge/route.ts
Normal file
51
src/app/api/billing/auto-charge/route.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user