Download the PHP package vimatech/laravel-integrations without Composer
On this page you can find all versions of the php package vimatech/laravel-integrations. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download vimatech/laravel-integrations
More information about vimatech/laravel-integrations
Files in vimatech/laravel-integrations
Package laravel-integrations
Short Description Config-driven ports & adapters foundation for integrating external providers in Laravel: capability drivers, context routing and normalized webhooks.
License MIT
Homepage https://github.com/vimatech-io/laravel-integrations
Informations about the package laravel-integrations
Laravel Integrations
A config-driven ports & adapters foundation for integrating external providers in Laravel.
Adding a provider means writing one isolated adapter class and a config entry — you never touch
business logic, routing, or the webhook pipeline. It generalizes Laravel's own Manager/driver pattern
with context routing (route a capability to a driver by country, tenant, …) and a normalized
inbound webhook pipeline (verify → translate → de-duplicate → dispatch canonical events).
This package is intentionally domain-free: it ships no concrete vendor and no business logic. The capabilities (what an adapter actually does) are contracts defined by your application or by consumer packages.
Why Laravel Integrations?
External providers leak into business logic in predictable ways: a match ($country) here, a
hard-coded SDK client there, bespoke webhook controllers everywhere. This package gives you a single,
boring seam:
Your business logic depends on a capability contract; the concrete provider is selected by configuration and runtime context.
Feature Matrix
| Feature | Supported |
|---|---|
| Config-driven drivers (ports & adapters) | ✅ |
| Context routing (by country, tenant, …) | ✅ |
| Per-tenant driver overrides (from your DB) | ✅ |
| Normalized inbound webhook pipeline | ✅ |
| Canonical, provider-agnostic events | ✅ |
| Webhook idempotency (cache or database) | ✅ |
| Pluggable credential storage | ✅ |
Strict resolution (resolveStrict) |
✅ |
| Test fakes & driver-usage assertions | ✅ |
| Octane / FrankenPHP safe | ✅ |
| Concrete vendors / business logic | ❌ (you own them) |
| UI | ❌ |
Installation
The service provider is auto-discovered. Publish the config (and, if you use the database idempotency store, the migration):
Requires PHP 8.3+ and Laravel 11, 12 or 13.
Core concepts
| Concept | Description |
|---|---|
| Capability | A named contract owned by a consumer (e.g. einvoice, payments). This package never sees it. |
| Driver | An adapter implementing a capability. Marked with Vimatech\Integrations\Contracts\Driver. |
IntegrationManager |
Resolves a driver by capability + key from config, à la Illuminate\Support\Manager. |
ContextRouter |
Resolves a driver by default or by a context array (['country' => 'FR']). |
ResolvesTenantDriver |
Optional contract to override the driver per tenant from your database. |
WebhookTranslator |
Verifies an inbound request and translates it into canonical events. |
CanonicalEvent |
Provider-agnostic event base class with a stable idempotency key. |
Configuration
config/integrations.php (abbreviated — see the published file for full comments):
Adding a driver
1. Define the capability contract (in your app or a consumer package). It extends the Driver
marker:
2. Write the adapter. Adapter constructors receive the resolved config array:
3. Register it in config under the capability's drivers map. That's it — no business-logic
changes.
Need bespoke construction (a pre-built SDK client, etc.)? Register a factory:
Resolving & routing drivers
Context resolution order for for($capability)->resolve($context):
- A bound
ResolvesTenantDriver(per-tenant override). - Static routing on the configured
routing.bydimension. - The capability
default. - Otherwise
UnresolvableDriveris thrown.
Need to fail instead of falling back to the default when context doesn't match? Use
resolveStrict():
Other router methods: default(), via('sdi'), and key($context) (returns the resolved driver key
without instantiating).
Per-tenant overrides
Bind an implementation of ResolvesTenantDriver to let the database decide. Return null to defer to
static routing:
Webhooks
A single generic inbound route is registered:
For each request, the pipeline:
- Checks that webhooks are enabled for the capability (else
404). - Resolves a
WebhookTranslator— the configuredwebhooks.translator, or the resolved driver if it implementsWebhookTranslator. - Calls
verify($request). On failure it dispatchesWebhookRejectedand returns403. - Dispatches
WebhookReceived. - Calls
translate($request)and, for eachCanonicalEvent, enforces idempotency via the event key store before dispatching it through Laravel's event system.
Make a driver translate its own webhooks:
Define canonical events your application listens for. The idempotencyKey() must be stable across
redeliveries:
Idempotency store is configurable via webhooks.event_store:
cache(default) — uses the atomicCache::add()operation.database— uses a unique index on the publishedintegration_webhook_eventstable.
Idempotency is claimed before dispatch. An event key is marked as seen as soon as it is accepted, so a redelivery is skipped even if a listener fails. Make your canonical-event listeners queued (
ShouldQueue): the webhook returns200immediately, and listener failures are retried by the queue rather than by the provider re-sending the webhook. Keep listeners idempotent on your own side too.
Credentials & secure storage
By default credentials are read straight from config (store => 'config'). Set
store => 'encrypted' to decrypt the keys listed in a driver's encrypted array using Laravel's
encrypter:
To store credentials with vimatech/laravel-secure-fields or any
other backend, bind your own CredentialStore — the package never assumes a vendor:
The integrations:list command
Prints every configured capability with its drivers, default, routing map and webhook status.
Testing
Swap the manager for a fake and assert which drivers your code used:
Integrations::fake() keeps the real routing logic (so context routing still resolves to the right
key) while returning recording doubles. Provide your own capability fakes when you need behaviour:
Available assertions on the fake: assertDriverUsed(), assertDriverNotUsed(), assertNothingUsed(),
and used() for the raw record.
Octane & FrankenPHP
The package is built for long-lived workers. It keeps no static or global state; the only mutable
state is the per-key driver instance cache on the IntegrationManager singleton — which is a
performance win under workers, since each adapter is built once and reused across requests.
Three rules keep it safe and fast in worker mode:
-
Keep adapters stateless per request. Read from the injected
$config; never store request-bound state (the current user, theRequest, a cart) on an adapter, or it will leak into the next request. Driver resolution itself is just array lookups plus a one-time container build. -
Queue your canonical-event listeners (
ShouldQueue) — see the webhook idempotency note. The worker returns200immediately and retries happen on the queue. - Per-tenant credentials via
extend()? The instance cache is keyed bycapability:key, not by tenant. That is correct when credentials come from config (static per key). Only if you register anextend()factory that captures per-tenant credentials do you need to avoid the shared cache — resolve those per tenant in your own code instead.
If (and only if) you intentionally keep request state on an adapter, flush the cache each request:
Leave this off otherwise — it discards the build cache that makes workers fast.
env() is only ever read inside config/integrations.php, and routes are registered once, so the
package is fully compatible with config:cache and route:cache.
Quality
Contributing
Contributions are welcome.
Please ensure:
- Tests pass (
composer test) - PHPStan passes (
composer analyse) - Code style is formatted with Pint (
composer format)
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our Security Policy for reporting vulnerabilities.
License
The MIT License (MIT). Please see the License File for more information.
Credits
Built and maintained by Vimatech. Created by Adel Zemzemi.
All versions of laravel-integrations with dependencies
illuminate/contracts Version ^11.0 || ^12.0 || ^13.0
illuminate/support Version ^11.0 || ^12.0 || ^13.0