الإصدار 1 · واجهة الشركاء

واجهة برمجة التطبيقات لشركات الشحن الشريكة

أرسل طلبات التوريد نيابةً عن عملائك، استقبل عروض الأسعار، حمّل إثباتات الدفع، وتابع تحديثات حالة الطلب عبر Webhooks موقّعة، كل ذلك عبر HTTPS بمفتاح API واحد.

نظرة عامة

تتيح واجهة الشركاء لشركة شحن أو شريك توريد خارجي إنشاء طلبات داخل منصتنا برمجياً. يمر كل طلب عبر نفس مسار التنفيذ المستخدم في واجهتنا، ويستقبل الشريك إشعارات Webhook عند كل تغيير حالة مهم.

إرسال الطلبات
أنشئ طلبات توريد بوجهة واحدة أو عدة وجهات.
استقبال عروض الأسعار
احصل على عروض أسعار لكل وجهة عبر Webhook والبريد الإلكتروني.
رفع الملفات
ارفع الصور وملفات PDF والفيديوهات إلى S3، احصل على رابط دائم.
اكتشف الخدمات
اعرض كتالوج شركات الشحن التي ندعمها لكل دولة.
تعديل وإلغاء
عدّل الوجهات طالما الطلب في حالة Processing أو Unpaid.
Webhooks موقّعة
تدفق أحداث موقّع بـ HMAC-SHA256 للعروض والحالة والوسائط.
العنوان الأساسي: https://kuaisourcing.com/api-backجميع نقاط النهاية أدناه نسبية لهذا العنوان.

المصادقة

كل طلب يجب أن يحتوي على مفتاح API في رأس x-api-key. يحدد المفتاح حساب الشريك المتصل، احتفظ به سرياً.

http
POST /api/partner/sourcing HTTP/1.1
Host: kuaisourcing.com
Content-Type: application/json
x-api-key: ks_live_yourkeyhere1234567890abcdef
احتفظ بالمفتاح سرياً

لا تضع المفتاح أبداً في كود طرف العميل أو في مستودع git. تعامل معه كأنه كلمة مرور. عند تسربه، اطلب من مدير حسابك تدويره، يتم إلغاء المفتاح القديم فوراً.

دورة حياة الطلب

يمر الطلب بهذه الحالات. يُطلَق Webhook الخاص بـ order.status_changed عند كل انتقال.

ProcessingUnpaidPayment pendingPaidIn ProductionPackedShippedIn TransitDelivered to Destination

الحالات النهائية خارج المسار: Cancelled, Refunded, Order Rejected, OutOfStock.

إرسال طلب توريد

POST/api/partner/sourcing

يمكن أن يتضمن الطلب الواحد عدة وجهات. يجب على كل وجهة تحديد خدمة الشحن، من كتالوجنا أو شحن ذاتي.

json
{
  "productName": "Bluetooth Earbuds Pro",
  "productImageUrl": "https://yourcdn.com/img.jpg",
  "productURL": "https://supplier-page.example/product/123",
  "category": "Electronics",
  "targetMarket": "Africa",
  "additionalNotes": "Need OEM packaging",

  "airFreight": true,
  "seaFreight": false,
  "byTrain": false,
  "expressDelivery": false,
  "normalDelivery": true,
  "domesticDelivery": "slow",
  "shippingResponsibility": "kuai",

  "destinations": [
    {
      "country": "Gabon",
      "city": "Libreville",
      "address": "1 Example Street",
      "quantity": 50,
      "variants": "[{\"color\":\"Black\",\"quantity\":30},{\"color\":\"White\",\"quantity\":20}]",
      "service": "DHL",
      "recipientName": "Jane Doe",
      "contactNumber": "+241 00 00 00 00"
    },
    {
      "country": "Tunisia",
      "city": "Tunis",
      "quantity": 30,
      "service": "Other ...",
      "customService": "Local forwarder name",
      "recipientName": "John Doe",
      "contactNumber": "+216 00 000 000",
      "isCompanyService": false
    }
  ]
}

الحقول الرئيسية

الحقلمطلوبملاحظات
productNameنعماسم مختصر للمنتج
targetMarketنعممثال: "Africa"
destinationsنعمإدخال واحد على الأقل. كل إدخال يحتاج country و quantity.
airFreight / seaFreight / byTrainواحد على الأقل trueإذا كان airFreight = true، اضبط أيضاً expressDelivery أو normalDelivery.
domesticDeliveryاختياري"fast" أو "slow" (داخل الصين)
shippingResponsibilityاختياري"kuai" / "service" / "self"
productImageUrlاختيارييجب أن يكون الرابط متاحاً. ارفع أولاً عبر uploads للأمان.

الاستجابة ·
201 Created

