株式会社WR

株式会社WR

WEB TOTAL CONSULTING

Amazon SP-APIの基本——MWS廃止後の商品管理自動化
ブログ一覧へ
技術ブログ

Amazon SP-APIの基本——MWS廃止後の商品管理自動化

旧Amazon MWS APIが廃止となり、Selling Partner API(SP-API)への移行が必須となりました。SP-APIの認証設定から基本的なAPIコールまでをNode.jsで解説します。

Amazon SP-APIとは——MWS廃止後の新標準

Amazon MWS(Marketplace Web Service)は2023年にサポートを終了し、後継のSP-API(Selling Partner API)が現在の標準となっています。SP-APIはOAuth2認証を採用し、より安全でモダンな設計になっています。


SP-APIで できること

カテゴリ 主なAPI 用途
Catalog Items 商品情報の取得 ASIN・JANから詳細情報を取得
Listings Items 出品情報管理 価格・在庫・商品情報の更新
Orders 注文管理 注文一覧取得・ステータス更新
Reports レポート 在庫レポート・売上レポートの取得
Feeds データ送信 大量の商品情報・在庫を一括更新
FBA Inventory FBA在庫 FBA在庫数・位置情報の取得

認証の仕組み

SP-APIはLWA(Login with Amazon)というOAuth2フローを使います。

1. Seller Central でアプリを登録
2. Client ID・Client Secret を取得
3. セラーがアプリにアクセス許可(Refresh Token を取得)
4. Refresh Token → Access Token(有効期限1時間)
5. Access Token でAPIリクエスト

Node.jsでの実装

require('dotenv').config();
const axios = require('axios');
const crypto = require('crypto');

class AmazonSPAPI {
    constructor(config) {
        this.clientId      = config.clientId;
        this.clientSecret  = config.clientSecret;
        this.refreshToken  = config.refreshToken;
        this.marketplaceId = config.marketplaceId ?? 'A1VC38T7YXB528'; // JP
        this.region        = config.region ?? 'us-east-1'; // FE region for JP
        this.endpoint      = 'https://sellingpartnerapi-fe.amazon.com';
        this.accessToken   = null;
        this.tokenExpiry   = null;
    }

    /**
     * Access Tokenを取得(キャッシュ付き)
     */
    async getAccessToken() {
        if (this.accessToken && this.tokenExpiry > Date.now()) {
            return this.accessToken;
        }

        const response = await axios.post(
            'https://api.amazon.com/auth/o2/token',
            new URLSearchParams({
                grant_type:    'refresh_token',
                client_id:     this.clientId,
                client_secret: this.clientSecret,
                refresh_token: this.refreshToken,
            }),
            { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
        );

        this.accessToken = response.data.access_token;
        this.tokenExpiry = Date.now() + (response.data.expires_in - 60) * 1000; // 1分前に期限切れ

        return this.accessToken;
    }

    /**
     * APIリクエストを実行
     */
    async request(method, path, params = {}) {
        const token = await this.getAccessToken();

        const url = new URL(this.endpoint + path);
        if (method === 'GET') {
            Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
        }

        const response = await axios({
            method,
            url: url.toString(),
            headers: {
                'x-amz-access-token': token,
                'Content-Type':       'application/json',
            },
            data: method !== 'GET' ? params : undefined,
        });

        return response.data;
    }

    /**
     * 注文一覧を取得
     */
    async getOrders(options = {}) {
        const params = {
            MarketplaceIds: this.marketplaceId,
            CreatedAfter:   options.createdAfter ?? new Date(Date.now() - 86400000).toISOString(),
            OrderStatuses:  options.statuses?.join(',') ?? 'Unshipped,PartiallyShipped',
            ...options,
        };

        return this.request('GET', '/orders/v0/orders', params);
    }

    /**
     * 商品情報をASINで取得
     */
    async getCatalogItem(asin) {
        return this.request('GET', `/catalog/2022-04-01/items/${asin}`, {
            marketplaceIds: this.marketplaceId,
            includedData:   'attributes,images,productTypes,salesRanks',
        });
    }

    /**
     * FBA在庫を取得
     */
    async getFBAInventory(options = {}) {
        return this.request('GET', '/fba/inventory/v1/summaries', {
            granularityType: 'Marketplace',
            granularityId:   this.marketplaceId,
            marketplaceIds:  this.marketplaceId,
            ...options,
        });
    }
}

注文処理の自動化

const sp = new AmazonSPAPI({
    clientId:      process.env.SP_API_CLIENT_ID,
    clientSecret:  process.env.SP_API_CLIENT_SECRET,
    refreshToken:  process.env.SP_API_REFRESH_TOKEN,
});

async function processNewOrders() {
    const response = await sp.getOrders({
        createdAfter: new Date(Date.now() - 3600000).toISOString(), // 直近1時間
    });

    const orders = response.payload?.Orders ?? [];
    console.log(`新規注文: ${orders.length}件`);

    for (const order of orders) {
        // DB に保存
        await saveOrder({
            amazon_order_id: order.AmazonOrderId,
            status:          order.OrderStatus,
            total:           parseFloat(order.OrderTotal?.Amount ?? 0),
            currency:        order.OrderTotal?.CurrencyCode,
            purchased_at:    new Date(order.PurchaseDate),
            buyer_name:      order.BuyerInfo?.BuyerName,
        });

        // Slack通知
        await notifySlack(`新規注文: ${order.AmazonOrderId} (${order.OrderTotal?.Amount}円)`);
    }

    return orders.length;
}

// 5分ごとに注文チェック
const cron = require('node-cron');
cron.schedule('*/5 * * * *', () => {
    processNewOrders().catch(console.error);
}, { timezone: 'Asia/Tokyo' });

FBA在庫レポートの取得

async function checkLowInventory(threshold = 10) {
    const response = await sp.getFBAInventory();
    const inventory = response.payload?.inventorySummaries ?? [];

    const lowStock = inventory.filter(item =>
        item.inventoryDetails?.fulfillableQuantity < threshold
    );

    if (lowStock.length > 0) {
        const message = [
            `⚠️ *FBA在庫が少ない商品: ${lowStock.length}件*`,
            ...lowStock.map(item =>
                `• ASIN: ${item.asin} (${item.fnSku}) — 残${item.inventoryDetails.fulfillableQuantity}個`
            ),
        ].join('\n');

        await notifySlack(message);
    }
}

まとめ

Amazon SP-APIを活用することで、注文管理・在庫管理・商品情報更新を自動化できます。MWSからの移行は必須となっており、弊社ではSP-APIを使ったEC管理システムの開発実績があります。

EC自動化・Amazon連携システムの開発についてはお気軽にご相談ください。

Category 技術ブログ

Related Posts

関連記事

開発・技術のご相談はお気軽に

お見積りは無料です。まずはお気軽にご相談ください。

お問い合わせ →