Looking to hire Laravel developers? Try LaraJobs

laravel-config-webhook maintained by cleaniquecoders

Description
Define, sign, dispatch and log outgoing webhooks in Laravel with retries, HMAC signatures, and an optional Livewire + Flux admin UI.
Last update
2026/06/08 15:28 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

Laravel Config Webhook

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Define, sign, dispatch and log outgoing webhooks in any Laravel app. Subscribers register a URL, a secret, and the event types they care about; when one of those events fires, the package delivers an HMAC-signed JSON payload with automatic retries and exponential backoff, and records every attempt in a delivery log. Ships with an optional Livewire + Flux admin UI.

The package is completely app-agnostic — it knows nothing about your domain. You register your own event catalogue (via config or at runtime) and either dispatch payloads manually or map your domain events to webhook types.

Features

  • 🔌 Outgoing webhooks — per-subscriber URL, secret, subscribed events, custom headers
  • 🔏 HMAC-SHA256 signatures — every request is signed; helpers to verify incoming ones too
  • 🔁 Retries with exponential backoff — configurable base/multiplier, full delivery log
  • 🧾 Delivery logs — status, HTTP code, response time, attempt, error, response body
  • 🧩 Config- or runtime-driven event catalogue — no hardcoded domain events
  • 🖥️ Optional Livewire + Flux admin UI — works headless without it
  • 🔐 Secrets encrypted at rest, configurable authorization gate, configurable user model
  • ✅ Laravel 12 & 13, PHP 8.3+

Requirements

  • PHP 8.3+
  • Laravel 12 or 13
  • (Optional, for the admin UI) livewire/livewire ^3 || ^4 and livewire/flux

Installation

composer require cleaniquecoders/laravel-config-webhook

The service provider and ConfigWebhook facade are auto-discovered — no manual registration needed.

Publish and run the migrations:

php artisan vendor:publish --tag="laravel-config-webhook-migrations"
php artisan migrate

Publish the config:

php artisan vendor:publish --tag="laravel-config-webhook-config"

Optionally publish the views (to customise the Flux UI):

php artisan vendor:publish --tag="laravel-config-webhook-views"

The optional admin UI requires livewire/livewire and livewire/flux. The service, job, and signing all work without them.

Configuration

Register the event types your app can emit, either in config/config-webhook.php:

'events' => [
    'order.created'   => 'Order Created',
    'order.cancelled' => 'Order Cancelled',
    'user.registered' => 'User Registered',
],

…or at runtime (e.g. in a service provider's boot()):

use CleaniqueCoders\ConfigWebhook\Facades\ConfigWebhook;

ConfigWebhook::registerEvents([
    'order.created' => 'Order Created',
    'user.registered' => 'User Registered',
]);

Usage

1. Dispatch a payload manually

Fan a payload out to every active webhook subscribed to the event type:

use CleaniqueCoders\ConfigWebhook\Facades\ConfigWebhook;

ConfigWebhook::send('order.created', [
    'id' => $order->id,
    'total' => $order->total,
]);

The receiver gets:

// POST https://subscriber.example.com/hook
// Headers: X-Webhook-Signature, X-Webhook-Event, X-Webhook-Delivery
{
    "event": "order.created",
    "timestamp": "2026-06-08T12:00:00+00:00",
    "data": { "id": 123, "total": 49.90 }
}

2. Map a domain event (auto-dispatch)

Wire a domain event to a webhook type once and the package dispatches automatically whenever the event fires:

use App\Events\OrderCreated;
use CleaniqueCoders\ConfigWebhook\Facades\ConfigWebhook;

ConfigWebhook::listen(
    OrderCreated::class,
    'order.created',
    fn (OrderCreated $event) => [
        'id' => $event->order->id,
        'total' => $event->order->total,
    ],
);

3. Verifying signatures on the receiving side

use CleaniqueCoders\ConfigWebhook\Support\WebhookSignature;

$valid = WebhookSignature::verify(
    payload: $request->getContent(),
    signature: $request->header('X-Webhook-Signature'),
    secret: $sharedSecret,
);

Admin UI

Enable the bundled full-page route in config/config-webhook.php:

'route' => [
    'enabled' => true,
    'prefix' => 'admin/webhooks',
    'name' => 'config-webhook.index',
    'middleware' => ['web', 'auth'],
],

Or drop the Livewire component anywhere in your own layout:

<livewire:config-webhook::webhooks />

Restrict access with a gate:

'gate' => 'manage-webhooks', // ability string, or a fn ($user) => bool

Pruning logs

php artisan config-webhook:prune --days=30

How it works

Concern Class
Manager (facade root) ConfigWebhookregisterEvent(s), listen, send, dispatchFromEvent
Models Models\Webhook, Models\WebhookDeliveryLog (package Concerns\HasUuid)
Status Enums\DeliveryStatusPENDING, SUCCESS, FAILED, RETRYING
Delivery Jobs\SendWebhookEvent (queued, retry + backoff)
Signing Support\WebhookSignaturegenerate / verify
Events Events\WebhookDelivered, Events\WebhookFailed
CLI Commands\PruneWebhookDeliveryLogsCommand
UI Livewire\Webhooks + resources/views/livewire/webhooks.blade.php (Flux, optional)

Testing

composer test

The suite includes a true end-to-end test (tests/EndToEndTest.php) that mirrors how a consuming app uses the package: a domain event is mapped with ConfigWebhook::listen(), a subscriber webhook is created, the event is fired, and the queued job runs on the sync queue to deliver a signed HTTP request — asserting both the outgoing request and the recorded delivery log.

Local development (try it in a real app)

The package ships an Orchestra Testbench Workbench setup (testbench.yaml + workbench/) so you can boot a real Laravel app around it:

composer install
vendor/bin/testbench workbench:build   # creates the sqlite db + runs migrations
vendor/bin/testbench serve             # http://127.0.0.1:8000
  • GET /webhooks — the bundled Livewire admin UI (needs livewire/flux installed to render)
  • GET /fire — dispatches the sample OrderShipped domain event through the full pipeline

workbench/app/Providers/WorkbenchServiceProvider.php shows exactly how a host app registers its event catalogue and maps a domain event to a webhook type.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

This package was extracted and generalised from the G8Stack webhook integrations feature.

License

The MIT License (MIT). Please see License File for more information.