Issue
I am trying to call the batch process for getItemOffersBatch
using PHP and curl to sign and make the call -- I am able to call the getItemOffers
individually with no issues. I ran a batch of 2 and I get a 403 Forbidden error -- here is the code (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
Where there are ***** is valid private Amazon data. After going back and forth with amazon and using POSTMAN i got it to work in POSTMAN but i am struggling to add the data part correctly here is the code from POSTMAN that worked.
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"
}
]
}'
i tried adding data to
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
but that did not work any help would be great i almost have it
Solution
Here is the answer --simple sometimes is best
$canonicalRequest = $method . "\n" // HTTP method
. $path . "\n" // Path component of the URL
. $qs . "\n" // Query string component of the URL (without '?')
. 'host:' . HOST . "\n" // Header
. 'user-agent:' . USER_AGENT . "\n" // Header
. 'x-amz-access-token:' . $accessToken . "\n" // Header
. 'x-amz-date:' . $date . "\n" // Header
. "\n" // A newline is needed here after the headers
. 'host;user-agent;x-amz-access-token;x-amz-date' . "\n" // Header names
. hash('sha256', $data); // Hash of the payload (empty string okay)
function httpRequest($url, $post = '', $header = null, &$status = null) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5,
]);
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;
}
was not putting in the data into the canonicalRequest so it could go through hash
Answered By - Scottmike Forgiven Answer Checked By - Dawn Plyler (WPSolving Volunteer)