昨天德華在會議上,用 Odoo CRM 把 pipeline 打開,老闆終於能看到哪些客戶快簽、哪些還在觀望。
但下一句問題,卻讓德華心裡一沉:
「這些名單,是從哪裡來的?」
小李(倉庫)說:前台商品明明缺貨,卻還在賣。
小王(財務)說:電商的稅額和運費,月底還得自己補。
德華(業務)說:有些客戶填了官網表單,CRM 根本沒看到。
CRM pipeline 再漂亮,如果「名單進不來」,就只是空轉。
📌 市場數據顯示:
WooCommerce 以約 39% 市占居全球第一,Shopify 也有 10%,在美國甚至佔到 30%。
在台灣,WooCommerce 約 7,700 家(20.3%),Shopify 約 2,500 家(6.7%)。
雖然兩者在台灣的市佔率都低於 SHOPLINE,但因為其跨境友善、國際常用,已成為中小企業的主要跨境電商選擇。
方式 | 特點 | 成本 | 工時 |
---|---|---|---|
官方 Shopify Connector | 穩定、功能完整 | 高 | 低 |
OCA 社群模組 | 免費、可擴充 | 低 | 中 |
API 自建 | 完全客製、彈性高 | 中 | 高 |
┌──────────────────────────────┐
│ Shopify / Woo │
│ (E-commerce Frontend) │
└────────────────────┬─────────┘
│ 一、商品/庫存同步
▼
┌──────────────────────────────┐
│ Odoo ERP │
│ (Product / Orders / AR) │
└────────────────────┬─────────┘
│ 二、訂單/稅務回填
▼
┌──────────────────────────────┐
│ Odoo CRM │
│ (Leads / Opportunities) │
└────────────────────▲─────────┘
│ 三、顧客資料回寫CRM
⚠️ 注意事項
多平台同步時,建議在 Odoo 設定「安全庫存量」,避免 Shopify/Woo 前端顯示可售數量過高,
導致熱銷商品超賣,影響客戶體驗與品牌信任。
問題:前台價格和庫存顯示不一致,導致下錯單、退貨率高。
解法:以 Odoo 為主檔,商品、價格、庫存改一次,前台自動更新。
📌 驗收方法
問題:電商的訂單進不來 Odoo,財務月底還要人工補帳。
解法:平台訂單 → Odoo 自動生成銷售單,金額、稅費、運費全部正確。
💻 技術示範:Shopify 訂單轉 Odoo 銷售單
# Shopify 訂單 → Odoo 銷售單(示意)
order = shopify.Order.find(order_id) # 若是 REST JSON,取值方式改用 dict.get()
Partner = env['res.partner']
SaleOrder = env['sale.order']
Product = env['product.product']
# 1) 去重:以 Shopify 訂單編號做外部參考
client_ref = getattr(order, 'name', None) or getattr(order, 'order_number', None)
existing = SaleOrder.search([('client_order_ref', '=', client_ref)], limit=1)
if existing:
so = existing
else:
# 2) 對應/建立客戶
email = getattr(order, 'email', None)
cust = getattr(order, 'customer', None)
full_name = f"{getattr(cust, 'first_name', '')} {getattr(cust, 'last_name', '')}".strip() if cust else ''
partner = Partner.search(['|', ('email', '=ilike', email), ('email_formatted', '=ilike', email)], limit=1) if email else False
if not partner:
partner = Partner.create({'name': full_name or email or 'Shopify Customer', 'email': email})
# 3) 準備訂單行
lines = []
for li in (getattr(order, 'line_items', None) or []):
sku = getattr(li, 'sku', None)
qty = float(getattr(li, 'quantity', 0) or 0)
price = float(getattr(li, 'price', 0.0) or 0.0)
barcode = getattr(li, 'barcode', None)
variant_id = getattr(li, 'variant_id', None)
# 以 SKU 優先對到 product;無 SKU 時以條碼或自訂映射(variant_id)備援
product = False
if sku:
product = Product.search([('default_code', '=', sku)], limit=1)
if not product and barcode:
product = Product.search([('barcode', '=', barcode)], limit=1)
if not product and variant_id:
product = Product.search([('x_shopify_variant_id', '=', str(variant_id))], limit=1)
if not product:
continue # 規範:可改為自動建商品的策略
lines.append((0, 0, {
'product_id': product.id,
'product_uom_qty': qty,
'price_unit': price,
# 稅由產品稅/公司稅制自動計算(不手填 amount_tax)
}))
# 4) 運費:累加 shipping_lines,作為「運費商品」新增一行(不手填 amount_delivery)
shipping_total = 0.0
for s in (getattr(order, 'shipping_lines', None) or []):
try:
shipping_total += float(getattr(s, 'price', 0) or 0.0)
except Exception:
pass
if shipping_total:
delivery_product = env.ref('delivery.product_product_delivery', raise_if_not_found=False) \
or Product.search([('name', 'ilike', 'Shipping')], limit=1)
if delivery_product:
lines.append((0, 0, {
'product_id': delivery_product.id,
'product_uom_qty': 1.0,
'price_unit': shipping_total,
}))
# 5) 建立 SO(總額/稅額由 Odoo 自動計算)
so = SaleOrder.create({
'partner_id': partner.id,
'client_order_ref': client_ref,
'order_line': lines,
})
# (可選)標記來源,便於 CRM/報表
# so.write({'x_source': 'shopify'})
📌 驗收方法
sale.order
問題:客戶買過東西,但 CRM 沒紀錄,業務無法追蹤。
解法:訂單顧客 → Odoo res.partner
,自動建檔或合併,並生成 crm.lead
。
📌 驗收方法
res.partner
,帶 Email、電話有了這三條集成,德華的 pipeline 不再「看得到、吃不到」。
小李的庫存正確了,小王的月底不再補帳,德華也能在 CRM 追到電商客戶。
不過,就算前端打通,德華每天依舊要在信件堆裡掙扎:
詢價、垃圾信、重複郵件,一不小心半天就耗在收件匣裡。
👉 下一篇(Day 14),我們就看德華如何解開這場「Email 困局」。