واجهة برمجة التطبيقات لشركات الشحن الشريكة
أرسل طلبات التوريد نيابةً عن عملائك، استقبل عروض الأسعار، حمّل إثباتات الدفع، وتابع تحديثات حالة الطلب عبر Webhooks موقّعة، كل ذلك عبر HTTPS بمفتاح API واحد.
نظرة عامة
تتيح واجهة الشركاء لشركة شحن أو شريك توريد خارجي إنشاء طلبات داخل منصتنا برمجياً. يمر كل طلب عبر نفس مسار التنفيذ المستخدم في واجهتنا، ويستقبل الشريك إشعارات Webhook عند كل تغيير حالة مهم.
https://kuaisourcing.com/api-backجميع نقاط النهاية أدناه نسبية لهذا العنوان.المصادقة
كل طلب يجب أن يحتوي على مفتاح API في رأس x-api-key. يحدد المفتاح حساب الشريك المتصل، احتفظ به سرياً.
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 عند كل انتقال.
الحالات النهائية خارج المسار: Cancelled, Refunded, Order Rejected, OutOfStock.
إرسال طلب توريد
يمكن أن يتضمن الطلب الواحد عدة وجهات. يجب على كل وجهة تحديد خدمة الشحن، من كتالوجنا أو شحن ذاتي.
{
"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
{
"success": true,
"data": {
"orderId": "9f5e2c3a-...",
"customOrderId": "KS0000",
"message": "Sourcing request submitted successfully"
}
}استخدم orderId (UUID) في كل النداءات اللاحقة. customOrderId (KS0001, KS0002, …) هو نفس المعرّف التسلسلي الذي يظهر في لوحة تحكمنا الداخلية.
قائمة طلباتك
| المعامل | الافتراضي | ملاحظات |
|---|---|---|
| status | (any) | تصفية حسب الحالة بالضبط (انظر قسم دورة الحياة) |
| details | true | false لإرجاع حمولة أخف (بدون عروض / صور / وجهات) |
| page | 0 | مفهرس من الصفر |
| size | 100 | الحد الأقصى 100 |
يُرجع صفحة Spring من الطلبات (انظر جلب طلب لمعرفة البنية).
جلب طلب
كلا الشكلين يُرجعان نفس الحمولة.
{
"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
}
}
]
}
}تعديل طلب
نفس بنية جسم الإرسال. أعد تمرير id كل وجهة لتحديثها في مكانها (يحافظ على عرض السعر المرتبط بها). الوجهات غير المُرسلة تُحذف؛ الوجهات الجديدة (بدون id) تُنشأ.
رفع ملف
نموذج Multipart. يُرجع رابط S3 دائم يمكنك إعادة استخدامه كـ productImageUrl، url إثبات دفع، إلخ.
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 ميغابايت.
إرسال إثبات دفع
أرفق وصل دفع بطلب موجود. ارفع الملف أولاً عبر نقطة uploads وأرسل الرابط الناتج هنا.
{
"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.
قائمة الخدمات المتاحة
مزال التكرار حسب الاسم (مع تجاهل حالة الأحرف). خدمة واحدة قد تعمل في عدة دول، كل صف يعرض قائمة التغطية.
{
"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 لها معنى، يجب أن يتفرّع عميلك بناءً عليها قبل قراءة الجسم.
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 لمعرفة المشكلة. لا تُعد المحاولة دون تصحيح. |
401 | x-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 | قائمة كتالوج خدمات الشحن |