Accessing Amazon Product Advertising API

Updated: 19th October 2011

In this post we will see how to access the Amazon Product Advertising API from PHP. Amazon has recently changed (from 15th Aug ’09) the authentication mechanism for accessing their API which must now be signed with your Amazon keys. Unsigned requests will be rejected by Amazon. Also now Amazon Associate Tag is required in the query (effective from 25th Oct. 2011). Note that the code uses the hash_hmac() hash function which is only available for PHP versions 5.1.2 and above, so the code will not work for versions below that.

A small example

Below is an example to access the Amazon Product Advertising API using the provided class.

<?php
 
    /* Example usage of the Amazon Product Advertising API */
    include("amazon_api_class.php");
 
    $obj = new AmazonProductAPI();
 
    try
    {
        /* Returns a SimpleXML object */
         $result = $obj->searchProducts("X-Men Origins",
                                       AmazonProductAPI::DVD,
                                       "TITLE");
    }
    catch(Exception $e)
    {
        echo $e->getMessage();
    }
 
    print_r($result);
 
?>

You can convert the returned xml to json with the following line.

$result = json_encode($result);

The API access class

Given below is the implementation of the class to access the Amazon Product Advertising API. Comments have been removed for brevity, but are included in the source download. Note that only a few access operations are implemented in the class: ItemLookup, ItemSearch; there are more available in the API, a complete list can be found here. It’s just a simple matter of changing some parameters to implement others.

<?php
 
require_once 'aws_signed_request.php';
 
class AmazonProductAPI
{
 
    private $public_key     = "YOUR AMAZON ACCESS KEY ID";
    private $private_key    = "YOUR AMAZON SECRET KEY";
 
    /* 'Associate Tag' now required, effective from 25th Oct. 2011 */
    private $associate_tag  = "YOUR AMAZON ASSOCIATE TAG";
 
    const MUSIC = "Music";
    const DVD   = "DVD";
    const GAMES = "VideoGames";
 
    private function verifyXmlResponse($response)
    {
        if ($response === False)
        {
            throw new Exception("Could not connect to Amazon");
        }
        else
        {
            if (isset($response->Items->Item->ItemAttributes->Title))
            {
                return ($response);
            }
            else
            {
                throw new Exception("Invalid xml response.");
            }
        }
    }
 
    private function queryAmazon($parameters)
    {
        return aws_signed_request("com",
                                  $parameters,
                                  $this->public_key,
                                  $this->private_key,
                                  $this->associate_tag);
    }
 
    public function searchProducts($search,$category,$searchType="UPC")
    {
        $allowedTypes = array("UPC", "TITLE", "ARTIST", "KEYWORD");
        $allowedCategories = array("Music", "DVD", "VideoGames");
 
        switch($searchType) 
        {
            case "UPC" :
                $parameters = array("Operation"     => "ItemLookup",
                                    "ItemId"        => $search,
                                    "SearchIndex"   => $category,
                                    "IdType"        => "UPC",
                                    "ResponseGroup" => "Medium");
                            break;
 
            case "TITLE" :
                $parameters = array("Operation"     => "ItemSearch",
                                    "Title"         => $search,
                                    "SearchIndex"   => $category,
                                    "ResponseGroup" => "Medium");
                            break;
 
        }
 
        $xml_response = $this->queryAmazon($parameters);
 
        return $this->verifyXmlResponse($xml_response);
 
    }
 
    public function getItemByUpc($upc_code, $product_type)
    {
        $parameters = array("Operation"     => "ItemLookup",
                            "ItemId"        => $upc_code,
                            "SearchIndex"   => $product_type,
                            "IdType"        => "UPC",
                            "ResponseGroup" => "Medium");
 
        $xml_response = $this->queryAmazon($parameters);
 
        return $this->verifyXmlResponse($xml_response);
 
    }
 
    public function getItemByAsin($asin_code)
    {
        $parameters = array("Operation"     => "ItemLookup",
                            "ItemId"        => $asin_code,
                            "ResponseGroup" => "Medium");
 
        $xml_response = $this->queryAmazon($parameters);
 
        return $this->verifyXmlResponse($xml_response);
    }
 
    public function getItemByKeyword($keyword, $product_type)
    {
        $parameters = array("Operation"   => "ItemSearch",
                            "Keywords"    => $keyword,
                            "SearchIndex" => $product_type);
 
        $xml_response = $this->queryAmazon($parameters);
 
        return $this->verifyXmlResponse($xml_response);
    }
 
}
 
