Shopify + Odoo ERP Integration: The Complete Guide

Comprehensive guide to integrating Shopify with Odoo ERP — inventory sync, order management, customer data, financial reporting, and automation workflows.

E
ECOSIRE Research and Development Team
|2026年3月19日6 分で読める1.3k 語数|

eCommerce Integrationシリーズの一部

完全ガイドを読む

Shopify + Odoo ERP 統合: 完全ガイド

Shopify ストアが拡大するにつれて、Shopify がネイティブに処理する内容と、ビジネスが優れたオペレーションを実現するために実際に必要とする内容との間のギャップが大きな制約になります。複数の倉庫にわたる在庫管理、多通貨会計、Shopify の販売によって引き起こされる製造オーダー、完全な顧客履歴を備えた高度な CRM、自動ベンダー補充など、これらには ERP が必要であり、Odoo はますます中規模市場の e コマース ビジネスに選ばれるシステムとなっています。

Shopify + Odoo はプラグアンドプレイの統合ではありません。どのシステムがどのデータを所有するか、何をどの方向に同期するか、部分出荷、返品処理、バリアント マッピングなどのエッジ ケースをどのように処理するかについて、慎重なアーキテクチャ上の決定が必要です。このガイドでは、統合アーキテクチャから特定の実装パターンまですべてを説明します。

重要なポイント

  • Odoo は在庫、顧客、会計に関する真実の情報源です。 Shopify は e コマース取引の信頼できる情報源です
  • 双方向の在庫同期 (注文については Shopify → Odoo、在庫レベルについては Odoo → Shopify) が統合要件の中核です
  • 製品カタログ管理は Odoo に存在し、Shopify に同期する必要があります。その逆ではありません
  • 電子メールを一意の識別子として使用して、システム間で顧客レコードをマージします
  • 注文ライフサイクル: Shopify が注文を作成 → Odoo が注文を受け取る → Odoo が配送を作成 → フルフィルメントが Shopify を更新
  • 返品処理には調整が必要です: Shopify が返品を開始 → Odoo が受け取りを処理 → 両方のシステムが更新
  • Shopify の Webhook API はリアルタイムの注文イベントを提供します。 Odoo はコネクタ ミドルウェア経由でこれらを受け取ります
  • 直接の Odoo-Shopify コネクタ (Syncee、OdooConnector) が存在しますが、REST API を介したカスタム統合により、より詳細な制御が可能になります

統合アーキテクチャを理解する

実装する前に、各データ ドメインに対して権限のあるシステムを定義します。

データ型権威あるシステム同期方向周波数
製品カタログオドゥOdoo → Shopify製品変更について
在庫レベルオドゥOdoo → Shopifyリアルタイム
注文ショッピファイShopify → オドゥーリアルタイム (Webhook)
顧客記録Odoo (マージ)双方向 (電子メール キー)注文中
価格オドゥOdoo → Shopify価格変更について
配送料ショッピファイShopify のみ該当なし
支払いショッピファイShopify → Odoo (会計)決済について
返品Shopify を開始Shopify → オドゥー返品時の作成

Odoo が在庫を所有する理由:

Shopify の在庫追跡は機能しますが、複数の倉庫、複数のチャネルの運用には制限されています。 Odoo の在庫モジュールは、ロットとシリアル番号の追跡、複数拠点の倉庫管理、自動補充ルール、製造統合 (完成品のコンポーネント在庫の減少)、およびバーコード駆動のフルフィルメント操作を処理します。 Shopify は Odoo の在庫の現実を反映する必要があり、その逆ではありません。

Shopify がコマース層である理由:

Shopify のチェックアウト、支払い処理、配送料計算、税徴収、顧客対応エクスペリエンスはクラス最高です。 Odoo の B2C e コマース (Odoo Website) は機能しますが、DTC コマースに関しては Shopify のレベルには達していません。最適なアーキテクチャにより、Shopify がコマース インターフェイスとして維持され、Odoo が運用バックボーンとして維持されます。


統合方法: コネクタ アプリとカスタム API

オプション 1: 事前構築されたコネクタ アプリ

いくつかの Shopify および Odoo マーケットプレイス アプリは、事前構築された統合を提供します。

コネクタアプローチ月額料金長所短所
ザピエト + オドゥZapier 経由のミドルウェア$50-200クイックセットアップ限られたカスタマイズ、単一点障害
同期ダイレクトコネクタ$29-99カタログの同期注文処理が制限されている
OdooConnector.com専用$200-500総合Odoo の専門知識が必要
Eshop+ (Odoo アプリ)オドゥネイティブコミュニティ無料オドゥネイティブShopify の基本サポート
Webkul Shopify Odoo専用カスタム全ライフサイクル複雑な構成

