サラリーのほうで、各ショッピングサイトの在庫連動システムを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作れなくもないです。
ではでは。
おすすめのコンテンツ
広告
