Shopify 自動化2026-06-08

【Shopify】在庫ズレと売り越しをゼロにする、Vercel Workflows + Upstash Redisによる自動同期システム


ECサイトにおける「在庫管理」の死活問題

ECサイト、特にShopifyで自社サイトを運営しながらモール(楽天市場やYahoo!ショッピングなど)にも並行出品しているマルチチャネルブランドにおいて、**「在庫ズレによる売り越し(在庫切れ商品の二重販売)」**は顧客満足度の低下とアカウント停止リスクを直結させる深刻な問題です。

特に以下のようなケースで在庫ズレが発生しやすくなります。

  • 限定商品のローンチ: 数十〜数百件の注文が数秒の間に集中し、Shopify APIの更新速度を超える。
  • バッチ更新の遅延: 深夜の在庫一括更新中にデータが衝突し、一部のバリエーション(サイズ・カラーなど)が正しく同期されない。
  • APIレートリミット: ShopifyのGraphQL/REST APIのAPI上限(Leaky Bucket)に引っかかり、外部の在庫同期ツールからの連携リクエストが破棄される。

これらの課題を解決するには、分散型インメモリデータベース(Upstash Redis)による超高速な在庫ロックと、失敗した処理を自動的にリトライ・待機(ディレイ)させることができるVercel Workflowsを組み合わせた在庫同期パイプラインの導入が最適です。


2. 課題解決のビフォー・アフター

項目 従来のバッチ/GAS同期(Before) Vercel Workflows + Redis(After)
同期遅延 10分〜30分(バッチ実行間隔) リアルタイム(秒単位)
競合制御 同時購入時に在庫の「売り越し」が発生 Redisのデクリメント(decr)による厳密な割り当て
API障害対策 エラー時に同期が未完了のまま停止 Workflowsのリトライ・バックオフにより自動復旧
インフラコスト サーバーの維持費が常時発生 サーバーレス(完全従量課金)で運用コスト最小化

3. 在庫同期のワークフロー設計

以下は、Shopifyの注文(Webhook)をトリガーにして在庫数を安全に他システムへ反映・ロックするVercel Workflowsの実装例です。

import { Redis } from "@upstash/redis";
import { workflow } from "@vercel/workflows";

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL!,
  token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});

export const syncInventoryWorkflow = workflow(async (context) => {
  const { productId, sku, quantityChange } = context.payload;

  // Step 1: Redisで在庫の在庫引き当て処理を実行
  const currentStock = await context.run("allocate-redis-stock", async () => {
    const stockKey = `stock:${sku}`;
    // インクリメント/デクリメントでアトミックに数値を操作
    const newStock = await redis.decrby(stockKey, quantityChange);
    
    if (newStock < 0) {
      // 在庫不足の場合はアトミックに戻す
      await redis.incrby(stockKey, quantityChange);
      throw new Error(`Insufficient stock for SKU: ${sku}`);
    }
    return newStock;
  });

  // Step 2: Shopify APIへのリクエスト(レートリミット対策としてリトライ制御つき)
  await context.run("update-shopify-inventory", async () => {
    const shopifyDomain = process.env.SHOPIFY_DOMAIN!;
    const accessToken = process.env.SHOPIFY_ACCESS_TOKEN!;
    
    const response = await fetch(
      `https://${shopifyDomain}/admin/api/2024-01/inventory_levels/set.json`,
      {
        method: "POST",
        headers: {
          "X-Shopify-Access-Token": accessToken,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          location_id: process.env.SHOPIFY_LOCATION_ID,
          inventory_item_id: productId,
          available: currentStock,
        }),
      }
    );

    if (!response.ok) {
      // 5xxエラーやレートリミット(429)時はワークフロー側で再実行される
      throw new Error(`Shopify API responded with status ${response.status}`);
    }
  });

  // Step 3: Discordなどのチャットツールへの完了通知
  await context.run("send-notifications", async () => {
    await fetch(process.env.DISCORD_WEBHOOK_URL!, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        content: `📦 SKU: ${sku} の在庫を ${currentStock} 件に更新・同期しました。`,
      }),
    });
  });
});

4. HadayaLabのShopify自動化パッケージ

HadayaLabでは、自社Shopifyストアの運用負荷を劇的に低減するための「Touchless EC運用基盤」の構築をサポートしています。

  • 注文・出荷データのWMS(倉庫管理システム)自動連携
  • Upstash Redisを用いた高スケーラブルな瞬間在庫のロック制御
  • Vercel Workflowsによるリトライ・耐障害性の高い外部モール在庫同期
  • 新商品の予約販売時における、特定顧客枠・在庫数の制御

「売り越しによるキャンセル対応に追われている」「API制限による同期ズレをなくしたい」とお悩みのEC事業者様は、ぜひHadayaLabの無料の診断サービスをご利用ください。