事前構築されたコネクタは、複雑なバリアント構造、複数の倉庫、または製造依存関係のないシンプルなビジネス モデルの標準製品カタログと注文の同期に適しています。

オプション 2: API を介したカスタム統合

複雑なビジネス要件の場合、Shopify の REST/GraphQL API と Odoo の JSON-RPC/REST API を使用したカスタム統合により、最大限の制御と信頼性が提供されます。

カスタム統合アーキテクチャ:

Shopify (Commerce Layer)
│
│ Webhooks (orders/create, orders/updated, refunds/create, inventory_levels/update)
│
▼
Integration Service (Node.js / Python middleware)
│
│ Event processing, transformation, error handling, retry logic
│
▼
Odoo (ERP Layer)
│
│ Odoo JSON-RPC API (sales orders, inventory, customers, accounting)
│
└── Inventory updates → Shopify Admin API

カスタム統合のためのテクノロジースタック:

  • ミドルウェア: Node.js (Shopify エコシステム調整用) または Python (Odoo エコシステム調整用)
  • キュー: 信頼性の高いイベント処理のための Redis または RabbitMQ
  • データベース: 統合状態、べき等キー、エラー ログ用の PostgreSQL
  • ホスティング: Webhook ハンドラー用の AWS Lambda または類似のもの (Shopify トラフィックの急増に応じて自動的にスケールします)

注文同期: Shopify → Odoo

注文の同期は最も重要な統合パスです。すべての Shopify 注文は、フルフィルメントをトリガーして財務記録を更新する、対応する Odoo 販売注文を作成する必要があります。

注文イベント用の Shopify Webhook セットアップ:

// Register webhooks via Shopify API
const webhooks = [
  {
    topic: 'orders/create',
    address: 'https://your-integration.com/webhooks/shopify/orders',
    format: 'json'
  },
  {
    topic: 'orders/updated',
    address: 'https://your-integration.com/webhooks/shopify/orders/updated',
    format: 'json'
  },
  {
    topic: 'orders/fulfilled',
    address: 'https://your-integration.com/webhooks/shopify/orders/fulfilled',
    format: 'json'
  },
  {
    topic: 'refunds/create',
    address: 'https://your-integration.com/webhooks/shopify/refunds',
    format: 'json'
  }
];

Shopify 注文を Odoo 販売注文に変換:

def shopify_order_to_odoo_sale_order(shopify_order: dict) -> dict:
    """Transform Shopify order payload to Odoo sale.order format"""

    # Find or create Odoo partner (customer)
    partner_id = find_or_create_odoo_partner(
        email=shopify_order['email'],
        name=shopify_order['customer']['first_name'] + ' ' + shopify_order['customer']['last_name'],
        phone=shopify_order['customer'].get('phone'),
        shipping_address=shopify_order['shipping_address']
    )

    # Map line items
    order_lines = []
    for item in shopify_order['line_items']:
        odoo_product_id = get_odoo_product_from_shopify_variant(
            item['variant_id']
        )
        order_lines.append({
            'product_id': odoo_product_id,
            'product_uom_qty': item['quantity'],
            'price_unit': float(item['price']),
            'name': item['name'],
            'shopify_line_id': item['id'],  # Custom field for traceability
        })

    # Add shipping as a service product line
    if float(shopify_order.get('shipping_lines', [{}])[0].get('price', 0)) > 0:
        order_lines.append({
            'product_id': SHIPPING_PRODUCT_ID,  # Configured in settings
            'product_uom_qty': 1,
            'price_unit': float(shopify_order['shipping_lines'][0]['price']),
            'name': shopify_order['shipping_lines'][0]['title'],
        })

    return {
        'partner_id': partner_id,
        'order_line': [(0, 0, line) for line in order_lines],
        'shopify_order_id': shopify_order['id'],  # Custom field
        'shopify_order_name': shopify_order['name'],  # e.g., #1001
        'note': shopify_order.get('note', ''),
        'state': 'sale',  # Confirm order automatically
    }

冪等性の処理:

Shopify は同じ Webhook イベントを複数回配信する場合があります (ネットワーク再試行)。統合では、重複したイベントを適切に処理する必要があります。

