Ошибка фида Amazon

Я хочу обновить количество на Amazon, используя Feed Api->Sumbit Feed (_POST_INVENTORY_AVAILABILITY_DATA_)

Вот мой код:

$action = 'SubmitFeed';
$path = $_SERVER['DOCUMENT_ROOT'].'/resources/amazon_xml/quantity.xml';

$feed = '<?xml version="1.0" ?><AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>A3QPCC6I4V1QU3</MerchantIdentifier>
</Header>
<MessageType>Inventory</MessageType>
<Message>
<MessageID>1</MessageID>
<OperationType>Update</OperationType>
<Inventory>
<SKU>6000013953</SKU>
<Quantity>1</Quantity>
</Inventory>
</Message>
</AmazonEnvelope>';

$feedHandle = fopen($path, 'rw+');
fwrite($feedHandle, $feed);
rewind($feedHandle);

$params = array(
'AWSAccessKeyId' => $data['aws_access_key'],
'Action' => $action,
'Merchant' => $data['merchant_id'],
'SignatureMethod' => "HmacSHA256",
'SignatureVersion' => "2",
'Timestamp'=> gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()),
'Version'=> "2009-10-01",
'MarketplaceIdList.Id.1' => $data['marketplace_id'],
'FeedType'=> "_POST_INVENTORY_AVAILABILITY_DATA_",
'PurgeAndReplace'=> 'false',
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true))
);// 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.in\n" . $url_string;

// Sign the request
$signature = hash_hmac("sha256", $string_to_sign, $data['aws_secret_key'], TRUE);

// Base64 encode the signature and make it URL safe
$signature = urlencode(base64_encode($signature));$url = "https://mws.amazonservices.in" . '?' . $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 $url;exit;

echo '<pre>';
print_r($response);
echo '</pre>';
exit;

Но я получаю следующий ответ: —

<ErrorResponse xmlns="https://mws.amazonservices.com/">
<Error>
<Type>Sender</Type>
<Code>SignatureDoesNotMatch</Code>
<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.
</Message>
</Error>
<RequestID>105f88cb-76e2-49c0-9d33-83d6069dd119</RequestID>
</ErrorResponse>

Может кто-нибудь сказать, пожалуйста, как отправить XML-файл в API? Или я что-то не так делаю?

quantity.xml файл правильный

Обновить :-

Код отлично работает на Amazon Scratchpad

3

Решение

Amazon AWS очень непостоянен в своей подписи. Версия 2 требует, чтобы вы использовали RFC 3986 закодировать ваши данные

Добавьте компоненты строки запроса (пары имя-значение, не включая начальный вопросительный знак (?)) В виде символов UTF-8, которые URL закодирован согласно RFC 3986 (шестнадцатеричные символы должны быть в верхнем регистре) и отсортированы с использованием лексикографического порядка байтов. Лексикографический порядок байтов чувствителен к регистру.

Похоже, ваша проблема в кодировке подписи.

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

Это не будет соответствовать RFC 3986. PHP имеет rawurlencode сделать это вместо этого.

$signature = rawurlencode(base64_encode($signature));
0

Другие решения

Ваш $string_to_sign кажется, отсутствует третья строка в локальной части URL. В вашем случае эта часть пуста, так что вам просто понадобится дополнительный разрыв строки.

$string_to_sign = "GET\nmws.amazonservices.in\n\n" . $url_string;
-1

По вопросам рекламы [email protected]