suare-su/pyrus_client_symfony
Symfony integration for the Pyrus client, making it easy to connect Symfony applications to Pyrus services through a configurable bundle. Provides the glue for using Pyrus APIs within your Symfony project.
suare-su/pyrus_client_symfony is a Symfony-bundle-flavored client for the Pyrus API (tasks, comments, catalogs, forms). It has no Laravel service provider, so plan on ~15 minutes of wiring before your first call.
Install the dependency
composer require suare-su/pyrus_client_symfony
Pin the minor version (^0.16) — this is still pre-1.0 and method signatures have moved between releases.
Add credentials to config. Put Pyrus credentials in config/services.php rather than reading env() at call sites:
'pyrus' => [
'base_url' => env('PYRUS_URL', 'https://api.pyrus.com/v4'),
'login' => env('PYRUS_LOGIN'), // account e-mail
'key' => env('PYRUS_SECURITY_KEY'),
'timeout' => 10,
],
Register the client in a service provider. The bundle's DI extension won't run inside Laravel, so instantiate the client yourself in AppServiceProvider::register() and bind it as a singleton. Wrap it in a thin App\Support\Pyrus\PyrusClient adapter so the rest of your app never imports package namespaces — this is what makes the next 0.x upgrade cheap.
Look here first: the package's Client/Api class and the *Create / *Get request objects. The README examples are Symfony-console-shaped; translate them into the adapter. The tests/ directory is the most reliable documentation of the actual payload shapes.
First use case: post a comment onto an existing Pyrus task — the subject of this release. Given a task ID (stored on your Eloquent model), build a CommentCreate request with the comment body and dispatch it. That single call unlocks the most common Laravel↔Pyrus integration: pushing status from your app into the task thread where business users actually read it.
$client->comments()->create(
CommentCreate::make($order->pyrus_task_id)->text("Shipped: {$order->tracking_number}")
);
Outbound notification (most common). Map Laravel domain events to Pyrus comments via a queued listener. Because CommentCreate is now a first-class request object, the listener stays declarative:
class CommentOnPyrusTask implements ShouldQueue
{
public function handle(OrderShipped $event): void
{
$this->pyrus->comments()->create(
CommentCreate::make($event->order->pyrus_task_id)
->text(view('pyrus.shipped', ['order' => $event->order])->render())
);
}
}
Keep the HTTP call out of the request cycle — Pyrus latency should never block a user action or an HTTP response.
Wrap, don't sprinkle. Expose your own interface (PyrusGateway) with the 5–6 operations you actually use (create comment, get task, list catalog, upload file, create task). Bind the package behind it. When the package reorganizes namespaces in 0.17, you patch one file.
Idempotency guard. Pyrus has no idempotency key on comment creation. Add a pyrus_comments table keyed by (model_type, model_id, event) and skip if a row exists; this also gives you an audit trail and a replay path after failed jobs.
Throttling. Route all Pyrus traffic through a named queue with RateLimited middleware (RateLimiter::for('pyrus', fn () => Limit::perSecond(3))). Comment bursts from a bulk import will otherwise 429, and the Symfony transport will surface that as a generic exception.
Testing. Http::fake() does nothing here — the package uses Symfony HttpClient, not the Laravel HTTP client. Test your own gateway interface with a fake implementation, and if you must test the adapter, inject Symfony\Component\HttpClient\MockHttpClient and assert on the recorded request body. Never let CI touch the real API.
Formatting comments. Business users read these in the Pyrus UI, so render a Blade view to a string rather than concatenating text — but keep the result plain-ish; Pyrus comment markup is not HTML.
Symfony\Contracts\HttpClient\Exception\* (ClientExceptionInterface, TransportExceptionInterface), not Illuminate\Http\Client\RequestException. Catch those types explicitly, and let TransportExceptionInterface retry while treating 4xx as terminal.config/pyrus.php to publish. If you copy a bundle config array anywhere, it will be silently ignored — construct the client with explicit arguments and test that the base URL and credentials actually land.tries = 1 plus your idempotency table, or make the comment body carry a dedupe marker you can detect before retrying.PYRUS_SECURITY_KEY in any exception reporter before it reaches Sentry/Bugsnag.timeout (5–10s) and a short max_duration for retries; otherwise a hung connection occupies a queue worker for minutes.CommentCreate's constructor/method names may change in a patch. Use "suare-su/pyrus_client_symfony": "~0.16.0" and read the changelog before bumping — this release itself is a pure addition, but there's no BC promise yet.CommentCreate exposes them; if not, subclass your adapter's request builder rather than forking the package — you want to stay on the upstream upgrade path for when those land.How can I help you explore Laravel packages today?