creating-integration · git:20260922.7ecf42a · 2026-09-22 · sha256 d69263d3d0196f00
creating-integration git:20260922.7ecf42aA
Immutable. This exact content never changes and is served at /api/v1/blob/d69263d3d0196f00.
---
name: creating-integration
description: Add, change, or debug external API integrations, vendor SDK adapters, and bridges to legacy business workflows. Use when an Action or domain service needs an outer technical dependency.
---
# External and legacy integrations
Put concrete external adapters in `App\Infrastructure\Integrations`, grouped by provider when useful. Legacy workflow bridges may live in `App\Infrastructure\Legacy`. Keep HTTP clients, SDK objects, transport failures, and provider-specific payloads at this boundary; translate them into consumer concepts.
## Connect the consumer
A consumer in Domain or Application cannot depend on a concrete Infrastructure class. This boundary is a concrete reason for a contract:
- Application need: `App\Application\<Capability>\Contracts`.
- Domain need: `App\Domain\<Capability>\Contracts`.
- Implementation: Infrastructure.
- Binding: a standard Laravel service provider.
```php
// App\Application\Orders\Contracts\PaymentGateway
interface PaymentGateway
{
public function refund(string $paymentReference, string $idempotencyKey): void;
}
// In a service provider's register() method:
$this->app->bind(
\App\Application\Orders\Contracts\PaymentGateway::class,
\App\Infrastructure\Integrations\Payments\ProviderPaymentGateway::class,
);
```
After `OrderCancelled` commits, a queued listener can invoke a refund Action that receives `PaymentGateway`. The adapter implements that interface and translates the provider response. Derive a stable idempotency key for a refund operation and use the provider's supported mechanism or an application deduplication strategy.
Do not inject SDK types into the contract or resolve concrete adapters from Actions through `app()`, strings, or custom facades. Do not create an interface for every helper inside Infrastructure.
Keep external calls outside database transactions where possible. A local rollback cannot reverse a remote refund; design retries and failure handling for the actual use case rather than treating the database transaction as distributed atomicity.
For migrated code using legacy business workflows, the same contract/adapter pattern applies. Direct Eloquent persistence is still allowed; it must not become a shortcut into legacy workflow orchestration.
Use events by default for asynchronous reactions. A scheduling contract is warranted only for a real infrastructure capability, not merely because a Job exists.