From 86edb9358dfb643664b4a14b463ee1c2a4dfdb60 Mon Sep 17 00:00:00 2001 From: dirtybits Date: Tue, 25 Aug 2026 09:45:48 -0700 Subject: [PATCH] fix(api): normalize Stripe checkout request body --- web/__tests__/api/stripe-routes.test.ts | 13 +++++++++++++ web/app/api/stripe/checkout/route.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/web/__tests__/api/stripe-routes.test.ts b/web/__tests__/api/stripe-routes.test.ts index c78c9863..2a1a9fd9 100644 --- a/web/__tests__/api/stripe-routes.test.ts +++ b/web/__tests__/api/stripe-routes.test.ts @@ -356,6 +356,19 @@ describe("Stripe checkout and webhook routes", () => { mockSkillRow(); }); + it("rejects a null checkout body before rate-limit or database work", async () => { + const res = await checkoutPOST( + jsonRequest("http://localhost/api/stripe/checkout", null) + ); + const body = await res.json(); + + expect(res.status).toBe(400); + expect(body.error).toBe("skillId is required"); + expect(mocks.checkRateLimit).not.toHaveBeenCalled(); + expect(mockSql).not.toHaveBeenCalled(); + expect(mocks.createCheckoutSession).not.toHaveBeenCalled(); + }); + it("requires wallet auth before creating a checkout session", async () => { const res = await checkoutPOST(checkoutRequest({ skillId })); const body = await res.json(); diff --git a/web/app/api/stripe/checkout/route.ts b/web/app/api/stripe/checkout/route.ts index 241901e7..2d3ac141 100644 --- a/web/app/api/stripe/checkout/route.ts +++ b/web/app/api/stripe/checkout/route.ts @@ -84,7 +84,7 @@ export async function POST(req: NextRequest) { auth?: AuthPayload; }; try { - body = await req.json(); + body = (await req.json()) ?? {}; } catch { return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); }