0503
@0503

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

SP-API 403 Unauthorized Error

解決したいこと

SP-API 403のエラー を解決したい

例)
PHPを利用して、amazon api であるsp-apiを使用して、amazon seller sentralの情報を得たいのですが、postman を使用してもエラーが生じます

解決方法を教えて下さい。

発生している問題・エラー

    {
      "code": "Unauthorized",
      "message": "Access to requested resource is denied.",
      "details": "The access token you provided is revoked, malformed or invalid."
    }

実際のソースコード

<?php

class Signature
{
    public static function calculateSignatureForService(
        $host,
        $method,
        $uri,
        $queryString,
        $data,
        $service,
        $accessKey,
        $secretKey,
        $region,
        $accessToken,
        $securityToken,
        $userAgent,
        $amzdate
    ) {
        $terminationString = 'aws4_request';
        $algorithm = 'AWS4-HMAC-SHA256';
        $date = substr($amzdate, 0, 8);

        if (is_array($data)) {
            $param = json_encode($data);
            if ('[]' == $param) {
                $requestPayload = '';
            } else {
                $requestPayload = $param;
            }
        } else {
            $requestPayload = $data;
        }

        $hashedPayload = hash('sha256', $requestPayload);

        $canonicalHeaders = [
            'host' => $host,
            'user-agent' => $userAgent,
        ];

        if (!is_null($accessToken)) {
            $canonicalHeaders['x-amaz-access-token'] = $accessToken;
        }
        $canonicalHeaders['x-amz-date'] = $amzdate;

        if (!is_null($securityToken)) {
            $canonicalHeaders['x-amz-security-token'] = $securityToken;
        }

        $canonicalHeadersStr = '';
        foreach ($canonicalHeaders as $h => $v) {
            $canonicalHeadersStr .= $h.':'.$v."\n";
        }
        $signedHeadersStr = join(';', array_keys($canonicalHeaders));

        $credentialScope = $date.'/'.$region.'/'.$service.'/'.$terminationString;

        // パラメータは辞書順に並べ替える必要がある
        if (!empty($queryString)) {
            $queryArray = explode("&", $queryString);
            sort($queryArray);
            $queryString = implode("&", $queryArray);
        }

        $canonicalRequest = $method."\n".$uri."\n".$queryString."\n".$canonicalHeadersStr."\n".$signedHeadersStr."\n".$hashedPayload;

        $stringToSign = $algorithm."\n".$amzdate."\n".$credentialScope."\n".hash('sha256', $canonicalRequest);

        $kSecret = 'AWS4'.$secretKey;
        $kDate = hash_hmac('sha256', $date, $kSecret, true);
        $kRegion = hash_hmac('sha256', $region, $kDate, true);
        $kService = hash_hmac('sha256', $service, $kRegion, true);
        $kSigning = hash_hmac('sha256', $terminationString, $kService, true);

        $signature = trim(hash_hmac('sha256', $stringToSign, $kSigning));

        $authorizationHeader = $algorithm." Credential={$accessKey}/{$credentialScope}, SignedHeaders={$signedHeadersStr}, Signature={$signature}";
        return $authorizationHeader;
    }
}


$host = 'sellingpartnerapi-fe.amazon.com'; // 日本だとこの値
$service = 'execute-api';
$region = 'us-west-2'; // 日本だとこの値

$accessKey = "******"; // アクセスキーID
$secretKey = '******'; // シークレットアクセスキー
$accessToken = '********'; // アクセストークン

$marketplaceId = 'A1VC38T7YXB528'; // 日本だとこの値

$requestUrl = 'https://sellingpartnerapi-fe.amazon.com/orders/v0/orders?MarketplaceIds=' . $marketplaceId . '&CreatedAfter=2023-01-01';
$httpRequestMethod = 'GET';
$canonicalURI = '/orders/v0/orders';
$canonicalQueryString  = 'MarketplaceIds=' + $marketplaceId + '&CreatedAfter=2023-01-01'; // パラメータはSiguniture生成時に辞書順に変更する必要があるので注意

$userAgent = 'cs-php-sp-api-client/2.1';

$currentDateTime = new DateTime('UTC');
$amzdate = $currentDateTime->format('Ymd\THis\Z');

$signature = new Signature();
$authorizationHeader = $signature->calculateSignatureForService($host, $httpRequestMethod, $canonicalURI, $canonicalQueryString, '', $service, $accessKey, $secretKey, $region, $accessToken, null, $userAgent, $amzdate);

// Request headers
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
$headers[] = 'host: ' . $host;
$headers[] = 'user-agent: ' . $userAgent;
$headers[] = 'x-amz-access-token: ' . $accessToken;
$headers[] = 'x-amz-date: ' . $amzdate;
$headers[] = 'Authorization:'. $authorizationHeader;


$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_URL => $requestUrl,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_POST => false,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => $httpRequestMethod,
    CURLOPT_VERBOSE => 0,
    CURLOPT_SSL_VERIFYHOST => 0,
    CURLOPT_SSL_VERIFYPEER => 0,
    CURLOPT_HEADER => false,
    CURLINFO_HEADER_OUT=>true,
    CURLOPT_HTTPHEADER => $headers,
));

$response = curl_exec($curl);

var_dump($response);

$err = curl_error($curl);
$responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);


curl_close($curl);

if ($err) {
    echo "<h5>Error:" . $responseCode . "</h5>";
    echo "<pre>";
    echo $err;
    echo "</pre>";
} else {
    echo "<h5>Response:" . $responseCode . "</h5>";
    echo "<pre>";
    echo $response;
    echo "</pre>";
}

自分で試したこと

1.以下を使用して

IAMユーザー作成
IAMユーザーにSP-API利用権限付与
アプリクライアントの追加
postmanを使ったアクセストークンの発行
postmanを使った注文情報取得

を一通り行いました。

問題点

IAM ARN の追加の欄がamazon seller sentral のところで入力ができない

以上、アマゾンapiのsp-apiでアクセスはできたものの、権限がないため、跳ね返されました。

ぜひアドバイスをよろしくお願いします

0

No Answers yet.

Your answer might help someone💌