サラリーのほうで、各ショッピングサイトの在庫連動システムをLaravelを用いて構築したのですが、
MWSが近々終了という事でSPAPIに移行しました。
すでに大半の移行が完了していたのですが、なぜかFBA在庫レポートのみ動作せずMWSを使っていました。
しかしながらMWS終了のメールが何度も来るので、重い腰を上げて再度向き合った時のメモ。
広告
Amazon SP-API の署名のメモ
上記のFBA在庫レポートに関してはどうしても動作しませんでした。
GET_AFN_INVENTORY_DATA を reportType に渡すとどうにもエラーです。
GIT上でもバグがあるってのが議論されてました。
日本では使えないのだろうか・・・
という事で別の方法で取得しました。
その時、署名の計算でハマったのでメモを残します。
GETの場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | $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 ; } else { } $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の場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | $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" ; /** * 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作れなくもないです。
ではでは。
おすすめのコンテンツ
広告