Giter VIP home page Giter VIP logo

selling-partner-api's Introduction

Total downloads Latest stable version License

Selling Partner API for PHP

A PHP library for connecting to Amazon's Selling Partner API.

Note

If you're looking for the documentation for v5 of this package, you can find it here.

Related packages


I'm available for consulting work! If you need support designing and building applications with Amazon, Walmart, or other e-commerce APIs, or building SDKs in PHP, I can help. Shoot me an email at [email protected].

If you've found any of my packages useful, please consider becoming a Sponsor, or making a one-time donation via the button below. I appreciate any and all support! Keeping open source projects alive is a community effort.

Donate to Jesse Evers

Sponsored by Tesmo.


Features

  • Supports all Selling Partner API operations (for Sellers and Vendors) as of 6/19/2024
  • Automatically generates Restricted Data Tokens for all calls that require them -- no extra calls to the Tokens API needed
  • Includes a Document helper class for uploading and downloading feed/report documents

Installation

composer require jlevers/selling-partner-api

Contributing

See CONTRIBUTING.md for details.

Table of Contents

Check out the Getting Started section below for a quick overview.

This README is divided into several sections:

Getting Started

Prerequisites

To get started, you need an approved Selling Partner API developer account, and SP API application credentials, which you can get by creating a new SP API application in Seller Central.

Setup

The SellingPartnerApi class acts as a factory to generate Seller and Vendor API connector instances. Its seller() and vendor() methods each take a set of identical (and optionally, named) parameters. Its basic usage looks like this:

use SellingPartnerApi\SellingPartnerApi;
use SellingPartnerApi\Enums\Endpoint;

$connector = SellingPartnerApi::seller(
    clientId: 'amzn1.application-oa2-client.asdfqwertyuiop...',
    clientSecret: 'amzn1.oa2-cs.v1.1234567890asdfghjkl...',
    refreshToken: 'Atzr|IwEBIA...',
    endpoint: Endpoint::NA,  // Or Endpoint::EU, Endpoint::FE, Endpoint::NA_SANDBOX, etc.
);

Note

Older versions of the Selling Partner API used AWS IAM credentials to authenticate, and so this library had additional AWS configuration options. If you're upgrading from an older version of this library and are confused about what to do with your AWS creds, you can just ignore them. The SP API no longer authenticates via AWS IAM roles or users.

Now you have a Selling Partner API connector instance, and you can start making calls to the API. The connector instance has methods for each of the API segments (e.g., sellers, orders, fba-inbound), and you can access them like so:

$ordersApi = $connector->ordersV0();
$response = $ordersApi->getOrders(
    createdAfter: new DateTime('2024-01-01'),
    marketplaceIds: ['ATVPDKIKX0DER'],
);

Once you have a response, you can either access the raw JSON response via $response->json(), or you can automatically parse the response into a DTO by calling $response->dto(). Once the response is turned into a DTO, you can access the data via the DTO's properties. For instance, you can get the first order's purchase date like so:

$dto = $response->dto();
$purchaseDate = $dto->payload->orders[0]->purchaseDate;

See the Working with DTOs section for more details on how to work with requests and responses.

Configuration options

The SellingPartnerApi::seller() and SellingPartnerApi::vendor() builder methods accept the following arguments:

  • clientId (string): Required. The LWA client ID of the SP API application to use to execute API requests.
  • clientSecret (string): Required. The LWA client secret of the SP API application to use to execute API requests.
  • refreshToken (string): The LWA refresh token of the SP API application to use to execute API requests. Required, unless you're only using grantless operations.
  • endpoint: Required. An instance of the SellingPartnerApi\Enums\Endpoint enum. Primary endpoints are Endpoint::NA, Endpoint::EU, and Endpoint::FE. Sandbox endpoints are Endpoint::NA_SANDBOX, Endpoint::EU_SANDBOX, and Endpoint::FE_SANDBOX.
  • dataElements (array): Optional. An array of data elements to pass to restricted operations. See the Restricted operations section for more details.
  • delegatee (string): Optional. The application ID of a delegatee application to generate RDTs on behalf of.
  • authenticationClient (GuzzleHttp\Client): Guzzle client instance that will be used to generate the access token from the refresh token. If not provided, the default Saloon Guzzle client will be used.
  • cache (SellingPartnerApi\Contracts\TokenCache): A cache interface instance that will be used to cache access tokens. If not provided, a basic in-memory cache will be used. If set to null, caching will be disabled.

Debugging

To get detailed debugging output, you can take advantage of Saloon's debugging hooks. This package is built on top of Saloon, so anything that works in Saloon will work here. For instance, to debug requests:

use SellingPartnerApi\SellingPartnerApi;

$connector = SellingPartnerApi::seller(
    clientId: 'amzn1.application-oa2-client.asdfqwertyuiop...',
    clientSecret: 'amzn1.oa2-cs.v1.1234567890asdfghjkl...',
    refreshToken: 'Atzr|IwEBIA...',
    endpoint: Endpoint::NA,
);

$connector->debugRequest(
    function (PendingRequest $pendingRequest, RequestInterface $psrRequest) {
        dd($pendingRequest->headers()->all(), $psrRequest);
    }
);

Then make requests with the connector as usual, and you'll hit the closure above every time a request is fired. You can also debug responses in a similar fashion – check out the Saloon docs for more details.

If you want to output your debug data to a file, you can do so with the SellingPartnerApi::debugRequestToFile(), SellingPartnerApi::debugResponseToFile(), and SellingPartnerApi::debugToFile() methods. These methods all take an $outputPath argument and an optional $die argument.

