Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Webhook Client Laravel Package

spatie/laravel-webhook-client

Receive and process incoming webhooks in Laravel. Verify signatures, store webhook payloads, and handle them asynchronously via queued jobs. Includes flexible configuration for endpoints and processing logic.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer and publishing its config and migration:

composer require spatie/laravel-webhook-client
php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-config"
php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-migrations"
php artisan migrate

Next, configure your WEBHOOK_CLIENT_SECRET in .env and update config/webhook-client.php. In routes/web.php, register your webhook endpoint using Route::webhooks('/webhook') and exclude it from CSRF validation. Finally, create a job extending ProcessWebhookJob and set it as the process_webhook_job in the config—this is where you’ll handle the actual business logic (e.g., sync user data, update orders).

Implementation Patterns

Use a single default config for simple apps or define multiple named configs (e.g., stripe, github) in config/webhook-client.php to support multiple webhook sources. Implement custom WebhookProfile classes to filter incoming webhooks by event type (e.g., only(ProcessStripePaymentSucceeded::class)). Store required headers (e.g., X-Request-ID) via store_headers for auditability. Leverage queued jobs for non-blocking processing, and consider augmenting WebhookCall with metadata (e.g., processed_at, error_count) via model observers. For complex apps, wrap your handle() logic in DTOs and services for testability.

Gotchas and Tips

  • CSRF exceptions are mandatory: Forgot to exclude your webhook route from CSRF? Laravel will block requests silently—always double-check VerifyCsrfToken::$except.
  • Signing secret mismatches cause 500s: Ensure the signing_secret in config exactly matches what the sender uses (case-sensitive, no surrounding quotes in .env).
  • Webhooks store everything by default: If you’re not careful, you’ll exhaust DB space. Set delete_after_days and/or implement a custom WebhookProfile to avoid storing low-value events (e.g., ping).
  • Job failures persist: If ProcessWebhookJob throws an exception, the WebhookCall model records it in exception. Don’t forget to monitor webhook_calls.exception or set up retries/failures.
  • Multiple configs use name key: When defining multiple configs, use unique names (e.g., ['name' => 'stripe']) and point routes via Route::webhooks('/stripe-webhook', 'stripe').
  • Testing tip: Use pest’s withoutMiddleware('VerifyCsrfToken') or make test calls with ->withHeaders(['Signature' => $validSignature])—but remember to generate signatures identically (hash_hmac('sha256', $payload, $secret)).
  • EXTENSION POINT: Override storeHeaders() on WebhookCall or use model events (e.g., created) to trigger downstream processing.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport