Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Amazon Ecs Php Laravel Package

exeu/amazon-ecs-php

PHP library for the Amazon Product Advertising API (ECS). Search Amazon catalogs, look up items by ASIN, browse nodes, and parse XML responses through a simple object-oriented client. Useful for affiliate product feeds, price checks, and availability lookups.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: this library targets Amazon ECS (the old Product Advertising API 4.0), which Amazon retired in May 2021, and the repo is archived and GPL-3.0. It is not a viable dependency for new Laravel work. Everything below is written for the two legitimate scenarios: you inherited a codebase that already uses it, or you are evaluating it for replacement.

  • Skim the short README, then go straight to src/Exeu/AmazonECS/Service.php and src/Exeu/AmazonECS/Service/*.php. Service is the entry point; each class under Service/ maps 1:1 to a PAAPI operation (ItemLookup, ItemSearch, SimilarityLookup, BrowseNodeLookup, plus the old cart operations).
  • Install only inside a throwaway branch — old tags pull abandoned transitive deps and often fail to resolve against Laravel 9/10 (composer why-not exeu/amazon-ecs-php is your first debugging step).

Minimal wiring (v2.x style; method names shift between tags — verify against the version you install):

use Exeu\AmazonECS\Service;

$service = Service::factory(
    config('amazon.access_key'),
    config('amazon.secret_key'),
    config('amazon.associate_tag'),
    'de' // locale / endpoint
);

$lookup = $service->itemLookup();
$lookup->setItemIds(['B00EXAMPLE']);
$lookup->setResponseGroups(['ItemAttributes', 'Images', 'Offers']);

$response = $lookup->execute();

First use case: a product detail page. Resolve an ASIN to title, price, image and availability, cache the normalized result, and never call the library directly from a controller — put it behind a repository class so the swap to PAAPI 5.0 later is a one-file change.

Implementation Patterns

Config + container binding. Keep one source of truth in config/amazon.php and bind a singleton in AppServiceProvider:

$this->app->singleton(\Exeu\AmazonECS\Service::class, fn () => \Exeu\AmazonECS\Service::factory(
    config('amazon.access_key'),
    config('amazon.secret_key'),
    config('amazon.associate_tag'),
    config('amazon.locale'),
));

Repository boundary (the pattern that matters). Wrap the vendor classes in an interface returning your own DTOs. This is the single highest-leverage decision, because the vendor package is dead and the repository lets you reimplement against PAAPI 5.0 without touching call sites.

interface ProductCatalog
{
    public function findByAsin(string $asin): ?ProductData;
    public function search(string $keywords, int $page = 1): Collection;
}

Cache aggressively, key by ASIN. Historically the quota was ~1 request/second and a daily cap tied to prior-month revenue. Cache::remember("amazon:item:{$asin}", now()->addHours(12), fn () => ...) is not optional. Cache negative/"not found" results too, briefly, so a bad ASIN doesn't burn quota.

Queue anything that isn't a single lookup. Batch ItemLookup accepts up to 10 ASINs; chunk array_chunk($asins, 10) inside a job and use Laravel's rate limiter:

RateLimiter::for('amazon', fn () => Limit::perSecond(1));

Persist search results rather than proxying. Run ItemSearch in a job, normalize into an amazon_products table, and serve pages from the database. This survives the quota and lets you filter/sort locally — PAAPI never supported more than 10 pages of 10 results anyway.

Error handling wrapper. Amazon returns business errors with HTTP 200, so try/catch alone is insufficient:

try {
    $response = $lookup->execute();
    if ($response->isError()) { /* inspect error code */ }
} catch (\Exception $e) {
    report($e);
    return null;
}

Map RequestThrottled to a retry with exponential backoff; map AWS.InvalidParameterValue and AWS.ECommerceService.NoExactMatches to a domain exception or null. Retry only throttle-type errors.

Testing. Never hit the network in tests. Bind a fake ProductCatalog in the container; if you must test the vendor path, serialize a recorded response via the response object's raw XML/string output into a fixture and feed it to the parser.

Gotchas and Tips

  • The API is gone. ECS/PAAPI 4.0 was retired in May 2021. Live calls fail regardless of credentials, region, or associate tag. The library's request format, endpoints and signing are all for a protocol Amazon no longer serves. Treat it as reference code, not a dependency.
  • GPL-3.0 is a real problem. It is a viral copyleft license; shipping it inside a distributed closed-source Laravel app is a compliance risk. The Laravel ecosystem is MIT throughout — get this cleared before it lands, and be aware internal-only use is a different calculus from distribution.
  • Archived, zero dependents, no security patches. Expect PHP 8.x incompatibilities (dynamic properties, removed functions) and Composer conflicts with the Guzzle/Symfony versions modern Laravel requires. If install fails, don't fight it — that's a signal, not a puzzle.
  • Credentials: the associate tag is mandatory; without it every request errors. Keep access key/secret in .env, never in the config file, and rotate if a committed .env ever leaked.
  • Clock skew breaks signing. If you're reviving code around this, SignatureDoesNotMatch on a working keypair is usually NTP drift on the host, not bad credentials.
  • HTTP 200 with errors. Always inspect the error nodes on the response object. Status-code-only handling silently returns empty product data.
  • Batch limits. Max 10 IDs per ItemLookup; more than 10 pages/100 results per ItemSearch is not available.
  • Price parsing. FormattedPrice is locale-localized ("1.234,56 €"); Amount is an integer in 1/100 units — divide by 100 and store the currency code alongside it. Don't parse the formatted string.
  • XML namespaces. If you bypass the response objects and touch SimpleXML directly, you'll need ->children('http://webservices.amazon.com/AWSECommerceService/2011-08-01') or var_dump shows empty nodes. This trips up most debugging sessions.
  • Only request the response groups you need. They don't cost extra quota, but they inflate payload and parsing time on large ItemSearch batches.
  • Debugging. Log the raw request (redact the signature) and raw response body on failure. Once the endpoint is dead, the error you get back will look like a generic AWS rejection — don't spend a day chasing credentials.
  • Migration path. The author's own successor is exeu/apai-io, but for new work go directly to aws/aws-sdk-php against PAAPI 5.0 (GetItems, SearchItems, JSON body, SigV4, x-amz-target header). Because everything is behind ProductCatalog, you can ship the new implementation next to the old one and flip the container binding.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels