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
)
スケジュールされた在庫調整:
イベント駆動型同期を使用する場合でも、毎日の完全な在庫調整をスケジュールします。
- 指定された Shopify 同期の場所からすべての Odoo 製品数量をエクスポートします
- 現在の Shopify 在庫レベルと比較する
- 不一致があれば更新します(同期イベントの失敗や手動調整が原因で発生する可能性があります)。
- 監査目的で調整結果をログに記録する
この調整により、蓄積された小さな同期エラーによる在庫の変動が防止されます。
製品カタログの同期: 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 は、中規模市場の販売者向けに Shopify と Odoo ERP 統合 を構築し、アーキテクチャ設計、カスタム開発、データ移行、テスト、継続的なサポートをカバーします。当社の統合チームは、さまざまな製品カテゴリにわたる 30 以上の販売者に Shopify-Odoo 接続を実装しました。
Shopify-Odoo 統合アーキテクチャを設計するには、統合チームにお問い合わせください。
執筆者
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
関連記事
電子商取引のための AI コンテンツ生成: 商品説明、SEO など
AI を使用して e コマース コンテンツを拡張します: 商品説明、SEO メタ タグ、電子メールのコピー、ソーシャル メディア。品質管理フレームワークとブランドの声の一貫性に関するガイド。
AI を活用した顧客セグメンテーション: RFM から予測クラスタリングまで
AI が顧客セグメンテーションを静的な RFM 分析から動的な予測クラスタリングにどのように変換するかを学びます。 Python、Odoo、および実際の ROI データを使用した実装ガイド。
サプライチェーン最適化のための AI: 可視性、予測、自動化
AI を使用してサプライ チェーンの運用を変革します。需要の検知、サプライヤーのリスク スコアリング、ルートの最適化、倉庫の自動化、混乱の予測などです。 2026年のガイド。
eCommerce Integrationのその他の記事
コンポーザブル コマース: 2026 年の MACH アーキテクチャ ガイド
2026 年に MACH アーキテクチャを使用したコンポーザブル コマースをマスターします。スケーラブルな e コマースのためのマイクロサービス、API ファースト、クラウドネイティブ、ヘッドレス戦略を学びます。
Odoo eBay コネクタ: 出品、注文、在庫の同期
Odoo 19 用の Odoo eBay コネクタをセットアップします。Odoo から、商品の管理、注文の同期の自動化、在庫の同期、返品の処理、複数店舗の eBay アカウントの管理を行います。
Shopify での返品と交換の管理
Shopify 返品管理の完全ガイド: ポリシーの設計、自動化されたワークフロー、リバース ロジスティックス、交換処理、収益性の高い返品率の削減。
水素を使用したヘッドレス Shopify: 高性能のカスタム ストアフロントを構築
Remix、Storefront API、Oxygen ホスティング、パフォーマンスの最適化をカバーする、Hydrogen フレームワークを使用してヘッドレス Shopify ストアフロントを構築するための完全なガイドです。
マルチチャネル在庫同期: 在庫切れや過剰販売を防止
マルチチャネル在庫同期ガイド。リアルタイム同期方法、安全在庫割り当て、ERP 統合、過剰販売防止、倉庫管理をカバーします。
データ マッピングと変換: さまざまな API とデータ形式の処理
マスター フィールド マッピング、データ正規化、単位変換、通貨処理、および e コマース API とデータ形式にわたるカテゴリ分類マッピング。