Product Decisions This Supports
- Build vs. buy on outbound integration plumbing. Every B2B SaaS eventually needs "tell someone else when something happened." The default build is bespoke: a Slack poster, a Zapier hook, an internal service call, a client-specific endpoint. Each one re-implements HTTP, queuing, retries, and error handling. This package collapses outbound delivery into a single Laravel Notification channel, so the marginal cost of the n-th integration destination approaches zero and the effort moves to the layer that actually differentiates (see below).
- "Customer-configurable webhooks" as a shippable roadmap item. Because delivery is driven by
via() and a per-notifiable route lookup, per-tenant destinations become a data problem, not a code problem — one row per tenant (destination_url, secret, enabled, event_types) instead of a new integration per customer. This is a legitimate sales-engineering feature ("integrate with your stack on day one") that can be scoped in days rather than a quarter.
- Architecture standard: Notifications as the outbound event bus. Committing to this package implies committing to Laravel's notification abstraction for external fanout, rather than ad-hoc jobs or event listeners. That buys you queueing,
ShouldQueue, per-channel failure isolation, and the ability to add mail/Slack/database delivery of the same event without new code. It also sets a clean seam: the notification becomes the canonical "event contract."
- Use cases it makes cheap to evaluate and ship:
- Internal service fanout (order created → fulfillment service).
- Low-code automation triggers (Zapier / Make / n8n) — a fast path to "we integrate with 5,000 apps" marketing.
- Chat-ops via incoming webhook URLs (Slack, Teams, Discord, Google Chat) without pulling in each provider's SDK.
- Ops/audit alerting into an internal collector.
- Risk/effort sizing for the roadmap conversation. The integration surface is deliberately tiny — it is a thin wrapper over Laravel's HTTP client. That means low adoption cost and low switching cost, which in turn means you should budget the real engineering for the governance layer: HMAC request signing with secret rotation, delivery attempt logging, exponential backoff beyond queue defaults, idempotency keys, per-tenant rate limiting, endpoint auto-disable on repeated failure, and payload versioning. Plan for "1 day to adopt, 1–2 sprints to make it trustworthy."
- Vendor/partner dependency decision. A webhooks feature is an implicit contract with customers. Deciding to use a library here is fine; deciding not to wrap it in an internal adapter is not. The wrapper (your
WebhookChannel subclass or a WebhookMessage factory) is what lets you swap in a hosted delivery provider (Svix, Hookdeck) later if volume or compliance demands it.
- Framework upgrade cadence. The 2.7.0 release (Laravel 12.x compatibility) is a reminder that this dependency tracks Laravel majors. That is cheap to absorb now, but it should be an explicit line item in any future framework-upgrade plan — an unmaintained channel package is the classic thing that silently blocks a Laravel upgrade.
When to Consider This Package
Adopt when:
- You're on Laravel (8+ through 12.x) and already use the Notification system — the marginal learning cost is one method on a class you already write.
- Destination count is small-to-moderate and mostly internal or trusted (your own services, a Slack channel, a customer-provided Zapier catch hook).
- Events are idempotent or non-critical: a missed "user invited" ping is recoverable; a missed "payment captured" is not.
- Best-effort delivery with queue-level retries is an acceptable SLA, and you can tolerate occasional duplicate deliveries.
- You want an integration surface shipped this sprint, not next quarter, and you're willing to own the governance layer yourself.
- You value a small, auditable codebase: MIT-licensed, sub-500-line surface, replaceable in an afternoon if abandoned.
Look elsewhere (or build) when:
- You need guaranteed, at-least-once delivery with durable retry schedules, dead-letter queues, and replay — queue retries are not a delivery guarantee.
- You need request signing, secret rotation, and replay protection as a first-class product feature (security review will ask; the package alone won't answer).
- You need delivery observability: per-endpoint success rates, response bodies, latency, and a customer-facing delivery log. This is table stakes for a public webhooks feature and is entirely outside this package's scope.
- Volume and fanout are high (thousands of events/minute to many endpoints) — you'll want batching, per-destination concurrency control, and circuit breaking.
- You need endpoint lifecycle management: self-serve registration, verification handshakes, auto-disable on repeated 4xx/5xx, and re-enable flows.
- You're not on Laravel, or you're standardizing outbound events across polyglot services where a language-neutral broker/producer is the better center of gravity.
Dependency-risk note: ~176 stars and no listed dependents signals a small maintainer pool and low community gravity. Mitigants: MIT license, minimal surface area, and an actively maintained release line — 2.7.0 landed Laravel 12.x support, so the package is current through the newest framework major. Note what that release is: a single compatibility PR with no functional change, which confirms maintenance without closing any of the functional gaps above. Treat it as a utility, not a platform bet — pin the version, keep it behind an internal adapter, and don't let vendor-specific quirks leak into domain code.
How to Pitch It (Stakeholders)
For executives (30 seconds): Outbound webhooks are a standard expectation in B2B products and normally cost weeks of bespoke integration work per destination. This package turns "send an event to an external URL" into a few lines inside our existing notification classes, so the n-th integration costs near zero instead of near a sprint. It is current and maintained — 2.7.0 just added Laravel 12 support. Recommendation: adopt it as a small dependency behind an internal wrapper, and invest the saved time in the things customers and security actually judge us on — signed payloads, retry guarantees, and a delivery log.
For engineering (what it is and isn't): It's a thin channel adapter over Laravel's HTTP client — you add toWebhook() to a notification, return a URL + payload, and it POSTs (queueable, testable with Http::fake()). It is not a delivery system: no signing, no persistence, no backoff policy, no idempotency, no dead-letter. 2.7.0 is a Laravel 12 compatibility bump only — no new capability, no breaking change, no action required beyond a routine composer update and a test run on the 12.x matrix. Adopting it is roughly a day of work; making it production-grade for external customers is one to two sprints of governance work we should plan explicitly rather than discover.
The decision being asked for: Approve the dependency and the wrapper pattern (low risk, easily reversed), and approve the follow-on scope for signing + delivery logging if we intend to expose this to customers rather than use it internally.
How we'll know it worked: time-to-first-integration drops from weeks to days; number of supported destinations grows without proportional engineering; the governance backlog (signing, retries, delivery log) is tracked as explicit product scope rather than accumulating as invisible technical debt; and framework upgrades never stall on this dependency.