אנו בונים עגלות קניות שמתמודדות עם פריטים שאבדו בעת טעינת עמוד מחדש, התנגשויות סשן, ותנאי מרוץ. במשך למעלה מ-5 שנים בשוק, יישמנו עגלות קניות עבור יותר מ-50 חנויות מקוונות בכל הגדלים—מדפי נחיתה קטנים ועד קטלוגים עם מיליוני פריטים. הצוות שלנו מביא ניסיון של למעלה מ-10 שנים בפיתוח מסחר אלקטרוני, ומבטיח פתרונות חזקים.
העגלה היא הרכיב המרכזי שבו מתרחשים רוב התקלות. ניהול כמויות לא מדויק, טעינה איטית של מיני-עגלה, ושגיאות בחישוב הנחות—כל אלה משפיעים ישירות על שיעור ההמרה. פיתוח העגלה שלנו מפחית את נטישת העגלה ב-15–20%, מה שעשוי לחסוך 10,000 דולר בחודש עבור חנות עם הכנסות של 100,000 דולר. בניית עגלה מאפס אורכת 3 עד 6 ימי עבודה, תלוי במורכבות הלוגיקה העסקית.
ארכיטקטורה ואחסון
העגלה קיימת בשלושה מצבים: אורח (אנונימי), משתמש (מקושר לחשבון), וממוזג (בעת התחברות). עבור אורחים, הנתונים מאוחסנים ב-localStorage או sessionStorage—הבחירה תלויה במדיניות האתר. בעת אימות, מיזוג בין לקוח לשרת חייב לפתור התנגשויות: אם אותו מוצר קיים בשני המקומות, יש לסכם את הכמויות או לקחת את הערך המקסימלי.
בצד השרת, טבלת העגלה בדרך כלל נראית כך:
CREATE TABLE cart_items (
id BIGSERIAL PRIMARY KEY,
cart_id UUID NOT NULL,
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
session_id VARCHAR(255),
product_id BIGINT NOT NULL,
variant_id BIGINT,
quantity INT NOT NULL DEFAULT 1,
price_snapshot NUMERIC(12,2) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_cart_items_cart_id ON cart_items(cart_id);
CREATE INDEX idx_cart_items_user_id ON cart_items(user_id);
השדה CREATE TABLE cart_items ( id BIGSERIAL PRIMARY KEY, cart_id UUID NOT NULL, user_id BIGINT REFERENCES users(id) ON DELETE CASCADE, session_id VARCHAR(255), product_id BIGINT NOT NULL, variant_id BIGINT, quantity INT NOT NULL DEFAULT 1, price_snapshot NUMERIC(12,2) NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_cart_items_cart_id ON cart_items(cart_id); CREATE INDEX idx_cart_items_user_id ON cart_items(user_id); קובע את המחיר ברגע ההוספה—קריטי למבצעים מוגבלים בזמן ולשינויי מחירים בזמן אמת.
העגלה של אורח נשמרת למשך 30 יום בקוקיה (cart_id). בעת התחברות, מתרחש מיזוג והעגלה מועברת למסד הנתונים. אם משתמש מחובר מתנתק, העגלה נשארת במסד הנתונים ומשוחזרת בכניסה הבאה.
לוגיקת עגלה: כמות, מלאי והזמנה
שינויי כמות צריכים להיות אופטימיים: ממשק המשתמש מתעדכן מיד בזמן שהבקשה נשלחת ברקע. גישה זו מפחיתה את זמן התגובה הנתפס ב-50% בהשוואה לעדכונים פסימיים. במקרה של שגיאה, יש לבטל את השינוי עם הודעה. יישום באמצעות React Query:
const updateQuantity = useMutation({
mutationFn: ({ itemId, qty }: { itemId: number; qty: number }) =>
api.patch(`/cart/items/${itemId}`, { quantity: qty }),
onMutate: async ({ itemId, qty }) => {
await queryClient.cancelQueries({ queryKey: ['cart'] });
const prev = queryClient.getQueryData(['cart']);
queryClient.setQueryData(['cart'], (old: Cart) => ({
...old,
items: old.items.map(i => i.id === itemId ? { ...i, quantity: qty } : i),
}));
return { prev };
},
onError: (_, __, ctx) => {
queryClient.setQueryData(['cart'], ctx?.prev);
toast.error('Не удалось обновить количество');
},
});כמויות מינימום ומקסימום מוגדרות ברמת המוצר: const updateQuantity = useMutation({ mutationFn: ({ itemId, qty }: { itemId: number; qty: number }) => api.patch(`/cart/items/${itemId}`, { quantity: qty }), onMutate: async ({ itemId, qty }) => { await queryClient.cancelQueries({ queryKey: ['cart'] }); const prev = queryClient.getQueryData(['cart']); queryClient.setQueryData(['cart'], (old: Cart) => ({ ...old, items: old.items.map(i => i.id === itemId ? { ...i, quantity: qty } : i), })); return { prev }; }, onError: (_, __, ctx) => { queryClient.setQueryData(['cart'], ctx?.prev); toast.error('Не удалось обновить количество'); }, }); ו-max_order_qty. אם נותרו רק 3 יחידות במלאי, כפתור ה-'+' מושבת כאשר מגיעים לערך זה.
בעת הוספה לעגלה, יש להחליט אם לבצע הזמנה רכה (הפחתת מלאי זמין) או לא. הזמנה רכה מפחיתה תחרות על המוצר אך יוצרת הזמנות 'מתות' מעגלות נטושות. פשרה היא להזמין רק בתחילת תהליך התשלום (checkout init) ולהשאיר את העגלה כאינפורמטיבית.
בעת הצגת העגלה, המלאי בפועל נבדק באמצעות שאילתה למחסן. אם מוצר אזל מהמלאי, יש להציג אזהרה ישירות בשורת הפריט מבלי לחסום את כל העגלה.
הזמנה רכה שימושית לפריטים במהדורה מוגבלת עם ביקוש גבוה. היא מבטיחה שמשתמש שהוסיף פריט לא יאבד אותו לקונה אחר. עם זאת, עבור אתרי מסחר אלקטרוני גדולים עם מחזור מהיר, עדיף לוותר על הזמנה בעגלה—זה מפחית נעילות מתות ב-30–40%. לפי Google, גישה זו משפרת את חוויית המשתמש.
מנגנון הזמנה
ניתן להשתמש בשדה `reserved_stock` בטבלת המוצרים או בשירות נפרד. בתחילת תהליך התשלום, נקראת פרוצדורה חוסמת: הפחתת מלאי ויצירת רשומה זמנית עם טיימר. אם ההזמנה לא הושלמה תוך 15–30 דקות, ההזמנה משוחררת.חישוב סה"כ ותמחור
סה"כ העגלה כולל מספר שכבות:
| רכיב | לוגיקה |
|---|---|
| סכום ביניים | סכום של price_snapshot × כמות עבור כל הפריטים |
| הנחות | מיושמות לפי עדיפות: מבצעי > קופון > מצטבר |
| משלוח | מוערך מראש, מדויק בתשלום |
| מע"מ | כלול במחיר או מתווסף בנפרד (תלוי בתצורה) |
החישוב מתבצע בצד השרת בכל שינוי בעגלה. הלקוח מקבל סכומים מוכנים—ללא חישובים בצד הדפדפן.
עגלה בממשק המשתמש: מיני-עגלה, עמוד מלא ושמירה
המיני-עגלה בכותרת (תפריט נפתח או סרגל צד) מציגה את 5 הפריטים האחרונים, תגית ספירה, וכפתור 'לתשלום'. עמוד ה-/cart המלא מציג את כל הפריטים עם אפשרויות עריכה. שני הרכיבים נרשמים לאותו מצב—באמצעות React Query או Zustand.
חשוב: מונה הכותרת מתעדכן באמצעות Server-Sent Events או סקירה כל 30 שניות—חיוני אם למשתמש יש מספר לשוניות פתוחות.
סנכרון בין מכשירים
בעת התחברות ממכשיר חדש, השרת מחזיר את מצב העגלה הנוכחי. כל שינוי נדחף דרך API ונשמר מיד. כך, אם משתמש מוסיף פריט בטלפון, הוא יראה אותו במחשב הנייד לאחר רענון. סנכרון זה מגדיל את שיעור ההמרה ב-15–20% לפי הנתונים שלנו.
אנליטיקה ובעיות נפוצות
כל אירועי העגלה צריכים להישלח לאנליטיקה: add_to_cart, remove_from_cart, view_cart. עבור Google Analytics 4, אלה אירועי מסחר אלקטרוני סטנדרטיים עם פרמטרים item_id, item_name, price, quantity. עבור Yandex.Metrica, מבנה דומה דרך ym(id, 'reachGoal', 'cart_add', {...}).
עגלות נטושות מנוטרות בנפרד: אם משתמש הוסיף פריטים אך לא הגיע לתשלום תוך N שעות, מופעל רצף אימיילים.
בעיות יישום נפוצות:
- תנאי מרוץ בהוספה בו-זמנית: נפתר באמצעות
SELECT FOR UPDATEברמת מסד הנתונים או מפתח אידמפוטנטיות ב-API. - מחיר השתנה לאחר ההוספה: הצגת הודעה, חישוב מחדש אוטומטי.
- מוצר הופסק: חסימת תשלום, הצעה להסרת הפריט.
- מע"מ למדינות שונות: קביעה לפי IP/כתובת משלוח, החלת השיעור המתאים.
תהליך הפיתוח ותוצרים
תהליך הפיתוח שלנו בשלבים:
- ניתוח לוגיקה עסקית: סוגי מוצרים, הנחות, משלוח.
- עיצוב סכמת נתונים ו-API (REST או GraphQL).
- פיתוח חזית עם עדכונים אופטימיים.
- אינטגרציה עם מערכת תשלום ולוגיסטיקה.
- בדיקת עומס (עד 1000 בקשות/שנייה).
- פריסה ומתן תיעוד.
בהזמנת פיתוח עגלה, אתה מקבל:
- תיעוד ארכיטקטוני עם סכמת נתונים ותיאור API.
- קוד מקור לחזית ולשרת עם הערות.
- אנליטיקה מוגדרת (GA4 או Yandex.Metrica).
- אינטגרציה עם מערכת תשלום ושירות משלוחים.
- תמיכה טכנית למשך 30 יום לאחר המסירה.
אנו מבטיחים מסירה בזמן וביצועים יציבים של העגלה תחת עומס. יישום העגלה שלנו ב-React מהיר פי 3 מפתרונות ישנים בזכות עדכונים אופטימיים. קבל ייעוץ לפרויקט שלך—צור קשר כדי לדון בפרטים.







