phpsdkamazon-selling-partner-api

How to check status of uploaded inventory JSON to Amazon via (selling-partner-api sdk)


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 SellingPartnerApi\SellingPartnerApi;
use SellingPartnerApi\Enums\Endpoint;

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

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.


Solution

  • 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.