איך להעלות את הקטלוג שלך עבור SiteChat
אם אתם משתמשים ב-SiteChat באתר האינטרנט שלכם (ולא בחנות Shopify), תוכלו לשלוח רשומות מוצרים מובנות ל-Shoply כדי שלקוחות יוכלו למצוא אותן בצ’אט של SiteChat ובחיפוש מוצרים.
נקודות הקצה האלה משתמשות באותו Settings → Store owner API secret כמו שאר Shoply Merchant API, ועמוד Product Catalog בממשק הניהול של SiteChat יכול לקרוא להן באמצעות אסימון הגישה של מנהל המחובר למערכת. חנויות Shopify ממשיכות לסנכרן נתוני קטלוג דרך Shopify; מסלולי ההעלאה האלה זמינים רק לחשבונות SiteChat שאינם מסנכרנים כבר קטלוג Magento.
בממשק הניהול של 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 | עדכון חלקי של מוצר אחד; החלפת וריאנטים או metafields מחייבת את הגרסה מ-GET |
/merchant/products | DELETE | ארכוב רך של מוצר (status=archived) |
/merchant/products/list | GET | דפדוף בין מוצרים מיובאים עבור טבלאות ניהול |
/merchant/products/images | POST | העלאת תמונת מוצר וקבלת URL ציבורי ב-HTTPS |
/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 תקף של בעל החנות או באסימון גישה של מנהל SiteChat עבור ה-
store_keyהמדויק שבבקשה. - אסימוני Shopify Admin API אינם יכולים לקרוא למסלולים האלה.
צרו או החליפו את סוד הבעלים באותה דרך כמו אינטגרציות אחרות של Merchant API: How to Use the Shoply Merchant API. במסוף הניהול של SiteChat, פתחו את Product Catalog כדי לנהל מוצרים, אוספים ומלאי — או לייבא קובץ CSV או Excel — בלי לנהל את הסוד בעצמכם.
איך האימות עובד?
ממחבר שרת
קראו ל-API מ-backend מהימן דרך HTTPS. שימו מחרוזת 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 חייב להתאים לכותרת. שמרו סודות בעלים רק במשתני סביבה בצד השרת — לעולם לא בסקריפט storefront, ב-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 תווים. מוצרים שנוצרים דרך טפסים בממשק הניהול מקבלים כברירת מחדל את sourceadmin.- זהות מוצר היא השילוב של חנות, source ומזהה חיצוני. פעולות upsert של
POSTבודד או באצווה הן החלפות מלאות, לא תיקונים: שדות אופציונליים שמושמטים ינוקו. השתמשו ב-PATCHלעדכונים חלקיים. - אצוות מכילות 1–50 מוצרים ולכל היותר 2,000,000 בתים בבקשה. ה-JSON המאומת של כל מוצר מוגבל ל-128,000 בתים, עם לכל היותר 250 וריאנטים.
- העדיפו מחרוזות עשרוניות למחירים. המטבע הוא קוד בן שלוש אותיות גדולות.
- כתובות URL של מוצרים ותמונות חייבות להיות HTTP(S). הייבוא לא מושך עבורכם את ה-URL-ים האלה.
- השתמשו ב-
metafieldsציבוריים עבור מפרטי מוצרים הניתנים לחיפוש (המקבילה של SiteChat ל-metafields של מוצרים ב-Shopify). הערכים חייבים להיות מחרוזות פשוטות.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.
אחרי שה-indexer ברקע מפרסם בנייה מחדש, סטטוס הקריאה החוזרת לכל מוצר הופך ל-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"])איך אני מעדכן בבטחה וריאנטים או Metafields?
עבור PATCH שמכיל variants, metafields או את השדה הישן attributes, קראו קודם את המוצר באמצעות GET. בנו את העריכה מתוך התגובה הזו וכללו את הערך העליון של updated_at שלה בתור expected_updated_at בגוף ה-PATCH. זה חל גם כאשר מנקים וריאנטים או 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 פירושו שהגרסה הייתה חסרה או שעדכון אחר שינה את המוצר. קראו את המוצר העדכני ביותר ומזגו שוב את השינויים הרצויים שלכם לפני ניסיון חוזר. אל תחברו גרסה חדשה לרשימת וריאנטים ישנה: זה עלול לדרוס ערכי מלאי חדשים יותר.
אינטגרציות קיימות שמבצעות PATCH לשדות האלה בלי גרסה חייבות להתעדכן. בקשות PATCH של שדות סקלריים בלבד, התאמות מלאי ייעודיות והחלפות מלאות דרך POST או ייבוא אצווה אינם דורשים את השדה הזה. החלפות מלאות עדיין מחליפות את כל המוצר.
האם אפשר להעלות תמונות מוצר?
כן. אם תמונה כבר זמינה ב-URL ציבורי קבוע ב-HTTPS, שימו את ה-URL הזה ברשימת images של המוצר או בשדה image של וריאנט. כתובות HTTPS ציבוריות של S3 עובדות. נתיבי s3:// גולמיים וכתובות URL חתומות קצרות-חיים אינם עובדים.
כדי ש-Shoply תארח את הקובץ, העלו בתים גולמיים של התמונה מה-backend שלכם:
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 ו-20 מיליון פיקסלים. תמונות מונפשות אינן נתמכות. Shoply ממירה את התמונה ל-WebP ומסירה metadata מוטמע.
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" עד שה-worker מפרסם את האינדקס החדש. אין הבטחת זמן השלמה קבועה.
- מוצרים שפורסמו נכנסים גם לחיפוש המוצרים וגם לידע שבו משתמש צ’אט SiteChat.
- מוצרים במצב draft ו-archived מוחרגים בבנייה מחדש הבאה.
- אם האינדוקס לא תוזמן (
index_status: "request_failed"), נסו שוב את האצווה עבור המוצרים שכבר נשמרו בהצלחה.
אילו שגיאות כדאי לצפות?
| HTTP status | משמעות |
|---|---|
403 | סוד חסר, לא תקף, שפג תוקפו או שבוטל; חנות שגויה; או חשבון שאינו SiteChat |
404 | המוצר המיובא המבוקש אינו קיים |
413 | הבקשה או התמונה חורגות ממגבלת הגודל |
415 | העלאת התמונה השתמשה ב-Content-Type שאינו נתמך |
422 | שדות לא תקינים, מזהים כפולים, תמונות מונפשות או גדולות מדי, או חריגה ממגבלות המודל |
503 | כשל אחסון זמני |
סודות פגים לאחר 90 ימים. צרו סוד חלופי ב-Settings → Store owner API secret לפני הפקיעה, ובטלו כל סוד שכבר אינכם צריכים. אותו סוד יכול גם לקרוא לנקודות קצה של אנליטיקה, שיחות וידע המתועדות ב-Merchant API guide.
לעזרה עם אינטגרציה, צרו קשר עם Shoply AI.
