Skip to content

שגיאות ​

ל-v1 אין מעטפת שגיאה נפרדת. כשל חוזר באותו גוף בעל ארבעה מפתחות כמו הצלחה, כאשר success מתהפך ל-false והסיבה נמצאת ב-message:

json
{
  "data": [],
  "message": "Invalid License Key",
  "success": false,
  "warning": ""
}
Keyסוגתיאור
dataarray/objectמערך JSON ריק ([]) ברוב הכשלים. חלק מנקודות הקצה מכניסות לכאן פרטים — ראו שגיאות ולידציה ואת ההערה על change_order_status למטה.
messagestringסיבה קריאה-אנוש, לעיתים קרובות הטקסט של חברת השילוח עצמה, לפעמים מתורגם.
successboolfalse בכשל. האות המחייב.
warningstringתמיד קיים, ריק בנקודות הקצה של השילוח ב-v1.

אין קוד שגיאה קריא-מכונה

v1 קדמה לשדה ה-code היציב שנושאות שגיאות v2. שום דבר בכשל של v1 אינו מתוכנן להתאמה תוכניתית: message הוא טקסט חופשי והוא עשוי להשתנות או להגיע מתורגם. הסתעפו לפי סטטוס ה-HTTP בתוספת success, והתייחסו ל-message כמשהו לרישום ביומן או להצגה לאדם.

success: false אינו מרמז על סטטוס שאינו 2xx

כמה מסלולים ב-v1 מחזירים מעטפת כשל בסטטוס HTTP 200 שהוא ברירת המחדל. המקרה הברור ביותר הוא change_order_status: כאשר קוד המעקב לא נמצא תחת הרישיון הקורא, הוא מחזיר 200 עם success: false ועם message: "Something went wrong". לקוח שבודק רק את response.ok יקרא את זה כביטול שהצליח. בדקו תמיד את success.


סטטוסי HTTP שצריך לטפל בהם ​

Statusמתי זה קורהניסיון חוזר?
200הצלחה — וגם חלק מהכשלים המטופלים (ראו האזהרה למעלה). בדקו success.—
400נדחה לפני שחברת השילוח נקראה: מכסת חבילות המשלוח של החשבון מוצתה, סטטוס ההזמנה מוחרג מיצירת משלוח על ידי מסנן סטטוסי ההזמנה של הרישיון, הפעולה אינה נתמכת על ידי חברת השילוח של הרישיון הזה, או שחיפוש הצעת מחיר / משלוח אקספרס נכשל.לא — התנאי נוגע לחשבון או לבקשה.
403בדיקת הרישיון נכשלה. מפתח לא מוכר, רישיון שבוטל, או שער פרימיום. ראו אימות.לא.
404הדבר שאליו פנו אינו קיים תחת הרישיון הקורא. שני מבנים: המעטפת (order-label, למשל Order not found, No active shippings found for this order) והגוף החשוף של Laravel {"message": "..."} עבור נקודות הקצה ששולפות עם firstOrFail (get_order_details, get_shipping_status, label).לא.
409open_new_order בלבד. בקשה אחרת עבור אותו מפתח רישיון ואותו מזהה הזמנה נמצאת בתהליך והחזיקה את המנעול לכל אורך החלון שלה. message מבקש מהקורא לנסות שוב.כן, לאחר השהיה — אבל ראו קודם את ההערה על קריאה חוזרת (replay) למטה.
422ולידציית הבקשה נכשלה. ראו שגיאות ולידציה.לא, לא ללא שינוי.
429הגבלת קצב: 500 בקשות לדקה לכל IP (לכל משתמש כששולחים token).כן, עם backoff.
500יצירת המשלוח עצמה נכשלה — דחייה של חברת השילוח מדווחת כ-500 עם הטקסט של חברת השילוח ב-message — או שגיאת שרת בלתי מטופלת, או Error Retrieving Locations מ-pickup_locations.רק במקרים הבלתי-מטופלים / pickup_locations; דחייה של חברת השילוח תיכשל באופן זהה עד שגוף הבקשה ישתנה.

ניסיון חוזר ל-open_new_order בטוח למשך שעה ​

תגובת open_new_order מוצלחת נשמרת במטמון לשעה לפי license_key + order.id, וקריאה חוזרת בתוך החלון הזה מחזירה את התגובה מהמטמון כפי שהיא, בתוספת data.idempotent: true, במקום ליצור משלוח שני. כשלים אינם נשמרים במטמון, ולכן יצירה שנכשלה נשארת ניתנת לניסיון חוזר. זו הסיבה שאפשר לנסות שוב 409 או timeout ברשת בלי לייצר כפילות: הבקשה שסיימה ראשונה היא הבעלים של קוד המעקב, והניסיון החוזר מקבל אותו.

