1

SubmitFeedAmazon マーケットプレイスにリクエストを送信しようとしていますが、リクエストを送信すると次のエラーが表示されます。

フィードに渡した Content-MD5 HTTP ヘッダーが、フィード用に計算した Content-MD5 と一致しませんでした

そこで、Amazon Marketplace Scratchpadでリクエストをテストしました。XML を本文とヘッダーに追加すると、次の MD5 ハッシュが生成されます。

1db3b177e743dc8c0df4dc9eb5c1cbcf

Content-MD5 (Base64)ただし、次の値のヘッダーもあります。

HbOxd+dD3IwN9NyetcHLzw==

そして、生の MD5 ハッシュではなく、HTTP ヘッダーとして実際に Amazon MWS に送信される値のようです。Content-MD5

PHP スクリプトをチェックしたところ、生の MD5 ハッシュが正しく生成されています。md5関数 ( md5($xml)) で XML 文字列をラップすると、Amazon が生成するのと同じ生の MD5 ハッシュが得られます。しかし、それを関数にラップすると、base64_encodeAmazon が Content-MD5 (Base64) 値としてリストするものとはまったく異なる値が得られます。

これまでのところ、base64_encode関数で次をラップしようとしました。

  • 生の XML 文字列
  • 生の XML 文字列の MD5 ハッシュ

しかし、Amazon の Content-MD5 (Base64) 値と同じ値を生成するものはありません。

では、その値を取得するための Amazon Base64 エンコーディングとは正確には何でしょうか? 値をデコードしようとしましたが、エンコーディングの問題と思われるランダムな文字が大量に発生したため、Amazon がエンコーディングして正しい方向を示している生の文字列を確認できません。

これに関するガイダンスをいただければ幸いです。

4

1 に答える 1

3

解決策を見つけました。関数のドキュメントを調べてみたところ、関数の生の出力md5を取得するための 2 番目のパラメーターがあることがわかりました。これはデフォルトです。そのため、代わりにそのフラグを設定し、その呼び出しの結果を Base64 エンコードすることにしました。falsetrue

ほら!Amazonと同じBase64値を取得しました!

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

これが他の誰かに役立つことを願っています!

于 2015-04-23T10:22:04.333 に答える