?>

Amazon signed request

The above class uses the ‘aws_signed_request’ function to generate the new request signature. Original code is by Ulrich Mierendorff, modified here to use cURL.

<?php
 
function  aws_signed_request($region,
                             $params,
                             $public_key,
                             $private_key,
                             $associate_tag)
{
 
    $method = "GET";
    $host = "ecs.amazonaws.".$region;
    $uri = "/onca/xml";
 
 
    $params["Service"]          = "AWSECommerceService";
    $params["AWSAccessKeyId"]   = $public_key;
    $params["AssociateTag"]     = $associate_tag;
 
    $params["Timestamp"]        = gmdate("Y-m-d\TH:i:s\Z");
    $params["Version"]          = "2009-03-31";
 
    /* The params need to be sorted by the key, as Amazon does this at
      their end and then generates the hash of the same. If the params
      are not in order then the generated hash will be different from
      Amazon thus failing the authentication process.
    */
    ksort($params);
 
    $canonicalized_query = array();
 
    foreach ($params as $param=>$value)
    {
        $param = str_replace("%7E", "~", rawurlencode($param));
        $value = str_replace("%7E", "~", rawurlencode($value));
        $canonicalized_query[] = $param."=".$value;
    }
 
    $canonicalized_query = implode("&", $canonicalized_query);
 
    $string_to_sign = $method."\n".$host."\n".$uri."\n".
                            $canonicalized_query;
 
    /* calculate the signature using HMAC, SHA256 and base64-encoding */
    $signature = base64_encode(hash_hmac("sha256", 
                                  $string_to_sign, $private_key, True));
 
    /* encode the signature for the request */
    $signature = str_replace("%7E", "~", rawurlencode($signature));
 
    /* create request */
    $request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature;
 
    /* I prefer using CURL */
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
 
    $xml_response = curl_exec($ch);
 
    if ($xml_response === False)
    {
        return False;
    }
    else
    {
        /* parse XML and return a SimpleXML object, if you would
           rather like raw xml then just return the $xml_response.
         */
        $parsed_xml = @simplexml_load_string($xml_response);
        return ($parsed_xml === False) ? False : $parsed_xml;
    }
}
?>
Download Source
Downloads : 17863 / File size : 0 B

