Ошибка расчета MD5 хэша фида Amazon Marketplace
Я пытаюсь представить SubmitFeed
запрос к Amazon Marketplace, но когда я отправляю запрос, я получаю следующую ошибку:
HTTP-заголовок Content-MD5, который вы передали для своего канала, не соответствует содержимому MD5, рассчитанному нами для вашего канала.
Поэтому я протестировал запрос на скретчпаде Amazon Marketplace. Я добавляю свой XML в тело и заголовки, и он генерирует следующий хеш MD5:
1db3b177e743dc8c0df4dc9eb5c1cbcf
Но есть также Content-MD5 (Base64)
заголовок, с этим значением:
HbOxd + dD3IwN9NyetcHLzw ==
И это, как представляется, это значение, которое на самом деле отправляется в Amazon
MWS как Content-MD5
Заголовок HTTP, а не необработанный хэш MD5.
Я проверил свой PHP-скрипт, и он правильно генерирует необработанный хеш-код MD5, как при переносе строки XML в md5
функция (md5($xml)
) Я получаю тот же необработанный хэш MD5, который генерирует Amazon. Но если я тогда заверну это в base64_encode
функция, я получаю совершенно другое значение относительно того, что Amazon перечисляет значение Content-MD5 (Base64).
До сих пор я пытался обернуть следующее в base64_encode
функция:
- Необработанная строка XML
- MD5 хэш необработанной строки XML
Но ни один из них не дает того же значения, что и Amazon Content-MD5 (Base64).
Так что же такое Amazon Base64-кодировка, чтобы получить это значение? Я пытался расшифровать значение, но только что получил кучу случайных символов, что, похоже, является проблемой кодирования, поэтому я не вижу исходную строку, которую кодирует Amazon, чтобы указать мне правильное направление.
Любое руководство по этому вопросу будет оценено.
1 ответ
Нашел решение. Я решил посмотреть на документацию для md5
функция и обнаружил, что есть второй параметр, чтобы получить необработанный вывод функции, который false
по умолчанию. Итак, я решил установить этот флаг true
вместо этого и Base64-закодировать результат этого вызова.
Вуаля! Я получил то же значение Base64, что и Amazon!
Используя Guzzle, это то, что я отправляю в Amazon, и теперь я получаю успешные ответы:
$xml = trim($xml);
// For some reason, the time my PHP script is sending is about 20 minutes out
// from my system time. This fixes that.
$timestamp = gmdate('c', time() + 1200);
$url = 'https://mws.amazonservices.co.uk/';
$parameters = [
'Action' => 'SubmitFeed',
'AWSAccessKeyId' => '#MY_ACCESS_KEY_ID#',
'FeedType' => '_POST_PRODUCT_DATA_',
'MarketplaceIdList.Id.1' => 'A1F83G8C2ARO7P', # UK marketplace ID
'Merchant' => '#MY_SELLER_ID#',
'PurgeAndReplace' => 'false',
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'Timestamp' => $timestamp,
'Version' => '2009-01-01',
];
/**
* Custom class that generates signature for request.
*
* @see http://stackru.com/a/29724063/102205
*/
$signature = new Signature($url, $parameters, '#MY_SECRET_ACCESS_KEY#');
$parameters['Signature'] = (string) $signature;
try {
$response = $this->client->post($url, [
'headers' => [
'Content-MD5' => base64_encode(md5($xml, true)),
'User-Agent' => '#MY_USER_AGENT_STRING#',
],
'query' => $parameters,
'body' => $xml,
]);
} catch (\GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
}
return $response->xml();
Надеюсь, это поможет кому-то еще!