/** * Stripe — Retrieve Checkout Session status * ----------------------------------------- * The success return page calls this with the `session_id` Stripe appended to * the success_url. We retrieve the session server-side (using the secret key) * and return a trimmed, safe status object the UI can render and record. * * Returning here does NOT replace the webhook — the webhook is the authoritative * record of truth (it fires even if the customer closes the tab). This endpoint * just gives the returning customer immediate, verified confirmation. * * Env: STRIPE_SECRET_KEY */ export default async function handler(req, res) { if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } const secretKey = (process.env.STRIPE_SECRET_KEY || '').trim(); if (!secretKey) { return res.status(503).json({ error: 'Stripe is not configured.', code: 'stripe_not_configured', }); } const sessionId = req.query?.session_id; if (!sessionId) { return res.status(400).json({ error: 'session_id is required' }); } try { const Stripe = (await import('stripe')).default; const stripe = new Stripe(secretKey, { apiVersion: '2024-06-20' }); const session = await stripe.checkout.sessions.retrieve(sessionId); return res.status(200).json({ id: session.id, // status: open | complete | expired status: session.status, // payment_status: paid | unpaid | no_payment_required paymentStatus: session.payment_status, amountTotal: session.amount_total, currency: session.currency, customerEmail: session.customer_details?.email || null, invoiceId: session.metadata?.invoiceId || null, created: session.created ? session.created * 1000 : null, }); } catch (err) { console.error('[session-status] error:', err.message); return res.status(500).json({ error: err.message || 'Failed to retrieve session' }); } }