ספק המימוש האופייני (FulfillmentProvider) ב-Medusa.js הוא ידני. הוא רק יוצר רשומות במסד נתונים, ואינו מסוגל לחשב תעריפים, ליצור משלוחים או לעקוב אחר סטטוסים. זה מוביל לעבודה ידנית של מפעילים, לשגיאות בעלויות ולעיכובים. אנו פותרים זאת באמצעות ספקים מותאמים אישית שמבצעים אוטומציה של כל מחזור המשלוח.
לדוגמה, בעת אינטגרציה עם DHL Express, יישמנו חישוב עלויות דינמי לפי משקל ואזור משלוח, יצירת חשבוניות וקבלת מספר מעקב דרך API. מהירות עיבוד ההזמנות גדלה פי 10 בהשוואה לספק הידני. חיסכון ממוצע בעלויות תפעול של 30–50%, וטיפול בהחזרות מתבצע באופן אוטומטי לחלוטין, מה שמפחית הוצאות. לפי תיעוד Medusa.js, פיתוח ספק מותאם אישית מומלץ לפרויקטים עם לוגיסטיקה לא סטנדרטית.
למה להתאים אישית את FulfillmentProvider?
הספק הידני מתאים רק לפרויקטי בדיקה. בסביבת ייצור הוא נכשל תחת עומס: חוסר חישוב תעריפים מוביל לאובדן רווחים, וחוסר מעקב מוביל לאובדן חבילות. ספק מותאם אישית מטפל ב-100% מהתרחישים, כולל החזרות וביטולים חלקיים. הפחתת עלויות ההחזרות יכולה להגיע ל-50%.
בעיות שנפתרות באמצעות אינטגרציה
- אי-תאימות יחידות: API של חברת השילוח עשוי לדרוש משקל בק"ג, בעוד Medusa מאחסנת בגרמים. מתאם (Adapter) ממיר נתונים באופן אוטומטי.
- חוסר Webhooks: שירותים אזוריים רבים אינם שולחים התראות — אנו מיישמים סקירה תקופתית (Polling) בתדירות של 5 דקות.
- תמיכה בשתי גרסאות Medusa: v1 ו-v2 משתמשות בארכיטקטורות שונות. אנו כותבים ספק עם ליבה משותפת ותוספים לכל גרסה.
- טיפול בהחזרות: אנו יוצרים מטפלים מותאמים אישית עבור cancelFulfillment ומודיעים ללקוח בדוא"ל.
- מספר חברות שילוח: עבור לוגיסטיקה גלובלית, הספק יכול לעבור בין DHL, FedEx ושירותים מקומיים בהתאם לאזור.
50% מהאינטגרציות נתקלות באי-תאימות יחידות, 30% חסרות Webhooks, ו-20% דורשות תמיכה בשתי גרסאות. אנו פותרים כל בעיה באמצעות מתאמים, סקירה תקופתית חלופית וארכיטקטורה מודולרית.
כיצד אוטומציה של החזרות מפחיתה עלויות תפעול
החזרות הן אחד השלבים היקרים ביותר במסחר אלקטרוני. עיבוד ידני אורך זמן, ושגיאות מובילות למשלוחים חוזרים. ספק מותאם אישית יוצר אוטומטית בקשת החזרה, מייצר תווית משלוח ומודיע לכל הצדדים. זה מקצר את זמן העיבוד משעות לדקות — מהיר פי 24 מאשר ידני. כתוצאה מכך, עלויות התפעול של החזרות יורדות ב-30–50%, והחיסכון הממוצע לכל החזרה מגיע עד 4–6 דולר באמצעות אוטומציה.
איך אנחנו עושים את זה
אנו משתמשים ב-TypeScript, Medusa.js (v1 ו-v2), Axios ל-HTTP ו-Express ל-Webhooks. מחלקת הספק הבסיסית:
import { AbstractFulfillmentService } from '@medusajs/medusa';
class CustomFulfillmentService extends AbstractFulfillmentService {
static identifier = 'custom-courier';
async getFulfillmentOptions() {
return [
{
id: 'standard',
name: 'Стандарт',
},
{
id: 'express',
name: 'Экспресс',
},
];
}
async calculatePrice(optionData, data, cart) {
const weight = cart.items.reduce(
(sum, item) => sum + (item.variant?.weight ?? 100) * item.quantity,
0
);
return await this.apiClient.getRate(optionData.id, weight, cart.shipping_address.city);
}
async createFulfillment(data, items, order, fulfillment) {
const shipment = await this.apiClient.createShipment({
service: data.id,
recipient: order.shipping_address,
items: items.map((i) => ({
sku: i.variant?.sku,
qty: i.quantity,
})),
order_ref: order.display_id.toString(),
});
return {
tracking_number: shipment.tracking,
shipment_id: shipment.id,
};
}
async cancelFulfillment(fulfillment) {
await this.apiClient.cancelShipment(fulfillment.data.shipment_id);
return {};
}
}
export default CustomFulfillmentService;
לקוח ה-HTTP עבור API של חברת השילוח עוטף בקשות, טיפול בשגיאות והמרת נתונים:
import axios from 'axios';
class CourierApiClient {
private client;
constructor(apiKey: string) {
this.client = axios.create({
baseURL: 'https://api.courier.ru/v2',
timeout: 10_000,
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
}
async getRate(serviceCode: string, weightGrams: number, toCity: string) {
const { data } = await this.client.post('/calculate', {
service: serviceCode,
weight: Math.max(0.1, weightGrams / 1000),
to_city: toCity,
});
return Math.round(data.price * 100); // в копейках
}
async createShipment(payload) {
const { data } = await this.client.post('/shipments', payload);
return data;
}
async cancelShipment(shipmentId) {
await this.client.delete(`/shipments/${shipmentId}`);
}
}נתיב ה-Webhook מטפל באירועים מחברת השילוח ומעדכן את סטטוס ההזמנה דרך EventBus:
import { Router } from 'express';
const router = Router();
router.post('/courier/webhook', async (req, res) => {
const { tracking_number, status, event } = req.body;
const fulfillmentRepo = req.scope.resolve('fulfillmentRepository');
const fulfillment = await fulfillmentRepo.findOne({ where: { data: { tracking_number } } });
if (!fulfillment) return res.sendStatus(404);
const eventBus = req.scope.resolve('eventBusService');
await eventBus.emit('fulfillment.tracking_updated', { fulfillment_id: fulfillment.id, tracking_number, status });
res.sendStatus(200);
});
export default router;תהליך שלב-אחר-שלב ליצירת ספק מותאם אישית:
- ניתוח API של חברת השילוח ויצירת סכמת בקשות.
- יצירת מחלקת לקוח עם מתודות לכל נקודת קצה.
- מימוש AbstractFulfillmentService על ידי דריסת מתודות מפתח.
- הגדרת נתיבי Webhook לקבלת אירועים.
- כתיבת בדיקות יחידה ובדיקת האינטגרציה בסביבת Staging.
דוגמה לארכיטקטורת ספק
הארכיטקטורה כוללת שלוש שכבות: שכבת אינטגרציה (לקוח API), שכבת לוגיקה עסקית (שירות) ושכבת הצגה (נתיבי Webhook). כל שכבה נבדקת בנפרד, ובדיקות אינטגרציה מכסות את כל התרחישים מול חברת השילוח.לסביבת ייצור, אנו מוסיפים ניטור באמצעות Grafana והתראות ב-Telegram עבור השבתת API של חברת השילוח או שגיאות בהמרת נתונים.
השוואה: ספק ידני מול ספק מותאם אישית
| פרמטר | ספק ידני | ספק מותאם אישית |
|---|---|---|
| חישוב תעריפים | רק מחיר קבוע | חישוב דינמי דרך API של חברת השילוח |
| יצירת משלוח | ידני בממשק הניהול | אוטומטי בעת הזמנה |
| מעקב | אין | Webhook + עדכוני סטטוס |
| החזרות | אין | תמיכה מלאה בביטולים |
ציר זמן ושלבי יישום
| שלב | תיאור | משך |
|---|---|---|
| ניתוח API | לימוד תיעוד, בדיקת נקודות קצה | 0.5 יום |
| עיצוב | סכמת מחלקות, טיפול בשגיאות, תמיכה ב-v1/v2 | יום אחד |
| יישום | חבילה עם בדיקות יחידה ובדיקות אינטגרציה | 2–3 ימים |
| בדיקות | בסביבת Staging עם הזמנות אמיתיות | יום אחד |
| פריסה וניטור | פריסה לייצור, התראות | 0.5 יום |
- אינטגרציה בסיסית (חברת שילוח אחת, ללא החזרות): 3–5 ימים.
- הוספת Webhooks ומעקב: +1–2 ימים.
- חבילת npm מלאה עם תמיכה ב-Medusa v1 ו-v2: 5–7 ימים.
מה כלול
- קוד מקור של הספק (TypeScript).
- קונפיגורציה עבור
import { AbstractFulfillmentService } from '@medusajs/medusa'; class CustomFulfillmentService extends AbstractFulfillmentService { static identifier = 'custom-courier'; async getFulfillmentOptions() { return [ { id: 'standard', name: 'Стандарт' }, { id: 'express', name: 'Экспресс' }, ]; } async calculatePrice(optionData, data, cart) { const weight = cart.items.reduce((sum, item) => sum + (item.variant?.weight ?? 100) * item.quantity, 0); return await this.apiClient.getRate(optionData.id, weight, cart.shipping_address.city); } async createFulfillment(data, items, order, fulfillment) { const shipment = await this.apiClient.createShipment({ service: data.id, recipient: order.shipping_address, items: items.map(i => ({ sku: i.variant?.sku, qty: i.quantity })), order_ref: order.display_id.toString(), }); return { tracking_number: shipment.tracking, shipment_id: shipment.id }; } async cancelFulfillment(fulfillment) { await this.apiClient.cancelShipment(fulfillment.data.shipment_id); return {}; } } export default CustomFulfillmentService;. - תיעוד התקנה וקונפיגורציה.
- הדרכה לצוות (שעה אחת).
- חודש אחריות ותמיכה.
הזמינו את האינטגרציה, ואנו נבצע אוטומציה של הלוגיסטיקה שלכם תוך שבוע. קבלו ייעוץ מהנדס והערכת עלות מדויקת. צרו קשר לבדיקה של הפרויקט שלכם — נעריך את המורכבות ונציע את הפתרון האופטימלי.







