מוצרים באתר שלך מציגים רמות מלאי שגויות, מנהלים מעדכנים מחירים ב-MoySklad אך הם לא משתקפים באתר. יש להזין הזמנות ידנית—מה שמוביל לשגיאות משלוח של 20–30% ולאובדן לקוחות. סנכרון דו-כיווני פותר זאת: מוצרים, מלאי, הזמנות וסטטוסים מתעדכנים אוטומטית. התוצאה היא נתונים מדויקים גם באתר וגם ב-MoySklad ללא מאמץ ידני מצידך. חיסכון בהזנת נתונים ידנית יכול להגיע ל-$1.8k–2.6k בשנה.
אילו בעיות פותר סנכרון דו-כיווני?
אי-התאמות במלאי הן נקודת הכאב הנפוצה ביותר. לקוח רואה מוצר במלאי, אבל הוא כבר אזל, או להיפך. הסנכרון שלנו מעדכן מלאי כל 5 דקות, ומפחית שגיאות משלוח ב-80% בהשוואה לניהול ידני. הבעיה השנייה היא העברת הזמנות ידנית. עובדים מבזבזים עד שעתיים ביום על שכפול מידע. סנכרון דו-כיווני יוצר אוטומטית הזמנה ב-MoySklad כאשר היא מוזמנת באתר ומעדכן את הסטטוס בעת המשלוח. הבעיה השלישית היא התנגשויות נתונים. אם מחיר משתנה בו-זמנית בשתי המערכות, אנו מיישמים כלל ברור של מקור אמת: מחירים ומלאי מ-MoySklad, SEO ותמונות מהאתר.
כיצד אנו מיישמים את האינטגרציה
ארכיטקטורה וטכנולוגיות
אנו משתמשים ב-MoySklad REST API גרסה 1.2, PHP 8.3 עם framework Laravel 11 ותורים דרך Redis. אימות מתבצע באמצעות Bearer token. כל הבקשות עוברות דרך HTTP client עם לוגיקת ניסיון חוזר בשגיאות. Webhooks מוגדרים לאירועי שינוי הזמנות כך שהסטטוסים מתעדכנים מיידית. הארכיטקטורה מתחשבת בשאילתות N+1 ומשתמשת בטעינת נתונים בקבוצות (batch של 100 פריטים).
לפי התיעוד הרשמי של MoySklad API, זה מבטיח אינטגרציה אמינה.
דוגמה למימוש לקוח API
class MoiSkladClient {
private string $baseUrl = 'https://api.moysklad.ru/api/remap/1.2';
private function headers(): array {
return [
'Authorization' => 'Bearer ' . config('services.moysklad.token'),
'Content-Type' => 'application/json;charset=utf-8',
'Accept-Encoding' => 'gzip',
];
}
public function get(string $path, array $params = []): array {
return Http::withHeaders($this->headers())
->get("{$this->baseUrl}/{$path}", $params)
->throw()
->json();
}
public function post(string $path, array $data): array {
return Http::withHeaders($this->headers())
->post("{$this->baseUrl}/{$path}", $data)
->throw()
->json();
}
} | ישות | מקור אמת | הערות |
|---|---|---|
| מוצרים (שם, תיאור, מחיר) | MoySklad | מנהלים עורכים שם |
| מלאי | MoySklad | מתעדכן בקבלה/מכירה |
| תמונות מוצר | אתר | מועלות דרך CMS |
| שדות SEO (meta, slug) | אתר | לא קיימים ב-MS |
| הזמנות | אתר → MS | נוצרות באתר, נשלחות ל-MS |
| סטטוסי הזמנות | MS → אתר | מנהל משנה ב-MS |
שליפת מוצרים ומלאי
class ProductSyncService {
public function fetchProducts(int $offset = 0, int $limit = 100): array {
return $this->ms->get('entity/product', [
'offset' => $offset,
'limit' => $limit,
'expand' => 'productFolder,images',
'filter' => 'archived=false',
]);
}
public function fetchStocks(): array {
return $this->ms->get('report/stock/all/current', [
'stockType' => 'stock',
'includeRelated' => false,
]);
}
public function syncToSite(): void {
$offset = 0;
$limit = 100;
do {
$response = $this->fetchProducts($offset, $limit);
$products = $response['rows'];
foreach ($products as $msProduct) {
$this->upsertProduct($msProduct);
}
$offset += $limit;
} while ($offset < $response['meta']['size']);
$stocks = $this->fetchStocks();
foreach ($stocks as $stock) {
Product::whereExternalId($stock['assortmentId'])
->update(['stock' => max(0, (int)$stock['stock'])]);
}
}
private function upsertProduct(array $msProduct): void {
$msId = $msProduct['id'];
$data = [
'external_id' => $msId,
'name' => $msProduct['name'],
'article' => $msProduct['article'] ?? null,
'price' => $this->parsePrice($msProduct['salePrices'][0]['value'] ?? 0),
'description' => $msProduct['description'] ?? '',
'ms_updated_at' => Carbon::parse($msProduct['updated']),
];
$product = Product::updateOrCreate(['external_id' => $msId], $data);
}
private function parsePrice(int $msPrice): float {
return $msPrice / 100;
}
} העברת הזמנות ו-webhooks
public function pushOrder(Order $order): string
{
$positions = [];
foreach ($order->items as $item) {
$positions[] = [
'assortment' => [
'meta' => [
'href' => "{$this->baseUrl}/entity/product/{$item->product->external_id}",
'type' => 'product',
],
],
'quantity' => $item->quantity,
'price' => $item->price * 100,
];
}
$msOrder = $this->ms->post('entity/customerorder', [
'name' => "Заказ #{$order->id}",
'organization' => [
'meta' => [
'href' => "{$this->baseUrl}/entity/organization/" . config('services.moysklad.org_id'),
'type' => 'organization',
],
],
'agent' => $this->getOrCreateCounterparty($order->customer),
'positions' => $positions,
'description' => "Источник: сайт\nEmail: {$order->customer->email}",
'attributes' => [
[
'meta' => ['href' => $this->orderIdAttributeHref()],
'value' => (string)$order->id,
],
],
]);
$order->update(['ms_order_id' => $msOrder['id']]);
return $msOrder['id'];
}כאשר הזמנה משתנה ב-MoySklad, ה-webhook מודיע לשרת שלנו והסטטוס מתעדכן אוטומטית באתר:
public function handleMsWebhook(Request $request): Response
{
$events = $request->json('events', []);
foreach ($events as $event) {
if ($event['meta']['type'] === 'customerorder') {
$msOrderId = basename($event['meta']['href']);
SyncOrderStatusJob::dispatch($msOrderId);
}
}
return response()->noContent();
} class SyncOrderStatusJob implements ShouldQueue {
public function handle(MoiSkladClient $ms): void {
$msOrder = $ms->get("entity/customerorder/{$this->msOrderId}");
// маппинг статусов и обновление заказа
}
} באיזו תדירות מתעדכן הנתונים וכיצד נפתרות התנגשויות?
המלאי מסונכרן כל 5 דקות, מוצרים והזמנות כל 10 דקות. זה שומר על נתונים עדכניים ללא עומס מיותר על ה-API. ניתן להתאים את התדירות לצרכים שלך.
התנגשויות הן בלתי נמנעות בסנכרון דו-כיווני. הגישה שלנו: מחיר, מלאי, SKU — עדיפות ל-MoySklad; שדות SEO ותמונות — האתר; כותרת — לפי תאריך השינוי האחרון. אנו מבטיחים ששינויים חשובים לעולם לא יאבדו. שגיאות משלוח עולות בממוצע $450–650 בחודש — הסנכרון ממזער אותן.
השוואת גישות
| מאפיין | חד-כיווני | דו-כיווני |
|---|---|---|
| מוצרים, מחירים, מלאי | ✅ | ✅ |
| הזמנות (אתר→MS) | ❌ | ✅ |
| סטטוסים (MS→אתר) | ❌ | ✅ |
| פתרון התנגשויות | לא נדרש | ✅ |
| עבודה ידנית של מנהל | ~שעה ביום | אוטומטי |
| שגיאות משלוח | 20-30% | <5% |
סנכרון דו-כיווני מקצר את זמן עיבוד ההזמנות פי 10 וכמעט מבטל שגיאות משלוח.
למה לבחור בסנכרון דו-כיווני?
אנו משלבים חנויות מקוונות עם MoySklad כבר למעלה מ-5 שנים, עם למעלה מ-30 פרויקטים כולל מורכבים עם אלפי SKU. למהנדסים שלנו יש מומחיות מוכחת ב-Laravel ו-REST APIs. אנו מבטיחים שהאינטגרציה תעבוד ונתקן כל תקלה במהירות. החיסכון בהזנת נתונים ידנית מגיע ל-$1.8k–2.6k בשנה, והעלויות לתיקון שגיאות משלוח יורדות ל-$450–650 בחודש.
תהליך ולוח זמנים
- ניתוח — אנו חוקרים את מבנה הקטלוג, מגדירים ישויות וכללי מיפוי.
- עיצוב — אנו מתכננים את האינטגרציה: אילו שדות, תדירות, טיפול בשגיאות.
- יישום — אנו כותבים קוד, מגדירים webhooks ותורים.
- בדיקות — אנו מריצים סנכרון ניסיון על עותק נתונים ומשווים תוצאות.
- השקה — אנו מעלים לסביבת production ומנטרים.
לוח זמנים משוער: סנכרון חד-כיווני (MoySklad → אתר) — 2–3 ימי עסקים; דו-כיווני (עם הזמנות, סטטוסים, webhooks) — 6–8 ימי עסקים. לוח הזמנים עשוי להתארך עבור מבני קטלוג מורכבים (וריאנטים, חבילות). אנו מציעים בדיקה חינמית של המערכת הנוכחית שלך ומציעים פתרון אופטימלי. צור קשר כדי לחסל לצמיתות העברת נתונים ידנית. קבל ייעוץ היום.







