answear/acs-bundle
Symfony bundle for ACS pickup point integration. Configure API credentials via YAML, then use ParcelShopsService to fetch parcel shops by country (Greece or Cyprus) and optional kind, returning ParcelShop DTOs. Includes clear exceptions for service and response errors.
Architecture fit
answear/acs-bundle is a Symfony bundle, not a Laravel package. That distinction is the central product constraint: the code is consumable in a Laravel/PHP application, but it is not drop-in. It ships Symfony DI extension/config loading, a bundle class registered through config/bundles.php, Symfony Serializer/PropertyInfo-based DTO hydration, and Symfony-style exceptions. Laravel has no bundle registry or Flex auto-registration, so the README installation path does not apply unchanged.
The functional scope is narrow and clear: a read-only lookup of ACS parcel shops/pickup points for Greece and Cyprus, with an optional shop kind filter. That is useful for checkout delivery-option discovery, store-locator experiences, and carrier selection in GR/CY. It is not a shipping, label, tracking, or rate-quote integration. A TPM should treat it as an ACS parcel-shop reference implementation and API-contract accelerator, not as a complete logistics capability.
Architecture fit is good only if the roadmap need is parcel-shop discovery in those two markets and the team accepts a thin adaptation layer. It is poor if the team expects Laravel-native conventions, multi-country coverage, or write-side carrier operations.
Integration feasibility
apiKey, companyId, companyPassword, userId, userPassword, and optional language (default GR). These map cleanly to Laravel config/acs.php and environment variables.ParcelShopsService::getList(CountryIdEnum $countryId, ?int $kind = null) returning ParcelShop[] is small enough to wrap or port in days, not weeks.ServiceUnavailable for Guzzle failures and MalformedResponse for bad payloads. Adequate for a first release, but insufficient for nuanced retry/circuit-breaker policy without additional mapping.composer require [email protected]:answear/acs-bundle.git, which is not a normal Packagist package install. Expect to configure a Composer VCS repository or vendor/fork the code. This affects supply-chain review, version pinning, and CI reproducibility.answear_gls rather than answear_acs, and the prose duplicates companyId while omitting companyPassword. These are small but real signals that the integration path needs verification against source, not just the README.Technical risk
| Risk | Likelihood | Impact | TPM mitigation |
|---|---|---|---|
| Symfony-to-Laravel impedance mismatch (DI, config, serializer) | High | Medium | Budget an explicit adapter/port; do not plan a same-day install |
| Low adoption and maintainer concentration (0 stars, 0 dependents, Answear-internal ownership) | High | Medium | Treat as forkable MIT code; assign internal ownership and pin versions |
| ACS API contract drift or undocumented limits | Medium | High | Validate against ACS sandbox/credentials early; add contract tests |
| Dependency conflicts with Laravel’s Symfony component versions | Medium | Medium | Resolve a Composer matrix before committing; prefer isolating the package |
| Scope gap vs. roadmap (no labels, tracking, shipping) | Medium | High | Confirm product scope is discovery-only before adoption |
| Config/documentation errors causing silent misconfiguration | Medium | Medium | Verify extension alias and required keys in a spike; add config validation |
| PHP 8.4 / Symfony 7 requirements vs. current platform | Medium | Medium | Check Laravel/PHP versions; older platforms may need bundle 3.x or an upgrade |
| Security/supply-chain review of a Git-based dependency | Low–Medium | Medium | Vendor or mirror; run SCA; store credentials in secrets manager |
Key questions
Stack fit
| Symfony/bundle concern | Laravel equivalent | TPM note |
|---|---|---|
Bundle registration via config/bundles.php |
Illuminate\Support\ServiceProvider |
No Flex in Laravel; manual registration required |
YAML extension config (answear_acs.yaml) |
config/acs.php + env() |
Straightforward, but validate extension alias |
| Symfony Serializer / PropertyInfo DTO hydration | Manual mapping, JsonMapper, or Laravel validation |
Decide whether to keep Symfony components or simplify |
CountryIdEnum custom enum |
Native PHP/Laravel enum | Drop-in conceptually; verify backing values |
| Symfony exceptions | Laravel-friendly domain exceptions or HTTP client exceptions | Map at the adapter boundary |
| Guzzle client | Guzzle directly or Illuminate\Http\Client |
Prefer one HTTP abstraction across the app |
| PSR-3 logging removed upstream | Laravel Log facade in wrapper |
Add logging in our adapter, not upstream |
The cleanest Laravel fit is a thin application-level AcsParcelShopService that owns configuration, HTTP concerns, DTO mapping, caching, and exception translation. The upstream package can sit behind that service if dependency resolution is clean; otherwise the service becomes the replacement.
Migration path
ParcelShopsService manually with Guzzle and required config. Call ACS with real or sandbox credentials for GR and CY.kind values. Verify ParcelShop DTO fields, nullability, encoding, and error payloads. Confirm the CountryIdEnum values and the extension/config key names.AcsParcelShopService with:
config/acs.php and secrets via environment/vault.ServiceUnavailable, MalformedResponse → domain/HTTP exceptions).Compatibility
Sequencing
Run the work as a product-discovery and technical-feasibility spike in parallel, not as a sequential “install then build.” The commercial ACS access and the product fallback behavior are on the critical path more than the code adaptation. Gate full build on: credentials available, GR/CY response schema validated, Composer resolution clean, and product sign-off that discovery-only scope is sufficient.
Maintenance
answear_gls config typo and key inconsistencies mean our internal runbook — not the README — should be the source of truth.Support
Scaling
PickupPointProvider interface now. This package should be one adapter, not the domain model.Failure modes
| Failure | User/product impact | Mitigation |
|---|---|---|
| ACS API downtime or timeout | ACS delivery option unavailable at checkout | Feature flag, fallback carrier/static list, clear messaging |
| Malformed or changed response schema | DTO mapping failure, option disappears | Contract tests with fixtures, schema guards, alerting on MalformedResponse rate |
| Credential expiry or rotation | All lookups fail | Secrets manager, expiry monitoring, documented rotation runbook |
| Rate limiting | Intermittent failures under load | Shared cache, throttling, backoff, request coalescing |
Silent config error (answear_gls vs answear_acs, missing key) |
Service appears configured but fails at runtime | Startup config validation, health check, integration smoke test |
| Composer dependency conflict | Build/deploy failure | Lockfile discipline, isolated adapter package, CI matrix |
| Upstream abandonment | No fixes for ACS changes | Internal fork readiness, small surface, assigned owner |
| Geo/kind coverage gap | Wrong or missing shops for a market | Validate GR/CY and each kind; product acceptance tests |
Ramp-up
How can I help you explore Laravel packages today?