Я пытаюсь отправить 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
функция:
Но ни один из них не дает такое же значение, как значение Amazon Content-MD5 (Base64).
Так что именно является Amazon Base64-кодирование, чтобы получить это значение? Я пытался расшифровать значение, но только что получил кучу случайных символов, что, похоже, является проблемой кодирования, поэтому я не вижу исходную строку, которую кодирует Amazon, чтобы указать мне правильное направление.
Любое руководство по этому вопросу будет оценено.
Нашел решение. Я решил посмотреть на документацию для 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();
Надеюсь, это поможет кому-то еще!
Других решений пока нет …