The following example demonstrates a professional configuration for a Laravel application. It showcases how to set up routes, middleware, and CSRF token exceptions for specific cases like handling Stripe webhooks.
bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'stripe/webhook',
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
routes/web.php
Route::post('/stripe/webhook', [StripeController::class, 'webhook'])->name('stripe.webhook');
app/controllers/StripeController.php
public function webhook()
{
$endpoint_secret = config('stripe.wh'); // Use your Stripe webhook key
$payload = file_get_contents('php://input');
if (!$payload) {
return response('Empty payload', 400);
}
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'] ?? null;
if (!$sig_header) {
return response('Missing signature header', 400);
}
try {
$event = \Stripe\Webhook::constructEvent(
$payload,
$sig_header,
$endpoint_secret
);
} catch (\UnexpectedValueException $e) {
// Invalid payload
return response('Invalid payload', 400);
} catch (\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
return response('Invalid signature', 400);
}
$session = $event->data->object;
try {
switch ($event->type) {
case 'checkout.session_completed':
// Do something if payment is completed, maybe call a function
break;
default:
Log::info("Received unknown event type {$event->type}");
}
} catch (\Exception $e) {
Log::error("Error processing Stripe webhook: {$e->getMessage()}");
return response('Webhook handling error', 500);
}
return response('Webhook received', 200);
}