135 thoughts on “Accessing Amazon Product Advertising API

  1. Thanks for the code, i was searching for this kind of the code, its working fine. But i have a question, I am getting the result for SearchIndex as “Book” an Keywirds as a”audio recording, it giving the result fine, it shows that there are [TotalResults] => 6795 [TotalPages] => 680 but i am able to display only 10 items out of that, how do i get remaining items?
    thanks in Advance

    Regards,
    Chaitanya

  2. You will need to add the ‘ItemPage’ parameter in the given class. For example :

    $parameters = array(“Operation” => “ItemSearch”,
    “Keywords” => $keyword,
    “ItemPage” => 2,
    “SearchIndex” => $product_type);

    Check the Amazon API documentation for more info.

  3. Hi Can anyone tell me how to dislplay the reviews and how to sort them in decending order This is the code of amazon

    function theItemWindow() {
    global $Result;
    global $bn;

    echo ”;
    $rowcount=0;
    if ($bn != FIRST_TIME) {
    foreach ($Result[‘MultiOperationResponse’][‘ItemSearchResponse’][‘Items’][0][‘Item’] as $item) {
    if (isset($item[‘SmallImage’][‘URL’])) {
    $image=”;

    //$res= $item[“CustomerReviews”][“TotalReviews”];
    //echo “$res”;
    // $reviews = $item[“”]
    } else {
    $image=”;
    }

    $title = ‘‘. $item[“ItemAttributes”][ “Title”].’‘;
    if (is_int($rowcount/5)) echo ”;

    echo ”.$title.”.$image.”.$reviews.”;
    $rowcount++;

    }
    }
    else {
    echo ‘Choose a category on the left’;
    }

    echo ”;

    }

  4. I get a search result which has 18 items. I choose to list the products which has only the Offers->Offer->OfferListing->OfferListingId

    Now even though the result set has 2 pages, in the first page only 3 products get displayed because of the above criteria.

    Is there a way to tell amazon to fetch records which has only the Offers->Offer->OfferListing->OfferListingId so that the Items->TotalResults and Items->TotalPages are correct?

    thanks in advance

  5. Hi Sameer

    It is a great code, Thanks for publishing it.
    I am using the same example after downloading it. But i am not getting any response.

    I am getting “Could not connect to Amazon” error. I had tried and checked that the response is blank.

    Can you please help me.

    Thanks in advance.

  6. I am querying Amazon trying to get seller’s listing using the following parameters:

    $parameters = array(“Operation” => “SellerListingSearch”,
    “ListingPage” => 1,
    “SellerId” => “XXXXXXXXXXX”,
    “BrowseNode” => 266239,
    “SearchIndex” => “Marketplace”,
    “ResponseGroup” => “SellerListing”
    );

    Although I can successfully get a list of 2400 books at amazon.co.uk, I am unable yet to find their exact browse nodes nor the BrowseNode parameter work for any value.

    I get same number of books every time no matter what BrowseNode is sent in parameter. Please tell me how I can get categorized items under a BrowseNode against a seller id?

    Thanks in advance!!!

  7. Sameer,

    Excellent code and very easy to impliment. I have a similar question to poster #52.

    For your getItemByKeyword(), function, if I type in for example, biology, and make the search Index “books”, I get about 6000 items. I would like to print the picture of say the first 200. How would I modify your code to do that?

  8. This api is basically a referal program. i mean i will get paid about 15% of the books sold through my refrence. Actually i am bit worried about this and i don’t know that which link should i use to make that thing possible. My motive is to send user to amazon site from my site by clicking a book so that i can get about 15% commision of the purchase. Please guide me what should i do…………
    Thanks for posting such a nice tutorial…..Even amazon documentation is not that much helpful

  9. Hi Sameer,
    The code is working fine if i query amazon with 10 digit ISBN code. but if i query the amazon with 13 digit ISBN number then it gives excetion error.
    Have look on my function :-
    public function getItemByAsin($asin_code)
    {
    $parameters = array(“Operation” => “ItemLookup”,
    “ItemId” => $asin_code,
    “ResponseGroup” => “Medium”);

    $xml_response = $this->queryAmazon($parameters);

    return $this->verifyXmlResponse($xml_response);
    }

    $isbn_number = 978-0979181511; //(gives error)
    //$isbn_number = 0979181511; // (runs without error)

    $result1 = $obj->getItemByAsin($isbn_number);

    Both the ISBN number belongs to same book. even then they are showing error.. please check and reslove this issue…….

  10. Hi Guys! I had my site working fine implementing this code but all of a sudden everything stopped working. I noticed that the new documentation requires the “amazon associates tag,” in which I updated but still no response coming back. I re-checked my amazon access key, it is valid and active. The only thing I can think about that might have messed things up is the recent change on GoDaddy servers to PHP 5.3, which may have broken some things. Can anyone help please?

  11. Hi!

    I’ve just tested the above code and it is working fine. To debug add the following line in the ‘aws_signed_request.php’ file after ‘$xml_response = curl_exec($ch);’

    So it should look like this:

    $xml_response = curl_exec($ch);
    echo $xml_response;
    exit;

    This will surely help you pinpoint any errors Amazon is throwing and will help you resolve the issue.

  12. How do I make it so it doesn’t return anything on my screen expect for what I echo. I’m trying to return just the ASIN but its returning every bit of information there is about the item I’m looking up

  13. Hi to all.,

    The code working super it saved my time lot and one doubt on this code i need to display the reviews like 4.5 currently it shows the all reviews URL i just want to display the rating only please any one help to me..

    Thanks in advance
    Thanks & Regards
    Dharma

  14. Samir

    Can you pls send me an email, i would like your help to an AMAZON API site. My website stopped working with the new signing in

  15. U guys always said it display 10 products on the screen. Using the Example.php file, managed to get loads of XML coding but with only 1 image at the bottom. Does anyone has the code to display the 10 products?

    Thks

  16. Hi Sameer,

    Do we need to pay amazon every time we are querying their database using your script?

    regards,
    Rey

  17. Hello I am using Amazon Api for display songs of an artist. I am using

    case “TITLE” : $parameters = array(“Operation” => “ItemSearch”,
    “Title” => $search,
    “SearchIndex” => $category,
    “ResponseGroup” => “Medium”);
    break;

    and send parameters as

    $params[“Service”] = “AWSECommerceService”;
    $params[“AWSAccessKeyId”] = $public_key;
    $params[“AssociateTag”] = $associate_tag;
    $params[“Timestamp”] = gmdate(“Y-m-d\TH:i:s\Z”);
    $params[“Version”] = “2009-03-31”;
    $params[“Sort”] = “artistrank”;

    But the results I am getting are not in correct order
    Means sort is not working.

    My Results should be like this URL: http://www.amazon.com/s/ref=sr_st?keywords=Anita+Baker&qid=1355907713&rh=n%3A5174%2Ck%3AAnita+Baker&sort=relevancerank

    But I am getting different results as :
    http://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=AWSAccessKeyId&AssociateTag=MYAssociateTag&Operation=ItemSearch&ResponseGroup=Medium&SearchIndex=Music&Service=AWSECommerceService&Sort=artistrank&Timestamp=2012-12-19T12%3A41%3A21Z&Title=anita-baker&Version=2009-03-31&Signature=MYSignature

    Please tell me how can I get top 10 results as given url http://www.amazon.com/s/ref=sr_st?keywords=Anita+Baker&qid=1355907713&rh=n%3A5174%2Ck%3AAnita+Baker&sort=relevancerank

    Thanks

  18. Hi all and thank You for sharing your code. I don’t understand Amazon API very nice. I’m trying lo learn it :-). How could I search for toys. For examples, all LEGO products in Toys category? Im’m trying to modify your code but I receive dvd.

    Thank You again for sharing.
    King regards
    Fabio

  19. Just another question. How to “point to” Amazon.it ??? I’ve found a $region variable but changing it, I receive an error 🙁

    Thank You again
    Fabio

  20. Hi Sameer,
    Thanks very much for this code.. I just try it..

    But, I am still confusing searching to solve my problem,

    The code of (on the example.php):

    echo “Sales Rank : {$result->Items->Item->SalesRank}”;
    echo “ASIN : {$result->Items->Item->ASIN}”;
    echo “Items->Item->MediumImage->URL . “\” />”;

    it just show 1 product.. As people said that it show 10 products, but not on me.

    Just try to add “array” code, but I think I was wrong.. 😀

    Would you suggest me to correct which code I should change and how..

    I downloaded the file on the zipped above..

    Thanks for your help..

    Have a great day Sameer.. ^_^

  21. Hi Sameer,

    Can you please help me in this regard. I need to get the top 100 best sellers of tablets from Amazon. I have given this request and its giving me the 10 best seller products. I gave page number in the request and its showing the same 10 results. How to get this 100 products using pagination. My current request is like below.

    http://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=%5BACCESSKEY%5D&AssociateTag=%5BASSOCIATE TAG]&BrowseNodeId=565108&Condition=Large&ItemPage=3&Operation=BrowseNodeLookup&ResponseGroup=TopSellers&Service=AWSECommerceService&Timestamp=2013-02-12T13%3A10%3A01.000Z&Version=2010-11-01&Signature=[Signature]

    Can you please help me to get the 100 best seller products? Thanks in advance.

  22. Hi Sameer,
    I want to pull book image from amazon and display on my webpage.
    any body help me here please
    thankx a lot

  23. Sir, i am try to implement the api of amazon to fetch the result from amazon site.

    but i am not going in right direction, can you please tell me the step by step procedure to implement this code and please send me detail of code to used in my site.

    Thank You

    Pankaj

  24. Excellent post, and much appreciated. The Amazon help resources are not great for this, and your example is both a great way to implement as well as learn the resource.

  25. Is this api still valid in 2014 or is the new Amazon product api mws? I want to create a WordPress shopping cart site (ex. getshopped) where physical products are sold and compare the cart’s prices to Amazon’s product api. Could you help me figure out the best way to do this?

  26. hi i getting fatal error on this code

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

    $xml_response = curl_exec($ch);

    wht should i do?

  27. Just wanted to say thank you for this resource! Just the start I needed to figure it out.

  28. Hi,
    Not work, I get error like this :

    Invalid xml response.
    Notice: Undefined variable: result in C:\xampp\htdocs\web14\Example.php on line 19

    Notice: Undefined variable: result in C:\xampp\htdocs\web14\Example.php on line 21

    Notice: Trying to get property of non-object in C:\xampp\htdocs\web14\Example.php on line 21

    Notice: Trying to get property of non-object in C:\xampp\htdocs\web14\Example.php on line 21

    Notice: Trying to get property of non-object in C:\xampp\htdocs\web14\Example.php on line 21

Comments are closed.