1

我正在尝试向SubmitFeedAmazon Marketplace 提交请求,但是当我提交请求时出现以下错误:

您为供稿传递的 Content-MD5 HTTP 标头与我们为您的供稿计算的 Content-MD5 不匹配

所以我在Amazon Marketplace Scratchpad上测试了这个请求。我将我的 XML 添加到正文和标题中,它会生成以下 MD5 哈希:

1db3b177e743dc8c0df4dc9eb5c1cbcf

但也有一个Content-MD5 (Base64)标题,这个值:

HbOxd+dD3IwN9NyetcHLzw==

它似乎是实际作为 HTTP 标头发送到亚马逊 MWS 的值Content-MD5而不是原始 MD5 哈希值。

我检查了我的 PHP 脚本,它正确地生成了原始 MD5 散列,当我将 XML 字符串包装在md5函数 ( md5($xml)) 中时,我得到了与 Amazon 生成的相同的原始 MD5 散列。但是,如果我将其包装函数base64_encode中,我会得到一个完全不同的值,即亚马逊为 Content-MD5 (Base64) 值列出的值。

到目前为止,我已经尝试在base64_encode函数中包装以下内容:

  • 原始 XML 字符串
  • 原始 XML 字符串的 MD5 哈希

但没有一个产生与亚马逊的 Content-MD5 (Base64) 值相同的值。

那么究竟什么Amazon Base64 编码来获得这个值呢?我已经尝试解码该值,但只是加载了似乎是编码问题的随机字符,所以我看不到亚马逊编码的原始字符串指向正确的方向。

对此的任何指导将不胜感激。

4

1 回答 1

3

找到了解决方案。我决定查看md5函数的文档,发现有第二个参数可以获取函数的原始输出false,默认情况下。因此,我决定将该标志设置为,并对该调用true的结果进行 Base64 编码。

瞧!我得到了与亚马逊相同的 Base64 值!

使用 Guzzle,这是我发送给亚马逊的内容,现在我得到了成功的回复:

$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();

希望这对其他人有帮助!

于 2015-04-23T10:22:04.333 回答