# 18 — الرصيد التشغيلي وعمولة السائق (نموذج الدفع المسبق) > **طبقتان مختلفتان لا تُخلطان:** > - **[05-pricing-billing](05-pricing-billing.md)** = كيف تقبض **Tripz** من المستأجر (اشتراك + نسبة GMV). > - **هذا الملف** = كيف يقبض **المستأجر** (سيرو مثلاً) عمولته من **سائقيه**. > > مصدره: قرار المالك (2026-07-17) — «فلسفة التطبيق اللي بدنا إياه». --- ## 1. الفكرة في سطر واحد السائق **يشتري رصيداً تشغيلياً مقدَّماً**. الراكب يدفع للسائق **الأجرة كاملة** (كاش أو محفظة). المنصة **لا تلمس أجرة الرحلة إطلاقاً** — بل تخصم عمولتها من الرصيد التشغيلي المدفوع سلفاً. ## 2. المثال المرجعي (كلام المالك حرفياً) ``` السائق يشحن رصيده التشغيلي → 4.000 دينار الراكب يصل ويدفع للسائق (كاش/محفظة) → 4.000 دينار ← يأخذها السائق كاملة عمولة التطبيق 10% من 4.000 → 0.400 دينار تُخصم من الرصيد التشغيلي → 4.000 - 0.400 = 3.600 دينار ``` **الرصيد التشغيلي بعد الرحلة = 3.600 دينار.** أجرة الراكب لم تُمسّ. > ملاحظة على الترقيم: الـ«4 دنانير» في المثال صدفة — رصيد الشحن وأجرة الرحلة رقمان مستقلان تماماً. لو شحن السائق 50 ديناراً وأنهى نفس الرحلة لصار رصيده 49.600. ## 3. هل هذا نموذج متعارف عليه عالمياً؟ — **نعم، لكنه ليس نموذج أوبر** هناك نموذجان سائدان، وكلاهما شرعي: | | **اقتطاع من الأرباح (take-rate)** | **الرصيد المدفوع مسبقاً (prepaid credit)** ← نموذجنا | |---|---|---| | **من يقبض المال؟** | المنصة تقبض الأجرة ثم تحوّل للسائق الصافي | السائق يقبض الأجرة كاملة مباشرة | | **من يستعمله** | Uber · Bolt · Careem · Grab · Didi | **inDrive** · Yango/Yandex (شركاء) · Maxim · أغلب التطبيقات المحلية في الشرق الأوسط وأفريقيا وجنوب آسيا · **سيرو** | | **يناسب** | أسواق الدفع الإلكتروني الغالب | **أسواق الكاش الغالب** | | **مشكلة الكاش** | السائق يصير **مديناً** للمنصة → تحصيل ومطاردة وديون معدومة | **لا توجد** — العمولة مقبوضة سلفاً | | **التدفق النقدي** | متأخر | **مقدَّم** | | **حاجز الدخول للسائق** | صفر | يدفع قبل أن يكسب ← يحتاج معالجة | **الحكم:** النموذج الذي تصفه هو **المعيار الفعلي في الأسواق التي تستهدفها** (سوريا · الأردن · مصر) حيث الكاش هو الغالب. أوبر نفسها في الأسواق كثيفة الكاش تضطر لتتبّع **رصيد سائق سالب** ثم مطاردة تحصيله — وهو بالضبط الوجع الذي يلغيه نموذجك من أصله. اختيارك سليم، وليس نسخاً أعمى عن سيرو. **لكن ثمنه ثلاثة التزامات** (تفصيلها في §5): الحجب عند نفاد الرصيد، وباقات شحن لكل عملة، ومعالجة حاجز دخول السائق الجديد. ## 4. ما الذي يتغيّر في الكود (تصحيح لما نُفِّذ في B6) الشريحة الأولى من المجموعة B (commit `f3fdc1b`) نُفِّذت على **نموذج الاقتطاع**: ```ts price_for_driver = price_for_passenger - commission // ❌ ليس فلسفتنا ``` الصحيح حسب هذا المستند: ```ts price_for_driver = price_for_passenger // السائق يأخذ الأجرة كاملة commission_amount = split(price_for_passenger) // تُحسب وتُسجَّل على الرحلة → ثم تُخصم من driver_credit (رصيد منفصل تماماً)، لا من الأجرة ``` **`price_for_driver` و`price_for_passenger` يبقيان مفيدين** — لكن سبب اختلافهما ليس العمولة، بل: خصم على الراكب (كوبون/عرض) بينما السائق يقبض كاملاً، أو مكافأة تفاوض (`ai_negotiated_bonus` عند سيرو). ## 5. الآليات المطلوبة ### 5.1 الرصيد التشغيلي (`driver_credit`) - محفظة **ثانية منفصلة** عن محفظة أرباح السائق. لا تُخلط: هذه للعمولة سلفاً، وتلك لأمواله. - دفتر قيود append-only + خصم ذرّي — **نفس نمط I1 حرفياً** (`UPDATE … WHERE balance >= :amount`). - الخصم يحدث عند `completed` (لا عند `paid`): الرحلة تمّت فالعمولة استُحقّت، بغضّ النظر عن وسيلة الدفع. ### 5.2 الحجب عند نفاد الرصيد — **الالتزام الأهم** بلا حجب، النموذج **ينهار**: سائق برصيد صفر يعمل مجاناً إلى الأبد. ``` driver_credit < min_balance → لا يدخل فهرس geo:drivers:available → لا تُعرض عليه رحلات → إشعار: «اشحن رصيدك التشغيلي» ``` - الفحص عند: `setOnline` وقبل `accept` وبعد كل خصم. - `min_balance` لكل مستأجر/عملة (قد يكون صفراً أو أعلى من أغلى عمولة متوقعة). - **سباق حقيقي**: رحلة تُنهى ورصيده لا يكفي العمولة → نسمح بأرضية سالبة محدودة (`credit_floor`، مثلاً −1 عمولة) ثم نحجبه فوراً. البديل (رفض الخصم) يعني عمولة ضائعة. ### 5.3 باقات الشحن لكل عملة كما في سيرو — لكل عملة باقاتها وأسعارها: ``` JOD: [5, 10, 25, 50] SYP: [50k, 100k, 250k] EGP: [100, 250, 500] ``` - الشحن عبر **[07-integrations](07-integrations.md)** وطرق الدفع لكل دولة (كليك · شام كاش · إي كاش · بيموب · فوري …). - باقة قد تحمل **حافزاً**: «اشحن 50 واحصل على 55» — أداة تسويق مباشرة بيد المستأجر. - الحافز يُسجَّل قيداً منفصلاً في الدفتر (`bonus`) لا يُخلط بالمدفوع فعلاً — وإلا فسدت المحاسبة. ### 5.4 حاجز دخول السائق الجديد النموذج يطلب من السائق أن يدفع **قبل** أن يكسب — وهذا يقتل التجنيد. المعالجات (قرار مالك، لا افتراض تقني): - **رصيد ترحيبي** (مثلاً 5 دنانير مجاناً) — الأشيع. - **فترة سماح** (أول 7 أيام أو أول 20 رحلة بلا خصم). - **أرضية سالبة أوسع للسائق الجديد** ثم تُشدَّد. ### 5.5 وسيلة الدفع لا تغيّر شيئاً | الدفع | من يقبض الأجرة | من أين العمولة | |---|---|---| | كاش | السائق مباشرة | الرصيد التشغيلي | | محفظة الراكب | السائق (تُحوَّل لمحفظة أرباحه) | الرصيد التشغيلي | **قاعدة واحدة لا استثناء لها** — وهذا أبسط بكثير من تفريع المنطق حسب وسيلة الدفع، وهو ما قاله المالك حرفياً: «إن كانت كاش أو محفظة». > **مفارقة تستحق الانتباه:** في الدفع بالمحفظة، المنصة **تلمس المال فعلاً**، فتستطيع تقنياً اقتطاع العمولة منه. لكننا **لا نفعل** — عمداً. لأن قاعدتين مختلفتين حسب وسيلة الدفع تعني منطقاً مزدوجاً، ومحاسبةً مزدوجة، وسائقاً لا يفهم لماذا اختلف دخله. الاتساق أثمن من التحسين هنا. ## 6. لماذا تُحسب العمولة على الرحلة رغم أنها تُخصم من مكان آخر؟ لأن `commission_amount` على الرحلة هو **سبب** القيد في دفتر الرصيد التشغيلي. بدونه لا يستطيع السائق (ولا خدمة العملاء) الإجابة عن: «لماذا نقص رصيدي 400 فلس؟». كل خصم يشير إلى `trip_id`. ## 7. البنود المطلوبة (تُضاف للـ[17-backend-backlog](17-backend-backlog.md) كمجموعة J) | # | البند | |---|-------| | J1 | جدول `driver_credit` + دفتر قيوده — خصم ذرّي داخل معاملة (نمط I1) | | J2 | خصم العمولة من الرصيد التشغيلي عند `completed` (لا من الأجرة) | | J3 | **تصحيح B6**: `price_for_driver = price_for_passenger` (السائق يقبض كاملاً) | | J4 | الحجب عند نفاد الرصيد: `setOnline` + `accept` + بعد كل خصم | | J5 | باقات الشحن لكل عملة + الحافز كقيد منفصل | | J6 | رصيد ترحيبي / فترة سماح للسائق الجديد | | J7 | أرضية سالبة محدودة (`credit_floor`) لسباق «أنهى الرحلة ورصيده لا يكفي» | | J8 | شاشة/نقاط: رصيدي · تاريخ الخصومات · الشحن | --- ← ذو صلة: [05-pricing-billing](05-pricing-billing.md) · [17-backend-backlog](17-backend-backlog.md) · [19-entitlements-licensing](19-entitlements-licensing.md)