サラリーのほうで、各ショッピングサイトの在庫連動システムをLaravelを用いて構築したのですが、
MWSが近々終了という事でSPAPIに移行しました。
すでに大半の移行が完了していたのですが、なぜかFBA在庫レポートのみ動作せずMWSを使っていました。
しかしながらMWS終了のメールが何度も来るので、重い腰を上げて再度向き合った時のメモ。
広告
Amazon SP-API の署名のメモ
上記のFBA在庫レポートに関してはどうしても動作しませんでした。
GET_AFN_INVENTORY_DATA を reportType に渡すとどうにもエラーです。
GIT上でもバグがあるってのが議論されてました。
日本では使えないのだろうか・・・
という事で別の方法で取得しました。
その時、署名の計算でハマったのでメモを残します。
GETの場合
$spapi = new AmazonSpapiController; $access_token = $spapi->get_actoken(); $host = $spapi::Api_set['host']; $mid = $spapi::Api_set['MarketplaceId']; $user_agent = $spapi::Api_set['user-agent']; if ($queryString !== '') { $queryString .= '&MarketplaceIds=' . $mid; $request_url = 'https://' . $host . $request . '?' . $queryString; } else { $request_url = 'https://' . $host . $request; } $gmtDate = gmdate("Ymd\THis\Z"); $ymdData = substr($gmtDate, 0, 8); $headers = [ 'content-type:application/json;charset=UTF-8', 'host:' . $host, 'user-agent:' . $user_agent, 'x-amz-access-token:' . $access_token, //事前取得アクセストークン 'x-amz-date:' . $gmtDate ]; $canonicalRequest = [ 'method' => 'GET', 'uri' => $request, //署名作成のまえに作ったリクエストURL 'query' => $queryString, //署名作成のまえに作ったリクエストパラメーター 'headers' => $headers, 'signedheaders' => 'content-type;host;user-agent;x-amz-access-token;x-amz-date', 'payload' => hash('sha256', ''), ]; //リクエスト生成 -1 $canonical_request = $spapi->CanonicalRequest($canonicalRequest); //署名を計算 -2 $signing_key = $spapi->signatureKey($ymdData); $algorithm = 'AWS4-HMAC-SHA256'; $param['amzdate'] = $gmtDate; $param['datestamp'] = $ymdData; $param['method'] = 'GET'; $signature = $spapi->signature($param, $canonical_request, $algorithm, $signing_key); $auth = $spapi->createAuthorization($param, $canonicalRequest, $signature, $algorithm); //これがバージョン4の署名で必要になる文字列 //ヘッダ情報に追加 $headers[] = 'Authorization: ' . $auth; $json_response = $spapi->get_spapi_json($headers, $request_url, false);
こんな感じ。
他の関数とやり取りしてるので、コピペじゃ動きませんのであしからず・・・。
POSTの場合
$spapi = new AmazonSpapiController; $access_token = $spapi->get_actoken(); $host = $spapi::Api_set['host']; $mid = $spapi::Api_set['MarketplaceId']; $user_agent = $spapi::Api_set['user-agent']; $request = "/reports/2021-06-30/reports"; $request_url = 'https://' . $host . $request; /** * GET_FLAT_FILE_OPEN_LISTINGS_DATA -> 出品レポート */ $queryString = '{ "reportType": "GET_FLAT_FILE_OPEN_LISTINGS_DATA", "marketplaceIds":["' . $mid . '"] }'; $gmtDate = gmdate("Ymd\THis\Z"); //リクエストごとの先頭で予め取得しとくといいです。 $ymdData = substr($gmtDate, 0, 8); $request_headers = []; $request_headers['content-type'] = 'application/json'; $request_headers['host'] = $host; $request_headers['x-amz-access-token'] = $access_token; $request_headers['x-amz-content-sha256'] = hash('sha256', $queryString); $request_headers['x-amz-date'] = $gmtDate; //Canonical headers & Signed headers $csheaders = $spapi->MakeheadInner($request_headers); $canonicalRequest = [ 'method' => 'POST', 'uri' => $request, //署名作成のまえに作ったリクエストURL 'headers' => [$csheaders['ch']], 'signedheaders' => $csheaders['sh'], 'payload' => hash('sha256', $queryString), ]; //リクエスト生成 -1 $hashed_canonical = $spapi->CanonicalRequest($canonicalRequest); //署名を計算 -2 $signature = $spapi->signatureKey($ymdData); $algorithm = 'AWS4-HMAC-SHA256'; $param['amzdate'] = $gmtDate; $param['datestamp'] = $ymdData; $param['method'] = 'POST'; $signature = $spapi->signature($param, $hashed_canonical, $algorithm, $signature); $auth = $spapi->createAuthorization($param, $canonicalRequest, $signature, $algorithm); // Curl headers $curl_headers = ['Authorization: ' . $auth]; foreach ($request_headers as $key => $value) { $curl_headers[] = $key . ": " . $value; } $json_response = $spapi->get_spapi_json($curl_headers, $request_url, $queryString);
GETとちょっとだけ違う。
たしかこれ作った時、どっちかを先に作って使いまわしたんで、無駄なコードがあると思います。
FBA在庫取得の解消方法
/fba/inventory/v1/summaries にリクエスト出すとFBAの在庫を取得できました。
こっちのがFBA在庫レポートを発行させるより効率良いようです。
だから GET_AFN_INVENTORY_DATA は動かないのかな??
分からんけど。
ちなみにバイト代くれればSPAPI対応のPHP作れなくもないです。
ではでは。
おすすめのコンテンツ
広告