Skip to content

אימות ​

ה-API של v1 מאמת באמצעות מפתח רישיון שנשלח בגוף הבקשה. אין כותרות פרטי גישה, אין החלפת token ואין session: כל קריאה לנקודת קצה shipping/* נושאת שדה license_key ושדה domain, וה-middleware מפענח אותם לרישיון (License) שהבקשה פועלת תחתיו.

כך זה לא עובד ב-v2

v2 מאמתת את החשבון באמצעות הכותרות X-Client-Id / X-Client-Secret ובוחרת את הרישיון בנפרד באמצעות פרמטר license_key. v1 ממזגת את השניים: מפתח הרישיון הוא פרטי הגישה. אם אתם בונים משהו חדש, השתמשו באימות של v2 במקום.

שדות חובה ​

שלחו את שני השדות בכל בקשה ל-shipping/*. בנקודות הקצה מסוג POST הם שייכים לגוף ה-JSON; בנקודות הקצה מסוג GET (same_day_delivery_quote, create_shipping_promise, get_express_delivery_enabled, get_express_delivery_status, user-by-license) הם נשלחים ב-query string.

שדהסוגחובהתיאור
license_keystringכןה-key של הרישיון. מזהה גם את הקורא וגם את חשבון חברת השילוח שהפעולה מתבצעת מולו.
domainstringכןהדומיין של החנות הקוראת, למשל your-store.example.com. נדרש על ידי הוולידציה — ראו על domain למה שנבדק ומה שלא.
tokenstringלאtoken אישי של Sanctum שמשתמש ShipOS שבבעלותו הרישיון. נבדק רק עבור רישיונות של חברות פרימיום (למטה).

ה-license_key נוצר ב-ShipOS ומועתק להגדרות התוסף בחנות; אין נקודת קצה ב-v1 שמנפיקה אותו.

אל תשלחו שדה license

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


מה נבדק ​

ה-middleware hasLicense רץ לפני הוולידציה של נקודת הקצה עצמה, בסדר הזה:

  1. ולידציה של גוף הבקשה — license_key ו-domain חייבים שניהם להיות קיימים, מחרוזות שאינן ריקות. חוסר הוא שגיאת ולידציה 422, לא 403.
  2. פענוח ה-token — אם קיים שדה token, הוא נבדק כ-token אישי של Sanctum והבעלים שלו הופך למשתמש הפועל. בלי token, המשתמש הפועל הוא מי שה-session מאמת — ובעבור קורא API חיצוני, זה אף אחד. token שאינו מפוענח אינו שגיאה בפני עצמו; הוא פשוט משאיר את המשתמש הפועל כ-null.
  3. חיפוש הרישיון — שורת הרישיון נמצאת לפי key. מפתח לא מוכר → כשל.
  4. בדיקת פעילות — הדגל is_active של הרישיון חייב להיות true. רישיון שבוטל → כשל.
  5. שער פרימיום — אם החברה של הרישיון מסומנת is_premium, הבקשה דורשת בנוסף משתמש פועל (שלב 2) וגם שהחברות בפרימיום של אותו משתמש תהיה פעילה. חוסר באחד מהם → כשל.

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

אין בדיקת תוקף במסלול הזה: רישיון שתוקפו לא פג אך אינו פעיל נדחה בשלב 4, ותוקף מבוסס-זמן אינו נבדק כאן.

על domain ​

domain הוא שדה חובה, אבל הבדיקה שהשוותה אותו ל-domain המאוחסן של הרישיון מסומנת כהערה בקוד הנוכחי — הערך שלו נבדק לקיום ואז אינו בשימוש להרשאה. המשיכו לשלוח את הדומיין האמיתי של החנות (השדה נדרש, הוא נרשם ביומן הבקשות, והבדיקה עשויה לחזור), אבל אל תתייחסו לדומיין תואם כגבול אבטחה.

עמודת ה-domain של הרישיון עצמו מאוכלסת בפעם הראשונה שחנות קוראת ל-GET /api/license/activate_license, ורק אם היא עדיין ריקה.


תגובות כשל ​

כל כשל רישיון מוחזר על ידי ה-middleware כ-HTTP 403 במעטפת v1 הסטנדרטית, כאשר data הוא מערך ריק והסיבה נמצאת ב-message:

json
{
  "data": [],
  "message": "License key has been deactivated",
  "success": false,
  "warning": ""
}
תנאיStatusmessage
license_key או domain חסרים422גוף ולידציה של Laravel — ראו שגיאות
אין רישיון עם ה-key הזה403Invalid License Key
is_active של הרישיון הוא false403License key has been deactivated
חברת פרימיום, לא פוענח משתמש פועל403Premium companies are not supported in this version of plugin
חברת פרימיום, הפרימיום של המשתמש הפועל אינו פעיל403You must be a premium member to use this company

שתי הערות על הסטטוסים:

  • המקרה של מפתח לא מוכר מסווג פנימית כ-404, אבל ה-middleware מחזיר 403 עבור כל כשלי הרישיון. אל תצפו ל-404 כאן.
  • הודעות הפרימיום עוברות דרך תרגום, ולכן הן עשויות לחזור מתורגמות. הסתעפו לפי סטטוס ה-HTTP ו-success, לעולם לא לפי message.

דוגמה מלאה ​

קריאת הפרטים המאוחסנים של משלוח לא דורשת דבר מלבד פרטי הגישה בתוספת קוד המעקב:

bash
curl --location 'https://app.shipos.co.il/api/shipping/get_order_details' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
    "license_key": "{license_key}",
    "domain": "your-store.example.com",
    "shipping_id": "66747921"
}'
js
// Node.js 18+ / דפדפנים — בלי תלויות
const response = await fetch('https://app.shipos.co.il/api/shipping/get_order_details', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({
    license_key: process.env.SHIPOS_LICENSE_KEY,
    domain: process.env.SHIPOS_DOMAIN,
    shipping_id: '66747921',
  }),
})

const body = await response.json()

if (response.status === 403) {
  // הרישיון נדחה: מפתח לא מוכר, רישיון שבוטל, או שער פרימיום.
  throw new Error(`ShipOS license rejected: ${body.message}`)
}

if (!response.ok || !body.success) {
  throw new Error(`ShipOS v1: ${body.message}`)
}

console.log(body.data)
php
<?php

use Illuminate\Support\Facades\Http;

$response = Http::acceptJson()
    ->post('https://app.shipos.co.il/api/shipping/get_order_details', [
        'license_key' => config('services.shipos.license_key'),
        'domain' => config('services.shipos.domain'),
        'shipping_id' => '66747921',
    ]);

$body = $response->json();

if ($response->forbidden()) {
    throw new RuntimeException('ShipOS license rejected: '.$body['message']);
}

if (! ($body['success'] ?? false)) {
    throw new RuntimeException('ShipOS v1: '.$body['message']);
}

logger()->info('Shipment details', $body['data']);

רישיון שמפוענח בהצלחה אומר שהשלב הבא הוא חיפוש המשלוח עצמו: v1 מצמצמת כל שאילתת משלוח לרישיון הקורא, ולכן קוד מעקב ששייך לחשבון אחר מתנהג בדיוק כמו קוד שאינו קיים.


ריבוי רישיונות ​

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

קוראים פנימיים (First-party) ​

ה-middleware מזהה גם שדה secret השווה למפתח האפליקציה, שמדלג על ולידציית הדומיין ועל בדיקות הרישיון שלמעלה וטוען את הרישיון לפי המפתח ישירות. המסלול הזה קיים עבור השירותים הפנימיים של ShipOS עצמה; הוא אינו זמין לאינטגרטורים ומתועד כאן רק כדי שנוכחותו ביומני הבקשות לא תיתפס בטעות כדרך פנימה.