यह लेख वर्तमान में केवल अंग्रेज़ी में उपलब्ध है। अनुवाद जल्द आ रहा है।
By the end of this recipe, your Shopify store will sync products, inventory, orders, and customers bidirectionally with Odoo 19 — every Shopify order auto-creates an Odoo sales order with stock allocation, and every Odoo inventory adjustment pushes back to Shopify in under 60 seconds. Skill required: Odoo administrator with Shopify Admin access. Time required: 4 hours setup, 2 hours testing. ECOSIRE has built this for retail clients running 200 to 100,000 orders per month, and the recipe below is the playbook we ship.
The reason DIY Shopify-Odoo integrations break: people sync everything bidirectionally without defining the source of truth per object. Products are usually mastered in Odoo (because pricing rules and BoMs live there), but inventory after a Shopify checkout is mastered in Shopify (because the customer expects "out of stock" updates instantly). Get the directionality wrong and you race-condition yourself into negative inventory.
What you will need
- Odoo version: 17, 18, or 19. The official
shopify_connectorEnterprise module covers v17+; for Community, use the OCAconnector_shopifymodule. - Shopify plan: any tier above Basic (the API rate limits on Lite are too tight for a real shop).
- Shopify Admin API access token: a Custom App with
read_orders,write_orders,read_products,write_products,read_inventory,write_inventory,read_customers,write_customersscopes. - Webhook endpoint: a public URL on your Odoo where Shopify can POST webhooks. If your Odoo is behind a VPN, set up a tunnel (Cloudflare Tunnel, ngrok for testing).
- Time: 4 hours setup, 2 hours testing.
- Decision: which system masters which object?
| Object | Mastered in | Pushed to | Frequency |
|---|---|---|---|
| Product (SKU, title, price) | Odoo | Shopify | On change |
| Inventory (stock levels) | Odoo | Shopify | Every 5 min |
| Order | Shopify | Odoo | Webhook (instant) |
| Customer | Shopify (for new) | Odoo | Webhook |
| Tracking number | Odoo | Shopify | On confirmation |
Step-by-step
1. Create the Shopify Custom App
In Shopify Admin > Apps > Develop apps > Create an app. Name it "Odoo Integration". On the API credentials tab, click "Configure Admin API scopes" and tick the 8 scopes listed above. Click Save and Install. Copy the Admin API access token — it starts with shpat_. You will paste it into Odoo in step 3.
Verification: from the Shopify Admin, run a quick curl test:
curl -H "X-Shopify-Access-Token: shpat_XXXXX" \
https://yourstore.myshopify.com/admin/api/2025-04/shop.json
Returns the shop JSON. If you get 401, regenerate the token.
2. Install the Odoo Shopify connector
In Odoo, go to Apps > search "Shopify". Install shopify_connector (Enterprise) or connector_shopify (OCA Community). The module installs ~15 dependent modules including queue_job for background processing.
Verification: a new menu "Sales > Shopify" appears.
3. Configure the Shopify backend in Odoo
Go to Sales > Shopify > Backends > Create. Fill in:
- Name: My Shop
- Shop URL:
https://yourstore.myshopify.com - API version:
2025-04(use the latest stable Shopify version) - Admin API access token: paste the
shpat_XXXXXfrom step 1 - Default warehouse: pick the warehouse that fulfills Shopify orders
- Default sales team: e.g., "Online Sales"
- Pricelist: "Online Pricelist" (a dedicated pricelist used only for Shopify orders)
- Default product category: "All / Saleable / Online"
Click "Test Connection". You should see "Connection successful". Verification: a green check mark appears next to the backend record.
4. Set up the initial product sync
Click "Import Products" on the backend. Odoo pulls every Shopify product, matches by SKU to existing product.product records, and creates new ones for unmatched SKUs. For a 1,000-product catalog this takes about 3 minutes.
After the import, decide direction: from this moment on, do you edit products in Odoo (push to Shopify) or in Shopify (pull to Odoo)? Configure on the backend record:
# In a small custom module if you want fine-grained control
from odoo import models, api
class ShopifyBackend(models.Model):
_inherit = 'shopify.backend'
@api.model
def _push_product_changes(self, product):
"""Push Odoo product change to Shopify."""
if not self.auto_push_products:
return
product_id = product.shopify_product_id
if not product_id:
return
self._shopify_request('PUT', f'products/{product_id}.json', {
'product': {
'title': product.name,
'body_html': product.description_sale or '',
'vendor': product.product_brand_id.name if product.product_brand_id else '',
'tags': ', '.join(product.product_tag_ids.mapped('name')),
'variants': [{
'sku': product.default_code,
'price': str(product.list_price),
}],
},
})
Verification: edit a product in Odoo, save, and within 5 seconds the change appears in Shopify Admin.
5. Configure webhooks for orders
In Shopify Admin > Settings > Notifications > Webhooks, create webhooks for:
orders/create→https://your-odoo.com/shopify/webhook/orders/createorders/updated→https://your-odoo.com/shopify/webhook/orders/updatedorders/cancelled→https://your-odoo.com/shopify/webhook/orders/cancelledorders/paid→https://your-odoo.com/shopify/webhook/orders/paidcustomers/create→https://your-odoo.com/shopify/webhook/customers/create
Format = JSON. Webhook secret = shared secret (paste into Odoo backend > Webhook Secret field). Shopify signs every webhook with this secret; Odoo verifies via HMAC-SHA256.
# Webhook controller (ships with the connector but you may need to extend)
from odoo import http
from odoo.http import request
import hashlib
import hmac
import base64
class ShopifyWebhookController(http.Controller):
@http.route('/shopify/webhook/orders/create', auth='public', csrf=False, methods=['POST'])
def orders_create(self, **kwargs):
secret = request.env['shopify.backend'].sudo().search([], limit=1).webhook_secret
body = request.httprequest.get_data()
received = request.httprequest.headers.get('X-Shopify-Hmac-Sha256')
digest = base64.b64encode(hmac.new(secret.encode(), body, hashlib.sha256).digest()).decode()
if not hmac.compare_digest(digest, received):
return request.make_response('Invalid signature', status=401)
# Queue the import as a background job
request.env['shopify.backend'].sudo().with_delay()._import_order(request.jsonrequest)
return request.make_response('OK', status=200)
Verification: place a test order on Shopify (use a test gateway like Bogus). Within 5 seconds, an sale.order appears in Odoo with the Shopify reference.
6. Configure inventory push
Go to the backend > Inventory tab. Set "Push interval" to 5 minutes. Odoo will push the qty_available of each variant to the corresponding Shopify inventory level. Add a fail-safe: if Odoo's qty for a SKU drops below the configured "Safety stock", push 0 to Shopify (don't oversell).
@api.model
def _cron_push_inventory(self):
backends = self.search([('active', '=', True)])
for backend in backends:
for product in self.env['product.product'].search([
('shopify_inventory_item_id', '!=', False),
('type', '=', 'product'),
]):
qty = max(0, product.qty_available - product.shopify_safety_stock)
backend._shopify_request('POST', 'inventory_levels/set.json', {
'inventory_item_id': product.shopify_inventory_item_id,
'location_id': backend.shopify_location_id,
'available': int(qty),
})
Verification: validate a stock picking that takes 5 units off a SKU, wait 5 minutes, and check Shopify Admin — the SKU's available qty has dropped by 5.
7. Push tracking numbers back to Shopify
When the Odoo Delivery picking is validated and gets a carrier tracking number, push it to Shopify so the customer sees it on their order page:
@api.model
def _push_fulfillment(self, picking):
backend = picking.sale_id.shopify_backend_id
order_id = picking.sale_id.shopify_order_id
backend._shopify_request('POST', f'orders/{order_id}/fulfillments.json', {
'fulfillment': {
'tracking_number': picking.carrier_tracking_ref,
'tracking_company': picking.carrier_id.name,
'notify_customer': True,
},
})
Verification: validate a Delivery in Odoo with a tracking number. Check the Shopify Admin order — fulfillment shows up with tracking, and the customer gets the standard Shopify "Your order is on its way" email.
8. Handle conflicts and edge cases
Build a "Sync Issues" dashboard showing failed jobs from queue.job. Common issues: SKU on Shopify that doesn't exist in Odoo, currency mismatch, address country code mismatch (US vs USA). Set up a daily Slack alert on jobs in failed state.
Verification: induce a failure (e.g., delete a product in Odoo without removing it from Shopify, then place an order for it). The job appears in the dashboard with a clear error message.
Common mistakes
- Bidirectional product sync without a source of truth. Edit a price in Shopify and Odoo, race condition picks one — usually the wrong one. Pick one master per field.
- Skipping webhook HMAC verification. Anyone can POST to your endpoint and create fake orders. Always verify the signature.
- Pushing inventory without safety stock. Real-world e-commerce sells the same unit twice if you push your full Odoo qty. Reserve 1 to 5 percent.
- Ignoring Shopify rate limits. Default is 2 calls per second on Basic, 4 on Plus. Burst over and Shopify returns 429. Always use the queue with backoff.
- Currency mismatches. Shopify multi-currency uses
presentment_currency; Odoo usescurrency_id. Map them explicitly.
Going further
Multi-store / multi-channel: each Shopify store gets its own backend record. A single Odoo can sync 10+ stores if you configure each backend with a distinct sales team and warehouse.
B2B + B2C in one Odoo: tag B2B orders by Shopify customer tag and route them to a different sales team with different payment terms. The connector supports per-tag automation rules.
Shopify POS sync: orders from a physical Shopify POS terminal flow through the same webhook pipeline. Tag them by source_name = pos to apply different fulfillment rules.
Recurring subscriptions: if you use a Shopify subscriptions app (ReCharge, Bold), each renewal creates a new order. Configure the connector to recognize renewal orders and link them to the original Odoo subscription record.
For full Shopify-Odoo integration including custom field mapping, multi-warehouse fulfillment, and B2B price gating, ECOSIRE Shopify implementation ships fully configured connectors. Pair this with how to connect Stripe to Odoo Payments for the payment side.
Frequently Asked Questions
Can I sync historical orders from before the integration went live?
Yes. The connector has a "Backfill Orders" wizard that imports orders by date range. Be aware: importing 50,000 historical orders takes 2 to 4 hours and creates that many sale.order records, which can affect Odoo report performance.
What about refunds and cancellations?
Configure the orders/cancelled and refunds/create webhooks. The connector creates a return picking + credit note in Odoo automatically. Test with a real test refund before going live.
How do I handle Shopify customers without email?
Shopify allows phone-only customers (especially in APAC). Configure the connector to use phone as the matching field instead of email if your store has phone-only checkouts.
Does this work with Shopify Plus?
Yes. Plus adds higher rate limits (4 calls/sec base, 200/sec for bulk operations) and the GraphQL Bulk Operations API for very large catalogs. The connector takes advantage of bulk ops when it detects Plus.
For complex integrations including multi-store, B2B, and headless storefronts, ECOSIRE Shopify Plus services handle the full implementation. Or read how to integrate Power BI with Odoo for unified analytics across Shopify and Odoo data.
लेखक
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.
ECOSIRE
Odoo ERP के साथ अपना व्यवसाय बदलें
आपके संचालन को सुव्यवस्थित करने के लिए विशेषज्ञ ओडू कार्यान्वयन, अनुकूलन और समर्थन।
संबंधित लेख
How to Add a Custom Button to an Odoo Form View (2026)
Add custom action buttons to Odoo 19 form views: Python action method, view inheritance, conditional visibility, confirmation dialogs. Production-tested.
How to Add a Custom Field in Odoo Without Studio (2026)
Add custom fields via custom module in Odoo 19: model inheritance, view extension, computed fields, store/non-store decisions. Code-first, version-controlled.
How to Add a Custom Report in Odoo Using External Layout
Build a branded PDF report in Odoo 19 using web.external_layout: QWeb template, paperformat, action binding. With print logo + footer overrides.