json
{
  "success": true,
  "data": {
    "orderId": "9f5e2c3a-...",
    "customOrderId": "KS0000",
    "message": "Sourcing request submitted successfully"
  }
}

استخدم orderId (UUID) في كل النداءات اللاحقة. customOrderId (KS0001, KS0002, …) هو نفس المعرّف التسلسلي الذي يظهر في لوحة تحكمنا الداخلية.

قائمة طلباتك

GET/api/partner/sourcing?status=Unpaid&details=true&page=0&size=50
المعاملالافتراضيملاحظات
status(any)تصفية حسب الحالة بالضبط (انظر قسم دورة الحياة)
detailstruefalse لإرجاع حمولة أخف (بدون عروض / صور / وجهات)
page0مفهرس من الصفر
size100الحد الأقصى 100

يُرجع صفحة Spring من الطلبات (انظر جلب طلب لمعرفة البنية).

جلب طلب

GET/api/partner/sourcing/{orderId}
GET/api/partner/sourcing/by-order-id/{customOrderId}

كلا الشكلين يُرجعان نفس الحمولة.

json
{
  "success": true,
  "data": {
    "id": "9f5e2c3a-...",
    "customOrderId": "KS0000",
    "productName": "Bluetooth Earbuds Pro",
    "status": "Unpaid",
    "formCreationDate": "2026-05-10T08:14:32",
    "lastUpdated": "2026-05-13T11:02:08",
    "realImages": [
      { "id": "...", "image": "https://files.example.com/uploads/real-1.jpg",  "addedAt": "2026-05-13T10:55:00" },
      { "id": "...", "image": "https://files.example.com/uploads/demo.mp4",   "addedAt": "2026-05-13T11:00:00" }
    ],
    "destinations": [
      {
        "id": "d4...",
        "country": "Gabon",
        "city": "Libreville",
        "quantity": 50,
        "service": { "name": "DHL", "recipientName": "Jane Doe" },
        "quotation": {
          "totalCost": 1840.00,
          "unitPrice": 35.00,
          "internationalShippingCost": 90.00,
          "deliveryCostInChina": 70.00,
          "extraFees": 0.00
        }
      }
    ]
  }
}

تعديل طلب

PUT/api/partner/sourcing/{orderId}

نفس بنية جسم الإرسال. أعد تمرير id كل وجهة لتحديثها في مكانها (يحافظ على عرض السعر المرتبط بها). الوجهات غير المُرسلة تُحذف؛ الوجهات الجديدة (بدون id) تُنشأ.

قابل للتعديل فقط عندما تكون الحالة Processing أو Unpaid. أي حالة أخرى تُرجع 409 Conflict.

رفع ملف

POST/api/partner/uploads

نموذج Multipart. يُرجع رابط S3 دائم يمكنك إعادة استخدامه كـ productImageUrl، url إثبات دفع، إلخ.

bash
curl -X POST https://kuaisourcing.com/api-back/api/partner/uploads \
  -H "x-api-key: $KEY" \
  -F "file=@receipt.pdf" \
  -F "purpose=proof-of-payment"

# Response
{
  "success": true,
  "data": {
    "url": "https://files.example.com/uploads/receipt.pdf",
    "size": 27695,
    "contentType": "application/pdf"
  }
}

المقبولة: jpg, jpeg, png, webp, pdf, mp4, mov, webm. الحد الأقصى 25 ميغابايت.

إرسال إثبات دفع

POST/api/partner/sourcing/{orderId}/proof-of-payment

أرفق وصل دفع بطلب موجود. ارفع الملف أولاً عبر نقطة uploads وأرسل الرابط الناتج هنا.

json
{
  "country": "Gabon",
  "url": "https://files.example.com/uploads/receipt.pdf",
  "paymentNote": "Bank transfer EUR to USD, reference KS0000"
}

عند النجاح، تنتقل حالة الطلب تلقائياً من Unpaid إلى Payment pending ويُطلق Webhook بـ order.status_changed.

قائمة الخدمات المتاحة

مزال التكرار حسب الاسم (مع تجاهل حالة الأحرف). خدمة واحدة قد تعمل في عدة دول، كل صف يعرض قائمة التغطية.

GET/api/partner/services
json
{
  "success": true,
  "data": [
    { "id": "00000000-0000-4000-8000-000000000001", "name": "Example Freight Co", "countries": ["Morocco"] },
    { "id": "00000000-0000-4000-8000-000000000002", "name": "Sample Logistics",   "countries": ["Senegal", "Madagascar"] },
    { "id": "00000000-0000-4000-8000-000000000003", "name": "Demo Shipping Line", "countries": ["Spain"] }
  ]
}

قواعد اختيار الخدمة

