export const runtime = "nodejs"; import { NextRequest, NextResponse } from "next/server"; import { capturePayPalOrder } from "@/lib/paypal"; import { findByPaypalOrderId, markPaymentPaid } from "@/lib/summit-requests"; interface CaptureBody { token: string; // PayPal Order ID (from query param after redirect) PayerID: string; } export async function POST(req: NextRequest): Promise { let body: CaptureBody; try { body = (await req.json()) as CaptureBody; } catch { return NextResponse.json({ error: "Invalid JSON body." }, { status: 400 }); } // Validate required fields if (!body.token || !body.PayerID) { return NextResponse.json( { error: "token and PayerID are required." }, { status: 400 } ); } const { token, PayerID } = body; console.log(`[capture] Received capture request for orderId=${token} PayerID=${PayerID}`); // Look up the registration by PayPal Order ID const registration = await findByPaypalOrderId(token); if (!registration || registration.paymentStatus !== "payment_pending") { console.log( `[capture] Order not found or not in payment_pending state: orderId=${token} paymentStatus=${registration?.paymentStatus ?? "not found"}` ); return NextResponse.json( { error: "Order not found or not in payment_pending state." }, { status: 409 } ); } console.log(`[capture] Found registration publicId=${registration.publicId}, proceeding to capture`); // Capture the PayPal order let captureId: string; try { const result = await capturePayPalOrder(token); captureId = result.captureId; console.log(`[capture] PayPal capture succeeded: captureId=${captureId} status=${result.status}`); } catch (err) { const message = err instanceof Error ? err.message : "PayPal capture failed."; console.error(`[capture] PayPal capture failed for orderId=${token}: ${message}`); return NextResponse.json({ error: message }, { status: 502 }); } // Mark the registration as paid in the DB await markPaymentPaid(token, captureId); console.log(`[capture] Marked payment as paid for orderId=${token} captureId=${captureId}`); return NextResponse.json( { ok: true, captureId, registrationId: registration.publicId }, { status: 200 } ); }