Supported API segments

Each API accessor method contains the API's version. This allows for multiple versions of the same API to be accessible in a single version of this package. It makes the method names a little uglier, but allows for simultaneously using new and old versions of the same API segment, which is often useful. It also means that if a new version of an existing API is introduced, the library can be updated to include that new version without introducing breaking changes.

Seller APIs

Seller APIs are accessed via the SellingPartnerApi::seller() class:

<?php
use SellingPartnerApi\SellingPartnerApi;

$sellerConnector = SellingPartnerApi::seller(/* ... */);
  • Amazon Warehousing and Distribution API (v2024-05-09) (docs)
    $amazonWarehousingAndDistributionApi = $sellerConnector->amazonWarehousingAndDistributionV20240509();
  • Application Management API (v2023-11-30) (docs)
    $applicationManagementApi = $sellerConnector->applicationManagementV20231130();
  • A+ Content API (v2020-11-01) (docs)
    $aPlusContentApi = $sellerConnector->aPlusContentV20201101();
  • Catalog Items API (v2022-04-01) (docs)
    $catalogItemsApi = $sellerConnector->catalogItemsV20220401();
  • Catalog Items API (v2021-12-01) (docs)
    $catalogItemsApi = $sellerConnector->catalogItemsV20211201();
  • Catalog Items API (v0) (docs)
    $catalogItemsApi = $sellerConnector->catalogItemsV0();
  • Data Kiosk API (v2023-11-15) (docs)
    $dataKioskApi = $sellerConnector->dataKioskV20231115();
  • EasyShip API (v2022-03-23) (docs)
    $easyShipApi = $sellerConnector->easyShipV20220323();
  • FBA Inbound API (v2024-03-20) (docs)
    $fbaInboundApi = $sellerConnector->fbaInboundV20240320();
  • FBA Inbound API (v0) (docs)
    $fbaInboundApi = $sellerConnector->fbaInboundV0();
  • FBA Inbound Eligibility API (v1) (docs)
    $fbaInboundEligibility = $sellerConnector->fbaInboundEligibilityV1();
  • FBA Inventory API (v1) (docs)
    $fbaInventoryApi = $sellerConnector->fbaInventoryV1();
  • FBA Outbound API (v2020-07-01) (docs)
    $fbaOutboundApi = $sellerConnector->fbaOutboundV20200701();
  • Feeds API (v2021-06-30) (docs)
    $feedsApi = $sellerConnector->feedsV20210630();
  • Finances API (v0) (docs)
    $financesApi = $sellerConnector->financesV0();
  • Listings Items API (v2021-08-01) (docs)
    $listingsItemsApi = $sellerConnector->listingsItemsV20210801();
  • Listings Items API (v2020-09-01) (docs)
    $listingsItemsApi = $sellerConnector->listingsItemsV20200901();
  • Listings Restrictions API (v2021-08-01) (docs)
    $listingsRestrictionsApi = $sellerConnector->listingsRestrictionsV20210801();
  • Merchant Fulfillment API (v0) (docs)
    $merchantFulfillmentApi = $sellerConnector->merchantFulfillmentV0();
  • Messaging API (v1) (docs)
    $messagingApi = $sellerConnector->messagingV1();
  • Notifications API (v1) (docs)
    $notificationsApi = $sellerConnector->notificationsV1();
  • Orders API (v0) (docs)
    $ordersApi = $sellerConnector->ordersV0();
  • Product Fees API (v0) (docs)
    $productFeesApi = $sellerConnector->productFeesV0();
  • Product Pricing API (v2022-05-01) (docs)
    $productPricingApi = $sellerConnector->productPricingV20220501();
  • Product Pricing API (v0) (docs)
    $productPricingApi = $sellerConnector->productPricingV0();
  • Product Type Definitions API (v2020-09-01) (docs)
    $productTypeDefinitionsApi = $sellerConnector->productTypeDefinitionsV20200901();
  • Replenishment API (v2022-11-07) (docs)
    $replenishmentApi = $sellerConnector->replenishmentV20221107();
  • Reports API (v2021-06-30) (docs)
    $reportsApi = $sellerConnector->reportsV20210630();
  • Sales API (v1) (docs)
    $salesApi = $sellerConnector->salesV1();
  • Sellers API (v1) (docs)
    $sellersApi = $sellerConnector->sellersV1();
  • Services API (v1) (docs)
    $servicesApi = $sellerConnector->servicesV1();
  • Shipment Invoicing API (v0) (docs)
    $shipmentInvoicingApi = $sellerConnector->shipmentInvoicingV0();
  • Shipping API (v2) (docs)
    $shippingApi = $sellerConnector->shippingV2();
  • Shipping API (v1) (docs)
    $shippingApi = $sellerConnector->shippingV1();
  • Solicitations API (v1) (docs)
    $solicitationsApi = $sellerConnector->solicitationsV1();
  • Supply Sources API (v2020-07-01) (docs)
    $supplySourcesApi = $sellerConnector->supplySourcesV20200701();
  • Tokens API (v2021-03-01) (docs)
    $tokensApi = $sellerConnector->tokensV20210301();
  • Uploads API (v2020-11-01) (docs)
    $uploadsApi = $sellerConnector->uploadsV20201101();

Vendor APIs

Vendor APIs are accessed via the SellingPartnerApi::vendor() method:

<?php
use SellingPartnerApi\SellingPartnerApi;

