Install the Bundle
Add to composer.json:
"require": {
"caponica/amazon-mws-bundle": "dev-master"
}
Run composer update.
Register the Bundle
Add to AppKernel.php:
new Caponica\AmazonMwsBundle\CaponicaAmazonMwsBundle(),
Configure Parameters
Define credentials in app/config/parameters.yml:
caponica_amazon_mws_config_<marketplace>:
seller_id: "YOUR_SELLER_ID"
access_key: "YOUR_ACCESS_KEY"
secret_key: "YOUR_SECRET_KEY"
application_name: "YourAppName"
application_version: "1.0"
amazon_site: "US|UK|DE|FR|IT|ES|JP|CA|IN|BR|MX|AU|CN|SG|TR|PL|NL|IT|SE|BE|CH|AT"
Define the Service
Configure the service in app/config/services.yml:
services:
amazon_mws.<marketplace>:
class: Caponica\AmazonMwsBundle\Service\AmazonMwsService
calls:
- [setConfig, [%caponica_amazon_mws_config_<marketplace>%]]
First Use Case Inject the service into a controller or command and call an MWS API method:
use Caponica\AmazonMwsBundle\Service\AmazonMwsService;
class MyController extends Controller
{
public function __construct(AmazonMwsService $amazonMws)
{
$this->amazonMws = $amazonMws;
}
public function getOrders()
{
$result = $this->amazonMws->getOrders([
'CreatedAfter' => date('Y-m-d\TH:i:s\Z', strtotime('-7 days')),
'CreatedBefore' => date('Y-m-d\TH:i:s\Z')
]);
return $this->renderOrders($result);
}
}
Multi-Marketplace Integration
Define separate services for each marketplace (e.g., amazon_mws.us, amazon_mws.uk) and inject the required one based on context (e.g., user location, product origin).
Command-Line Automation Use Symfony commands to automate MWS tasks (e.g., order processing, inventory updates):
namespace App\Command;
use Caponica\AmazonMwsBundle\Service\AmazonMwsService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SyncInventoryCommand extends Command
{
protected static $defaultName = 'amazon:sync_inventory';
private $amazonMws;
public function __construct(AmazonMwsService $amazonMws)
{
$this->amazonMws = $amazonMws;
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Syncing inventory...');
$result = $this->amazonMws->listInventorySupply([
'Query' => 'Available',
'Condition' => 'All'
]);
// Process $result
}
}
Event-Driven Integration
Trigger MWS actions in response to Symfony events (e.g., kernel.request for real-time order updates):
$container->get('event_dispatcher')->addListener('kernel.request', function () use ($container) {
$amazonMws = $container->get('amazon_mws.us');
$orders = $amazonMws->getOrders(['Status' => 'Unshipped']);
foreach ($orders as $order) {
// Process unshipped orders
}
});
Data Transformation Use Symfony’s serializer or custom mappers to transform MWS responses into domain objects:
$orders = $this->amazonMws->getOrders(['Status' => 'Unshipped']);
$serializer = $this->container->get('serializer');
$domainOrders = $serializer->deserialize(
json_encode($orders),
'array<App\Entity\Order>',
'json'
);
Rate Limiting and Retries Implement a decorator pattern to handle MWS rate limits and retries:
class AmazonMwsRateLimiterDecorator implements AmazonMwsServiceInterface
{
private $decorated;
private $maxRetries = 3;
public function __construct(AmazonMwsService $decorated)
{
$this->decorated = $decorated;
}
public function getOrders(array $params)
{
$retries = 0;
while ($retries < $this->maxRetries) {
try {
return $this->decorated->getOrders($params);
} catch (Exception $e) {
if ($retries === $this->maxRetries - 1) {
throw $e;
}
sleep(2 ** $retries); // Exponential backoff
$retries++;
}
}
}
}
AmazonMwsService via constructor for testability.parameters.yml entries (e.g., amazon_site must be a valid MWS marketplace code).$this->logger->info('Fetching orders', ['params' => $params]);
$result = $this->amazonMws->getOrders($params);
$this->logger->debug('Orders response', ['response' => $result]);
$cache = $this->container->get('cache.app');
$cacheKey = 'amazon_products_' . md5(json_encode($params));
if (!$cache->has($cacheKey)) {
$products = $this->amazonMws->listMatchingProducts($params);
$cache->set($cacheKey, $products, 3600); // Cache for 1 hour
} else {
$products = $cache->get($cacheKey);
}
Deprecated Package
amazon-mws/php-sdk to a maintained version like ^3.0).No Built-in Service
services.yml.parameters to dynamically generate service configurations:
services:
_defaults:
public: false
amazon_mws.%amazon_mws.config%:
class: Caponica\AmazonMwsBundle\Service\AmazonMwsService
calls:
- [setConfig, [%caponica_amazon_mws_config.%amazon_mws.config%]]
Error Handling
AWS.MWS.Error.InvalidParameter) are thrown as exceptions but may lack context.try {
$result = $this->amazonMws->getOrders($params);
} catch (Exception $e) {
$this->logger->error('MWS Error', [
'message' => $e->getMessage(),
'code' => $e->getCode(),
'params' => $params
]);
throw new \RuntimeException('Failed to fetch orders: ' . $e->getMessage(), 0, $e);
}
Marketplace-Specific Quirks
ListOrders) behave differently per marketplace (e.g., DE vs. US).Authentication Rotations
secret_key) may expire or require rotation.ParameterBag with encrypted values).AWS_MWS_DEBUG environment variable to log raw API requests/responses:
export AWS_MWS_DEBUG=1
DOMDocument or SimpleXMLElement to inspect responses:How can I help you explore Laravel packages today?