skip to Main Content

I am using the following SDK to work with the SP API.

I am trying to upload inventory (stock) data. I believe it’s done using the JSON you see me sending . When triggering this, I get back a document ID etc, which I think you then use to look up the status of that uploaded data.

Note: I have checked Amazon directly too (seller central), to check for stock changes and nothing is changing.

However, I am unclear how you continue to use this SDK to look up the status and see whether what I uploaded was successful etc.

Note: If anyone is aware of how to upload stock data without using the SDK and an easier means, happy to try anything!

*The JSON payload I am sending was suggested to me by someone else. It’s unclear if I need to be sending parts like the attributes and productType. I suspect once I can look up the status of what I uploaded, maybe it’ll tell me what I am missing or incorrect etc.

use SellingPartnerApiSellingPartnerApi;
use SellingPartnerApiEnumsEndpoint;

use SellingPartnerApiSellerFeedsV20210630DtoCreateFeedDocumentSpecification;
use SellingPartnerApiSellerFeedsV20210630DtoCreateFeedSpecification;
use SellingPartnerApiSellerFeedsV20210630ResponsesCreateFeedDocumentResponse;

public function send_stock_to_amazon( $data ) {

        $connector = SellingPartnerApi::seller(
            clientId: defined('LWA_CLIENT_ID') ? LWA_CLIENT_ID : '',
            clientSecret: defined('LWA_CLIENT_SECRET') ? LWA_CLIENT_SECRET : '',
            refreshToken: defined('LWA_REFRESH_TOKEN') ? LWA_REFRESH_TOKEN : '',
            endpoint: Endpoint::EU,  // Or Endpoint::EU, Endpoint::FE, Endpoint::NA_SANDBOX, etc.
        );

        $feedType = 'JSON_LISTINGS_FEED';
        $feedsApi = $connector->feedsV20210630();

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

        $feedContents = json_encode([
            "header" => [
                "sellerId" => "XXXXXXXXXX",
                "version" => "2.0",
                "issueLocale" => "en_US"
            ],
            "messages" => [
                [
                    "messageId" => 1,
                    "sku" => "592932GE",
                    "operationType" => "PARTIAL_UPDATE",
                    "productType" => "BATTERY",
                    "attributes" => [
                        "fulfillment_availability" => [
                            [
                                "fulfillment_channel_code" => "DEFAULT",
                                "quantity" => 2,
                                "lead_time_to_ship_max_days" => "5"
                            ]
                        ]
                    ]
                ]
            ]
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        try {
            $feedDocument->upload($feedType, $feedContents);
        }
        catch (Exception $e) {
            echo "Error: " . $e->getResponse()->getBody()->getContents();
        }

        // Check if the feed document has been processed.
        $createFeedSpecification = new CreateFeedSpecification(
            marketplaceIds: ['XXXXXXXXX'],
            inputFeedDocumentId: $feedDocument->feedDocumentId,
            feedType: $feedType,
        );

        // TODO - Check feed status.
        
    }

The result of: $feedDocument->upload($feedType, $feedContents); is like so:

feedDocumentId: "amzn1.tortuga.4.eu.b546cc55-b6d1-459d-8469-05e6fdefea9a.T35xxxxx"

url: "https://tortuga-prod-eu.s3-eu-west-1.amazonaws.com/b546cc55-b6d1-459d-8469-05e6fdefea9a.amzn1.tortuga.4.eu.T351S9........."

*I have redacted some parts above with xxxx for security.

2

Answers


  1. The reason it is complicated is they way SP API handles feeds. It follows the following steps:

    1. You need to tell Amazon you want to upload a file and which file type (createFeedDocument())
    2. You get back an URL to which you can upload the file (upload()) // The upload url is handled by the jlevers API in the background
    3. Next you need to create a feed (uploading the file alone does not create a feed) so now we need to call (createFeed())
    4. Once the feed has been created you get the feedId. Once you have the feed ID we can check the feed status using (getFeed())
    5. Once the feed has been processed eg. status === DONE we can get the download url with the result (getFeedDocument())
    6. Once we have the download url we can download the final file (download()) // the download url is handled by the jlevers API in the background

    You can do this using the following code:

    public function upload()
      {
        $connector = $this->connector;
    
        $feedType = "JSON_LISTINGS_FEED";
        $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 = json_encode([
          "header" => [
            "sellerId" => "XXXXXXX",
            "version" => "2.0",
            "issueLocale" => "en_US"
          ],
          "messages" => [
            [
              "productType" => "PRODUCT",
              "patches" => [
                [
                  "op" => "replace",
                  "operation_type" => "PARTIAL_UPDATE",
                  "path" => "/attributes/fulfillment_availability",
                  "value" => [
                    [
                      "fulfillment_channel_code" => "DEFAULT",
                      "quantity" => 9
                    ]
                  ]
                ]
              ]
            ]
          ]
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    
        $feedDocument->upload($feedType, $feedContents);
    
        $createFeedSpec = new CreateFeedSpecification(
          marketplaceIds: ['XXXXXXX'], // Replace with your marketplaceIds
          inputFeedDocumentId: $feedDocument->feedDocumentId,
          feedType: $feedType,
        );
    
        // Create feed with the feed document we just uploaded
        $createFeedResponse = $feedsApi->createFeed($createFeedSpec);
        $feedId = $createFeedResponse->dto()->feedId;
    
        // Save the $feedId for later use.
        }
    

    And the download function:

    public function downloadFile($feedId)
    {
        $connector = $this->connector;
        
        $feedType = "JSON_LISTINGS_FEED";
        $feedsApi = $connector->feedsV20210630();
        
        $feed = $feedsApi->getFeed($feedId);
        
        if ($feed->dto()->processingStatus === 'DONE') {
          $response = $feedsApi->getFeedDocument($feed->dto()->resultFeedDocumentId);
          $feedDocument = $response->dto();
          $contents = $feedDocument->download($feedType);
        
          // Use PHP fwrite to write the contents to a file
        }
    }
    

    You can now check the result file for errors or missing attributes. Note you can also download the result file manually if you check the inventory upload page in the Amazon Seller Central.

    Hope this helps.

    Login or Signup to reply.
  2. I prefer to go with the SDK because it simplifies the workflow. When working with the Amazon Selling Partner API (SP-API) feeds, the process involves several steps:

    1. Create a Feed document (You already did this)
    2. Upload feed document
      (You did this with $feedDocument->upload($feedType, $feedContents))
    3. Create the feed
    4. Poll for the feed status
    5. Retrieve the processing report

    Continuing from step 3:
    After uploading, create a feed that points to that feedDocumentId. This step actually tells Amazon: "Process this document as a feed."

    //After uploading the feed document
    $createFeedSpecification = new CreateFeedSpecification(
        marketplaceIds: ['XXXXXXXXX'],
        inputFeedDocumentId: $feedDocument->feedDocumentId,
        feedType: $feedType,
    );
    
    // Create the feed
    $createFeedResponse = $feedsApi->createFeed($createFeedSpecification);
    $feed = $createFeedResponse->dto();
    $feedId = $feed->feedId; // You'll need this to check status later
    
    

    Now that you have a feedId, this allows you to check the status of the feed. Amazon will process it asynchronously. You can call getFeed method in a loop with a delay (e.g., every few minutes) until you get a terminal status. Common statuses include PROCESSING, DONE, CANCELLED, etc.

    do {
        sleep(60); // wait a minute or so before checking
        $getFeedResponse = $feedsApi->getFeed($feedId);
        $feedStatus = $getFeedResponse->dto()->status;
    } while (!in_array($feedStatus, ['DONE', 'CANCELLED']));
    

    Now, last step is to retrieve the processing report. Once the feed is DONE, you can see if there were any issues. Also, check if the feed has a resultFeedDocumentId. If it has the resultFeedDocumentId, you can download the processing report.

    if ($feedStatus === 'DONE') {
        $resultFeedDocumentId = $getFeedResponse->dto()->resultFeedDocumentId;
        if ($resultFeedDocumentId) {
            $resultDocResponse = $feedsApi->getFeedDocument($resultFeedDocumentId);
            $resultDoc = $resultDocResponse->dto();
            
            // The resultDoc->url gives you another pre-signed URL to the processing report
            $reportContents = file_get_contents($resultDoc->url);
            
            print_r($reportContents);
        }
    }
    
    

    Check the SP-API JSON schema for listings feeds to ensure your JSON matches the expected structure. Its very important. So after uploading the feed document you also need to createFeed and then use getFeed to check the feed status. After that retrieve the processing report to see if it was successful or it has errors.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search