$vendorConnector = SellingPartnerApi::vendor(/* ... */);
  • Direct Fulfillment Inventory API (v1) (docs)
    $directFulfillmentInventoryApi = $vendorConnector->directFulfillmentInventoryV1();
  • Direct Fulfillment Orders API (v2021-12-28) (docs)
    $directFulfillmentOrdersApi = $vendorConnector->directFulfillmentOrdersV20211228();
  • Direct Fulfillment Orders API (v1) (docs)
    $directFulfillmentOrdersApi = $vendorConnector->directFulfillmentOrdersV1();
  • Direct Fulfillment Payments API (v1) (docs)
    $directFulfillmentPaymentsApi = $vendorConnector->directFulfillmentPaymentsV1();
  • Direct Fulfillment Sandbox API (v2021-10-28) (docs)
    $directFulfillmentSandboxApi = $vendorConnector->directFulfillmentSandboxV20211028();
  • Direct Fulfillment Shipping API (v2021-12-28) (docs)
    $directFulfillmentShippingApi = $vendorConnector->directFulfillmentShippingV20211228();
  • Direct Fulfillment Shipping API (v1) (docs)
    $directFulfillmentShippingApi = $vendorConnector->directFulfillmentShippingV1();
  • Direct Fulfillment Transactions API (v2021-12-28) (docs)
    $directFulfillmentTransactionsApi = $vendorConnector->directFulfillmentTransactionsV20211228();
  • Direct Fulfillment Transactions API (v1) (docs)
    $directFulfillmentTransactionsApi = $vendorConnector->directFulfillmentTransactionsV1();
  • Invoices API (v1) (docs)
    $invoicesApi = $vendorConnector->invoicesV1();
  • Orders API (v1) (docs)
    $ordersApi = $vendorConnector->ordersV1();
  • Shipments API (v1) (docs)
    $shipmentsApi = $vendorConnector->shipmentsV1();
  • Transaction Status API (v1) (docs)
    $transactionStatusApi = $vendorConnector->transactionStatusV1();

Restricted operations

When you call a restricted operation, a Restricted Data Token (RDT) is automatically generated. If you're calling restricted operations that accept a dataElements parameter, specify the restricted data elements you want to retrieve in the dataElements parameter of SellingPartnerApi::make(). Currently, getOrder, getOrders, and getOrderItems are the only restricted operations that take a dataElements parameter.

Note that if you want to call a restricted operation on a sandbox endpoint (e.g., Endpoint::NA_SANDBOX), you should not specify any dataElements. RDTs are not necessary for restricted operations in the sandbox.

If you would like to make calls on behalf of a delegatee application, you can specify the delegatee parameter in SellingPartnerApi::make(). This will cause the connector to generate a token for the delegatee application instead of the main application.

Uploading and downloading documents

The Feeds and Reports APIs include operations that involve uploading and downloading documents to and from Amazon. This library has integrated supports for uploading and downloading documents on the relevant DTOs: ReportDocument, CreateFeedDocumentResponse, and FeedDocument, which are the result of calling getReportDocument, createFeedDocument, and getFeedDocument, respectively.

Downloading a report document

use SellingPartnerApi\SellingPartnerApi;

$reportType = 'GET_MERCHANT_LISTINGS_DATA';
// Assume we already got a report document ID from a previous getReport call
$documentId = '1234567890.asdf';

$connector = SellingPartnerApi::seller(/* ... */);
$response = $connector->reportsV20210630()->getReportDocument($documentId, $reportType);

$reportDocument = $response->dto();

/*
 * - Array of arrays, where each sub array corresponds to a row of the report, if this is a TSV, CSV, or XLSX report
 * - A nested associative array (from json_decode) if this is a JSON report
 * - The raw report data if this is a TXT or PDF report
 * - A SimpleXMLElement object if this is an XML report
 */
$contents = $reportDocument->download($reportType);

The download method has three parameters:

  • documentType (string): The report type (or feed type of the feed result document being fetched). This is required if you want the document data parsed for you.
  • preProcess (bool): Whether to preprocess the document data. If true, the document data will be parsed and formatted into a more usable format. If false, the raw document text will be returned. Defaults to true.
  • encoding (string): The encoding of the document data. Defaults to UTF-8.

If you are working with huge documents you can use downloadStream() to minimize the memory consumption. downloadStream() returns a Psr\Http\Message\StreamInterface.

$streamContents = $reportDocument->downloadStream();  // The raw report stream

Uploading a feed document

use SellingPartnerApi\Seller\FeedsV20210630\Dto\CreateFeedDocumentSpecification;
use SellingPartnerApi\Seller\FeedsV20210630\Dto\CreateFeedSpecification;
use SellingPartnerApi\Seller\FeedsV20210630\Responses\CreateFeedDocumentResponse;

$feedType = 'POST_PRODUCT_PRICING_DATA';

$connector = SellingPartnerApi::seller(/* ... */);
$feedsApi = $connector->feedsV20210630();

// Create feed document
$contentType = CreateFeedDocumentResponse::getContentType($feedType);
$createFeedDoc = new CreateFeedDocumentSpecification($contentType);
$createDocumentResponse = $feedsApi->createFeedDocument($createFeedDoc);
$feedDocument = $createDocumentResponse->dto();

// Upload feed contents to document
$feedContents = file_get_contents('your/feed/file.xml');
$feedDocument->upload($feedType, $feedContents);

$createFeedSpec = new CreateFeedSpecification(
    marketplaceIds: ['ATVPDKIKX0DER'],
    inputFeedDocumentId: $feedDocument->feedDocumentId,
    feedType: $feedType,
);

