I keep getting an invalid date range response from my request. I am not sure what is wrong. I have all the parameters and a valid ReportID.
$params = array(
'AWSAccessKeyId' => AWS_ACCESS_KEY_ID,
'Action' => "GetReport",
'SellerId' => MERCHANT_ID,
'SignatureMethod' => "HmacSHA256",
'SignatureVersion' => "2",
'Timestamp' => $timestamp,
'Version'=> "2009-01-01",
'Marketplace' => MARKETPLACE_ID,
'ReportId' => $reportID
);
// 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/Reports/2009-01-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/Reports/2009-01-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);
print_r($response);
The output I get back is Invalid Date Range
Does it work through Amazon's scratchpad? I just tried a GetReport operation and it came back just fine. Of course no date range is needed because you're trying to get back a specific report by id. I usually go to the scratchpad as a quick and easy way to get info from MWS.
My POST looks like this:
Well after contacting Amazon this is what is came down to. When I requested the report using the RequestReport Action I supplied an invalid Date Range. So the report itself return Invalid Date Range as the content of the report.
Related
I have used following code for getting amazon product data and all products are getting in xml but product stock is not there in xml content.
Can anyone guide me for how to get product stock information.
<?php
define('AWS_ACCESS_KEY_ID', 'my-access-key');
define('AWS_SECRET_ACCESS_KEY', 'my-secret-key');
define('AMAZON_ASSOC_TAG', 'my-associate-tag');
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' => "ItemLookup", 'Service' => "AWSECommerceService", 'ResponseGroup' => "ItemAttributes", 'ItemId'=> $searchTerm);
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);
}
$getthis = 'B004XIE6WI'; /*---- Product ASIN-----*/
$show = amazon_get_signed_url($getthis);
$ch = curl_init($show);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$c = curl_exec($ch);
$xml = simplexml_load_string($c);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
echo "<pre>";
print_r($array);
echo "</pre>";
?>
Amazon Product Api does not provide stock information. A similar question was asked here: How to get remaining stock from Product Advertising API (AWS)
I'm trying to get the inventory of my fulfillment using the PHP API of the MWS. When I use the parameters given by amazon on the scratchpad I get the answer perfectly, but when I try using my code it says that the signature doesn't match, what am I doing wrong?
<?php
$base_url = "https://mws.amazonservices.co.uk/FulfillmentInventory/2010-10-01";
$method = "POST";
$host = "mws.amazonservices.co.uk";
$uri = "/FulfillmentInventory/2010-10-01";
function amazon_xml() {
$params = array(
'AWSAccessKeyId' => "123456788",
'Action' => "ListInventorySupply",
'SellerId' => "234234123412341",
'SignatureVersion' => "2",
//'Timestamp'=> gmdate("Y-m-d\TH:i:s.Z", time()),
'Timestamp'=> gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()),
'Version'=> "2010-10-01",
'SignatureMethod' => "HmacSHA256",
'SellerSkus.member.1' => '1EU-AMZ-FIRE-TV-MOUNT');
// 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 = "POST\nmws.amazonservices.co.uk\n/FulfillmentInventory/2010-10-01\n" . $url_string;
echo $string_to_sign."<br/>";
// Sign the request
$signature = hash_hmac("sha256", $string_to_sign, 'sdgsdfgsdfgsdgsdgsdg', TRUE);
echo $signature."<br />";
// Base64 encode the signature and make it URL safe
$signature = urlencode(base64_encode($signature));
echo $signature."<br />";
$url = "https://mws.amazonservices.co.uk/FulfillmentInventory/2010-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);
echo "La respuesta es ".$response;
$parsed_xml = simplexml_load_string($response);
//return ($parsed_xml);
echo $parsed_xml;
}
amazon_xml();
?>
You appear to be sorting your $url_parts array by value, where you should be sorting it by key.
ksort($url_parts);
I cannot see any other systematic problem in your code. Another point where my code differs from yours though, is that mine uses a Merchant parameter instead of SellerId - I have not checked if using SellerId actually works as well.
Using the below code, the only result I can get to echo is the URL. When I copy and paste into browser, I get:
<Message>
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.
Code Being Used;
<?php
date_default_timezone_set('America/New_York');
define('AWS_ACCESS_KEY_ID', '***');
define('AWS_SECRET_ACCESS_KEY', '***');
define('APPLICATION_NAME', 'test');
define('APPLICATION_VERSION', '1.0');
define ('MERCHANT_ID', '***');
define ('MARKETPLACE_ID', '***');
$base_url = "https://mws.amazonservices.com/Products/2011-10-01";
$method = "GET";
$host = "mws.amazonservices.com";
$uri = "/Products/2011-10-01";
function amazon_xml($searchTerm) {
$params = array(
'AWSAccessKeyId' => AWS_ACCESS_KEY_ID,
'Action' => "GetCompetitivePricingForASIN",
'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' => "Automotive");
// 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_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$response = curl_exec($ch);
echo $url;
// return $xml if you still want to parse the data elsewhere
$xml = simplexml_load_string($response);
// return this if you just want the raw XML string
return $xml->asXML();
echo $xml->GetMatchingProductResult->Product->Identifiers->MarketplaceASIN->ASIN;
}
$searchTerm = "B00FNNLBK2";
amazon_xml($searchTerm);
//foreach ($xml->GetMatchingProductResult->Product as $product) {
// do something for each <Product>, such as output the ASIN...
//}
echo $xml;
echo $searchTerm;
echo $xml->GetMatchingProductResult->Product->Identifiers->MarketplaceASIN->ASIN;
echo $url;
?>
I did verify multiple times that the sign in credentials are correct, with no absract leading or trailing space.
Those parameters (e.g. Query and QueryContextId) don't match with the Action you are trying to call (GetCompetitivePricingForASIN). They correspond to the ListMatchingProducts action.
Assuming that you meant ListMatchingProducts try this:
<?php
date_default_timezone_set('America/New_York');
define('AWS_ACCESS_KEY_ID', '***');
define('AWS_SECRET_ACCESS_KEY', '***');
define('APPLICATION_NAME', 'test');
define('APPLICATION_VERSION', '1.0');
define ('MERCHANT_ID', '***');
define ('MARKETPLACE_ID', '***');
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' => "Automotive"
);
$url_parts = array();
foreach (array_keys($params) as $key)
$url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));
sort($url_parts);
$url_string = implode("&", $url_parts);
$string_to_sign = "GET\nmws.amazonservices.com\n/Products/2011-10-01\n" . $url_string;
$signature = hash_hmac("sha256", $string_to_sign, AWS_SECRET_ACCESS_KEY, TRUE);
$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_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$response = curl_exec($ch);
$xml = simplexml_load_string($response);
return $xml->asXML();
}
$searchTerm = "B00FNNLBK2";
echo amazon_xml($searchTerm);
You can find the relevant parameters for each Action in the MWS documentation e.g. here:
http://docs.developer.amazonservices.com/en_US/products/Products_GetCompetitivePricingForASIN.html
You can also see them using the MWS Scratchpad:
https://mws.amazonservices.com/scratchpad/index.html
I'm trying to use the Google Api Calendar, but I'm not able to pass the auth step.
Following this tutorial, I've written some php code (yes, I know, I should use the API) that gives me "invalid grant" as response.
I'm very diehard and I really would know where my error is. I suppose is the sign step, but the private_key is a valid struct. I obtained the .pem by converting the p12 using this command:
openssl pkcs12 -in key.p12 -out key.pem -nodes
Could you please help me?
Thanks.
<?php
$private_key = openssl_pkey_get_private('file://key.pem', 'notasecret');
$header = array("alg" => "RS256", "typ" => "JWT");
$header = base64_encode(utf8_encode(json_encode($header)));
$exp = time() + (60 * 60);
$jwt_cs = array(
"iss" => "************************#developer.gserviceaccount.com",
"scope" => "https://www.googleapis.com/auth/calendar.readonly",
"aud" => "https://accounts.google.com/o/oauth2/token",
"exp" => $exp,
"iat" => time(),
"access_type" => "offline"
);
$jwt_cs = base64_encode(utf8_encode(json_encode($jwt_cs)));
openssl_sign($header.$jwt_cs, $sign, $private_key, 'sha256WithRSAEncryption');
$sign = base64_encode($sign);
$jwt = $header.$jwt_cs.$sign;
$login_data = array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
);
$url='https://accounts.google.com/o/oauth2/token';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = json_decode(curl_exec($ch));
curl_close($ch);
var_dump($res)
?>
When computing the signature, you need to concatenate the header and claim set with a dot '.', i.e., $header . '.' . $jwt_cs.
When building the JWT, you also need to concatenate the header, claim set and signature with a dot '.', i.e., $header . '.' . $jwt_cs . '.' . $sign.
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?
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.
You need to actually CALL the API. The string you are using doesn't specify the http:// portion of the URL.
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.