def process_shopify_order_webhook(payload: dict):
    shopify_order_id = str(payload['id'])

    # Check if already processed
    if OrderSyncLog.objects.filter(
        shopify_order_id=shopify_order_id,
        status='completed'
    ).exists():
        logger.info(f"Order {shopify_order_id} already processed, skipping")
        return

    # Process and log
    try:
        odoo_order_id = create_odoo_sale_order(payload)
        OrderSyncLog.objects.create(
            shopify_order_id=shopify_order_id,
            odoo_order_id=odoo_order_id,
            status='completed'
        )
    except Exception as e:
        OrderSyncLog.objects.create(
            shopify_order_id=shopify_order_id,
            status='failed',
            error=str(e)
        )
        raise

在庫同期: Odoo → Shopify

過剰販売を防ぐために、在庫レベルは Shopify における Odoo の現実をリアルタイム (またはほぼリアルタイム) で反映する必要があります。

トリガーベースのインベントリ同期:

最も信頼性の高いアプローチはイベント駆動型の同期です。Odoo で在庫が変更されると (販売、購入受領、製造完了、在庫調整)、Odoo は更新された数量を Shopify にプッシュします。

# In Odoo (using automated actions or override)
def _post_write_sync_to_shopify(self):
    """Called after inventory level changes in Odoo"""
    for move_line in self:
        product = move_line.product_id
        location = move_line.location_id

        if location.is_shopify_sync_location:
            shopify_variant_id = product.shopify_variant_id
            if shopify_variant_id:
                new_quantity = product.with_context(
                    location=location.id
                ).qty_available

                sync_inventory_to_shopify(
                    shopify_variant_id=shopify_variant_id,
                    quantity=int(new_quantity)
                )

def sync_inventory_to_shopify(shopify_variant_id: str, quantity: int):
    """Push inventory update to Shopify via Admin API"""
    inventory_item_id = get_inventory_item_id(shopify_variant_id)
    location_id = get_shopify_location_id()  # Primary Shopify location

    shopify.InventoryLevel.set(
        inventory_item_id=inventory_item_id,
        location_id=location_id,
        available=quantity
    )

スケジュールされた在庫調整:

イベント駆動型同期を使用する場合でも、毎日の完全な在庫調整をスケジュールします。

  1. 指定された Shopify 同期の場所からすべての Odoo 製品数量をエクスポートします
  2. 現在の Shopify 在庫レベルと比較する
  3. 不一致があれば更新します(同期イベントの失敗や手動調整が原因で発生する可能性があります)。
  4. 監査目的で調整結果をログに記録する

この調整により、蓄積された小さな同期エラーによる在庫の変動が防止されます。


製品カタログの同期: Odoo → Shopify

Odoo で製品カタログ (複数通貨の価格設定、詳細な仕様、複雑なバリアント マトリックス) を管理している企業の場合、カタログを Shopify に同期することで手動での二重入力が不要になります。

製品マッピング アーキテクチャ:

Odoo Product (product.template)
├── Shopify Product (via shopify_product_id field on Odoo template)
│
└── Odoo Product Variants (product.product)
    └── Shopify Variants (via shopify_variant_id field on Odoo product.product)

Odoo から Shopify に同期するもの:

  • 商品名(Odooの販売説明文)
  • 商品説明(HTMLの長い説明)
  • 画像 (製品.テンプレート画像)
  • 価格(設定されたShopify価格リストを使用)
  • SKU (Odoo の内部参照)
  • バーコード (Odoo の EAN/UPC)
  • 重量(送料計算用)
  • アクティブ/アーカイブ済みステータス (Odoo 製品がアーカイブされると Shopify で非公開になります)
  • インベントリ (指定された同期場所から)

Odoo から Shopify に同期してはいけないもの:

  • Shopify 固有の SEO メタデータ (タイトル タグ、メタ ディスクリプション — Shopify で管理)
  • Shopifyの商品タグ(Shopifyで管理)
  • Shopify コレクション/カテゴリ (Shopify で管理)
  • Shopify 固有のコンテンツ (ページビルダーセクション、Shopify 用にフォーマットされた豊富な説明)

顧客データ管理

Shopify (ストアフロント アカウントから) と Odoo (連絡先/パートナーとして) の両方に存在する顧客は、単一の統合プロファイルを作成するために慎重にマージする必要があります。

電子メールを使用した重複排除戦略:

def find_or_create_odoo_partner(email: str, name: str, **kwargs) -> int:
    """Find existing Odoo partner by email or create new one"""
    existing = Partner.search([
        ('email', '=', email)
    ], limit=1)

    if existing:
        # Update with latest data from Shopify
        existing.write({
            'phone': kwargs.get('phone', existing.phone),
        })
        return existing.id
    else:
        # Create new partner
        partner = Partner.create({
            'name': name,
            'email': email,
            'phone': kwargs.get('phone'),
            'type': 'contact',
            'customer_rank': 1,
            'shopify_customer_id': kwargs.get('shopify_customer_id'),
        })
        return partner.id

