如何為 SiteChat 上傳您的商品目錄
如果您是在自己的網站上使用 SiteChat(而非 Shopify 商店),您可以將結構化的商品記錄傳送到 Shoply,讓購物者能在 SiteChat 聊天與商品搜尋中找到這些商品。
這些端點使用與其餘 Shoply Merchant API 相同的 Settings → Store owner API secret,而 SiteChat 管理後台的 Product Catalog 頁面也可以使用您已登入的管理員存取權杖來呼叫這些端點。Shopify 商店仍會透過 Shopify 同步商品目錄資料;這些上傳路由僅提供給尚未同步 Magento 商品目錄的 SiteChat 帳戶使用。
在 SiteChat 管理後台中,Product Catalog 會開啟一個類似 Shopify 的區域,包含 Products、Collections 與 Inventory。您可以新增或編輯商品、匯入 CSV/Excel、將商品分組到手動集合,以及調整庫存數量。
可使用哪些 API?
| API | Method | 功能說明 |
|---|---|---|
/merchant/products/batch | POST | 在一次請求中建立或完整取代最多 50 項商品 |
/merchant/products | POST | 建立或完整取代單一商品 |
/merchant/products | GET | 依 source 與 external_id 讀取單一已匯入商品 |
/merchant/products | PATCH | 部分更新單一商品;若要取代 variants 或 metafields,必須提供來自 GET 的版本 |
/merchant/products | DELETE | 將商品軟封存(status=archived) |
/merchant/products/list | GET | 分頁瀏覽已匯入商品,供管理後台表格使用 |
/merchant/products/images | POST | 上傳商品圖片並取得公開 HTTPS URL |
/merchant/collections | GET / POST | 列出或建立手動集合 |
/merchant/collections/{id} | GET / PUT / DELETE | 讀取、取代或封存單一集合 |
/merchant/inventory | GET | 列出庫存資料列(商品與變體數量) |
/merchant/inventory/adjust | POST | 設定商品或變體的追蹤數量 |
商品成功儲存後,Shoply 會要求重建商店索引。在重建完成前,回應會顯示 index_status: "pending"。已發佈的商品之後會同時出現在商品索引,以及 SiteChat 聊天所使用的知識內容中。
誰可以使用這些 API?
- 您的商店必須是 SiteChat 帳戶(
app_platform為 SiteChat)。 - Shopify 商店金鑰(包含任何
*.myshopify.com網域)會被拒絕。 - 驗證必須使用有效的店主 API 密鑰,或是與請求中
store_key完全相符的 SiteChat 管理員存取權杖。 - Shopify Admin API 權杖無法呼叫這些路由。
建立或輪替 owner secret 的方式,與其他 Merchant API 整合相同:如何使用 Shoply Merchant API。在 SiteChat 管理控制台中,開啟 Product Catalog 即可管理商品、集合與庫存,或匯入 CSV / Excel 檔案,而無需自行管理密鑰。
驗證是如何運作的?
來自伺服器連接器
請從受信任的後端透過 HTTPS 呼叫 API。將 JSON 字串放入 Authorization 標頭:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"store_owner_api_secrete": "YOUR_STORE_OWNER_API_SECRET"
}store_owner_api_secrete 是公開欄位名稱,包含其歷史拼字。store_owner_api_secret 也同樣可接受。這不是 Bearer 權杖。
來自 SiteChat 管理後台
Product Catalog 頁面則會改為傳送您已登入的管理員工作階段:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN"
}access_token 可作為 admin_auth_token 的別名使用。
store_key 查詢參數必須與標頭相符。請僅將 owner secrets 保存在伺服器端環境變數中,絕不要放在店面腳本、URL 或公開儲存庫中。
export SHOPLY_STORE_KEY="your-sitechat-store-key"
export SHOPLY_STORE_OWNER_API_SECRETE="shoply_owner_key_example123.secret-value"我要如何上傳商品?
POST https://api.shoplyai.ai/merchant/products/batch?store_key=YOUR_SITECHAT_STORE_KEY
{
"source": "woocommerce-main",
"products": [
{
"external_id": "123",
"title": "Trail shoes",
"description": "Water-resistant hiking shoes.",
"url": "https://example.com/products/trail-shoes",
"currency": "USD",
"price": "49.95",
"original_price": "59.95",
"available": true,
"status": "published",
"images": ["https://example.com/images/trail-shoes.jpg"],
"categories": ["Footwear"],
"metafields": {"material": "Leather"},
"variants": [
{
"external_id": "124",
"title": "Brown / 42",
"sku": "TRAIL-BR-42",
"price": "49.95",
"available": true,
"metafields": {"color": "Brown", "size": "42"}
}
]
}
]
}必填欄位與規則
- 商品必填欄位:
external_id、title、url、currency、price與available。status預設為published。 - 選用庫存:在商品或變體上將
tracks_inventory設為true,並設定非負數的quantity。之後 Shoply 會依庫存推導可售狀態(quantity > 0),並儲存total_inventory供管理列表使用。 source用於命名商品目錄連線(不一定是平台)。請使用穩定名稱,例如woocommerce-main。允許字元:小寫英文字母、數字、底線與連字號;最長 64 個字元。於管理後台表單建立的商品,預設 source 為admin。- 商品識別方式是商店、source 與 external ID 的組合。批次與單筆
POSTupsert 都是完整取代,不是 patch:省略的選填欄位會被清除。若要部分更新,請使用PATCH。 - 批次需包含 1–50 項商品,且請求大小最多 2,000,000 位元組。每項商品驗證後的 JSON 上限為 128,000 位元組,最多可有 250 個 variants。
- 價格建議使用十進位字串。幣別必須是三碼大寫代碼。
- 商品與圖片 URL 必須是 HTTP(S)。匯入不會替您抓取那些 URL。
- 可搜尋的商品規格請使用公開
metafields(相當於 SiteChat 版的 Shopify 商品 metafields)。值必須是純字串。舊版attributes可作為別名使用。私有商品metadata已不再支援。 draft與archived商品不會納入下一次已發佈索引。已發佈但售罄的商品仍會保留在索引中,並附帶可售狀態。- 手動集合會儲存標題、描述、狀態,以及商品隸屬清單(
source+external_id)。目前版本不支援智慧/規則型集合。
成功回應範例
{
"results": [
{
"external_id": "123",
"product_id": "sitechat_product::woocommerce-main::<sha256-of-external-id>",
"status": "stored"
}
],
"index_status": "pending",
"index_revision": 1
}Shoply 會在寫入前先驗證整個請求。即使 HTTP 200,仍可能列出部分 failed 結果並附上 error: "storage_error"。請檢查每一筆結果,並重試失敗的商品。如果 index_status 是 request_failed,表示儲存成功但未排入索引作業,也請一併重試那些已儲存的商品。
Python 範例
import json
import os
import requests
store_key = os.environ["SHOPLY_STORE_KEY"]
headers = {
"Authorization": json.dumps({
"store_key": store_key,
"store_owner_api_secrete": os.environ["SHOPLY_STORE_OWNER_API_SECRETE"],
})
}
response = requests.post(
"https://api.shoplyai.ai/merchant/products/batch",
params={"store_key": store_key},
headers=headers,
json={
"source": "custom",
"products": [{
"external_id": "123",
"title": "Trail shoes",
"url": "https://example.com/products/trail-shoes",
"currency": "USD",
"price": "49.95",
"available": True,
}],
},
timeout=60,
)
response.raise_for_status()
result = response.json()
failed = [item["external_id"] for item in result["results"] if item["status"] != "stored"]
if failed:
raise RuntimeError(f"Products need retry: {failed}")
if result["index_status"] == "request_failed":
raise RuntimeError("Products saved, but retry the batch to request indexing")我要如何驗證已匯入的商品?
GET https://api.shoplyai.ai/merchant/products?store_key=YOUR_SITECHAT_STORE_KEY&source=woocommerce-main&external_id=123
請使用相同的 Authorization 標頭。回應會包含 schema_version、updated_at、index_status 與正規化後的 product。若找不到記錄,會回傳 HTTP 404。
在背景索引器發佈重建結果後,單筆商品讀取狀態會變為 indexed、excluded(適用於 draft 或 archived 商品),或 limit_exceeded。管理後台列表請使用 GET /merchant/products/list。若要讓商品不出現在下一次已發佈索引中,可透過 DELETE /merchant/products 進行軟封存(或將 status 設為 archived / draft);目前版本不提供硬刪除。
record = requests.get(
"https://api.shoplyai.ai/merchant/products",
params={
"store_key": store_key,
"source": "woocommerce-main",
"external_id": "123",
},
headers=headers,
timeout=30,
)
record.raise_for_status()
print(record.json()["index_status"], record.json()["product"]["title"])我要如何安全地更新 Variants 或 Metafields?
如果 PATCH 內容包含 variants、metafields 或舊版 attributes 欄位,請先用 GET 讀取商品。根據該回應建立修改內容,並在 PATCH request body 中加入其最上層 updated_at 值作為 expected_updated_at。即使是要清空 variants 或 metafields,也同樣適用。
current_response = requests.get(
"https://api.shoplyai.ai/merchant/products",
params={"store_key": store_key, "source": "woocommerce-main", "external_id": "123"},
headers=headers,
timeout=30,
)
current_response.raise_for_status()
current = current_response.json()
updated_metafields = {**current["product"].get("metafields", {}), "material": "Leather"}
response = requests.patch(
"https://api.shoplyai.ai/merchant/products",
params={"store_key": store_key},
headers=headers,
json={
"source": "woocommerce-main",
"external_id": "123",
"expected_updated_at": current["updated_at"],
"metafields": updated_metafields,
},
timeout=30,
)
response.raise_for_status()HTTP 409 表示缺少版本資訊,或有其他更新已更動該商品。請先讀取最新商品,再重新合併您要進行的變更後重試。不要把新的版本資訊附加到舊的 variants 清單上:那樣可能會覆寫較新的庫存值。
既有整合若在沒有版本資訊的情況下 PATCH 這些欄位,必須更新。僅更新純量欄位的 PATCH 請求、專用庫存調整,以及透過 POST 或批次匯入進行的完整取代,則不需要此欄位。不過完整取代仍會取代整個商品。
我可以上傳商品圖片嗎?
可以。如果圖片已經存在於可長期存取的公開 HTTPS URL,請將該 URL 放入商品的 images 清單或變體的 image 欄位。公開的 S3 HTTPS URL 可以使用;原始 s3:// 路徑與短效簽名 URL 則不行。
若要由 Shoply 代管檔案,請從您的後端上傳原始圖片位元組:
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY
Content-Type: image/png請傳送原始檔案位元組,而不是 JSON、base64 或 multipart form data。接受 JPEG、PNG 與 WebP,大小上限為 10 MiB 與 2,000 萬像素。不支援動態圖片。Shoply 會將圖片轉換為 WebP,並移除內嵌中繼資料。
with open("trail-shoes.png", "rb") as image_file:
response = requests.post(
"https://api.shoplyai.ai/merchant/products/images",
params={"store_key": store_key},
headers={**headers, "Content-Type": "image/png"},
data=image_file,
timeout=60,
)
response.raise_for_status()
image_url = response.json()["url"]HTTP 201 會回傳 url、content_type、size_bytes、width 與 height。單獨上傳圖片不會將其附加到商品,也不會觸發索引。請將回傳的 URL 放入完整商品資料中,並再次透過 /merchant/products/batch 提交。
同一張圖片若在同一帳戶下再次上傳,會重用其 URL。若圖片內容有變更,則會取得新的 URL。目前版本不提供圖片刪除端點。
商品何時會出現在聊天與搜尋中?
批次儲存成功後,Shoply 會要求背景重建索引。在工作程序發佈新索引之前,回應都會顯示 index_status: "pending"。目前沒有固定的完成時間保證。
- 已發佈商品會同時進入商品搜尋,以及 SiteChat 聊天所使用的知識內容。
- Draft 與 archived 商品會在下一次重建時被排除。
- 如果未排入索引作業(
index_status: "request_failed"),請針對那些其實已成功儲存的商品重試該批次。
我應該預期哪些錯誤?
| HTTP status | 含義 |
|---|---|
403 | 缺少、無效、已過期或已撤銷的密鑰;錯誤的商店;或非 SiteChat 帳戶 |
404 | 請求的已匯入商品不存在 |
413 | 請求或圖片超過大小限制 |
415 | 圖片上傳使用了不支援的 Content-Type |
422 | 欄位無效、ID 重複、圖片為動態或過大,或超出模型限制 |
503 | 暫時性儲存失敗 |
密鑰會在 90 天 後到期。請在到期前於 Settings → Store owner API secret 建立替代密鑰,並撤銷任何不再需要的密鑰。同一組密鑰也可呼叫 Merchant API 指南 中記載的分析、對話與知識端點。
如果您需要整合協助,請聯絡 Shoply AI。
