Ошибка расчета 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();

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

Другие вопросы по тегам