Odoo に保存されている Shopify 顧客 ID:

カスタム フィールド shopify_customer_id を Odoo の res.partner モデルに追加します。これにより、双方向の検索が可能になります。Shopify ID から Odoo パートナーを検索し、Odoo パートナーから Shopify 顧客を検索します。


フルフィルメント ループ: Odoo → Shopify

Odoo が配送を処理 (ピッキング + 検証) すると、注文は履行されます。 Shopify は次の宛先に通知する必要があります。

  • 注文を完了済みとしてマークします
  • 出荷確認メールを顧客に送信する
  • 追跡番号を記録します
def sync_fulfillment_to_shopify(odoo_picking: StockPicking):
    """Called after Odoo delivery is validated"""
    shopify_order_name = odoo_picking.sale_id.shopify_order_name
    tracking_number = odoo_picking.carrier_tracking_ref

    # Find Shopify order
    shopify_orders = shopify.Order.find(name=shopify_order_name)
    if not shopify_orders:
        return

    shopify_order = shopify_orders[0]

    # Create fulfillment in Shopify
    fulfillment = shopify.Fulfillment.create({
        'order_id': shopify_order.id,
        'tracking_number': tracking_number,
        'tracking_company': odoo_picking.carrier_id.name,
        'notify_customer': True,  # Sends Shopify's shipping email
        'line_items': [
            {'id': line.shopify_line_id}
            for line in odoo_picking.sale_id.order_line
            if line.shopify_line_id
        ]
    })

会計統合: Shopify Sales → Odoo Financials

Shopify のすべての売上は、最終的に、投稿された売上エントリとして Odoo の会計モジュールに表示される必要があります。

会計の統合アプローチ:

オプション 1 — 注文レベルの会計: Shopify の注文ごとに Odoo 請求書が作成されます (または、Odoo 販売注文が履行されると請求書が生成されます)。 Shopify に記録された支払いは、Odoo での支払い登録をトリガーします。

オプション 2 — 決済レベルの会計: Shopify Payments の決済 (毎日または毎週の銀行入金) は、銀行取引と照合する仕訳として Odoo に記録されます。これは保守が簡単ですが、アカウンティングの粒度は低くなります。

ほとんどの中規模市場の販売者にとって、決済レベルの会計 (オプション 2) で十分であり、実装と維持はそれほど複雑ではありません。

Shopify 支払いデータ → Odoo 仕訳帳:

def process_shopify_payout(payout_data: dict):
    """Create Odoo journal entry for Shopify Payments payout"""
    journal = ShopifyJournal.get_or_create()  # Shopify clearing account

    entry = AccountMove.create({
        'journal_id': journal.id,
        'date': payout_data['date'],
        'ref': f"Shopify Payout {payout_data['id']}",
        'line_ids': [
            (0, 0, {
                'account_id': SHOPIFY_CLEARING_ACCOUNT_ID,
                'credit': payout_data['amount'],
                'name': f"Shopify sales - {payout_data['period']}",
            }),
            (0, 0, {
                'account_id': SHOPIFY_FEES_ACCOUNT_ID,
                'debit': payout_data['fees'],
                'name': 'Shopify Payments fees',
            }),
            (0, 0, {
                'account_id': BANK_ACCOUNT_ID,
                'debit': payout_data['amount'] - payout_data['fees'],
                'name': f"Bank deposit - Shopify payout {payout_data['id']}",
            }),
        ]
    })
    entry.action_post()

よくある質問

Shopify と Odoo の統合の実装にはどのくらい時間がかかりますか?

事前に構築されたコネクタを使用した基本的な統合 (注文同期、在庫同期、顧客同期) には、構成、テスト、データ移行を含めて 2 ~ 4 週間かかります。ライフサイクル全体 (注文、在庫、履行同期、返品、会計) をカバーするカスタム統合には、ビジネスの複雑さに応じて 8 ~ 16 週間かかります。複雑なシナリオ (複数の倉庫、製造、複数通貨、複数の会社の Odoo) では、さらに 4 ~ 8 週間かかります。継続的なメンテナンスの予算: Shopify または Odoo のリリース API が変更されると、統合を更新する必要があります。

Shopify または Odoo で製品を管理する必要がありますか?

