PHPackages                             tims/laravel-amazon-spapi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. tims/laravel-amazon-spapi

ActiveLibrary

tims/laravel-amazon-spapi
=========================

Laravel integration for Amazon's official Selling Partner API PHP SDK

v1.1.0(1mo ago)03↓75%MITPHPPHP ^8.3

Since Jul 14Pushed 1mo agoCompare

[ Source](https://github.com/timslabs/laravel-amazon-spapi)[ Packagist](https://packagist.org/packages/tims/laravel-amazon-spapi)[ RSS](/packages/tims-laravel-amazon-spapi/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (11)Versions (3)Used By (0)

laravel-amazon-spapi
====================

[](#laravel-amazon-spapi)

Laravel integration for Amazon’s official Selling Partner API PHP SDK (`amzn-spapi/sdk`).

Why this package?
-----------------

[](#why-this-package)

`amzn-spapi/sdk` is the API client. This package adds the Laravel layer around it:

- Config and environment-based LWA credentials
- Single-seller and multi-seller credential storage
- Access-token and Restricted Data Token (RDT) caching
- Automatic RDT attachment for PII endpoints
- OAuth helpers for Seller Central authorization
- Grantless client helpers (Notifications, client-secret rotation)
- Feed and report document upload/download
- HTTP retries for 429 and transient 5xx responses
- Queue jobs for report/feed create → poll → download
- Test fakes via `SpApiFake`

You continue to call official `SpApi\Api\...` classes; this package configures and supports them in Laravel.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 10, 11, or 12

Installation
------------

[](#installation)

```
composer require tims/laravel-amazon-spapi
```

Publish the config:

```
php artisan vendor:publish --tag=amazon-spapi-config
```

Configuration
-------------

[](#configuration)

Add these to your `.env`:

```
AMAZON_SPAPI_INSTALLATION_TYPE=single

AMAZON_SPAPI_LWA_CLIENT_ID=
AMAZON_SPAPI_LWA_CLIENT_SECRET=
AMAZON_SPAPI_LWA_REFRESH_TOKEN=

# NA, EU, or FE
AMAZON_SPAPI_ENDPOINT_REGION=NA

# Optional
AMAZON_SPAPI_SANDBOX=false
AMAZON_SPAPI_APPLICATION_ID=
AMAZON_SPAPI_REDIRECT_URI=https://your-app.test/amazon/callback

# Automatic RDT (enabled by default)
AMAZON_SPAPI_RDT_AUTO=true
AMAZON_SPAPI_RDT_DATA_ELEMENTS=buyerInfo,shippingAddress

# Retries for 429 / 5xx (enabled by default)
AMAZON_SPAPI_RETRY_ENABLED=true
AMAZON_SPAPI_RETRY_MAX_ATTEMPTS=3
AMAZON_SPAPI_RETRY_BASE_DELAY_MS=500
```

Single-seller mode
------------------

[](#single-seller-mode)

Type-hint `SpApiManager` or use the facade to build official SDK API clients:

```
use SpApi\Api\sellers\v1\SellersApi;
use Tims\AmazonSpApi\Facades\AmazonSpApi;
use Tims\AmazonSpApi\SpApiManager;

public function index(SpApiManager $spApi)
{
    /** @var SellersApi $api */
    $api = $spApi->make(SellersApi::class);
    $result = $api->getMarketplaceParticipations();

    return response()->json($result);
}

// Or via facade:
$api = AmazonSpApi::make(SellersApi::class);
```

In single-seller mode you can also resolve `\SpApi\Configuration` from the container.

Multi-seller mode
-----------------

[](#multi-seller-mode)

1. Set `AMAZON_SPAPI_INSTALLATION_TYPE=multi` (or `installation_type` in config).
2. Publish and run migrations:

```
php artisan vendor:publish --tag=amazon-spapi-multi-seller
php artisan migrate
```

3. Store sellers and credentials:

```
use Tims\AmazonSpApi\Models\Credentials;
use Tims\AmazonSpApi\Models\Seller;

$seller = Seller::create(['name' => 'My Seller']);

$credentials = Credentials::create([
    'seller_id' => $seller->id,
    'selling_partner_id' => 'A********',
    'region' => 'NA',
    // Optional when using shared app credentials from .env
    'client_id' => null,
    'client_secret' => null,
    'refresh_token' => 'Atzr|...',
]);
```

4. Build API clients from a credentials row:

```
use SpApi\Api\sellers\v1\SellersApi;

$api = $credentials->make(SellersApi::class);
$result = $api->getMarketplaceParticipations();
```

`client_id` / `client_secret` fall back to the single-seller LWA env values when left null (shared SP-API application). Refresh tokens and client secrets are stored encrypted.

OAuth
-----

[](#oauth)

Build Seller Central authorize URLs and exchange authorization codes for refresh tokens:

```
use Tims\AmazonSpApi\Enums\Marketplace;
use Tims\AmazonSpApi\OAuth;

$oauth = OAuth::fromConfig();

$authorizeUrl = $oauth->getAuthorizationUri(
    marketplace: Marketplace::US,
    state: $state,
    draftApp: true,
);

// After Amazon redirects back with spapi_oauth_code:
$refreshToken = $oauth->getRefreshToken($request->query('spapi_oauth_code'));
```

Restricted Data Tokens (RDT)
----------------------------

[](#restricted-data-tokens-rdt)

Configure `dataElements` once. With automatic RDT enabled, restricted calls do not need a manual `restrictedDataToken` argument:

```
use SpApi\Api\orders\v0\OrdersV0Api;
use Tims\AmazonSpApi\Facades\AmazonSpApi;

$ordersApi = AmazonSpApi::make(OrdersV0Api::class, options: [
    'data_elements' => ['buyerInfo', 'shippingAddress'],
]);

$result = $ordersApi->getOrders(
    ['ATVPDKIKX0DER'],
    '2024-01-01T00:00:00Z',
);
```

Or use `.env` / config defaults:

```
AMAZON_SPAPI_RDT_AUTO=true
AMAZON_SPAPI_RDT_DATA_ELEMENTS=buyerInfo,shippingAddress
# AMAZON_SPAPI_RDT_TARGET_APPLICATION=
AMAZON_SPAPI_RDT_SKIP_IN_SANDBOX=true
```

```
$ordersApi = AmazonSpApi::make(OrdersV0Api::class);
$ordersApi->getOrder($orderId);
```

Disable automatic RDT when you want to pass tokens yourself:

```
AmazonSpApi::make(OrdersV0Api::class, options: ['auto_rdt' => false]);
```

### Manual RDT

[](#manual-rdt)

```
$rdt = AmazonSpApi::restrictedDataToken(
    path: '/orders/v0/orders',
    dataElements: ['buyerInfo', 'shippingAddress'],
);

$ordersApi = AmazonSpApi::make(OrdersV0Api::class, options: ['auto_rdt' => false]);
$result = $ordersApi->getOrders(
    ['ATVPDKIKX0DER'],
    '2024-01-01T00:00:00Z',
    restrictedDataToken: $rdt,
);
```

`AmazonSpApi::isRestrictedOperation('OrdersV0Api-getOrder')` uses the official SDK restricted-operations list.

In sandbox mode, automatic RDT is skipped (`skip_in_sandbox`). Restricted sandbox calls work without an RDT.

Grantless operations
--------------------

[](#grantless-operations)

Some Notifications and Application Management calls do not use a seller refresh token. They use app client id/secret plus an LWA scope:

```
use SpApi\Api\notifications\v1\NotificationsApi;
use Tims\AmazonSpApi\Enums\GrantlessScope;
use Tims\AmazonSpApi\Facades\AmazonSpApi;

$api = AmazonSpApi::makeGrantless(
    NotificationsApi::class,
    GrantlessScope::Notifications, // or ClientCredentialRotation
);

$destinations = $api->getDestinations();
```

Feed / report documents
-----------------------

[](#feed--report-documents)

After `createFeedDocument` / `getReportDocument` / `getFeedDocument`, use `Document` to upload or download (including GZIP):

```
use SpApi\Model\feeds\v2021_06_30\CreateFeedDocumentSpecification;
use Tims\AmazonSpApi\Document;

// Report download
$reportDoc = $reportsApi->getReportDocument($documentId);
$contents = Document::fromReportDocument($reportDoc)->download();
$rows = Document::fromReportDocument($reportDoc)->downloadParsed('tsv');

// Feed upload
$contentType = Document::contentTypeForFeed('POST_PRODUCT_PRICING_DATA');
$created = $feedsApi->createFeedDocument(new CreateFeedDocumentSpecification(['content_type' => $contentType]));
$doc = Document::fromCreateFeedDocumentResponse($created);
$doc->upload($xml, $contentType);
```

Retries
-------

[](#retries)

SP-API applies rate limits. Clients from `make()` / `makeGrantless()` retry `429`, selected `5xx` responses, and connection errors by default, with exponential backoff and support for `Retry-After`.

```
AMAZON_SPAPI_RETRY_ENABLED=true
AMAZON_SPAPI_RETRY_MAX_ATTEMPTS=3
AMAZON_SPAPI_RETRY_BASE_DELAY_MS=500
```

Disable per client:

```
AmazonSpApi::make(OrdersV0Api::class, options: ['retry' => false]);
```

Queued reports &amp; feeds
--------------------------

[](#queued-reports--feeds)

Report and feed flows: create → poll → download → event.

```
use Tims\AmazonSpApi\Events\ReportDocumentReady;
use Tims\AmazonSpApi\Jobs\RequestReportJob;

RequestReportJob::dispatch(
    reportType: 'GET_MERCHANT_LISTINGS_DATA',
    marketplaceIds: ['ATVPDKIKX0DER'],
    // credentialsId: $credentials->id, // multi-seller
);

Event::listen(ReportDocumentReady::class, function (ReportDocumentReady $event) {
    Storage::put("reports/{$event->reportId}.tsv", $event->contents);
});
```

Feeds:

```
use Tims\AmazonSpApi\Jobs\SubmitFeedJob;

SubmitFeedJob::dispatch(
    feedType: 'POST_PRODUCT_PRICING_DATA',
    marketplaceIds: ['ATVPDKIKX0DER'],
    contents: $xml,           // or contentsPath: storage_path('feeds/price.xml')
);
```

Events: `ReportDocumentReady`, `ReportFailed`, `FeedResultReady`, `FeedFailed`.

Poll settings: `AMAZON_SPAPI_REPORT_POLL_SECONDS`, `AMAZON_SPAPI_FEED_POLL_SECONDS`, `AMAZON_SPAPI_MAX_POLL_ATTEMPTS`.

Testing fakes
-------------

[](#testing-fakes)

In tests, swap `SpApiManager` so `make()` returns Mockery doubles:

```
use SpApi\Api\reports\v2021_06_30\ReportsApi;
use Tims\AmazonSpApi\Testing\SpApiFake;

$fake = SpApiFake::start();
$fake->mock(ReportsApi::class, function ($api) {
    $api->shouldReceive('getReport')->andReturn($report);
});

$api = AmazonSpApi::make(ReportsApi::class);
```

Access token caching
--------------------

[](#access-token-caching)

LWA access tokens and RDTs are stored in Laravel’s cache. Updating a `Credentials` row clears that seller’s cached tokens when the cache driver supports tags (for example Redis).

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

Copyright (c) 2026 TIMS.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance92

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 66.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1b9572b2d9e20e57d4cfd779f3f5734ae78d1e78651b4352c98c488c40020fc7?d=identicon)[MrHitss](/maintainers/MrHitss)

---

Top Contributors

[![MrHitss](https://avatars.githubusercontent.com/u/41452196?v=4)](https://github.com/MrHitss "MrHitss (2 commits)")[![timslabs](https://avatars.githubusercontent.com/u/102379998?v=4)](https://github.com/timslabs "timslabs (1 commits)")

---

Tags

laravelamazonsdkecommercesp-apiselling-partner-api

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/tims-laravel-amazon-spapi/health.svg)

```
[![Health](https://phpackages.com/badges/tims-laravel-amazon-spapi/health.svg)](https://phpackages.com/packages/tims-laravel-amazon-spapi)
```

###  Alternatives

[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k17.6M165](/packages/laravel-pulse)[psalm/plugin-laravel

Psalm plugin for Laravel

3365.5M359](/packages/psalm-plugin-laravel)[flarum/core

Delightfully simple forum software.

271.5M2.6k](/packages/flarum-core)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

1.0k2.5M152](/packages/roots-acorn)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k9.3M114](/packages/mongodb-laravel-mongodb)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
