Amazonのアフィリリンクを生成出来るProduct Advertising API(PA-API) PA-API 5.0の設定方法

Amazonのアフィリリンクを生成出来るProduct Advertising API(PA-API) PA-API 5.0の設定方法

以前まで使用していたPA-API4.0が機能しなくなっていた為、5.0にアップデートしました。公式は以下リンクです。

自社サービスにAmazonアフィリを組み込んでいる場合など以外で、例えばWordPressのプラグイン等で使用している場合は今回の記事はあまり参考にならないと思います。

https://affiliate.amazon.co.jp/help/node/topic/GZBFW3F79Y7FADBL/

SDKを使用しない方法

今回、自分はSDKを使用しない方法で実装しました。

公式ドキュメント

https://webservices.amazon.com/paapi5/documentation/without-sdk.html

コードは以下です。

パラメータとしては、タグ、アクセスキー、シークレットキー、リージョン、ホストです。

<?php
class AppAmazonAssociateComponent extends component {

    public function searchItemsApi($keyword) {

        $searchItemRequest = new SearchItemsRequest ();
        $searchItemRequest->PartnerType = "Associates";
        // Put your Partner tag (Store/Tracking id) in place of Partner tag
        $searchItemRequest->PartnerTag = AMAZON_ASSOCIATE_TAG;
        // $searchItemRequest->Keywords = $keyword;
        $searchItemRequest->Keywords = $keyword;
        $searchItemRequest->SearchIndex = "All";
        $searchItemRequest->Resources = ["Images.Primary.Medium","ItemInfo.Title","Offers.Listings.Price"];
        $host = AMAZON_HOST;
        $path = "/paapi5/searchitems";
        $payload = json_encode ($searchItemRequest);
        //Put your Access Key in place of <ACCESS_KEY> and Secret Key in place of <SECRET_KEY> in double quotes
        $awsv4 = new AwsV4 (AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_ACCESS_KEY);
        $awsv4->setRegionName(AMAZON_REGION);
        $awsv4->setServiceName("ProductAdvertisingAPI");
        $awsv4->setPath ($path);
        $awsv4->setPayload ($payload);
        $awsv4->setRequestMethod ("POST");
        $awsv4->addHeader ('content-encoding', 'amz-1.0');
        $awsv4->addHeader ('content-type', 'application/json; charset=utf-8');
        $awsv4->addHeader ('host', $host);
        $awsv4->addHeader ('x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems');
        $headers = $awsv4->getHeaders ();
        $headerString = "";
        foreach ( $headers as $key => $value ) {
            $headerString .= $key . ': ' . $value . "\r\n";
        }
        $params = array (
                'http' => array (
                    'header' => $headerString,
                    'method' => 'POST',
                    'content' => $payload
                )
            );
        $stream = stream_context_create ( $params );
        $fp = @fopen ( 'https://'.$host.$path, 'r', false, $stream );
        if (! $fp) {
            throw new Exception ( "Exception Occured !!!" );
        }
        $response = @stream_get_contents ( $fp );
        if ($response === false) {
            throw new Exception ( "Exception Occured" );
        }
        return $response;
    }
}

class SearchItemsRequest {
    public $PartnerType;
    public $PartnerTag;
    public $Keywords;
    public $SearchIndex;
    public $Resources;
}

class AwsV4 {

    private $accessKeyID = null;
    private $secretAccessKey = null;
    private $path = null;
    private $regionName = null;
    private $serviceName = null;
    private $httpMethodName = null;
    private $queryParametes = array ();
    private $awsHeaders = array ();
    private $payload = "";

    private $HMACAlgorithm = "AWS4-HMAC-SHA256";
    private $aws4Request = "aws4_request";
    private $strSignedHeader = null;
    private $xAmzDate = null;
    private $currentDate = null;

