从 Scratchpad 请求的亚马逊 MWS ListOrders
Amazon MWS ListOrders from Scratchpad to request
我正在尝试通过 MWS Scratchpad 获取订单列表。
在暂存器中一切正常。
HTTP POST 是
POST /Orders/2013-09-01?AWSAccessKeyId=$CHIAVE_ACCESSO
&Action=ListOrders
&SellerId=$SELLER_ID
&SignatureVersion=2
&Timestamp=2016-11-29T18%3A58%3A52Z
&Version=2013-09-01
&Signature=$SIGNATURE
&SignatureMethod=HmacSHA256
&CreatedAfter=2016-10-31T23%3A00%3A00Z
&MarketplaceId.Id.1=APJ6JRA9NG5V4 HTTP/1.1
Host: mws.amazonservices.it
x-amazon-user-agent: AmazonJavascriptScratchpad/1.0 (Language=Javascript)
Content-Type: text/xml
要签名的字符串(在第二个框中)是
POST
mws.amazonservices.it
/Orders/2013-09-01
AWSAccessKeyId=$CHIAVE_ACCESSO&Action=ListOrders&CreatedAfter=2016-10-31T23%3A00%3A00Z&MarketplaceId.Id.1=APJ6JRA9NG5V4&SellerId=$SELLER_ID&Signat ureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-11-29T18%3A58%3A52Z&Version=2013-09-01
显示暂存器的结果是正确的。
我想做的是通过 PHP 提出请求并详细说明结果。
但是如果我先尝试将请求放在我的浏览器上,比如
https://mws.amazonservices.it/Orders/2013-09-01?AWSAccessKeyId=$CHIAVE_ACCESSO&Action=ListOrders&MarketplaceId=APJ6JRA9NG5V4&SellerId=$SELLER_ID&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-11-29T19%3A13%3A01.000Z&Version=2013-09- 01&Signature=Q9Xnr9JhtkzeLUAsCFKPln8SS34FkCQRmELE2WiIhPo%3D&CreatedAfter=2016-10-31T23%3A00%3A00Z
错误是
我用来创建签名的方法是在 Whosebug 上找到的,如下所示:
$sign = 'GET' . "\n";
$sign .= 'mws.amazonservices.it' . "\n";
$sign .= '/Orders/2013-09-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $CHIAVE_SEGRETA, true);
$signature = urlencode(base64_encode($signature));
我做错了什么?
您是否看过 PHP client library 的订单 API?我使用 C# 版本,但我认为 PHP 库是相似的。大部分工作都为您完成。
参数的顺序很重要。
下面是一些示例代码,应该可以为您提供一个良好的起点。您只需要稍微修改它以适合您的系统。
class AmazonMWS
{
private $secretKey = '';
private $parameters = array();
/**
* Constructor for the AmazonMWS class.
* Initializes constants.
*/
public function __construct()
{
$this->secretKey = Constant::get('SECRET_KEY');
$this->parameters['AWSAccessKeyId'] = Constant::get('AWSAccessKeyId');
$this->parameters['MarketplaceId.Id.1'] = Constant::get('MarketplaceId.Id.1');
$this->parameters['SellerId'] = Constant::get('SellerId');
$this->parameters['SignatureMethod'] = Constant::get('SignatureMethod');
$this->parameters['SignatureVersion'] = Constant::get('SignatureVersion');
}
public function setListOrders()
{
$this->parameters['Action'] = 'ListOrders';
$this->parameters['Version'] = '2013-09-01';
$this->parameters['Timestamp'] = $this->getTimestamp();
// this part should change and depend on the method/parameter.. for now just for testing
$this->parameters['CreatedAfter'] = '2015-11-01';
}
public function listOrders()
{
$request = "https://mws.amazonservices.com/Orders/2013-09-01?";
$request .= $this->getParameterString($this->parameters) . "&Signature=" . $this->calculateSignature($this->calculateStringToSign($this->parameters));
echo $request;
return Curl::fetchSSL($request);
}
/**
* Calculates String to sign.
*
* @param array $parameters request parameters
* @return String to sign
*/
protected function calculateStringToSign(array $parameters)
{
$stringToSign = 'GET' . "\n";
$stringToSign .= 'mws.amazonservices.com' . "\n";
$stringToSign .= '/Orders/2013-09-01' . "\n";
$stringToSign .= $this->getParameterString($parameters);
return $stringToSign;
}
/**
* Gets the query parameters as a String sorted in natural-byte order.
*
* @param array $parameters request parameters
* @return String of parameters
*/
protected function getParameterString(array $parameters)
{
$url = array();
foreach ($parameters as $key => $val) {
$key = $this->urlEncode($key);
$val = $this->urlEncode($val);
$url[] = "{$key}={$val}";
}
sort($url);
$parameterString = implode('&', $url);
return $parameterString;
}
/**
* Computes RFC 2104-compliant HMAC signature.
*
* @param String to sign
*/
protected function calculateSignature($stringToSign)
{
$signature = hash_hmac("sha256", $stringToSign, $this->secretKey, true);
return urlencode(base64_encode($signature));
}
/**
* URL encodes a string.
*/
protected function urlEncode($string)
{
return str_replace("%7E", "~", rawurlencode($string));
}
/**
* Gets the current date as ISO 8601 timestamp
*/
protected function getTimestamp()
{
return gmdate("Y-m-d\TH:i:s.\0\0\0\Z", time());
}
}
我正在尝试通过 MWS Scratchpad 获取订单列表。 在暂存器中一切正常。
HTTP POST 是
POST /Orders/2013-09-01?AWSAccessKeyId=$CHIAVE_ACCESSO
&Action=ListOrders
&SellerId=$SELLER_ID
&SignatureVersion=2
&Timestamp=2016-11-29T18%3A58%3A52Z
&Version=2013-09-01
&Signature=$SIGNATURE
&SignatureMethod=HmacSHA256
&CreatedAfter=2016-10-31T23%3A00%3A00Z
&MarketplaceId.Id.1=APJ6JRA9NG5V4 HTTP/1.1
Host: mws.amazonservices.it
x-amazon-user-agent: AmazonJavascriptScratchpad/1.0 (Language=Javascript)
Content-Type: text/xml
要签名的字符串(在第二个框中)是
POST
mws.amazonservices.it
/Orders/2013-09-01
AWSAccessKeyId=$CHIAVE_ACCESSO&Action=ListOrders&CreatedAfter=2016-10-31T23%3A00%3A00Z&MarketplaceId.Id.1=APJ6JRA9NG5V4&SellerId=$SELLER_ID&Signat ureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-11-29T18%3A58%3A52Z&Version=2013-09-01
显示暂存器的结果是正确的。
我想做的是通过 PHP 提出请求并详细说明结果。
但是如果我先尝试将请求放在我的浏览器上,比如
https://mws.amazonservices.it/Orders/2013-09-01?AWSAccessKeyId=$CHIAVE_ACCESSO&Action=ListOrders&MarketplaceId=APJ6JRA9NG5V4&SellerId=$SELLER_ID&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-11-29T19%3A13%3A01.000Z&Version=2013-09- 01&Signature=Q9Xnr9JhtkzeLUAsCFKPln8SS34FkCQRmELE2WiIhPo%3D&CreatedAfter=2016-10-31T23%3A00%3A00Z
错误是
我用来创建签名的方法是在 Whosebug 上找到的,如下所示:
$sign = 'GET' . "\n";
$sign .= 'mws.amazonservices.it' . "\n";
$sign .= '/Orders/2013-09-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $CHIAVE_SEGRETA, true);
$signature = urlencode(base64_encode($signature));
我做错了什么?
您是否看过 PHP client library 的订单 API?我使用 C# 版本,但我认为 PHP 库是相似的。大部分工作都为您完成。
参数的顺序很重要。
下面是一些示例代码,应该可以为您提供一个良好的起点。您只需要稍微修改它以适合您的系统。
class AmazonMWS
{
private $secretKey = '';
private $parameters = array();
/**
* Constructor for the AmazonMWS class.
* Initializes constants.
*/
public function __construct()
{
$this->secretKey = Constant::get('SECRET_KEY');
$this->parameters['AWSAccessKeyId'] = Constant::get('AWSAccessKeyId');
$this->parameters['MarketplaceId.Id.1'] = Constant::get('MarketplaceId.Id.1');
$this->parameters['SellerId'] = Constant::get('SellerId');
$this->parameters['SignatureMethod'] = Constant::get('SignatureMethod');
$this->parameters['SignatureVersion'] = Constant::get('SignatureVersion');
}
public function setListOrders()
{
$this->parameters['Action'] = 'ListOrders';
$this->parameters['Version'] = '2013-09-01';
$this->parameters['Timestamp'] = $this->getTimestamp();
// this part should change and depend on the method/parameter.. for now just for testing
$this->parameters['CreatedAfter'] = '2015-11-01';
}
public function listOrders()
{
$request = "https://mws.amazonservices.com/Orders/2013-09-01?";
$request .= $this->getParameterString($this->parameters) . "&Signature=" . $this->calculateSignature($this->calculateStringToSign($this->parameters));
echo $request;
return Curl::fetchSSL($request);
}
/**
* Calculates String to sign.
*
* @param array $parameters request parameters
* @return String to sign
*/
protected function calculateStringToSign(array $parameters)
{
$stringToSign = 'GET' . "\n";
$stringToSign .= 'mws.amazonservices.com' . "\n";
$stringToSign .= '/Orders/2013-09-01' . "\n";
$stringToSign .= $this->getParameterString($parameters);
return $stringToSign;
}
/**
* Gets the query parameters as a String sorted in natural-byte order.
*
* @param array $parameters request parameters
* @return String of parameters
*/
protected function getParameterString(array $parameters)
{
$url = array();
foreach ($parameters as $key => $val) {
$key = $this->urlEncode($key);
$val = $this->urlEncode($val);
$url[] = "{$key}={$val}";
}
sort($url);
$parameterString = implode('&', $url);
return $parameterString;
}
/**
* Computes RFC 2104-compliant HMAC signature.
*
* @param String to sign
*/
protected function calculateSignature($stringToSign)
{
$signature = hash_hmac("sha256", $stringToSign, $this->secretKey, true);
return urlencode(base64_encode($signature));
}
/**
* URL encodes a string.
*/
protected function urlEncode($string)
{
return str_replace("%7E", "~", rawurlencode($string));
}
/**
* Gets the current date as ISO 8601 timestamp
*/
protected function getTimestamp()
{
return gmdate("Y-m-d\TH:i:s.\0\0\0\Z", time());
}
}