roundly-consulting / webhooks-for-laravel
Receive and send signed webhooks in Laravel: verified per-sender endpoints with replay protection and queued handlers, retried and throttled deliveries, secret rotation, an SSRF guard and a delivery log.
Package info
github.com/roundly-consulting/webhooks-for-laravel
pkg:composer/roundly-consulting/webhooks-for-laravel
Fund package maintenance!
Requires
- php: ^8.4
- ext-curl: *
- ext-json: *
- illuminate/bus: ^13.0
- illuminate/cache: ^13.0
- illuminate/console: ^13.0
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- illuminate/encryption: ^13.0
- illuminate/events: ^13.0
- illuminate/http: ^13.0
- illuminate/queue: ^13.0
- illuminate/routing: ^13.0
- illuminate/support: ^13.0
- illuminate/translation: ^13.0
- illuminate/validation: ^13.0
- roundly-consulting/crypto-for-laravel: ^2.1
- roundly-consulting/enums-for-laravel: ^2.0
- roundly-consulting/http-client-rate-limits-for-laravel: ^2.0
- roundly-consulting/package-toolkit-for-laravel: ^2.0
- roundly-consulting/safe-fetch-for-laravel: ^1.0
- roundly-consulting/sentinel-for-laravel: ^2.2
- symfony/uid: ^7.4|^8.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- nunomaduro/collision: ^8.5
- orchestra/testbench: ^11.0
- pestphp/pest: ^5.0
- pestphp/pest-plugin-arch: ^5.0
- pestphp/pest-plugin-laravel: ^5.0
- phpstan/extension-installer: ^1.4
- roundly-consulting/testing-for-laravel: ^2.0
Suggests
- ext-intl: International (IDN) webhook host names; without it they are refused.
Provides
None
Conflicts
None
Replaces
None
README
Webhooks for Laravel
Receive signed webhooks from any sender and send signed webhooks your customers can verify. Inbound deliveries are verified, deduplicated and handed to a queued handler exactly once; outbound deliveries are signed, retried with backoff, throttled per endpoint and SSRF-guarded — with a full delivery log, secret rotation and replay.
Installation
Requires PHP 8.4, Laravel 13 and ext-curl.
composer require roundly-consulting/webhooks-for-laravel php artisan webhooks:install php artisan migrate
webhooks:install publishes the config and the migrations (with sentinel's idempotency store).
A queue worker must run — deliveries are processed only on the queue — and the scheduler, which
runs webhooks:retry every minute.
Usage
Receive: one endpoint per sender. Give the sender the URL and the secret — it is shown once.
use RoundlyConsulting\Webhooks\Facades\Webhooks; $inbound = Webhooks::for($team)->inbound()->create(handler: 'billing'); $inbound->url; // https://app.test/webhooks/q8Zr… (an unguessable 32-character key) $inbound->secret; // whsec_… — never readable again
Bind the handler alias in config/webhooks.php ('handlers' => ['billing' => BillingWebhookHandler::class]):
use RoundlyConsulting\Webhooks\Contracts\InboundHandler; use RoundlyConsulting\Webhooks\DataTransferObjects\InboundWebhook; final class BillingWebhookHandler implements InboundHandler { public function handle(InboundWebhook $webhook): void { if ($webhook->type === 'invoice.paid') { // runs on the queue, once per delivery } } }
Send: signed, retried, throttled and SSRF-guarded.
$outbound = Webhooks::for($team)->outbound()->create('https://example.com/webhooks', events: ['invoice.*']); $outbound->secret; // whsec_… — hand it to the receiver once Webhooks::send($outbound->endpoint, 'invoice.paid', ['invoice' => 42]);
Documentation
The full documentation — configuration, every feature and its API, and testing — lives on our website: roundly-consulting.com/open-source/docs/webhooks-for-laravel
Release notes are in CHANGELOG.md. To contribute, see the contributing guide.
Support our work
This package is free and open source, built and maintained by Roundly Consulting. If it saves you time, please consider supporting our open-source work — a one-time donation, a monthly pledge on Patreon or a crypto donation helps fund maintenance, new features and new packages.
License
The MIT License (MIT). See LICENSE.md.