You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Amazon SP-API Feed上传XML遇SignatureDoesNotMatch错误求助

Amazon SP-API Feeds 上传时 SignatureDoesNotMatch 错误排查

我通过Amazon PHP SP-API SDK及Feeds API官方指南创建并上传Feed XML至AWS,已成功获取url和feedDocumentId,但上传时始终返回SignatureDoesNotMatch错误,错误信息如下:

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>AKIAX2ZVOZFBB4YFXXHU</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256 20231106T080142Z 20231106/eu-west-1/s3/aws4_request c2cbc4a511455b617c11d9ea1b41bfd2134b4f7d646b286e7848a9203ef5e13e</StringToSign>
<SignatureProvided>e01f1837a5e5cc2d4defae363a83812b2e48c5b4d9c28fcc46f6a96a9a7d24cf</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 33 31 31 30 36 54 30 38 30 31 34 32 5a 0a 32 30 32 33 31 31 30 36 2f 65 75 2d 77 65 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 63 32 63 62 63 34 61 35 31 31 34 35 35 62 36 31 37 63 31 31 64 39 65 61 31 62 34 31 62 66 64 32 31 33 34 62 34 66 37 64 36 34 36 62 32 38 36 65 37 38 34 38 61 39 32 30 33 65 66 35 65 31 33 65</StringToSignBytes>
<CanonicalRequest>GET /dc372987-1dd1-43b3-b516-27dc78dca0ec.amzn1.tortuga.4.eu.TH04D1RNGNQZS X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKIAX2ZVOZFBB4YFXXHU%2F20231106%2Feu-west-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20231106T080142Z&amp;X-Amz-Expires=300&amp;X-Amz-SignedHeaders=content-type%3Bhost content-type: host:tortuga-prod-eu.s3-eu-west-1.amazonaws.com content-type;host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 0a 2f 64 63 33 37 32 39 38 37 2d 31 64 64 31 2d 34 33 62 33 2d 62 35 31 36 2d 32 37 64 63 37 38 64 63 61 30 65 63 2e 61 6d 7a 6e 31 2e 74 6f 72 74 75 67 61 2e 34 2e 65 75 2e 54 48 30 34 44 31 52 4e 47 4e 51 5a 53 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 58 32 5a 56 4f 5a 46 42 42 34 59 46 58 58 48 55 25 32 46 32 30 32 33 31 31 30 36 25 32 46 65 75 2d 77 65 73 74 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 33 31 31 30 36 54 30 38 30 31 34 32 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 33 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 63 6f 6e 74 65 6e 74 2d 74 79 70 65 25 33 42 68 6f 73 74 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 0a 68 6f 73 74 3a 74 6f 72 74 75 67 61 2d 70 72 6f 64 2d 65 75 2e 73 33 2d 65 75 2d 77 65 73 74 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3b 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>EJ9N9STNFFT5FT97</RequestId>
<HostId>rVh8aMdyJ3nzfI2vIqgvn0WHCwkfEvZAAMtZ33JY6Bk8OyFNCucBKesfAe3gLyvLjo50ZVsfY223ZyzfEcYp+g==</HostId>
</Error>

我的实现代码如下:

public function createFeed($distributionChannelTeamId)
{

    $res=$this->createFeedDocument($distributionChannelTeamId);

    $url=$res['url'];
    $feedDocumentId=$res['feedDocumentId'];


if($res['url'] && $res['feedDocumentId']){
    $requestXml = '<?xml version="1.0" encoding="iso-8859-1"?>
    <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
      <Header>
        <DocumentVersion>1.01</DocumentVersion>
        <MerchantIdentifier>MYID</MerchantIdentifier>
      </Header>
      <MessageType>Product</MessageType>
      <PurgeAndReplace>false</PurgeAndReplace>
      <Message>
        <MessageID>1</MessageID>
        <OperationType>Update</OperationType>
        <Product>
          <SKU>56789</SKU>
          <StandardProductID>
            <Type>ASIN</Type>
            <Value>B0EXAMPLEG</Value>
          </StandardProductID>
          <ProductTaxCode>A_GEN_NOTAX</ProductTaxCode>
          <DescriptionData>
            <Title>Example Product Title</Title>
            <Brand>Example Product Brand</Brand>
            <Description>This is an example product description.</Description>
            <BulletPoint>Example Bullet Point 1</BulletPoint>
            <BulletPoint>Example Bullet Point 2</BulletPoint>
            <MSRP currency="USD">25.19</MSRP>
            <Manufacturer>Example Product Manufacturer</Manufacturer>
            <ItemType>example-item-type</ItemType>
          </DescriptionData>
          <ProductData>
            <Health>
              <ProductType>
                <HealthMisc>
                  <Ingredients>Example Ingredients</Ingredients>
                  <Directions>Example Directions</Directions>
                </HealthMisc>
              </ProductType>
            </Health>
          </ProductData>
        </Product>
      </Message>
    </AmazonEnvelope>';

    $response = Http::withHeaders(['Content-Type' => 'application/xml'
    ])->put($url,[            'body' => utf8_encode($requestXml)
    ]);

    Log::channel('amazon')->info('Amazon create feed response: ', ['response' => $response]);
    dd($response);

  }else{
    dump('no res');
    dd($res);
  }

}