// Create feed with the feed document we just uploaded
$createFeedResponse = $feedsApi->createFeed($createFeedSpec);
$feedId = $createFeedResponse->dto()->feedId;

If you are working with feed documents that are too large to fit in memory, you can pass anything that Guzzle can turn into a stream into FeedDocument::upload() instead of a string.

Downloading a feed result document

This process is very similar to downloading a report document:

use SellingPartnerApi\SellingPartnerApi;

$feedType = 'POST_PRODUCT_PRICING_DATA';
// Assume we already got a feed result document ID from a previous getFeed call
$documentId = '1234567890.asdf';

$connector = SellingPartnerApi::seller(/* ... */);
$response = $connector->feedsV20210630()->getFeedDocument($documentId);
$feedDocument = $response->dto();

$contents = $feedResultDocument->download($feedType);

Naming conventions

Wherever possible, the names of the classes, methods, and properties in this package are identical to the names used in the Selling Partner API documentation. There are limited cases where this is not true, such as where the SP API documentation itself is inconsistent: for instance, there are some cases the SP API docs name properties in UpperCamelCase instead of camelCase, and in those cases the properties are named in camelCase in this package. Methods are named in camelCase, and DTOs are named in UpperCamelCase.

Instead of maintaining a redundant set of documentation, we link to the official SP API documentation whenever possible. If it's unclear how to use a particular method or DTO, check out the corresponding section of the official SP API documentation.

Working with DTOs

Some methods take DTOs as parameters. For instance, the confirmShipment method in the Orders API takes a ConfirmShipmentRequest DTO as a parameter. You can call confirmShipment like so:

<?php

use SellingPartnerApi\Seller\OrdersV0\Dto;
use SellingPartnerApi\SellingPartnerApi;

$confirmShipmentRequest = new Dto\ConfirmShipmentRequest(
    packageDetail: new Dto\PackageDetail(
        packageReferenceId: 'PKG123',
        carrierCode: 'USPS',
        trackingNumber: 'ASDF1234567890',
        shipDate: new DateTime('2024-01-01 12:00:00'),
        orderItems: [
            new Dto\ConfirmShipmentOrderItem(
                orderItemId: '1234567890',
                quantity: 1,
            ),
            new Dto\ConfirmShipmentOrderItem(
                orderItemId: '0987654321',
                quantity: 2,
            )
        ],
    ),
    marketplaceId: 'ATVPDKIKX0DER',
);

$response = $ordersApi->confirmShipment(
    orderId: '123-4567890-1234567',
    confirmShipmentRequest: $confirmShipmentRequest,
)

selling-partner-api's People

Contributors

0xsekar avatar adamtoms avatar agan-bec avatar armageddon-cat avatar bgarret avatar booni3 avatar cpiggott avatar daygarcia avatar denisneuf avatar deyvidholz avatar dpash avatar gmauro99 avatar inbasecom avatar jbaelo avatar jlevers avatar krystalcode avatar meertensm avatar mudhoney avatar nilanth avatar pashamesh avatar pkiman avatar quazardous avatar richardthepratt avatar romerolweb avatar rustyfausak avatar spire-mike avatar suzol10 avatar tera911 avatar valigara avatar x140l31 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

selling-partner-api's Issues

getOrderAddress() returns missing address fields

Hi,

getOrderAddress() returns missing address fields. Am I missing something?

  <?php
  require_once(__DIR__ . '/vendor/autoload.php');
  
  
  $apiInstance = new SellingPartnerApi\Api\OrdersApi();
  
  $order_id = '204-*****'; // string | An Amazon-defined order identifier, in 3-7-7 format.
  
  try {
      $result = $apiInstance->getOrderAddress($order_id);
      print_r($result);
  } catch (Exception $e) {
      echo 'Exception when calling OrdersApi->getOrderAddress: ', $e->getMessage(), PHP_EOL;
  }