    public function __construct($accessKeyID, $secretAccessKey) {
        $this->accessKeyID = $accessKeyID;
        $this->secretAccessKey = $secretAccessKey;
        $this->xAmzDate = $this->getTimeStamp ();
        $this->currentDate = $this->getDate ();
    }

    function setPath($path) {
        $this->path = $path;
    }

    function setServiceName($serviceName) {
        $this->serviceName = $serviceName;
    }

    function setRegionName($regionName) {
        $this->regionName = $regionName;
    }

    function setPayload($payload) {
        $this->payload = $payload;
    }

    function setRequestMethod($method) {
        $this->httpMethodName = $method;
    }

    function addHeader($headerName, $headerValue) {
        $this->awsHeaders [$headerName] = $headerValue;
    }

    private function prepareCanonicalRequest() {
        $canonicalURL = "";
        $canonicalURL .= $this->httpMethodName . "\n";
        $canonicalURL .= $this->path . "\n" . "\n";
        $signedHeaders = '';
        foreach ( $this->awsHeaders as $key => $value ) {
            $signedHeaders .= $key . ";";
            $canonicalURL .= $key . ":" . $value . "\n";
        }
        $canonicalURL .= "\n";
        $this->strSignedHeader = substr ( $signedHeaders, 0, - 1 );
        $canonicalURL .= $this->strSignedHeader . "\n";
        $canonicalURL .= $this->generateHex ( $this->payload );
        return $canonicalURL;
    }

    private function prepareStringToSign($canonicalURL) {
        $stringToSign = '';
        $stringToSign .= $this->HMACAlgorithm . "\n";
        $stringToSign .= $this->xAmzDate . "\n";
        $stringToSign .= $this->currentDate . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "\n";
        $stringToSign .= $this->generateHex ( $canonicalURL );
        return $stringToSign;
    }

    private function calculateSignature($stringToSign) {
        $signatureKey = $this->getSignatureKey ( $this->secretAccessKey, $this->currentDate, $this->regionName, $this->serviceName );
        $signature = hash_hmac ( "sha256", $stringToSign, $signatureKey, true );
        $strHexSignature = strtolower ( bin2hex ( $signature ) );
        return $strHexSignature;
    }

    public function getHeaders() {
        $this->awsHeaders ['x-amz-date'] = $this->xAmzDate;
        ksort ( $this->awsHeaders );
        $canonicalURL = $this->prepareCanonicalRequest ();
        $stringToSign = $this->prepareStringToSign ( $canonicalURL );
        $signature = $this->calculateSignature ( $stringToSign );
        if ($signature) {
            $this->awsHeaders ['Authorization'] = $this->buildAuthorizationString ( $signature );
            return $this->awsHeaders;
        }
    }

    private function buildAuthorizationString($strSignature) {
        return $this->HMACAlgorithm . " " . "Credential=" . $this->accessKeyID . "/" . $this->getDate () . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "," . "SignedHeaders=" . $this->strSignedHeader . "," . "Signature=" . $strSignature;
    }

    private function generateHex($data) {
        return strtolower ( bin2hex ( hash ( "sha256", $data, true ) ) );
    }

    private function getSignatureKey($key, $date, $regionName, $serviceName) {
        $kSecret = "AWS4" . $key;
        $kDate = hash_hmac ( "sha256", $date, $kSecret, true );
        $kRegion = hash_hmac ( "sha256", $regionName, $kDate, true );
        $kService = hash_hmac ( "sha256", $serviceName, $kRegion, true );
        $kSigning = hash_hmac ( "sha256", $this->aws4Request, $kService, true );

        return $kSigning;
    }

    private function getTimeStamp() {
        return gmdate ( "Ymd\THis\Z" );
    }

    private function getDate() {
        return gmdate ( "Ymd" );
    }
}

注意点として、アクセスキーとシークレットキーは再度取得する必要があります。リージョンについてはus-west-2で、ホストもwebservices.amazon.co.jpです。

https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html

SDKを使用する方法

以下参照

https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html

Comments

No comments yet. Why don’t you start the discussion?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です