الحقل المُرسَلالسلوك
serviceIdالأفضل، غير ملتبس، يربط بصف الكتالوج المحدد
serviceمطابقة بالاسم، تتجاهل حالة الأحرف. "DHL" = "dhl" = "Dhl".
service: "Other ..."انظر الشحن الذاتي، حقول إضافية مطلوبة.
أي قيمة أخرى‏400 مع "Service 'X' is not in our catalog…"

الشحن الذاتي

عندما تتولى الشحن بنفسك، سائقك الخاص، شركة شحن محلية، أو الاستلام الشخصي، اضبط service: "Other ..." على الوجهة وقدّم نفس الحقول التي يملؤها مستخدم عادي في واجهتنا.

الحقلمطلوبالغرض
customService
نعم
اسم حر لشركة الشحن/السائق (مثلاً: "شركة الشحن المحلية في تونس")
recipientName
نعم
الشخص المستلم في الوجهة
contactNumber
نعم
هاتف المستلم، يستخدمه السائق المحلي
isCompanyServiceاختياريافتراضياً false. اضبطه true لشركات الشحن المسجلة.
address, cityاختياريموروث من الوجهة، يُستخدم أيضاً كعنوان الشحن.

هذه الصفوف مُعلَّمة userSubmitted=true في الخادم، لذا لا تظهر أبداً في كتالوج الخدمات المشترك.

إذا كان أي حقل مطلوب مفقوداً، تُرجع الواجهة 400 مع إشارة إلى هذا القسم.

Webhooks

اضبط رابط Webhook عند إنشاء مفتاح API. نسلّم الأحداث بشكل غير متزامن مع توقيع HMAC-SHA256 ومحاولات إعادة عند الفشل.

الحدثيُطلَق عندما…
quotation.createdيُصدر المسؤول عرض سعر على إحدى وجهاتك
quotation.updatedيتم تعديل عرض سعر قائم
order.status_changedتتغير الحالة (مثلاً Unpaid → Paid → In Production → Shipped)
realimages.addedتُرفَع صور/فيديوهات للمنتج الفعلي

إذا كان notificationEmail مُعدّ أيضاً على مفتاحك، فإن نفس الأحداث تُطلق ملخصاً عبر البريد بالتوازي. كلا القناتين اختياريتان.

التسليم + إعادة المحاولات

بأفضل جهد. نعيد المحاولة على الاستجابات غير 2xx بتراجع أُسي (1 ث، 2 ث، 4 ث، 8 ث، 16 ث). استجب بـ 2xx خلال 10 ثوانٍ وإلا اعتبرنا المحاولة فاشلة.

صيغة الأخطاء

كل الأخطاء تشترك في نفس المغلف. حالة HTTP لها معنى، يجب أن يتفرّع عميلك بناءً عليها قبل قراءة الجسم.

json
HTTP 400 Bad Request
{
  "success": false,
  "data": null,
  "error": "destinations: At least one destination is required",
  "timestamp": "2026-05-18T11:42:03.581"
}
الكودالمعنى
400فشل التحقق، راجع حقل error لمعرفة المشكلة. لا تُعد المحاولة دون تصحيح.
401x-api-key مفقود أو غير صالح
403المفتاح ملغى أو تم تجاوز الحصة
404الطلب أو المورد غير موجود (أو ليس مملوكاً لمفتاحك)
409الطلب في حالة لا تسمح بالتعديل
429تجاوز معدل الطلبات، تراجع وأعد المحاولة
500خطأ في الخادم، إعادة المحاولة مع تراجع أُسي آمنة

ملخص نقاط النهاية

الطريقة · المسارما يفعله
POST /api/partner/sourcingإنشاء طلب توريد
GET /api/partner/sourcingقائمة طلباتك (مُجزّأة وقابلة للتصفية)
GET /api/partner/sourcing/{orderId}جلب طلب واحد (تفاصيل كاملة)
GET /api/partner/sourcing/by-order-id/{customOrderId}نفس الشيء، بواسطة كود KS
PUT /api/partner/sourcing/{orderId}تعديل (فقط Processing / Unpaid)
POST /api/partner/uploadsرفع ملف → رابط S3 دائم
POST /api/partner/sourcing/{orderId}/proof-of-paymentإرفاق وصل دفع؛ تنتقل الحالة Unpaid → Payment pending
GET /api/partner/servicesقائمة كتالوج خدمات الشحن
هل تريد الدمج؟
راسلنا على باسم شركتك + رابط Webhook الذي ستستقبل عليه. نُجهّز المفاتيح في أقل من 24 ساعة.
الحالة والجاهزية
نستهدف 99.9% على الواجهة. إذا رأيت أخطاء 5xx مستمرة أو صمت Webhook، راسلنا على .
Kuai Sourcing: China Sourcing & Freight to 85+ Countries