getContent(); $signature = $request->header('Stripe-Signature'); $endpointSecret = env('STRIPE_WEBHOOK_SECRET'); try { $event = Webhook::constructEvent($payload, $signature, $endpointSecret); } catch (SignatureVerificationException $e) { Log::error('Stripe webhook signature verification failed: ' . $e->getMessage()); return response()->json(['error' => 'Invalid signature'], 400); } try { // Handle the event switch ($event->type) { case 'checkout.session.completed': $session = $event->data->object; $clientSessionId = $session->metadata->client_session_id; Log::info('Processing checkout.session.completed webhook', [ 'client_session_id' => $clientSessionId, 'session_id' => $session->id, 'payment_status' => $session->payment_status, 'status' => $session->status ]); $payment = Payment::where('client_session_id', $clientSessionId)->first(); if ($payment) { // Update the payment status to succeeded regardless of current status // This ensures webhook updates work even if user already processed the payment $updateData = ['status' => 'succeeded']; if (isset($session->metadata->type_appointment) && $session->metadata->type_appointment === 'true') { $dateTimeObj = new DateTime($session->metadata->appointment_date); $updateData['appointment_date'] = $dateTimeObj->format('Y-m-d'); } else { // Ensure draw_count is set correctly for card payments if (isset($session->metadata->draw_count)) { $updateData['draw_count'] = $session->metadata->draw_count; } } $payment->update($updateData); Log::info('Payment status updated via webhook', [ 'client_session_id' => $clientSessionId, 'payment_id' => $payment->id, 'new_status' => 'succeeded' ]); } else { // Log if no matching payment record is found Log::warning('No payment record found for webhook processing', [ 'client_session_id' => $clientSessionId, 'stripe_session_id' => $session->id ]); } break; case 'checkout.session.async_payment_failed': case 'checkout.session.expired': $session = $event->data->object; $clientSessionId = $session->metadata->client_session_id ?? null; if ($clientSessionId) { $payment = Payment::where('client_session_id', $clientSessionId)->first(); if ($payment) { $payment->update(['status' => 'failed']); Log::info('Payment marked as failed via webhook', [ 'client_session_id' => $clientSessionId, 'payment_id' => $payment->id, 'event_type' => $event->type ]); } } break; default: Log::info('Received unhandled webhook event', ['event_type' => $event->type]); break; } } catch (\Exception $e) { // Log any other unexpected errors Log::error('Stripe webhook processing error: ' . $e->getMessage(), ['exception' => $e]); return response()->json(['error' => 'Server error'], 500); } return response()->json(['status' => 'success'], 200); } }