109 lines
4.6 KiB
PHP
109 lines
4.6 KiB
PHP
<?php
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\User;
|
|
use App\Models\Payment; // Make sure this is imported
|
|
use Illuminate\Http\Request;
|
|
use Stripe\Stripe;
|
|
use Stripe\Webhook;
|
|
use Stripe\Exception\SignatureVerificationException;
|
|
use Log; // Import the Log facade
|
|
use DateTime;
|
|
|
|
class WebhookController extends Controller
|
|
{
|
|
public function handleWebhook(Request $request)
|
|
{
|
|
Stripe::setApiKey(env('STRIPE_SECRET_KEY'));
|
|
|
|
$payload = $request->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);
|
|
}
|
|
}
|