Rails MWS 見積もり手数料の取得 GetMyFeesEstimate


はじめに

MWSで見積もり手数料を取得できるオペレーションと言えばGetMyFeesEstimateですね?

リクエストクォーターは以下の通りです。

最大リクエストクォータ 回復レート 時間あたりのリクエストクォータ
20リクエスト 1秒あたり10商品 1時間あたり36000リクエスト

思ってたより緩いですね。

実装

事前準備

Rails MWS APIを利用するまでの事前準備
こちらよりpeddlerのclientインスタンスを作成できる状態にしておいてください

リクエストの送信

リファレンスではこう書いてあります。
get_matching_product_for_id(*fees_estimate_requests)

Parameters:
fees_estimate_requests (Array<Struct, Hash>)

うわぁ...それ以上でも以下でもねえ...
fees_estimate_requestsを作るのがキモになりますね。
(全然難しくないけどね)

client = MWS.products( 
  # 省略
)

# 取得したい商品のID(タイプは指定できる)と価格のリスト
id_prices = [
  {id: AAA, price: 100 },
  {id: BBB, price: 200 },
  {id: CCC, price: 300 },
  {id: DDD, price: 400 },
  {id: EEE, price: 500 },
  {id: FFF, price: 600 },
  {id: GGG, price: 700 },
  {id: HHH, price: 800 },
  {id: III, price: 900 },
  {id: JJJ, price: 1000 },
]

# 1リクエストごとにリクエストのハッシュを作成してそれを配列に
fees_estimate_requests = []
id_prices.each do |id_price|
  fees_estimate_requests << {
    marketplace_id: client.marketplace_id,
    id_type: id_type,
    id_value: id_price[:id],
    identifier: id_price[:id],
    is_amazon_fulfilled: true,
    price_to_estimate_fees: {
      listing_price: {
        currency_code: 'USD',
        amount: id_price[:price]
      },
      shippment: {...}, # 必要なら
      points: {...} # 必要なら
    }
  }
end

client.get_my_fees_estimate(fees_estimate_requests).xml

identifierはMWSのリファレンスには一意の値と記述されていますが、全部同じでも一応エラーが出ずに取得できました。

レスポンス例は以下の通りです。

<?xml version="1.0"?>
<GetMyFeesEstimateResponse
  xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
  <GetMyFeesEstimateResult>
    <FeesEstimateResultList>
      <FeesEstimateResult>
        <Status>Success</Status>
        <FeesEstimateIdentifier>
          <MarketplaceId>XXXXXXXXXX</MarketplaceId>
          <IdValue>XXXXXXXXXX</IdValue>
          <IdType>ASIN</IdType>
          <IsAmazonFulfilled>True</IsAmazonFulfilled>
          <PriceToEstimateFees>
            <ListingPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>58.00</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>0.00</Amount>
            </Shipping>
            <Points>
              <PointsNumber>0</PointsNumber>
            </Points>
          </PriceToEstimateFees>
          <SellerInputIdentifier>IDDDDDDDD</SellerInputIdentifier>
        </FeesEstimateIdentifier>
        <FeesEstimate>
          <TimeOfFeesEstimation>2015-07-19T23:15:11.859Z</TimeOfFeesEstimation>
          <TotalFeesEstimate>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>10.00</Amount>
          </TotalFeesEstimate>
          <FeeDetailList>
            <FeeDetail>
              <FeeType>AmazonReferralFee</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>8.70</Amount>
              </FeeAmount>
              <FeePromotion>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>1.00</Amount>
              </FeePromotion>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>7.70</Amount>
              </FinalFee>
            </FeeDetail>
            <FeeDetail>
              <FeeType>VariableClosingFee</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>0.00</Amount>
              </FeeAmount>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>0.0</Amount>
              </FinalFee>
            </FeeDetail>
            <FeeDetail>
              <FeeType>FulfillmentFees</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>2.30</Amount>
              </FeeAmount>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>2.30</Amount>
              </FinalFee>
              <IncludedFeeList>
                <FeeDetail>
                  <FeeType>OrderHandlingFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FinalFee>
                </FeeDetail>
                <FeeDetail>
                  <FeeType>PickAndPackFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>0.30</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>0.30</Amount>
                  </FinalFee>
                </FeeDetail>
                <FeeDetail>
                  <FeeType>WeightHandlingFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FinalFee>
                </FeeDetail>
              </IncludedFeeList>
            </FeeDetail>
          </FeeDetailList>
        </FeesEstimate>
      </FeesEstimateResult>
    </FeesEstimateResultList>
  </GetMyFeesEstimateResult>
  <ResponseMetadata>
    <RequestId>21534f03-e7e3-4d9a-9bea-0e15add3326d</RequestId>
  </ResponseMetadata>
</GetMyFeesEstimateResponse>

レスポンスの解析

レスポンスを掘って掘って解析していきます。
今回の例は単純にReferralFeeを配列に格納するだけのロジックです。


# 先ほどの続き
responce = client.get_my_fees_estimate(fees_estimate_requests).xml
referral_fees = []
results = response.dig('GetMyFeesEstimateResponse', 'GetMyFeesEstimateResult', 'FeesEstimateResultList', 'FeesEstimateResult', 'FeesEstimate', 'FeeDetailList', 'FeeDetail')
# [注意] 1商品だけ取得した場合eachで回す必要はないです。
results.each do |result|
  result.each do |fees|
    referral_fees << fees.dig('FinalFee', 'Amount').to_f if fees.dig('FeeType') == 'ReferralFee'
  end
end

最終的に欲しいデータは結構深いのでデバッグしながら試した方が確実です。

思ったこと

なんでこんなにレスポンスがごちゃごちゃしてるのかというと、FeesEstimateIdentifierがあるからだと思います。
FeesEstimateIdentifierは実際どんなリクエスト出した内容がそのまま返ってくるんですけど、
これ必要なんでしょうか?
同一商品で違う価格を設定してリクエストすることもあると思うので、
リクエストを一意に絞るための情報は必要なのは分かるのですが、
そのためにリクエストパラメータにidentifierがあるんじゃないんです?
まあなんでもいいんですけどね!

ブログで見たい方はこちら
Rails MWS 見積もり手数料の取得 GetMyFeesEstimate