シンプルな製品カタログの場合: Shopify で管理し、製造/調達の目的で Odoo を手動で更新します。複雑なカタログ (多くのバリエーション、複数通貨の価格設定、技術仕様、製造 BOM) の場合: Odoo で管理し、Shopify に同期します。重要な要素は、製品チームが実際にどこで働くかです。マーチャンダイジング チームが Shopify を使用している場合、Odoo で作業することを強制すると摩擦が生じます。運用チームが製造と調達のために Odoo で製品を管理している場合、Shopify 同期は適切なアプローチです。

統合が有効になると、既存の Shopify 注文はどうなりますか?

過去のオーダーを Odoo に移行する必要はありません。統合では、稼働日以降の新しい注文が処理されます。履歴データ (顧客レコード、製品カタログ、在庫ベースライン) については、統合が稼働する前に 1 回限りのデータ移行を実行します。つまり、顧客履歴データを Odoo にインポートし、製品カタログをインポートし、現在の Shopify 数量と一致するように Odoo で在庫ベースラインを設定します。

Odoo に存在しない商品を含む Shopify の注文はどのように処理すればよいですか?

この特殊なケースは、単純な統合を破壊します。フォールバックを構築する: Shopify 注文に Odoo 製品にマップされないバリアント ID が含まれている場合は、プレースホルダー「不明な製品」製品を使用して Odoo で注文を作成し、統合チームに警告します。通知付きのエラー キューを定義します。運用スタッフはマップされていない製品を確認し、Odoo 製品を作成し、失敗した注文を再処理します。これは、サイレント障害を発生させたり、マッピングの修正を待つ間にすべての注文をブロックしたりするよりも望ましい方法です。

この統合は複数の Shopify ストア (異なるマーケット ストアなど) をサポートできますか?

はい、ただし複雑さが増します。各 Shopify ストアは個別の API 接続です。 1 つの Odoo インスタンスは、カスタム フィールドを介して追跡されるストア ソースを使用して、複数の Shopify ストアから注文を受け取ることができます。店舗間の在庫割り当てには追加のロジックが必要です。共有在庫プール (Odoo は注文需要に基づいて店舗全体に割り当てます)、または場所別在庫 (各店舗には指定された Odoo 場所があります) のいずれかです。複数店舗の統合により、テストの範囲と継続的なメンテナンスの負担が 2 倍になります。


次のステップ

適切に実装された Shopify と Odoo の統合により、手動データ入力が不要になり、過剰販売が防止され、洗練されたレポートが可能になり、e コマースの販売が製造、調達、財務プロセスに接続されるなど、業務効率が変わります。

ECOSIRE は、中規模市場の販売者向けに ShopifyOdoo ERP 統合 を構築し、アーキテクチャ設計、カスタム開発、データ移行、テスト、継続的なサポートをカバーします。当社の統合チームは、さまざまな製品カテゴリにわたる 30 以上の販売者に Shopify-Odoo 接続を実装しました。

Shopify-Odoo 統合アーキテクチャを設計するには、統合チームにお問い合わせください

E

執筆者

ECOSIRE Research and Development Team

ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。

eCommerce Integrationのその他の記事

Odoo eBay Connector: Listing, Orders, and Inventory Sync

Set up the Odoo eBay Connector for Odoo 19. Manage listings, automate order sync, synchronize inventory, handle returns, and manage multi-store eBay accounts from Odoo.

Managing Returns and Exchanges on Shopify

Complete guide to Shopify returns management: policy design, automated workflows, reverse logistics, exchange processing, and reducing return rates profitably.

水素を使用したヘッドレス Shopify: 高性能のカスタム ストアフロントを構築

Remix、Storefront API、Oxygen ホスティング、パフォーマンスの最適化をカバーする、Hydrogen フレームワークを使用してヘッドレス Shopify ストアフロントを構築するための完全なガイドです。

マルチチャネル在庫同期: 在庫切れや過剰販売を防止

マルチチャネル在庫同期ガイド。リアルタイム同期方法、安全在庫割り当て、ERP 統合、過剰販売防止、倉庫管理をカバーします。

データ マッピングと変換: さまざまな API とデータ形式の処理

マスター フィールド マッピング、データ正規化、単位変換、通貨処理、および e コマース API とデータ形式にわたるカテゴリ分類マッピング。

ヘッドレス コマース アーキテクチャ: フロントエンドとバックエンドの分離

ヘッドレス コマースとモノリシック コマースを比較し、Shopify Storefront API、Next.js フロントエンド、最新のコマース プラットフォーム オプションを使用した API ファーストの設計を検討します。

WhatsAppでチャット