Я хочу обновить количество на амазонке, используя 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("Ymd\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
Amazon AWS очень непостоянна в своей подписке. Версия 2 требует, чтобы вы использовали RFC 3986 для кодирования данных
Добавьте компоненты строки запроса (пары имени-значения, не включая начальный знак вопроса (?) Как символы UTF-8, которые кодируются по URL для RFC 3986 (шестнадцатеричные символы должны быть в верхнем регистре) и отсортированы с использованием лексикографического байтового упорядочения. чувствителен к регистру.
Ваша проблема связана с вашей кодировкой подписи.
$signature = urlencode(base64_encode($signature));
Это не будет соответствовать RFC 3986. PHP имеет rawurlencode, чтобы сделать это вместо этого.
$signature = rawurlencode(base64_encode($signature));
Кажется, что ваш $string_to_sign
пропускает локальную часть URL- $string_to_sign
в качестве третьей строки. В вашем случае эта часть пуста, так что вам просто потребуется дополнительный разрыв строки.
$string_to_sign = "GET\nmws.amazonservices.in\n\n" . $url_string;