CData Software Blog

クラウド連携のCData Software の技術ブログです。

Amazon Marketplace SP-API に Postman からアクセスする

f:id:sugimomoto:20210511172852p:plain

こんにちは。CData Software Japanリードエンジニアの杉本です。

前回の記事でAmazon Marketplace SP-APIの基本的な使い方を解説しました。

www.cdatablog.jp

ただ、検証用のプログラムがC#だったので、普段C#にあまり馴染みが無い方々にはちょっと厳しい部分もあったのではないかなと思います。

そこで今回は Amazon Marketplace SP-API に Postman からアクセスする方法を紹介したいと思います。

必要な設定値などは前の Blog を参考にしてみてください。

なお、今回も AccessToken の取得は、アプリクライアントから生成できるRefreshTokenを用いました。

Postmanの入手

Postmanはデスクトップ版を使います。予め以下のURLからダウンロードしておきましょう。

www.postman.com

f:id:sugimomoto:20210511172456p:plain

ちなみにWeb版もありますが、ゲートウェイが必要になるので、今回のようなケースではおすすめしません。

RefreshToken を使った AccessToken の取得方法

それでは早速やっていきましょう。まず、実際にAPIアクセスを行う前に、必要となるAccessTokenの取得を実施します。

これはデベロッパーガイドで言うところの、自己認可に当たります。

github.com

必要な情報はRefreshToken、そしてClientIdとClientSecretです。

リフレッシュトークンは作成したアプリクライアントの「アプリケーションを承認」画面から取得できます。

f:id:sugimomoto:20210511172617p:plain

ClientIdとClientSecretはLWA認証情報から取得できるものですね。

f:id:sugimomoto:20210511172622p:plain

この情報をもとに、「https://api.amazon.com/auth/o2/token」に対してPOSTリクエストを行います。

Bodyには「application/x-www-form-urlencoded」形式で、各パラメータを指定しましょう。

Grant Typeはrefresh_tokenです。

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 524

grant_type=refresh_token&refresh_token=XXXXX&client_id=XXXX&client_secret=XXXXX

f:id:sugimomoto:20210511172627p:plain

これをリクエストするこで、以下のようなAccessTokenが取得できます。なお、AccessTokenの有効時間は1時間(3600秒)なので、1時間経過したら、新しくAccessTokenを取得し直しましょう。

{
    "access_token": "Atza|IwEBIHxWh9Zn3Qy0Ur00lgGicQPgy1NHRjctqrle7CEVsHTaRZX8DSEj4CXQhiX4i3ngZGT6q3EUcgzX5rXuigoh6ZC-ddFcNu37LJwspUjYXBVzjY-68v46twFwKWSvRfRrNctn23is40eKjyoJRSGv_6XB7zCuLchblaQ-2U0MLqS7e2SN8CWSRdg4ei6Qpa-fsaqjGHOqVypRR1WuiZBje4aeRzh3C_W3xhWRDQh6Gm2M5LYPzbSqz0oNooQGRLUaYCy30yz",
    "refresh_token": "Atzr|IwEBIMw6uUd94TqnJhea4uh3gDErvuTMDdJXphW9e3YF8vFVY5f2CP-jbncQDSWnNtDDvTI",
    "token_type": "bearer",
    "expires_in": 3600
}

注文APIにアクセスする

AccessTokenを取得したら実際にAPIを叩いてみましょう。

前の記事と同じように注文情報を取得するAPIを実行してみます。

github.com

その前に必要なこととして、AWS Signature があります。これは、APIリクエストのクエリパラメータとIAM のAccess Key・SecretKeyをもとにリクエストに署名を施す作業です。

クラッチでやろうとすると結構面倒ですが、

docs.aws.amazon.com

ありがたいことにPostmanにはAWS Signatureを自動的に実施してくれるモジュールが入っていますので、これを利用します。

APIリクエストの「Authorization」タブから「AWS Signature」Typeを選択しましょう。

ここで以下のように値を入力します。

f:id:sugimomoto:20210511172635p:plain

Access KeyとSecretKeyはIAMユーザーから取得しておいた以下の情報です。

f:id:sugimomoto:20210511172640p:plain

AWS Regionは日本のAmazon Marketplaceであれば「us-west-2」を選択します。

Service Nameは「execute-api」です。

合わせてリクエストヘッダーには「x-amz-access-token」「x-amz-date」「user-agent」を指定します。

必須なのは「x-amz-access-token」だけのようで、ここには先程取得したAccessTokenを指定します。

「x-amz-date」は実行時間として「20210511T081211Z」のようなフォーマットの値を指定します。「user-agent」は実行しているアプリケーション名で識別しやすいものを指定しましょう。

f:id:sugimomoto:20210511172646p:plain

「x-amz-date」「user-agent」はおそらく何か障害が発生した際に、Amazon側で調査を行うために必要となる情報かなと思います。実運用ではしっかりと指定しておいたほうが良いでしょう。

あとは実際のAPIリクエストを組み立てるだけです。

APIエンドポイントは日本リージョンの場合「https://sellingpartnerapi-fe.amazon.com」で

