حركات المخزون
نموذج الحركات الملحَقة فقط، وكتابة حركة، وحدث الحركة، ولماذا الكتابة المطلقة ممنوعة.
في هذه الصفحة
هذه الصفحة لمن يزامن مخزوناً أو يسجّل تلفاً أو مرتجعات. المخزون في دكان دفتر حركات ملحَق فقط؛ لا يوجد رقم مخزون تكتبه، بل حركات تضيفها ويحتسب الخادم الرصيد منها.
النموذج#
{
"id": "0a1b2c3d-0001-4e8f-9b70-2d1c3e4f5a6b",
"sequence": 418,
"variant_id": "c0ffee00-0001-4e8f-9b70-2d1c3e4f5a6b",
"location_id": "10c00000-0001-4e8f-9b70-2d1c3e4f5a6b",
"delta": -2,
"stock_after": 23,
"reason": "damage",
"occurred_at": "2026-08-18T16:10:00.000Z"
}| الحقل | المعنى |
|---|---|
sequence |
تسلسل رتيب لكل متجر؛ رتّب به الحركات |
variant_id |
المتغير؛ قد يكون null لحركات مرتبطة بمتغير محذوف |
location_id |
الموقع (لكل متجر موقع افتراضي وربما مستودعات) |
delta |
التغيير الموقّع؛ لا يكون صفراً أبداً |
stock_after |
الرصيد في هذا الموقع بعد الحركة، كما احتسبه الخادم |
reason |
سبب الحركة |
occurred_at |
وقت الحركة بصيغة RFC 3339 |
أسباب الحركات التي يكتبها التطبيق: correction وinitial وreturn وdamage. تظهر في القراءة أسباب أخرى تكتبها المنصّة (بيع، إلغاء، تحويل)؛ عامل reason كنص مفتوح عند القراءة.
لماذا الكتابة المطلقة ممنوعة#
كتابة «الرصيد = 40» تمحو ما حدث بين قراءتك وكتابتك: بيع من واجهة المتجر، أو نقطة بيع، أو تطبيق آخر. الحركة delta: +5 بسبب correction تُجمع بأمان مع كل ما سبقها، وتترك أثراً يراجعه التاجر. لذلك لا تقبل الواجهة رقماً مطلقاً أبداً.
اكتب حركة#
يتطلب inventory:write وIdempotency-Key:
curl -X POST https://dukkan.one/platform-api/v1/inventory/movements \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Idempotency-Key: damage-SHIPMENT_ID-1" \
-H "Content-Type: application/json" \
-d @movement.json{
"variant_id": "c0ffee00-0001-4e8f-9b70-2d1c3e4f5a6b",
"location_id": "10c00000-0001-4e8f-9b70-2d1c3e4f5a6b",
"delta": -2,
"reason": "damage",
"note": "Broken in transit"
}deltaبين −1,000,000 و1,000,000 وليس صفراً.reasonمنcorrectionأوinitialأوreturnأوdamage.noteاختياري حتى 500 حرف.- الاستجابة
201تحمل الحركة المسجّلة؛ يظهرstock_afterفيها فقط عندما يحمل التثبيتinventory:readأيضاً. - حركة تُنزل الرصيد المتاح تحت الكمية المحجوزة تعيد
409، وكذلك حركة على منتج غير مُدار مخزونياً.
اقرأ الحركات#
curl "https://dukkan.one/platform-api/v1/inventory/movements?limit=100" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"يتطلب inventory:read. تُصفَّح القائمة بمؤشر مبهم؛ للمزامنة التزايدية احفظ آخر sequence عالجته وتجاهل ما دونه.
حدث inventory.movement_created#
يصل لكل حركة، من أي مصدر، إلى الاشتراكات التي تحمل inventory:read:
{
"movement_id": "0a1b2c3d-0001-4e8f-9b70-2d1c3e4f5a6b",
"variant_id": "c0ffee00-0001-4e8f-9b70-2d1c3e4f5a6b",
"location_id": "10c00000-0001-4e8f-9b70-2d1c3e4f5a6b",
"delta": -2,
"stock_after": 23,
"reason": "damage"
}يحمل الحدث stock_after مباشرة، فلا تحتاج إلى استدعاء إضافي للرصيد في هذا الموقع. رتّب الأحداث بـ sequence الغلاف كما في Webhooks.
الإرجاع مع الاسترداد#
عند استرداد مبلغ لأسطر محدّدة، يمكنك إرجاع الكميات إلى المخزون في العملية نفسها بخيار restock: { "location_id": "…" } في POST /orders/{id}/refunds. يتطلب ذلك lines في الاسترداد ونطاق inventory:write؛ تُتجاوز المنتجات غير المُدارة مخزونياً بصمت. التفاصيل في المال بالوحدات الصغرى.