import { NextRequest, NextResponse } from 'next/server'; import { stripe } from '@/lib/stripe'; import { db } from '@/lib/db'; const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!; export async function POST(req: NextRequest) { const body = await req.text(); const sig = req.headers.get('stripe-signature')!; let event; try { event = stripe.webhooks.constructEvent(body, sig, webhookSecret); } catch (err: any) { console.error(`Webhook Error: ${err.message}`); return NextResponse.json({ error: `Webhook Error: ${err.message}` }, { status: 400 }); } const session = event.data.object as any; // Handle the business logic based on event type switch (event.type) { case 'payment_intent.succeeded': await handlePaymentSucceeded(session); break; case 'payment_intent.payment_failed': await handlePaymentFailed(session); break; default: console.log(`Unhandled event type ${event.type}`); } return NextResponse.json({ received: true }); } async function handlePaymentSucceeded(paymentIntent: any) { // 1. Update status in our DB const result = await db.query( 'UPDATE transactions SET status = $1 WHERE stripe_pi_id = $2 RETURNING *', ['succeeded', paymentIntent.id] ); const transaction = result.rows[0]; if (!transaction) { console.error('Transaction not found for success webhook:', paymentIntent.id); return; } // 2. If callback_url exists, notify the merchant (firm) if (transaction && transaction.callback_url) { try { console.log(`Sending callback to: ${transaction.callback_url}`); const response = await fetch(transaction.callback_url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: 'success', amount: transaction.amount, currency: transaction.currency, ref_id: transaction.source_ref_id, transaction_id: transaction.id, stripe_id: transaction.stripe_pi_id, customer_name: transaction.customer_name, timestamp: new Date().toISOString() }), }); if (!response.ok) { console.warn(`Callback failed with status: ${response.status}`); } } catch (err) { console.error('Error sending callback:', err); } } } async function handlePaymentFailed(paymentIntent: any) { await db.query( 'UPDATE transactions SET status = $1 WHERE stripe_pi_id = $2', ['failed', paymentIntent.id] ); }