注文データの取得は「/orders/v0/orders」を指定します。クエリパラメータには今回「MarketplaceIds」と「CreatedAfter」を指定しましたが、ここはリファレンスを見ながら任意の値を指定してください。

GET /orders/v0/orders?MarketplaceIds=A1VC38T7YXB528&CreatedAfter=2020-01-01 HTTP/1.1
Host: sellingpartnerapi-fe.amazon.com
x-amz-access-token: XXXXX
user-agent: My Selling Tool/2.0 (Language=Java/1.8.0.221;Platform=Windows/10)
X-Amz-Date: 20210511T081312Z
Authorization: AWS4-HMAC-SHA256 XXXXX

f:id:sugimomoto:20210511172653p:plain

これで以下のように注文データを取得することができました。

{
    "payload": {
        "CreatedBefore": "2021-05-11T08:10:12Z",
        "Orders": [
            {
                "AmazonOrderId": "503-3954979-1231231",
                "PurchaseDate": "2020-07-02T07:50:00Z",
                "LastUpdateDate": "2020-07-03T01:06:23Z",
                "OrderStatus": "Canceled",
                "FulfillmentChannel": "MFN",
                "SalesChannel": "Amazon.co.jp",
                "ShipServiceLevel": "Std JP D2D Dom 1",
                "OrderTotal": {
                    "CurrencyCode": "JPY",
                    "Amount": "134.00"
                },
                "NumberOfItemsShipped": 0,
                "NumberOfItemsUnshipped": 0,
                "PaymentMethodDetails": [
                    "Standard"
                ],
                "IsReplacementOrder": "false",
                "MarketplaceId": "A1VC38T7YXB528",
                "ShipmentServiceLevelCategory": "Standard",
                "OrderType": "StandardOrder",
                "EarliestShipDate": "2020-07-02T15:00:00Z",
                "LatestShipDate": "2020-07-06T14:59:59Z",
                "IsBusinessOrder": false,
                "IsSoldByAB": false,
                "IsPrime": false,
                "IsGlobalExpressEnabled": false,
                "IsPremiumOrder": false,
                "IsISPU": false
            },
            {
                "AmazonOrderId": "250-5869185-1231231",
                "PurchaseDate": "2020-08-26T02:53:01Z",
                "LastUpdateDate": "2020-08-26T03:01:33Z",
                "OrderStatus": "Shipped",
                "FulfillmentChannel": "MFN",
                "SalesChannel": "Amazon.co.jp",
                "ShipServiceLevel": "Std JP Domestic",
                "OrderTotal": {
                    "CurrencyCode": "JPY",
                    "Amount": "613.00"
                },
                "NumberOfItemsShipped": 1,
                "NumberOfItemsUnshipped": 0,
                "PaymentMethod": "Other",
                "PaymentMethodDetails": [
                    "Standard"
                ],
                "IsReplacementOrder": "false",
                "MarketplaceId": "A1VC38T7YXB528",
                "ShipmentServiceLevelCategory": "Standard",
                "OrderType": "StandardOrder",
                "EarliestShipDate": "2020-08-26T15:00:00Z",
                "LatestShipDate": "2020-08-28T14:59:59Z",
                "EarliestDeliveryDate": "2020-08-27T15:00:00Z",
                "LatestDeliveryDate": "2020-09-01T14:59:59Z",
                "IsBusinessOrder": false,
                "IsSoldByAB": false,
                "IsPrime": false,
                "IsGlobalExpressEnabled": false,
                "IsPremiumOrder": false,
                "IsISPU": false
            }
        ]
    }
}

Tips

ClientIdやClientSecretなどの情報はCollectionやEnvironmentの変数として登録しておくと使いまわしがしやすくなるので、楽ちんです。

f:id:sugimomoto:20210511172703p:plain

また、Tokenのリフレッシュは1回や2回なら気にならないですが、毎回毎回行っていると面倒なので、Pre-request ScriptでAPIリクエスト実行時に自動的にリフレッシュするように設定しています。

色んな作り方がありますが、参考までに貼り付けておきます。

const moment = require('moment');
pm.collectionVariables.set("x-amz-date", moment().format("YYYYMMDDTHHmmss") + "Z");

   pm.sendRequest({
      url:  'https://api.amazon.com/auth/o2/token', 
      method: 'POST',
      header: {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body:'grant_type=refresh_token&refresh_token=' + pm.collectionVariables.get("refresh_token") + '&client_id=' + pm.collectionVariables.get("client_id") + '&client_secret=' + pm.collectionVariables.get("client_secret")
  }, function (err, res) {
        pm.environment.set("access_token", res.json().access_token);
  });

f:id:sugimomoto:20210511172710p:plain

おわりに

PostmanからAPIリクエストができるようになると、APIの検証が捗りますね。

API定義は Open APIで公開されているので、この定義を取り込んで、Postman から実行することもできます。ただ、認証周りは一切指定が無いので、この記事で紹介した方法と組み合わせて試すのがおすすめです。

github.com

www.cdata.com

f:id:sugimomoto:20210511140113p:plain