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

使用PHP Curl调用Amazon SP API getItemOffersBatch遇403错误求助

解决Amazon SP API getItemOffersBatch批量接口403 Forbidden问题

问题说明

单独调用Amazon SP API的getItemOffers接口无异常,但调用包含2个请求的getItemOffersBatch批量接口时返回403 Forbidden错误。Postman中可成功调用该批量接口,但PHP代码调用失败。

我的PHP 8代码(存在问题)

json_encode($body, JSON_THROW_ON_ERROR);
$post = 'POST';
$body=json_encode($body, JSON_UNESCAPED_SLASHES);
//var_dump($body);
$urlbatch= "https://sellingpartnerapi-na.amazon.com/batches/products/pricing/v0/itemOffers". $body ;
//var_dump($urlbatch);
$ch = curl_init($urlbatch);
curl_setopt_array($ch, [CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true
,CURLOPT_CONNECTTIMEOUT => 5,]);
//  var_dump($header);
if ($post) curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
if ($header) curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('curl.log', 'a+'));
$out = curl_exec($ch);
if (curl_errno($ch)) exit('Error: ' . curl_error($ch));
if ($status !== null) $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
return $out

Postman可成功调用的Curl代码

curl --location 'https://sellingpartnerapi-na.amazon.com/batches/products/pricing/v0/itemOffers' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-amz-access-token: ****' \
--header 'Authorization: AWS4-HMAC-SHA256 Credential=****/20240110/us-east-1/execute-api/aws4_request,SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date,Signature=******' \
--data '{
"requests": [
    {
        "uri": "/products/pricing/v0/items/B000P6Q7MY/offers",
        "method": "GET",
        "MarketplaceId": "ATVPDKIKX0DER",
        "ItemCondition": "New",
        "CustomerType": "Consumer"
    },
    {
        "uri": "/products/pricing/v0/items/B001Q3KU9Q/offers",
        "method": "GET",
        "MarketplaceId": "ATVPDKIKX0DER",
        "ItemCondition": "New",
        "CustomerType": "Consumer"
    }
]
}'

问题分析与修复

核心错误点

  1. 请求体错误拼接至URL:批量接口是POST请求,请求体应放在POST的body中,而非拼接到URL末尾,这会导致请求格式完全错误。
  2. CURLOPT_POSTFIELDS参数错误:原代码将字符串'POST'传给该选项,正确做法是传入JSON格式的请求体内容。
  3. 缺少必要请求头:未设置Content-Type: application/json,Amazon无法正确解析请求体,这是403错误的关键原因之一。

修正后的PHP代码

// 构造批量请求的body数组
$bodyArray = [
    "requests" => [
        [
            "uri" => "/products/pricing/v0/items/B000P6Q7MY/offers",
            "method" => "GET",
            "MarketplaceId" => "ATVPDKIKX0DER",
            "ItemCondition" => "New",
            "CustomerType" => "Consumer"
        ],
        [
            "uri" => "/products/pricing/v0/items/B001Q3KU9Q/offers",
            "method" => "GET",
            "MarketplaceId" => "ATVPDKIKX0DER",
            "ItemCondition" => "New",
            "CustomerType" => "Consumer"
        ]
    ]
];

// 转为JSON格式
$body = json_encode($bodyArray, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);

// 批量接口URL,不要拼接body
$urlbatch = "https://sellingpartnerapi-na.amazon.com/batches/products/pricing/v0/itemOffers";

$ch = curl_init($urlbatch);

// 设置CURL选项
curl_setopt_array($ch, [
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_POST => true, // 明确设置为POST请求
    CURLOPT_POSTFIELDS => $body, // 传入正确的JSON请求体
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Accept: application/json',
        'x-amz-access-token: ****', // 替换为你的有效token
        // 替换为你的Authorization头内容
        'Authorization: AWS4-HMAC-SHA256 Credential=****/20240110/us-east-1/execute-api/aws4_request,SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date,Signature=******'
    ],
    CURLOPT_VERBOSE => true,
    CURLOPT_STDERR => fopen('curl.log', 'a+')
]);

$out = curl_exec($ch);

if (curl_errno($ch)) {
    exit('Error: ' . curl_error($ch));
}

$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); // 记得关闭CURL资源

return $out;

额外注意事项

  • 确保Authorization头的签名是基于正确的POST请求体生成的,因为AWS4签名会包含请求体的哈希值,如果签名时用的body和实际发送的不一致,会直接返回403。
  • 检查请求头是否包含所有必要字段(比如x-amz-date、User-Agent等),这些都是签名时需要包含的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:21:20