(
    [container:protected] => Array
        (
            [payload] => SellingPartnerApi\Model\Orders\OrderAddress Object
                (
                    [container:protected] => Array
                        (
                            [amazon_order_id] => *************************
                            [shipping_address] => SellingPartnerApi\Model\Orders\Address Object
                                (
                                    [container:protected] => Array
                                        (
                                            [name] => 
                                            [address_line1] => 
                                            [address_line2] => 
                                            [address_line3] => 
                                            [city] => LONDON
                                            [county] => 
                                            [district] => 
                                            [state_or_region] => 
                                            [municipality] => 
                                            [postal_code] => *** ***
                                            [country_code] => GB
                                            [phone] => 
                                            [address_type] => 
                                        )

                                )

                        )

                )

            [errors] => 
        )

)```

Dynamic User Credentials

When using dynamic user credentials, the library should not still try to load from the .env file.

Cannot get Feed Document using FeedsApi->getFeedDocument($feed_document_id)

📄 Summary

I can create a Feed Document and a Feed normally following the docs but when I try to get the same Feed Document I get this:

[400] {
  "errors": [
    {
      "code": "InvalidInput",
      "message": "Invalid feedDocumentId",
      "details": ""
    }
  ]
}

I'm using a feedDocumentId like this: amzn1.tortuga.3.65fec908-9f33-491d-477c-b46b14e085c3.T1YH3BPIW9AFIP (the same feedDocumetId returned from FeedsApi->createFeedDocument)

📕 More details

Here's my code:

Create Feed Document

const CONTENT_TYPE = "text/xml";
$feedsApi = new FeedsApi($config);

// Creating feedDocument
$createFeedDocSpec = new Feeds\CreateFeedDocumentSpecification(["content_type" => CONTENT_TYPE]);
$feedDocumentInfo = $feedsApi->createFeedDocument($createFeedDocSpec);
echo '<pre>';
print_r(json_encode($feedDocumentInfo->getPayload()->jsonSerialize()));
echo '</pre>';

echo '<hr>';
// Getting file data
$documentContents = file_get_contents("./files/Product.xsd");

// Sending file data to SP-API
$docToUpload = new SellingPartnerApi\Document($feedDocumentInfo->getPayload(), CONTENT_TYPE);
$uploaded = $docToUpload->upload($documentContents);

Response:

{
  "feedDocumentId": "amzn1.tortuga.3.65fec908-9f33-491d-477c-b46b14e085c3.T1YH3BPIW9AFIP",
  "url": "https://tortuga-prod-na.s3-external-1.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.65fec908-9f33-491d-477c-b46b14e085c3.T1YH3BPIW9AFIP?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210610T173945Z&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Expires=300&X-Amz-Credential=...%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=...",
  "encryptionDetails": {
    "standard": "AES",
    "initializationVector": "kgSN8v...==",
    "key": "dv7/WheiES4YT8...="
  }
}

Get Feed Document

$api = new SellingPartnerApi\Api\FeedsApi($config);

$feed_document_id = 'amzn1.tortuga.3.65fec908-9f33-491d-477c-b46b14e085c3.T1YH3BPIW9AFIP';

try {
  $result = $api->getFeedDocumentWithHttpInfo($feed_document_id);
  echo '<pre>';
  print_r($result);
  echo '</pre>';
} catch (Exception $e) {
  echo '<h2>Error:</h2> ';
  echo '<pre>';
  echo $e->getMessage();
  echo '</pre>';
}

Response:

[400] {
  "errors": [
    {
      "code": "InvalidInput",
      "message": "Invalid feedDocumentId",
      "details": ""
    }
  ]
}

Notes:

⚠️ However, when I call FeedsApi->createFeed using this body (with the same ID) below I get success:

$api = new SellingPartnerApi\Api\FeedsApi($config);

$body = new \SellingPartnerApi\Model\Feeds\CreateFeedSpecification([
  'feed_type' => 'POST_PRODUCT_PRICING_DATA',
  'marketplace_ids' => ['A2Q3Y263D00KWC'], // Brazil
  'input_feed_document_id' => 'amzn1.tortuga.3.65fec908-9f33-491d-477c-b46b14e085c3.T1YH3BPIW9AFIP',
  'feed_options' => null,
]);

$result = $api->createFeed($body);

Problems with download() method of Document class

Using v 3.0.7 (latest), I'm requesting a created GET_XML_BROWSE_TREE_DATA report, it gets created through:
\SellingPartnerApi\Api\ReportsApi->createReport(...)
the report document id is retrieved through
\SellingPartnerApi\Api\ReportsApi->getReport($report_id),
\SellingPartnerApi\Api\ReportsApi->getReportDocument(...) to get the document url,
and the raw contents is retrieved in Document->download(), but when it's run through:
$maybeZippedContents = openssl_decrypt($rawContents, static::ENCRYPTION_SCHEME, $this->key, OPENSSL_RAW_DATA, $this->iv);
it returns multiple blanks, but no XML.

Is this what you are getting? Pretty sure I'm following standard protocol.
NOTE: This is for GET_XML_BROWSE_TREE_DATA report type, it is working for GET_MERCHANT_LISTINGS_ALL_DATA.
I haven't tested any of the other report types.

API call for parent categories associated with a product or ... ?

On this Github page for the Selling Partner API docs: https://github.com/amzn/selling-partner-api-docs/blob/main/references/catalog-items-api/catalogItemsV0.md

there's an operation called: listCatalogCategories, that provides the parent-child category list associated with a product listing. I couldn't find the API call for this in your PHP library, can anyone assist?

Basically, I'm looking for a more descriptive subcategory name for the product listing other than what: getCatalogItem provides with the 'productTypes' dataset. it might be useful to get this category tree (complete with ids?) outside of the API, since it seems pretty fair to say the category tree isn't changed very often.

Thanks in advance for any help on this!

ReportsAPI -> createReport 500 Internal Error Always

Hello,

Love this library!

I am working on switching from MWS over to the SP-API and this tool is great. I was wondering if you have had any luck with the ReportsAPI working?

Whenever I try to create a report, I get back a 500 "Internal Failure" message from the API. Code and Response are below.

Code

    $api_tr = new ReportsApi();
        $api_tr->createReport(new CreateReportSpecification([
            'report_type' => ['GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE'],
            'date_start_time' => Carbon::now()->subDay()->startOfDay()->toISOString(),
            'date_end_time' => Carbon::now()->subDay()->endOfDay()->toISOString(),
            'marketplace_ids' => ['ATVPDKIKX0DER']
        ]));

Response

"errors": [
    {
      "code": "InternalFailure",
      "message": "We encountered an internal error. Please try again.",
      "details": ""
    }

getCatalogItem and searchCatalogItems sales rank

1st Issue: Sales rank is not passed to the item result for either of these calls in the catalog API.

Cause: Amazon passes the data back in the json as 'ranks' not 'sales_ranks' even though sales_ranks is how they want it to be set with the included_data.

Fix:
Line 124 on the Model/CatalogItem.php - change to.
'sales_ranks' => 'ranks',

That fixes it so rank data can be properly deserialized.

This uncovered a 2nd issue.

2nd Issue: The 'ranks' attribute in the Model/Catalog/ItemSalesRank.php should be 'value'.

Fix:
To fix this, I just replaced all 'ranks' with 'value' in the Model/Catalog/ItemSalesRank.php.

Amazon is fun with their buggy API and api docs.

Error on download tab delimeted

Thank you for this great library!

I am uploading a price and quantity feed upload. The upload content-type is text-tab/separated-values

That works great, and now I'm trying to download the results using the recommended code.

        //upload feed
        $feed_id = 60619018758;

        $api  = new FeedsApi();
        $feed = $api->getFeed($feed_id);

        $feed_document_id = $feed->getPayload()->getResultFeedDocumentId();

        $feed_document = $api->getFeedDocument($feed_document_id);
        $docToDownload       = new Document($feed_document->getPayload(), "text/tab-separated-values");
        $contents = $docToDownload->download();

everything seems fine until the download step, which gives me the error:

   ErrorException 

  Undefined offset: 1

 at C:\myfiles\webserver\www\myproject\vendor\jlevers\selling-partner-api\lib\Document.php:92
     88▕             $header = fgetcsv($bareStream, 0, $sep);
     89▕             while (($line = fgetcsv($bareStream, 0, $sep)) !== false) {
     90▕                 $row = [];
     91▕                 foreach ($line as $idx => $val) {
  ➜  92▕                     $row[$header[$idx]] = $val;
     93▕                 }
     94▕                 $data[] = $row;
     95▕             }
     96▕             $this->data = $data;

If i change the line to text/csv then I don't get an error. But the data still seems to be in tab format when doing a dump

        $docToDownload       = new Document($feed_document->getPayload(), "text/csv");

outputs on dump:

"""
Feed Processing Summary:\n
\tNumber of records processed\t\t31\n
\tNumber of records successful\t\t31\n
\n
"""

so there seems to be an issue in parsing tab delimited results possibly?

thanks!

Access to requested resource is denied.

I am getting an error for all endpoints where it saying that access to requested resource is denied and a code of unauthorized. I believe I have to assume a role as an IAM user along with the other variables in the .env file, but I don't see where I am supposed to do that?

I have a python version of the sp-api working with the same credentials but with the additional role_arn parameter being passed. any idea of what I have to do to authorize this with the php library?

InvalidInput Error on createFeed

I'm trying to upload a POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA file with "createFeed", but the Response is HTTP 400 InvalidInput everytime.

Here's my code that creates the document and uploads the file.

// Options are set via a Factory
$feedsApi = new FeedsApi(SellingPartnerApiConfigurationFactory::createSellingPartnerApiConfiguration($seller));

// Creating Feed Document - See my pull request for the charset addition.
$createFeedDocSpec = new CreateFeedDocumentSpecification(["content_type" => "text/tab-separated-values; charset=UTF-8"]);
$feedDocumentInfo = $feedsApi->createFeedDocument($createFeedDocSpec);

// Getting file data
$documentContents = file_get_contents($this->projectDir . '/var/files/test_add_delete.txt');

// Sending file data to SP-API
$docToUpload = new Document($feedDocumentInfo->getPayload(), "text/tab-separated-values; charset=UTF-8");
$docToUpload->upload($documentContents);

$body = new CreateFeedSpecification([
    'feed_type' => "POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA",
    'marketplace_ids' => ["A1PA6795UKMFR9"],
    'input_feed_document_id' => $feedDocumentInfo->getPayload()->getFeedDocumentId(),
    'feed_options' => null
]);
$result = $feedsApi->createFeed($body);
dump($result);

The JSON, that is send to the endpoint is this:
{"feedType":"POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA","marketplaceIds":["A1PA6795UKMFR9"],"inputFeedDocumentId":"*VALUE FROM RESPONSE HERE*"}

The response is following:

{
  "errors": [
    {
      "code": "InvalidInput",
      "message": "Invalid request parameters",
      "details": ""
    }
  ]
}

The options are correctly set in the FeedApi, I was able to generate reports with the same Factory and the ReportsApi. Other feedTypes create the same issue.

Checking the request with the API documentation doesn't reveal any errors or missing information. Any clues what the issue could be?

getAuthorizationCode API not working

When requesting getAuthorizationCode method, I am getting this error!!

Client error: POST https://api.amazon.com/auth/o2/token resulted in a 400 Bad Request response: {"error_description":"The request is missing a required parameter : refresh_token","error":"invalid_request"}

Add support for role-based authentication using STS

The library only supports SP API apps that are set up with the non-standard (but simpler) IAM user-based authentication method. Lots of people set up their SP API applications with an IAM role, per Amazon's developer guide. This library should support the official authentication strategy, using STS to make an AssumeRole call.

fees estimate request returning null

image

when trying to retrieve a product's estimated fees, the documentation stated that I have to pass an object from GetMyFeesEstimateRequest as a parameter, while this object is directly returning null, and eventually no data are being retrieved.

any clue on why this is happening ?

AWS User Issues

I am trying to connect via Selling Partner API application using an IAM role ARN instead of a user ARN but it returns error.

When logging in as root:
AccessDenied (client): Roles may not be assumed by root accounts. - Sender Access Denied Roles may not be assumed by root accounts.

Or when accessing with user with permissions:

AccessDenied (client): User: arn: aws: iam :: 1234567890123: user / EXAMPLE is not authorized to perform: sts: AssumeRole on resource: arn: aws: iam :: 1234567890123: user / EXAMPLE - Sender AccessDenied User: arn: aws: iam :: 1234567890123: user / EXAMPLE is not authorized to perform: sts: AssumeRole on resource: arn: aws: iam :: 1234567890123: user / EXAMPLE c1c9f242-13c5-4025-8ff0-

There is no way for Amazon to assist me. Can you think of where the error is?

Error SignatureDoesNotMatch on Document->upload

Hello !

We're struggling with Amazon to get our Invoices uploaded with the SP-API.

After digging around, we did the following :

$pdfFile = __DIR__ . "/my_pdf_invoice.pdf";
$pdfContent = file_get_contents($pdfFile);

// $config is an instance of SellingPartnerApi\ConfigurationOptions
$apiInstance = new Api\FeedsApi($config);
$docSpecs = new Feeds\CreateFeedDocumentSpecification([
    'content_type' => 'application/pdf'
]);

$feedInfos = null;
try {
    $createFeedDocumentResponse = $apiInstance->createFeedDocument($docSpecs);
    $feedInfos = $createFeedDocumentResponse->getPayload();
} catch (Exception $e) {
    die('Exception when calling FeedsApi->createFeedDocument : ' . $e->getMessage() . PHP_EOL);
}

try {
    $doc = new Document($feedInfos);
    $doc->upload($pdfContent);
} catch (Exception $e) {
    echo ("Exception when calling Document->upload :\n" . $e->getMessage() . PHP_EOL);
}

But then we get the error The request signature we calculated does not match the signature you provided. Check your key and signing method..

What are we doing wrong ?

Thanks in advance for your answer :)

Vendor api

Amazon enabled this api also for vendors. I do have the json files for this api.
Can these be added to your repository?

Invalid value 'GB_VOEC' for 'deemed_reseller_category'

When I'm trying to get the orders from the UK marketplace (A1F83G8C2ARO7P) I'm getting this error Invalid value 'GB_VOEC' for 'deemed_reseller_category', must be one of 'IOSS', 'UOSS'

From what I understand this is caused by Amazon changing the API without updating the documentation.

This can be fixed by adding this 2 lines in Model/Orders/OrderItem.php

  1. const DEEMED_RESELLER_CATEGORY_GB_VOEC = 'GB_VOEC' ( line 324, right after const DEEMED_RESELLER_CATEGORY_UOSS = 'UOSS'
  2. self::DEEMED_RESELLER_CATEGORY_GB_VOEC in getDeemedResellerCategoryAllowableValues() method

403 denied

Hi many thanks for this repo, as the aws team's java sdk is so tedious to set up. Also I am not a java guy. I have a question, I am new to aws api, I got 403 when I tried the example

           $api->getMarketplaceParticipations();

I thiink my aws and lwa cred are correct. What I am missing ?

Thanks

Docs should state PHP 7.3 requirement

But you have trailing commas - 7.2 throws a parse error for these in Configuration.php. Should update to reflect that 7.3 is needed.

PHP Parse error: syntax error, unexpected ')' in /var/www/html/integration/amazon_sp/lib/Configuration.php on line 124

Host is PHP Version 7.2.34-21+ubuntu16.04.1+deb.sury.org+1

403 error, unauthorized

Hi, thank you for this repo.
I am getting a 403 response on a simple getmarketplaceparticipation request, although the selling partner API policy is attached to the rule on which my application is running.

anyhow, I can make a request using the Postman AWS signature method and I am getting valid responses so I am sure my credentials are correct.
any thoughts about this ?

Move exception for missing lwaAuthToken/lwaAuthTokenExpiration from Authentication.php to Configuration.php

The docs currently say:

All [Configuration.php constructor options] array items are optional, but lwaClientId and lwaClientSecret must always be given together. If only one of those two options is provided, the Configuration constructor will throw an exception.

However, the relevant exception is actually thrown in the Authentication.php constructor. Since the user won't usually interact with Authentication.php directly, I think it makes more sense to move the exception to Configuration.php instead of updating the docs.

PHP script is Quarantined in Windows 10 by AVG

Awesome work on this! I've begun poking around and testing the different API calls, and they work great. Kudos to you for providing precise/easy-to-understand directions to get to the point of running it (ie AWS Seller API setup, etc).

Configuration's constructor requires the refresh token, but this causes error in MWS migration case

SellingPartnerApi\Configuration constructor always requires a refresh token, but this won't work for one case - a hybrid Selling Partner API application.

In a hybrid application, it uses Authorization API to get authorization to call Selling Partner API operations on behalf of a seller who previously authorized you as an Amazon MWS developer. The refresh token is not available in this case.

--- some background info ---

What is the Authorization API?
The Authorization API lets you migrate an Amazon Marketplace Web Service (Amazon MWS) authorization that a seller has granted you to a hybrid Selling Partner API application. This eliminates the need to request authorization from the seller again.

When would you need to use the Authorization API? Suppose you have published an Amazon MWS application on the Marketplace Appstore. A number of sellers have authorized you as an Amazon MWS developer so they can use your application. You later convert your Amazon MWS application into a hybrid Selling Partner API application that makes calls to both Amazon MWS and Selling Partner API. Now you want your application to make calls to Selling Partner API on behalf of these sellers without requesting authorization again. The Authorization API lets you do this.

Syntax error on SellersApi.php line 475 (PHP 7.2)

In SellersApi.php, at line 472 you have this function call:

            $headers = $this->headerSelector->selectHeaders(
                ['application/json', 'payload'],
                [],
            );

The comma after the empty array is producing a syntax error.
While it works with PHP 7.3, the Readme file says the library works with PHP 7.2

Getting Signature expired

What might be the cause for this error ?
Signature expired: 20210527T091025Z is now earlier than 20210527T093851Z (20210527T094351Z - 5 min.)

Got this error on getCatalogItem();

I got an "Invalid request body" error when creating the report.

When I create report, I got error:

[400] {
  "errors": [
    {
     "message": "Invalid request body: [instance type (boolean) does not match any allowed primitive type (allowed: [\"string\"])]",
     "code": "InvalidInput"
    }
  ]
}

Here is my code:

$apiInstance = new ReportsApi($config);
$body = (new \SellingPartnerApi\Model\Reports\CreateReportSpecification())
    ->setReportType(ReportType::GET_XML_BROWSE_TREE_DATA['name'])
    ->setReportOptions(['RootNodesOnly' => true])
    ->setMarketplaceIds($shop->marketplace_id_list);
try {
    $result = $apiInstance->createReport($body);
    dd($result);
} catch (\Exception $e) {
   dd($e->getMessage());
}

And here is request body(JSON format):

{"reportOptions":{"reportOptions":{"RootNodesOnly":true}},"reportType":"GET_XML_BROWSE_TREE_DATA","marketplaceIds":["A2EUQ1WTGCTBG2","A1AM78C64UM0Y8","A2Q3Y263D00KWC"]}

First, my seller account level is not Professional Selling Plan.
Second, I am sure that my configuration is correct, and the evidence is that the first example in Readme.md in this repo can be executed correctly and return the result.

Now I want ask:

  1. Do I have to upgrade to the professional selling plan for testing in a sandbox environment?
  2. Is my code above correct?

Please help , thank you very much.

Can't install package

  • You can only install one version of a package, so only one of these can be installed: vlucas/phpdotenv[dev-master, v4.0.0, ..., 4.2.x-dev, v5.2.0, 5.2.x-dev, v5.3.0].
    - jlevers/selling-partner-api 2.0.0 requires vlucas/phpdotenv ^5.2 -> satisfiable by vlucas/phpdotenv[v5.2.0, 5.2.x-dev, v5.3.0, 5.3.x-dev (alias of dev-master)].

DecryptionFailedException On Order Report

We're downloading a report with Report Type of GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL. It's a pretty big report that includes 30 days of order (the raw data is around 60mb).

Randomly we'll receive a "DecryptionFailedException" when our script reaches this:

$report = new Document($result->getPayload(), "text/tab-separated-values");
$contents = $report->download();

Here is the file/method throwing the exception:
Jsq\EncryptionStreams\AesDecryptingStream::decryptBlock
...\vendor\jsq\psr7-stream-encryption\src\AesDecryptingStream.php:127

Calling our script again every minute or so, it eventually gets past this and the data gets downloaded, but if we call our script again on the same Report ID, it could throw the exception again, or could download the data successfully - it's random and we have not been able to guarantee reproducing it.

Add support to use proxy server

Thanks for a very useful library!
Can you possibly add an option to insert proxy host, user and password on the configuration options (or somewhere else..), and have the GuzzleHttp\Client use them to make requests?

Argument To Not Build "$this->data" for Document.php

Hello,

First thanks for this application. I've just started using it and it works great.

We have 350k+ listings on Amazon so some of the reports for us are very large. This app is causing memory errors when attempting to build the data structure. Can you add an argument so that $this->data is not built? I made a quick change to the Document.php file that works and would not affect anyone unless they also wanted only the raw data for the report. Feel free to use it or build something similar that is more in line with your coding structure. Thanks again!

public function download($rawOnly = false): string {

Then I put the following around the switch that builds the data.

if(!$rawOnly) { }

Uploading a feed document signature error

When uploading the document feed the createFeedDocument method works fine but when I try to upload the document I always get the message "The request signature we calculated does not match the signature you provided. Check your key and signature method."

Snippet

use SellingPartnerApi;

const CONTENT_TYPE = "text/xml"; 
$feedsApi = new Api\FeedsApi();
$createFeedDocSpec = new Model\Feeds\CreateFeedDocumentSpecification(["content_type" => CONTENT_TYPE]);
$feedDocumentInfo = $feedsApi->createFeedDocument($createFeedDocSpec);

$docToUpload = new Document($feedDocumentInfo->getPayload(), CONTENT_TYPE)
$docToUpload->upload($xml_document);

are there other permissions to be enabled in AWS?

.

.

Can't get order address info in sandbox env.

Hi, jlevers. Sorry, my English is very bad.

In the SP-API sandbox environment, I can get the order list and order details, but I cannot get the buyer information and delivery address information. Below I list some relevant information, please help me. Thank you.

These are the permissions of my app:
微信截图_20210727230847

This is the code that I ran while testing (using the parameters provided by the official documentation):

$config = [];
$app = new OrdersApi($config);
$result = $app->getOrderAddress('TEST_CASE_200');
dd($result);

This is the information returned by SP-API:

"""
[403] {
  "errors": [
    {
      "message": "Access to requested resource is denied.",
     "code": "Unauthorized",
     "details": "The access token you provided is revoked, malformed or invalid."
    }
  ]
}
"""

At the same time, I checked this issue, but the amazon support team hasn't responded yet.

In addition, my seller account did not get access to PII when applying for MWS.

Now I want to ask three questions:
1, Is this situation related to my account not having access to PII?
2, Is the code running during my test correct?
3. Can you share the code you used when accessing buyer information in the sandbox environment?

Thank you very much.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.