שימו לב שההסרה הזו של כפילויות מוגבלת בזמן ואינה קבועה — יצירת משלוח שני לאותה הזמנה כן מותרת לאחר שחלפה השעה, מפני שסוחרים באופן לגיטימי שולחים את שאר ההזמנה במועד מאוחר יותר.


שגיאות ולידציה ​

איזה גוף נושא 422 תלוי באיזו נקודת קצה קראתם, מפני ש-v1 מעולם לא אחדה את זה.

נקודת קצהמבנהStatus
open_new_orderהמעטפת של v1, עם שגיאות השדות תחת data.errors וההודעה הראשונה מועתקת אל message.422
get_order_details, get_shipping_status, change_order_status, label, order-label, bulk-label, same_day_delivery_quote, והמקרה של license_key/domain חסרים ב-middleware של הרישיוןגוף הוולידציה המוגדר כברירת מחדל ב-Laravel: {"message": ..., "errors": {...}}. בלי מפתח success.422
order (חיפוש משלוחים מרוכז)מבנה שלישי: {"errors": {...}, "message": "Validation Failed", "success": false} — מוחזר עם HTTP 500, לא 422.500

open_new_order, נקודת הקצה שרוב האינטגרציות מתעניינות בה, נראית כך:

json
{
  "data": {
    "errors": {
      "ship_data.city": ["City is required"],
      "order_items.0.quantity": ["Each order item must have a quantity"]
    }
  },
  "message": "City is required",
  "success": false,
  "warning": ""
}

הכללים המבניים שלה הם ש-ship_data ו-order חייבים שניהם להיות מערכים, ושכל רשומה ב-order_items צריכה name, quantity שלם של 1 לפחות, ו-total מספרי. מעל אלה היא מריצה בדיקות חוצות-שדות שמקבלות את הערך מכל אחד מהמקומות: רחוב מ-ship_data.street או מ-order.billing.address_1, עיר מ-ship_data.city או מ-order.billing.city, ושם איש קשר מ-ship_data.contact_name או מ-order.billing.first_name/last_name. רק ערך ריק באמת נכשל — "0" הוא ערך רחוב לגיטימי והוא מתקבל. גם ship_data: {} ריק נכשל, מפני ש-required של Laravel מתייחס למערך ריק כאל חסר.

גוף שגיאה אחד יכול לערב שתי שפות

נבדק מול מכונה חיה: ההודעות של ה-framework מוחזרות בלוקאל של השרת (עברית במכונות הישראליות), בעוד שהכללים שמוגדרים בנקודת הקצה הזו נושאים הודעות באנגלית. תשובה אחת יכולה להכיל את שתיהן:

json
{
  "data": {
    "errors": {
      "ship_data": ["שדה ship data הוא חובה."],
      "ship_data.city": ["City is required"]
    }
  },
  "message": "שדה ship data הוא חובה.",
  "success": false,
  "warning": ""
}

message הוא תמיד רק העתק של השגיאה הראשונה, ולכן הוא יורש את השפה שבה היא נכתבה. אל תסתמכו על טקסט ההודעה. התאימו לפי סטטוס ה-HTTP ולפי מפתחות השדות ב-data.errors — שניהם יציבים ואינם תלויי לוקאל.

שלחו תמיד Accept: application/json

רק open_new_order כופה גוף JSON בכשל ולידציה. שאר נקודות הקצה מסתמכות על ה-content negotiation של Laravel, ולכן בקשה בלי Accept: application/json מקבלת הפניית HTTP במקום גוף 422. שלחו את הכותרת בכל קריאה.


שני מבנים שאינם המעטפת ​

כדאי לטפל בהם כמקרים מיוחדים בלקוח, מפני ששניהם אינם נושאים success:

  • {"message": ...} חשוף ב-404 — חיפושי ה-firstOrFail המפורטים בטבלת הסטטוסים.
  • {"error": "Invalid response from shipping company"} חשוף ב-HTTP 200 — label ו-bulk-label כאשר לא ניתן היה להפיק כתובת של תווית. לקוח שקורא את data.url בלי לבדוק קודם אם קיים error יראה כתובת undefined ולא שגיאה.

לקוח v1 הגנתי מתייחס אפוא לתגובה כמוצלחת רק כאשר סטטוס ה-HTTP הוא 2xx וגם success === true וגם לא קיים מפתח error ברמה העליונה.


איפה לחפש כשקריאה נכשלת ​

כל בקשה שעוברת בקבוצת השילוח נכתבת לטבלה api_request_logs לפני שהיא נשלחת — URL, כותרות, גוף, מספר הזמנה וקוד מעקב — והתגובה נכתבת בחזרה לאותה שורה, כולל הגוף המנורמל המדויק שהקורא קיבל. קריאות לצד חברת השילוח נרשמות שם גם כן. כשסוחר מדווח על משלוח שלא הופיע, השורה הזו היא התיעוד של מה שנשלח ומה שחזר; ציינו את קוד המעקב או את מספר ההזמנה כשאתם פונים לתמיכה של ShipOS.