Ошибка расчета MD5 хэша фида Amazon Marketplace

Я пытаюсь отправить SubmitFeed запрос в Amazon Marketplace, но когда я отправляю запрос, я получаю следующую ошибку:

HTTP-заголовок Content-MD5, который вы передали для своего канала, не соответствует содержимому MD5, которое мы рассчитали для вашего канала

Поэтому я проверил запрос на Amazon Marketplace Scratchpad. Я добавляю свой 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://stackoverflow.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();

Надеюсь, это поможет кому-то еще!

3

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

Других решений пока нет …