问题排查与修复方案

1. 请求方法与预签名不匹配

从错误信息的CanonicalRequest中可以看到,签名计算使用的是GET方法,但你的代码中使用了PUT方法。这是核心问题——预签名URL绑定了特定的HTTP方法,必须严格匹配。

2. 请求体传递方式错误

Laravel的Http::put方法第二个参数如果是数组,会被解析为表单参数,而非原始请求体。需要直接传递字符串内容,或者使用withBody方法明确指定原始内容。

3. 编码与Content-Type匹配

如果使用utf8_encode转换XML编码,需要在Content-Type头中添加对应的charset,确保服务器能正确解析内容。

修正后的代码

public function createFeed($distributionChannelTeamId)
{
    $res = $this->createFeedDocument($distributionChannelTeamId);
    $url = $res['url'];
    $feedDocumentId = $res['feedDocumentId'];

    if ($url && $feedDocumentId) {
        $requestXml = '<?xml version="1.0" encoding="iso-8859-1"?>
        <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
          <Header>
            <DocumentVersion>1.01</DocumentVersion>
            <MerchantIdentifier>MYID</MerchantIdentifier>
          </Header>
          <MessageType>Product</MessageType>
          <PurgeAndReplace>false</PurgeAndReplace>
          <Message>
            <MessageID>1</MessageID>
            <OperationType>Update</OperationType>
            <Product>
              <SKU>56789</SKU>
              <StandardProductID>
                <Type>ASIN</Type>
                <Value>B0EXAMPLEG</Value>
              </StandardProductID>
              <ProductTaxCode>A_GEN_NOTAX</ProductTaxCode>
              <DescriptionData>
                <Title>Example Product Title</Title>
                <Brand>Example Product Brand</Brand>
                <Description>This is an example product description.</Description>
                <BulletPoint>Example Bullet Point 1</BulletPoint>
                <BulletPoint>Example Bullet Point 2</BulletPoint>
                <MSRP currency="USD">25.19</MSRP>
                <Manufacturer>Example Product Manufacturer</Manufacturer>
                <ItemType>example-item-type</ItemType>
              </DescriptionData>
              <ProductData>
                <Health>
                  <ProductType>
                    <HealthMisc>
                      <Ingredients>Example Ingredients</Ingredients>
                      <Directions>Example Directions</Directions>
                    </HealthMisc>
                  </ProductType>
                </Health>
              </ProductData>
            </Product>
          </Message>
        </AmazonEnvelope>';

        // 直接传递转换后的XML字符串作为请求体
        $response = Http::withHeaders([
            'Content-Type' => 'application/xml; charset=utf-8'
        ])->put($url, utf8_encode($requestXml));

        Log::channel('amazon')->info('Amazon create feed response: ', ['response' => $response]);
        dd($response);
    } else {
        dump('no res');
        dd($res);
    }
}

额外排查点

  • 确认createFeedDocument返回的URL确实对应PUT方法,若返回的是GET方法的URL,需检查SDK调用逻辑。
  • 检查服务器时间与AWS服务器时间同步,签名对时间敏感,时间差超过5分钟会导致签名失败。
  • 不要添加SignedHeaders之外的额外HTTP头,错误中指定的允许头为content-type;host,请勿添加其他头信息。

内容的提问来源于stack exchange,提问作者Mica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 00:44:57