I recently provided Amazon’s Product Advertising API integration for one of the sites I did for a client in Drupal (along with iTunes search integration etc). I have to say providing Amazon’s Product Advertising API integration was more cumbersome than integration with other such API’s available, mainly because of Amazon’s requirement of signed url requests (which basically contain SHA hash of the url for authenticating the request to Amazon), and because of far less documentation available on the Product Advertising API’s request parameters and response formats.

The major headache was generating the signed urls required for making Product API requests. Amazon itself provides an example in javascript, which I was surprised to see because you would hardly want to expose your AWS Secret Access Key to everyone through javascript. But Amazon did not provide a single example of generating the signed urls for any server-side framework.

Google search threw up a good number of ready to use examples for PHP and other server-side frameworks, and I used one of them. Unfortunately, it had some bugs and typos and I had to spend sometime getting everything in place. So, here’s the complete method for generating signed urls in PHP together with an example on how to invoke it:

 

{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }define(‘AWS_ACCESS_KEY_ID’, ‘Your AWS Access Key ID’);
define(‘AWS_SECRET_ACCESS_KEY’, ‘Your AWS Secret Access Key’);
define(‘AMAZON_ASSOC_TAG’, ‘Your Associate tag, leave blank if not available’);

function amazon_get_signed_url($searchTerm) {
$base_url = “http://ecs.amazonaws.com/onca/xml”;
$params = array(
‘AWSAccessKeyId’ => AWS_ACCESS_KEY_ID,
‘AssociateTag’ => AMAZON_ASSOC_TAG,
‘Version’ => “2010-11-01”,
‘Operation’ => “ItemSearch”,
‘Service’ => “AWSECommerceService”,
‘Availability’ => “Available”,
‘Condition’ => “All”,
‘Operation’ => “ItemSearch”,
‘SearchIndex’ => ‘Music’, //Change search index if required, you can also accept it as a parameter for the current method like $searchTerm
‘Keywords’ => $searchTerm);

//’ItemPage’=>”1″,
//’ResponseGroup’=>”Images,ItemAttributes,EditorialReview”,

if(empty($params[‘AssociateTag’])) {
unset($params[‘AssociateTag’]);
}

// Add the Timestamp
$params[‘Timestamp’] = gmdate(“Y-m-d\TH:i:s.\\0\\0\\0\\Z”, time());

// Sort the URL parameters
$url_parts = array();
foreach(array_keys($params) as $key)
$url_parts[] = $key . “=” . str_replace(‘%7E’, ‘~’, rawurlencode($params[$key]));
sort($url_parts);

// Construct the string to sign
$url_string = implode(“&”, $url_parts);
$string_to_sign = “GET\necs.amazonaws.com\n/onca/xml\n” . $url_string;

// Sign the request
$signature = hash_hmac(“sha256”, $string_to_sign, AWS_SECRET_ACCESS_KEY, TRUE);

// Base64 encode the signature and make it URL safe
$signature = urlencode(base64_encode($signature));

$url = $base_url . ‘?’ . $url_string . “&Signature=” . $signature;

return ($url);
}

$searchTerm = $_REQUEST[‘searchTerm’];
$url = amazon_get_signed_url($searchTerm);

//Below is just sample request dispatch and response parsing for example purposes.

$response = file_get_contents($url);
$parsed_xml = simplexml_load_string($response);

$result = array();

foreach($parsed_xml->Items->Item as $current){
if($current->ItemAttributes->ProductGroup == ‘Music’) {
$item = array(
‘track_id’ => implode(((array)$current->ASIN), ‘, ‘),
‘source’ => 1,
‘track_name’ => implode(((array)$current->ItemAttributes->Title), ‘, ‘),
‘track_url’ => implode(((array)$current->DetailPageURL), ‘, ‘),
‘artist_name’ => implode(((array)$current->ItemAttributes->Artist), ‘, ‘),
‘artist_url’ => ”,
‘collection_name’ => ”,
‘collection_url’ => ”,
‘genre’ => ”,
);

$result[] = $item;
}
}
{/syntaxhighlighter}