Add comprehensive logging to debug checkout issues

Added console.log statements to track:
- Client: API response status, data, and errors
- Server: Stripe configuration check, rate limiting, order creation, Stripe session creation

This will help identify exactly where the checkout flow is failing.

Check browser console for client-side errors and server logs for API errors.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-18 06:13:15 +01:00
co-authored by Claude Haiku 4.5
parent c9f5626984
commit 3d48e4d545
2 changed files with 29 additions and 16 deletions
+25 -15
View File
@@ -29,23 +29,27 @@ type GuestInfo = {
}; };
export async function POST(req: Request) { export async function POST(req: Request) {
if (!process.env.STRIPE_SECRET_KEY) { try {
return NextResponse.json( if (!process.env.STRIPE_SECRET_KEY) {
{ error: 'Stripe is not configured on this server yet. Add STRIPE_SECRET_KEY to .env.' }, console.error('STRIPE_SECRET_KEY is not configured');
{ status: 500 }, return NextResponse.json(
); { error: 'Stripe is not configured on this server yet. Add STRIPE_SECRET_KEY to .env.' },
} { status: 500 },
);
}
const ip = getClientIp(req.headers); const ip = getClientIp(req.headers);
const { allowed } = await checkRateLimit(`checkout:${ip}`, 20, 10 * 60 * 1000); const { allowed } = await checkRateLimit(`checkout:${ip}`, 20, 10 * 60 * 1000);
if (!allowed) { if (!allowed) {
return NextResponse.json( console.error('Rate limit exceeded for IP:', ip);
{ error: 'Too many requests — please wait a moment and try again.' }, return NextResponse.json(
{ status: 429 }, { error: 'Too many requests — please wait a moment and try again.' },
); { status: 429 },
} );
}
const body = await req.json(); const body = await req.json();
console.log('Checkout request received with items:', body.items?.length, 'customerId:', body.customerId);
const items: CheckoutCartItem[] = body.items ?? []; const items: CheckoutCartItem[] = body.items ?? [];
const guest: GuestInfo | undefined = body.guest; const guest: GuestInfo | undefined = body.guest;
@@ -111,6 +115,7 @@ export async function POST(req: Request) {
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000'; const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000';
try { try {
console.log('Creating Stripe session for order:', order.id, 'total:', total);
const session = await stripe.checkout.sessions.create({ const session = await stripe.checkout.sessions.create({
mode: 'payment', mode: 'payment',
line_items: pricedItems.map((i) => ({ line_items: pricedItems.map((i) => ({
@@ -132,6 +137,8 @@ export async function POST(req: Request) {
metadata: { orderId: order.id }, metadata: { orderId: order.id },
}); });
console.log('Stripe session created:', session.id, 'URL:', session.url);
await prisma.order.update({ await prisma.order.update({
where: { id: order.id }, where: { id: order.id },
data: { stripeSessionId: session.id }, data: { stripeSessionId: session.id },
@@ -140,8 +147,11 @@ export async function POST(req: Request) {
return NextResponse.json({ url: session.url }); return NextResponse.json({ url: session.url });
} catch (err) { } catch (err) {
// Stripe call failed — don't leave an orphaned PENDING order with no way to pay it. // Stripe call failed — don't leave an orphaned PENDING order with no way to pay it.
console.error('Stripe session creation failed:', err);
await prisma.order.delete({ where: { id: order.id } }); await prisma.order.delete({ where: { id: order.id } });
const message = err instanceof Error ? err.message : 'Could not start checkout.'; const message = err instanceof Error ? err.message : 'Could not start checkout.';
console.error('Returning error to client:', message);
return NextResponse.json({ error: message }, { status: 500 }); return NextResponse.json({ error: message }, { status: 500 });
} }
} }
}
+4 -1
View File
@@ -123,12 +123,15 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag
body: JSON.stringify({ items, customerId: customer.id }), body: JSON.stringify({ items, customerId: customer.id }),
}); });
const data = await res.json(); const data = await res.json();
console.log('Checkout response:', { status: res.status, ok: res.ok, data });
if (!res.ok || !data.url) { if (!res.ok || !data.url) {
throw new Error(data.error ?? 'Something went wrong starting checkout.'); throw new Error(data.error ?? 'Something went wrong starting checkout.');
} }
window.location.href = data.url; window.location.href = data.url;
} catch (err) { } catch (err) {
setCheckoutError(err instanceof Error ? err.message : 'Something went wrong.'); const errorMsg = err instanceof Error ? err.message : 'Something went wrong.';
console.error('Checkout error:', errorMsg);
setCheckoutError(errorMsg);
setCheckingOut(false); setCheckingOut(false);
} }
}} }}