1

I am wondering if someone could help.

I am trying to list a product on Amazon through the API.

When using GetOrders it works perfectly but with similar code apart from the parameters I get the following error message when using SubmitFeed _POST_PRODUCT_DATA_

"Sender SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."

All my details are correct, the secret key, aws access key etc. and I have compared the string to sign in my code to the one that is generated in the Amazon API test tool and they are exactly the same so I am not sure what the problem is.

Here is the code I am using -

$timestamp = date('c', strtotime($todays_date_time));
$timestamp = gmdate('Y-m-d\TH:i:s\Z', strtotime($timestamp));

$params = array(
    'AWSAccessKeyId' => "MY_AWS_KEY",
    'Action' => "SubmitFeed",
    'Merchant' => "MY_SELLER_ID",
    'FeedType' => "_POST_PRODUCT_DATA_",
    'SignatureMethod' => "HmacSHA256",
    'SignatureVersion' => "2",
    'Timestamp'=> $timestamp,
    'Version'=> "2009-01-01",
    'MarketplaceIdList.Id.1' => "MY_MARKETPLACE_ID",
    'PurgeAndReplace'=>'false'
);

$secret = 'MY_SECRET_KEY';

$url_parts = array();

foreach(array_keys($params) as $key) {

    $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));

}

Then here I create the XML and store it in the variable $amazon_feed and then -

sort($url_parts);

$url_string = implode("&", $url_parts);
$string_to_sign = "POST\nmws.amazonservices.co.uk\n/\n" . $url_string;

$signature = hash_hmac("sha256", $string_to_sign, $secret, TRUE);

$http_header     =   array();
$http_header[]   =   'Transfer-Encoding: chunked';
$http_header[]   =   'Content-Type: application/xml';
$http_header[]   =   'Content-MD5: ' . base64_encode(md5($amazon_feed, true));
$http_header[]   =   'Expect:';
$http_header[]   =   'Accept:';

$signature = urlencode(base64_encode($signature));

$link = "https://mws.amazonservices.co.uk/Feeds/2009-01-01?".$url_string."&Signature=".$signature;

$ch = curl_init($link);
curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $amazon_feed); 
$response = curl_exec($ch);

print_r($response);

$info = curl_getinfo($ch);
curl_close($ch);

Would anyone be able to help?

Dan
  • 103
  • 1
  • 13
  • I had this issue not so long back. Have a look at this question (and answer) and see if it helps you: http://stackoverflow.com/questions/29679646/issues-calculating-signature-for-amazon-marketplace-api – Martin Bean Aug 09 '15 at 22:42

1 Answers1

1

You will have to ksort() your params before you pass them here:

foreach(array_keys($params) as $key) {

    $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));

}

e.g.

$params = array(
    'AWSAccessKeyId' => "MY_AWS_KEY",
    'Action' => "SubmitFeed",
    'SellerId' => "MY_SELLER_ID",
    'FeedType' => "_POST_PRODUCT_DATA_",
    'SignatureMethod' => "HmacSHA256",
    'SignatureVersion' => "2",
    'Timestamp'=> $timestamp,
    'Version'=> "2009-01-01",
    'MarketplaceIdList.Id.1' => "MY_MARKETPLACE_ID",
    'PurgeAndReplace'=>'false'
);

$secret = 'MY_SECRET_KEY';
$url_parts = array();
ksort($params);
foreach(array_keys($params) as $key) {

    $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));

}

I'm not entirely sure about the string you are signing, you should try it with this (adding /Feeds/2009-01-01 to it):

"POST\nmws-eu.amazonservices.com\n/Feeds/2009-01-01\n" . $url_string

Also, Amazon expects a SellerId for the _POST_PRODUCT_DATA_ operation, not Merchant.

I suggest you to use mws-eu-amazonservices.com instead of the co.uk one, you can use this for all the european marketplaces and don't need to change it for each. As a sidenote:

Amazon doesn't really report the correct error. The error you are getting can also occur if only SellerId is Merchant like above, or anything different that has nothing to do with what you are trying to do.

baao
  • 71,625
  • 17
  • 143
  • 203
  • Thank you for your reply Michael. I have tried using ksort with the same error. The reason I put merchant is because in the test tool that is what is passed in the url not SellerId but I have now tried with SellerId with the same error. I understand your sidenote but can't seem to find what I am missing. – Dan Aug 09 '15 at 22:55
  • Did you also try the last edit? the string you are signing is incomplete – baao Aug 09 '15 at 22:56
  • I didn't originally I hadn't refreshed the page but just tried it now and thank you it is now working. Changing the POST line your gave me and the url being sent to the mws-eu one worked. – Dan Aug 09 '15 at 23:08
  • Hi Michael, Sorry to ask again but just out of curiosity how long before the listing shows on amazon because the feed returns Successful but the product isn't in my inventory? – Dan Aug 09 '15 at 23:10
  • No problem. Depending on amazon about 5 to 30 minutes. This can take some time. But usually I have a time from up to 10 minutes @DanielOrmerod – baao Aug 09 '15 at 23:12
  • You can also get the feed submission list, once the result is _DONE_ the items are available for sale on amazon @DanielOrmerod – baao Aug 09 '15 at 23:12
  • 1
    Thank you Michael i checked the GetFeedSubmissionResult and I hadn't included the Condition so it threw an error. Thank you for all your help! – Dan Aug 09 '15 at 23:25