الصفحات والفلاتر في الـ API
كيف تُقسَّم قوائم الـ API إلى صفحات (page و per_page و meta) وأي الفلاتر تعمل فعلاً، ومنها قيم stage في واجهة التاجر: القيمتان processing و awaiting_funds تُتجاهلان بينما ترفض واجهة الشركة القيم المجهولة.
آخر تحديث 22 أكتوبر 2026 · آخر تحقق 22 أكتوبر 2026
الغرض#
تشرح هذه الصفحة كيف تُقسَّم قوائم الـ API إلى صفحات، وأي الفلاتر تعمل فعلاً كما هي مبرمجة، وخصوصاً قيم stage المقبولة في واجهة التاجر.
من يستخدمها وما المطلوب#
- التاجر (تاجر منصة) بمفتاح API على
/api/v1، ومدير شركة التوصيل بمفتاح الشركة على/api/company/v1. راجع مقالة حدود الطلبات.
القوائم المقسّمة إلى صفحات#
| الطلب | per_page الافتراضي |
الأقصى | الترتيب | الفلاتر |
|---|---|---|---|---|
GET /api/v1/parcels |
20 | 100 | الأحدث أولاً (بحسب id) |
reference وfrom وto وstage |
GET /api/v1/statement |
100 | 500 | الأقدم أولاً (التاريخ ثم id) |
from وto وwallet وcategory |
GET /api/company/v1/parcels |
20 | 100 | الأحدث أولاً (بحسب id) |
merchant_id وdeliveryman_id وreference وfrom وto وupdated_since وstage |
GET /api/company/v1/merchants |
50 | 100 | بحسب id تصاعدياً |
q |
أما هذه القوائم فلا ترقيم لها، وتعيد كل السجلات دفعة واحدة: في واجهة التاجر /companies و/governorates و/pickup-locations و/warehouse/stock و/webhooks و/webhooks/events، وفي واجهة الشركة /deliverymen.
شكل الرد#
{
"success": true,
"data": [ { "id": 1043, "tracking_number": "DS261013AB12CD", "reference": "ORDER-1043", "stage": "delivered", "status_code": 9 } ],
"meta": { "page": 1, "per_page": 50, "total": 132, "last_page": 3 }
}
(كائنات الطرد مختصرة هنا.) المفاتيح الأربعة في meta هي الوحيدة؛ لا يوجد links ولا مؤشر (cursor). ويشذ GET /statement في data: فهي كائن يضم period وcurrency وwallets وby_category وlines (المصفوفة المقسّمة إلى صفحات)، وتُحصي meta عناصر lines وحدها. القواعد:
pageيبدأ من 1. القيمة غير الصحيحة أو الأقل من 1 تعامَل كأنها 1.per_pageخارج المجال المسموح لا يُرفض بل يُقصّ إلى أقرب حد (مثلاً 500 في قائمة الطرود تصبح 100). والقيمة الفعلية تعود فيmeta.per_page.- صفحة بعد الأخيرة تعيد
dataفارغة، وتبقىtotalوlast_pageفيmetaكما هما. وعند عدم وجود نتائج تكون قيمةlast_pageهي 1. totalهو عدد السجلات بعد تطبيق الفلاتر.
فلاتر قائمة الطرود (التاجر)#
reference: تطابق تام مع مرجع الطرد الذي أرسلته عند الإنشاء.fromوto: بصيغةYYYY-MM-DD، وتشملان اليومين، وتُقارَنان بتاريخ إنشاء الطرد (التوقيت UTC). لا يُتحقَّق من الصيغة، فلا تستعمل غيرها.stage: ست قيم فقط تعمل، وهي تطابق حقلstageفي كائن الطرد:
قيمة stage |
تطابق status_code |
|---|---|
pending |
1 |
out_for_delivery |
7 و8 |
delivered |
9 |
partially_delivered |
32 |
returning |
24 و26 و27 و11 و12 |
returned |
30 و13 |
الطرود في حالة awaiting_funds (تُنشأ مع wait_for_balance أو من طلبات المتاجر المربوطة) لا تظهر في القائمة، لكن يمكن جلب الواحد منها برقم التتبع أو بـ reference عبر GET /parcels/{tracking}.
الاختلافات في واجهة الشركة#
- أي قيمة غير معروفة في
stageتُرفض بـ422 validation_failedمع رسالة تسرد القيم المتاحة، بدل تجاهلها. - القيمة
processingتعمل هنا وتطابق الأكواد 2 و3 و4 و5 و6 و19 فقط. وأي طرد يحمل كود حالة خارج الفئات الموثّقة (مثل كود قديم أو غير معتاد) يُعرض بقيمةstageتساويprocessing، لكن هذا الفلتر لا يطابقه. أماawaiting_fundsفغير مقبولة (422). updated_sinceبصيغةYYYY-MM-DD HH:MM:SSتعيد الطرود التي تحدّثت منذ ذلك الوقت، وهي الأنسب للمزامنة الدورية.merchant_idوdeliveryman_idيُطبَّقان عند إرسالهما، ويبحثqفي قائمة التجار عن اسم النشاط أو رقم الموبايل.
فلاتر كشف الحساب (/statement)#
fromوtoتُقبلان بصيغةYYYY-MM-DDحرفياً، وإلا تُهملان ويُستعمل الافتراضي: من أول الشهر إلى اليوم. إذا كانتfromبعدtoتُبدَّلان. والمدى الأطول من 366 يوماً يُقصَّر بتحريكfromإلى 366 يوماً قبلtoبدون خطأ.wallet: إحدى القيمrechargeأوheldأوreturnأوpayout_pending، وإلا تُهمل.category: أحرف لاتينية صغيرة وشرطة سفلية (من 2 إلى 60 حرفاً)، ولا تُقارَن بقائمة فئات معروفة: فالقيمة غير المعروفة لا تعيدlinesويبقىby_categoryفارغاً، أماwalletsفتبقى فيها المحافظ برصيدَي الافتتاح والإغلاق، وتكونcreditsوdebitsوcountأصفاراً.- أقسام
walletsوby_categoryتغطي الفترة كاملة بغض النظر عن الصفحة؛ الصفحات تخصlinesفقط.
قراءة كل الصفحات#
اطلب الصفحة 1 بقيمة `per_page` ثابتة
أرسل
per_page=100مع فلاترك، وأبقِ الفلاتر نفسها في الطلبات التالية.اقرأ `meta.last_page`
هذا هو عدد الصفحات. لا تعتمد على عدد عناصر
dataلتعرف أنك وصلت إلى النهاية.اطلب بقية الصفحات
زد
pageحتىlast_page، وعند رد 429 انتظرRetry-Afterثم أعد الطلب نفسه.تعامل مع تغيّر القائمة أثناء القراءة
تظهر الطرود الجديدة في أعلى القائمة وتختفي الملغاة، فقد يتكرر طرد أو يفوتك آخر. أزل التكرار بحسب
id، وثبّت المدى بـfromوto، وللمزامنة الدائمة استعمل الويب هوك أو (للشركات)updated_since.
import time
import requests
BASE = "https://YOUR_PLATFORM_DOMAIN/api/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Accept": "application/json"}
def all_parcels(filters):
page = 1
while True:
response = requests.get(
f"{BASE}/parcels",
headers=HEADERS,
params={**filters, "per_page": 100, "page": page},
timeout=30,
)
if response.status_code == 429:
time.sleep(int(response.headers.get("Retry-After", 60)))
continue
response.raise_for_status()
body = response.json()
yield from body["data"]
if page >= body["meta"]["last_page"]:
break
page += 1
for parcel in all_parcels({"stage": "delivered", "from": "2026-10-01", "to": "2026-10-31"}):
print(parcel["tracking_number"], parcel["stage"])
أخطاء شائعة#
- توقّع أن
stage=processingيصفّي النتائج في واجهة التاجر: لن تحصل إلا على كل الطرود. صفِّ النتائج من جانبك بحسب الحقلstage. per_page=500على الطرود: لا خطأ، لكنك لن تحصل إلا على 100؛ اقرأmeta.per_page.- تواريخ بصيغة مختلفة (مثل
13/10/2026): في قائمة الطرود لا يُتحقَّق منها (نتائج غير متوقعة)، وفي كشف الحساب تُهمل.
الصلاحيات والحدود#
يلزم مفتاح API فعّال، وميزة api في الباقة حين تنطبق الباقات على حسابك (وإلا 403 plan_feature)؛ وواجهة التاجر لتجار المنصة لا لتجار الشركات. كل طلب صفحة يحتسب ضمن 60 طلباً في الدقيقة لكل عنوان IP وضمن حد باقتك، لذلك اختر per_page كبيراً بدل كثرة الصفحات الصغيرة.
API
GET /api/v1/parcelsGET /api/v1/statementGET /api/company/v1/parcelsGET /api/company/v1/merchants