PHP

Handle and Verify Incoming Webhook Payloads (PHP Laravel)

Learn to securely receive and process incoming webhook payloads in a Laravel application, including validating signatures to ensure request authenticity.

<?php

// app/Http/Controllers/WebhookController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response; // Import Response for status codes

class WebhookController extends Controller
{
    public function handleStripeWebhook(Request $request)
    {
        $payload = $request->getContent();
        $signature = $request->header('stripe-signature'); // Example for Stripe webhooks

        // For security, always verify the webhook signature
        // Replace with your actual webhook secret
        $webhookSecret = env('STRIPE_WEBHOOK_SECRET'); 

        try {
            // This is a placeholder for actual signature verification logic
            // For Stripe, you'd use Stripe\Webhook::constructEvent()
            // e.g., $event = \Stripe\Webhook::constructEvent($payload, $signature, $webhookSecret);
            
            // Simple example of checking for a header or custom logic
            if (!$signature || $signature !== 'expected_secure_signature_from_service') { 
                Log::warning('Webhook: Invalid signature received.', ['signature' => $signature]);
                return response('Invalid signature', Response::HTTP_FORBIDDEN);
            }

            // Process the webhook payload
            $eventData = json_decode($payload, true);
            Log::info('Webhook received:', $eventData);

            // Example: Handle different event types
            if (isset($eventData['type']) && $eventData['type'] === 'invoice.payment_succeeded') {
                // Logic for successful payment
                Log::info('Invoice payment succeeded event processed.');
            }

            return response('Webhook Handled', Response::HTTP_OK);

        } catch (\UnexpectedValueException $e) {
            // Invalid payload
            Log::error('Webhook: Invalid payload.', ['error' => $e->getMessage()]);
            return response('Invalid payload', Response::HTTP_BAD_REQUEST);
        } catch (\Stripe\Exception\SignatureVerificationException $e) { // If using Stripe SDK
            // Invalid signature
            Log::error('Webhook: Invalid signature.', ['error' => $e->getMessage()]);
            return response('Invalid signature', Response::HTTP_FORBIDDEN);
        } catch (\Exception $e) {
            Log::error('Webhook processing error:', ['error' => $e->getMessage(), 'payload' => $payload]);
            return response('Internal Server Error', Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}

// routes/web.php or routes/api.php
// Route::post('/webhook/stripe', [WebhookController::class, 'handleStripeWebhook']);
How it works: This PHP Laravel snippet demonstrates how to set up an endpoint to receive and process incoming webhook payloads from third-party services. It includes critical steps like accessing the raw request body and headers (e.g., for signature verification), parsing the JSON payload, and handling different event types. Signature verification is crucial to ensure the authenticity and integrity of the incoming webhook request, preventing spoofed events.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs