11

I want to know if there is a way to convert my Amazon MWS scratchpad queries to an API call

e.g. when using the MWS scratchpad I'm given a String to sign

   "mws.amazonservices.co.uk"
   ."/Products/2011-10-01"
   ."AWSAccessKeyId=xxx&Action=ListMatchingProducts"
   ."&MarketplaceId=xxx&Query=star%20wars&SellerId=xxx"
   ."&SignatureMethod=HmacSHA256&SignatureVersion=2
   ."&Timestamp=2012-07-27T18%3A59%3A30Z&Version=2011-10-01

After spending days trying to get Amazons order API to work I have given up and have been hoping that the following function would return an xml string...but with no luck

function callAmazon(){
    $apicall =  "mws.amazonservices.co.uk"
   ."/Products/2011-10-01"
   ."AWSAccessKeyId=xxx&Action=ListMatchingProducts"
   ."&MarketplaceId=xxx&Query=star%20wars&SellerId=xxx"
   ."&SignatureMethod=HmacSHA256&SignatureVersion=2
   ."&Timestamp=2012-07-27T18%3A59%3A30Z&Version=2011-10-01   
    
    $resp = simplexml_load_file($apicall);   //make the call
}

Does anyone have any possible suggestions?

starball
  • 20,030
  • 7
  • 43
  • 238
mk_89
  • 2,692
  • 7
  • 44
  • 62

3 Answers3

13

I struggled with this for a long time as well, here is how I solved it for the Products API:

<?php
require_once('.config.inc.php');
$base_url = "https://mws.amazonservices.com/Products/2011-10-01";
$method = "POST";
$host = "mws.amazonservices.com";
$uri = "/Products/2011-10-01";

function amazon_xml($searchTerm) {

    $params = array(
        'AWSAccessKeyId' => AWS_ACCESS_KEY_ID,
        'Action' => "ListMatchingProducts",
        'SellerId' => MERCHANT_ID,
        'SignatureMethod' => "HmacSHA256",
        'SignatureVersion' => "2",
        'Timestamp'=> gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()),
        'Version'=> "2011-10-01",
        'MarketplaceId' => MARKETPLACE_ID,
        'Query' => $searchTerm,
        'QueryContextId' => "Books");

    // 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\nmws.amazonservices.com\n/Products/2011-10-01\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 = "https://mws.amazonservices.com/Products/2011-10-01" . '?' . $url_string . "&Signature=" . $signature;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    $response = curl_exec($ch);

    $parsed_xml = simplexml_load_string($response);

    return ($parsed_xml);
}

?>

The .inc.config.php file contains my access key, secret key etc.

EDIT:
$searchterm is the isbn I am passing from my form.

Emil Sierżęga
  • 1,785
  • 2
  • 31
  • 38
Jim
  • 1,315
  • 4
  • 17
  • 45
  • This looks interesting I'll give it a shot, all I need to do is grab the config file that I was using previously – mk_89 Jul 27 '12 at 19:39
  • 1
    I took the one that came with the new apis. – Jim Jul 27 '12 at 19:42
  • the function is not returning anything? do I have to change anything else? – mk_89 Jul 27 '12 at 19:44
  • 2
    you will need to change some of the params to meet what you want for the API that you are using. You can test it by hardcoding in all the information and the using print_r($parsed_xml) and that will show you the xml. – Jim Jul 27 '12 at 19:53
  • Thanks I was trying to use echo – mk_89 Jul 27 '12 at 19:55
  • 2
    No problem, like I said I struggled with this for a long time as well and someone else helped me out. Good luck, the Amazon documentation is pretty lacking. – Jim Jul 27 '12 at 20:00
  • I most definitely agree on the documentation lacking, and I can't believe how many errors I would get from samples when there should be none – mk_89 Jul 27 '12 at 20:03
1

You need to actually CALL the API. The string you are using doesn't specify the http:// portion of the URL.

Mike Brant
  • 70,514
  • 10
  • 99
  • 103
  • 1
    SO when actually using http or https, what result are you getting in $resp? Also what do you get it you try calling those URL's in a browser or by other methodologies (i.e. cURL, wget, etc.) – Mike Brant Jul 27 '12 at 19:35
  • $resp returns nothing but errors, but in the browser an XML string is returned – mk_89 Jul 27 '12 at 19:36
  • 1
    could be that the XML is malformed or perhaps has CDATA blocks in which case you would need to use the LIBXML_NOCDATA option. – Mike Brant Jul 27 '12 at 19:38
1

I had a little trouble with this code, I had it working when uploaded to a hosted web server but not when running local using windows and xampp.

If you are having problems, try adding this to the end of the curl-setopt block.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

btw you also need to modify your php.ini file in the xampp folder to enable curl.

AlanW
  • 63
  • 4