亚马逊 MWS API 返回 SignatureDoesNotMatch
Amazon MWS API returning SignatureDoesNotMatch
我需要调用亚马逊 MWS 操作 'RequestReport' 并将 ReportType 指定为“_GET_FLAT_FILE_OPEN_LISTINGS_DATA_”。我已成功连接以获取 FulfillmentInventory/ListInventorySupply,因此我知道 cURL 和亚马逊设置是正确的,但每次提交时我都会从服务器返回 '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.'。我已经在第 23 行和第 14 行尝试了 sort 和 ksort - 在调用 FulfillmentInventory/ListInventorySupply 时,我必须使用两个 ksort 来设置它,以便使 SKU 列表保持 [=26= 的正确顺序]
这是代码,正如我所说,secret、merchant 和 keyid 是正确的:
header('Content-type: application/xml');
$secret = 'secretcodehere';
$param = array();
$param['AWSAccessKeyId'] = 'accessidhere';
$param['Action'] = 'RequestReport';
$param['Merchant'] = 'merchantidhere';
$param['SignatureVersion'] = '2';
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s.\0\0\0\Z", time());
$param['Version'] = '2009-01-01';
$param['SignatureMethod'] = 'HmacSHA256';
$param['ReportType'] = '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_';
ksort($param);
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
sort($url);
$arr = implode('&', $url);
$sign = 'POST' . "\n";
$sign .= 'mws.amazonservices.com';
$sign .= '/doc/2009-01-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $secret, true);
$signature = urlencode(base64_encode($signature));
$link = "https://mws.amazonservices.com/doc/2009-01-01/?";
$link .= $arr . "&Signature=" . $signature;
/*
echo($link);//for debugging
exit(); */
$ch = curl_init($link);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/xml'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
print_r($response);
我已经在 MWS 暂存器中尝试过,信息正确并生成 200 响应,当我检查 url 与暂存器生成的响应时,它 'looks' 正确,所以我一定是遗漏了什么,我希望外面的人很明显,因为我很困惑。
btw-scratchpad 将其列为 SellerId,但 url 将其显示为 Merchant - 我都试过了,但并不满意
不是向你扔曲线球,但我在使用 RequestReport
方面取得的唯一成功是通过使用亚马逊创建的 PHP 库。如果你还没有,这里是 link.
这是我刚刚确认的用于请求报告的代码:
<?php
define('AWS_ACCESS_KEY_ID', $am_aws_access_key);
define('AWS_SECRET_ACCESS_KEY', $am_secret_key);
define('MERCHANT_ID', $am_merchant_id);
define('MARKETPLACE_ID', $am_marketplace_id);
include_once ('/link/to/Amazon/library/MarketplaceWebService/Samples/.config.inc.php');
include_once ('functions.php');
$serviceUrl = "https://mws.amazonservices.com";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebService_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
$config,
APPLICATION_NAME,
APPLICATION_VERSION);
echo '<br />';
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'ReportType' => '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_',
);
echo '<br /><br/>Request Report Request:<br><br>';
$request = new MarketplaceWebService_Model_RequestReportRequest($parameters);
print_r($request);
invokeRequestReport($service, $request);
echo '<br /><br/>';
和functions.php
文件(基本上是MarketplaceWebService\Samples\RequestReportSample.php
文件后半部分代码的重要功能:
function invokeRequestReport(MarketplaceWebService_Interface $service, $request)
{
try {
$response = $service->requestReport($request);
echo ("Service Response\n");
echo ("=============================================================================\n");
echo(" RequestReportResponse\n");
if ($response->isSetRequestReportResult()) {
echo(" RequestReportResult\n");
$requestReportResult = $response->getRequestReportResult();
if ($requestReportResult->isSetReportRequestInfo()) {
$reportRequestInfo = $requestReportResult->getReportRequestInfo();
echo(" ReportRequestInfo\n");
if ($reportRequestInfo->isSetReportRequestId())
{
echo(" ReportRequestId\n");
echo(" " . $reportRequestInfo->getReportRequestId() . "\n");
}
$report_request_id = $reportRequestInfo->getReportRequestId();
$report_type = '';
if ($reportRequestInfo->isSetReportType())
{
echo(" ReportType\n");
echo(" " . $reportRequestInfo->getReportType() . "\n");
$report_type = $reportRequestInfo->getReportType();
}
if ($reportRequestInfo->isSetStartDate())
{
echo(" StartDate\n");
echo(" " . $reportRequestInfo->getStartDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetEndDate())
{
echo(" EndDate\n");
echo(" " . $reportRequestInfo->getEndDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetSubmittedDate())
{
echo(" SubmittedDate\n");
echo(" " . $reportRequestInfo->getSubmittedDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetReportProcessingStatus())
{
echo(" ReportProcessingStatus\n");
echo(" " . $reportRequestInfo->getReportProcessingStatus() . "\n");
}
if($report_type == '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_') {
if(!empty($report_request_id)) {
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'Report' => @fopen('php://memory', 'rw+'),
'ReportRequestIdList' => $report_request_id,
);
$report = new MarketplaceWebService_Model_GetReportRequestListRequest($parameters);
print_r($report);
}
}
}
}
if ($response->isSetResponseMetadata()) {
echo(" ResponseMetadata\n");
$responseMetadata = $response->getResponseMetadata();
if ($responseMetadata->isSetRequestId())
{
echo(" RequestId\n");
echo(" " . $responseMetadata->getRequestId() . "\n");
}
}
} catch (MarketplaceWebService_Exception $ex) {
echo("Caught Exception: " . $ex->getMessage() . "\n");
echo("Response Status Code: " . $ex->getStatusCode() . "\n");
echo("Error Code: " . $ex->getErrorCode() . "\n");
echo("Error Type: " . $ex->getErrorType() . "\n");
echo("Request ID: " . $ex->getRequestId() . "\n");
echo("XML: " . $ex->getXML() . "\n");
}
}
编辑
以下是 .config.inc.php
文件的重要部分:
<?php
define ('DATE_FORMAT', 'Y-m-d\TH:i:s\Z');
date_default_timezone_set('America/Denver');
$app_name = "Just make up a name like 'Awesome Sync'";
$app_version = "1.0";
define('APPLICATION_NAME', $app_name);
define('APPLICATION_VERSION', $app_version);
set_include_path('/link/to/Amazon/library/');
...rest of code...
编辑
此代码将创建报告请求,但实际上并没有创建报告。您必须继续使用相同的代码对亚马逊进行民意调查,直到您收到 "Complete" 或类似的东西(不记得创建报告时亚马逊发回的确切单词)。然后你需要实际检索报告。
我需要调用亚马逊 MWS 操作 'RequestReport' 并将 ReportType 指定为“_GET_FLAT_FILE_OPEN_LISTINGS_DATA_”。我已成功连接以获取 FulfillmentInventory/ListInventorySupply,因此我知道 cURL 和亚马逊设置是正确的,但每次提交时我都会从服务器返回 '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.'。我已经在第 23 行和第 14 行尝试了 sort 和 ksort - 在调用 FulfillmentInventory/ListInventorySupply 时,我必须使用两个 ksort 来设置它,以便使 SKU 列表保持 [=26= 的正确顺序]
这是代码,正如我所说,secret、merchant 和 keyid 是正确的:
header('Content-type: application/xml');
$secret = 'secretcodehere';
$param = array();
$param['AWSAccessKeyId'] = 'accessidhere';
$param['Action'] = 'RequestReport';
$param['Merchant'] = 'merchantidhere';
$param['SignatureVersion'] = '2';
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s.\0\0\0\Z", time());
$param['Version'] = '2009-01-01';
$param['SignatureMethod'] = 'HmacSHA256';
$param['ReportType'] = '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_';
ksort($param);
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
sort($url);
$arr = implode('&', $url);
$sign = 'POST' . "\n";
$sign .= 'mws.amazonservices.com';
$sign .= '/doc/2009-01-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $secret, true);
$signature = urlencode(base64_encode($signature));
$link = "https://mws.amazonservices.com/doc/2009-01-01/?";
$link .= $arr . "&Signature=" . $signature;
/*
echo($link);//for debugging
exit(); */
$ch = curl_init($link);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/xml'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
print_r($response);
我已经在 MWS 暂存器中尝试过,信息正确并生成 200 响应,当我检查 url 与暂存器生成的响应时,它 'looks' 正确,所以我一定是遗漏了什么,我希望外面的人很明显,因为我很困惑。
btw-scratchpad 将其列为 SellerId,但 url 将其显示为 Merchant - 我都试过了,但并不满意
不是向你扔曲线球,但我在使用 RequestReport
方面取得的唯一成功是通过使用亚马逊创建的 PHP 库。如果你还没有,这里是 link.
这是我刚刚确认的用于请求报告的代码:
<?php
define('AWS_ACCESS_KEY_ID', $am_aws_access_key);
define('AWS_SECRET_ACCESS_KEY', $am_secret_key);
define('MERCHANT_ID', $am_merchant_id);
define('MARKETPLACE_ID', $am_marketplace_id);
include_once ('/link/to/Amazon/library/MarketplaceWebService/Samples/.config.inc.php');
include_once ('functions.php');
$serviceUrl = "https://mws.amazonservices.com";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebService_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
$config,
APPLICATION_NAME,
APPLICATION_VERSION);
echo '<br />';
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'ReportType' => '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_',
);
echo '<br /><br/>Request Report Request:<br><br>';
$request = new MarketplaceWebService_Model_RequestReportRequest($parameters);
print_r($request);
invokeRequestReport($service, $request);
echo '<br /><br/>';
和functions.php
文件(基本上是MarketplaceWebService\Samples\RequestReportSample.php
文件后半部分代码的重要功能:
function invokeRequestReport(MarketplaceWebService_Interface $service, $request)
{
try {
$response = $service->requestReport($request);
echo ("Service Response\n");
echo ("=============================================================================\n");
echo(" RequestReportResponse\n");
if ($response->isSetRequestReportResult()) {
echo(" RequestReportResult\n");
$requestReportResult = $response->getRequestReportResult();
if ($requestReportResult->isSetReportRequestInfo()) {
$reportRequestInfo = $requestReportResult->getReportRequestInfo();
echo(" ReportRequestInfo\n");
if ($reportRequestInfo->isSetReportRequestId())
{
echo(" ReportRequestId\n");
echo(" " . $reportRequestInfo->getReportRequestId() . "\n");
}
$report_request_id = $reportRequestInfo->getReportRequestId();
$report_type = '';
if ($reportRequestInfo->isSetReportType())
{
echo(" ReportType\n");
echo(" " . $reportRequestInfo->getReportType() . "\n");
$report_type = $reportRequestInfo->getReportType();
}
if ($reportRequestInfo->isSetStartDate())
{
echo(" StartDate\n");
echo(" " . $reportRequestInfo->getStartDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetEndDate())
{
echo(" EndDate\n");
echo(" " . $reportRequestInfo->getEndDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetSubmittedDate())
{
echo(" SubmittedDate\n");
echo(" " . $reportRequestInfo->getSubmittedDate()->format(DATE_FORMAT) . "\n");
}
if ($reportRequestInfo->isSetReportProcessingStatus())
{
echo(" ReportProcessingStatus\n");
echo(" " . $reportRequestInfo->getReportProcessingStatus() . "\n");
}
if($report_type == '_GET_FLAT_FILE_OPEN_LISTINGS_DATA_') {
if(!empty($report_request_id)) {
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'Report' => @fopen('php://memory', 'rw+'),
'ReportRequestIdList' => $report_request_id,
);
$report = new MarketplaceWebService_Model_GetReportRequestListRequest($parameters);
print_r($report);
}
}
}
}
if ($response->isSetResponseMetadata()) {
echo(" ResponseMetadata\n");
$responseMetadata = $response->getResponseMetadata();
if ($responseMetadata->isSetRequestId())
{
echo(" RequestId\n");
echo(" " . $responseMetadata->getRequestId() . "\n");
}
}
} catch (MarketplaceWebService_Exception $ex) {
echo("Caught Exception: " . $ex->getMessage() . "\n");
echo("Response Status Code: " . $ex->getStatusCode() . "\n");
echo("Error Code: " . $ex->getErrorCode() . "\n");
echo("Error Type: " . $ex->getErrorType() . "\n");
echo("Request ID: " . $ex->getRequestId() . "\n");
echo("XML: " . $ex->getXML() . "\n");
}
}
编辑
以下是 .config.inc.php
文件的重要部分:
<?php
define ('DATE_FORMAT', 'Y-m-d\TH:i:s\Z');
date_default_timezone_set('America/Denver');
$app_name = "Just make up a name like 'Awesome Sync'";
$app_version = "1.0";
define('APPLICATION_NAME', $app_name);
define('APPLICATION_VERSION', $app_version);
set_include_path('/link/to/Amazon/library/');
...rest of code...
编辑
此代码将创建报告请求,但实际上并没有创建报告。您必须继续使用相同的代码对亚马逊进行民意调查,直到您收到 "Complete" 或类似的东西(不记得创建报告时亚马逊发回的确切单词)。然后你需要实际检索报告。