Files
tripz-llc/docs/07-integrations.md
Hamza-AyedandClaude Sonnet 5 d4ac38ca87 feat: P1 — بوابات دفع حقيقية (PayMob) + إغلاق ثغرة webhook حرجة
الأهم أولاً: `PaymentsService.webhook()` كان يقبل أي جسم `{ payment_id }`
بلا أي تحقّق توقيع — من يعرف معرّف دفعة معلَّقة كان يستطيع تحويلها «ناجحة»
ويشحن رصيداً من عدم (محفظة راكب أو رصيد سائق تشغيلي). الآن كل تغيير حالة
محروس بـ`adapter.verifyWebhook(headers, payload, tenant)`، ولا شيء يُقرأ من
الحمولة قبل ذلك كقرار ثقة — قراءة المرجع لتحديد المستأجر ليست قراراً.

البنية (docs/07 · docs/24 — P1):
- `PaymentAdapter`: charge() يعيد instant (كاش) · redirect (بوابة API حقيقية)
  · invoice (بلا API، تسوية عبر P2).
- PayMob (مصر): تسلسل auth→order→payment_key→iframe حقيقي عبر fetch،
  وتحقّق HMAC-SHA512 على تسلسل حقول ثابت (بروتوكول PayMob الرسمي بالضبط)
  بمقارنة ثابتة الزمن. مفاتيح كل مستأجر مستقلة — حساب تاجر خاص به.
- كليق/شام كاش/MTN/سيرياتيل/زين كاش: محوّل مشترك واحد لأن سلوكها متطابق
  فعلياً في سيرو (`create_*_invoice.php` تُنشئ فاتورة فقط، لا نداء بوابة
  حيّاً) — مرجع + حساب استلام معروض، والتسوية عبر رسالة SMS لا webhook.
  MTN/سيرياتيل الحقيقيَّين (توكن+OTP) موثَّقان كبند مفتوح: لا نبني تكاملاً
  لا نملك اعتماداً حيّاً للتحقّق منه.
- `PATCH /payments/settings` لأدمن المستأجر: مفاتيح PayMob · حسابات
  الاستلام · سرّ webhook الرسائل — الاستجابة لا تُعيد الأسرار.

تنظيف: إزالة الإشارات المتبقّية لحاوية `martin` من docs/07 (أُزيلت فعلياً
سابقاً)، وتحديث هيكل الكود الموثَّق ليطابق ما هو مبنيّ فعلاً.

25 اختباراً جديداً (226 إجمالاً) — منها توقيع PayMob محسوب فعلياً ومُتحقَّق،
وتلاعبٌ بالحمولة بعد التوقيع يُرفض، وسبع حالات تثبت إغلاق ثغرة الـwebhook.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 15:50:05 +03:00

3.6 KiB

07 — طبقة التكاملات

المبدأ: كل تكامل خارجي = محوّل (Adapter) خلف واجهة موحّدة، يُفعَّل من country pack. إضافة مزوّد جديد = ملف adapter واحد، لا مساس بالمنطق.

1. الدفع (Payment Adapters) — منجَز (docs/24 — P1)

interface PaymentAdapter {
  charge(ctx, tenant): Promise<ChargeResult>   // instant | redirect | invoice
  verifyWebhook(headers, rawBody, tenant): boolean
  parseWebhook(payload): WebhookResult | null
}
المزوّد النمط الفعلي السوق
Cash instant الكل
PayMob redirect — API حقيقية (auth→order→payment_key→iframe) + HMAC مصر
CliQ · شام كاش · MTN · سيرياتيل · زين كاش invoice — بلا API فعلية، مرجع + تسوية عبر SMS (P2) الأردن/سوريا
  • التسويات (settlements) للسائقين والمستأجر عبر BullMQ + سجل payouts.
  • فلسفة المال (إيراد مقابل أمانة) ومحفظتا المستأجر: 24-tenant-wallet-revenue.

2. OTP و SMS

  • ذاتي أولاً (أصل موجود من مشروعك) + مزوّد احتياطي لكل دولة.
interface SmsAdapter { send(phone, message): SmsResult }
  • طول الـ OTP و TTL من country pack.

3. واجهة المنظّم الحكومي (ميزة تُباع لا عبء)

  • نقطة تصدير/بث موحّدة: رحلات، سائقون، مركبات — قابلة للتشكيل لكل هيئة.
  • مصمّمة على شاكلة متطلبات هيئة تنظيم النقل البري (تعليمات النقل الذكي).
interface RegulatorAdapter {
  exportTrips(range): RegulatorPayload
  streamTrip(trip): void      // بث لحظي حيث يُطلب
}
  • فصل الأدوار قانونياً: نحن مزوّد تقنية، المستأجر هو المشغّل المرخّص (يُوثَّق في العقد).

4. الإشعارات

  • FCM للراكب والسائق (قوالب من notifications).
  • Webhooks عامة للمستأجرين المتقدمين (أسطول+/سيادة): نظام محاسبة، ERP أسطول... — توقيع HMAC + إعادة محاولة.

5. الخرائط (انطلق) — الخندق التنافسي

  • البلاطات من خوادم انطلق نفسها مباشرة — لا نستضيفها (قرار مصحَّح 2026-07-18، docs/25 §1: أُزيلت حاوية martin التي كانت مخطَّطة سابقاً؛ انطلق منصّة قائمة بذاتها، دورنا طلبٌ وردّ).
  • الترميز/التوجيه/snapping من واجهات انطلق عبر سيرفرنا (يحمي المفتاح ويكيّش).
  • صفر اعتماد على Google في القلب.
  • سطر البيع: «خرائط غير محدودة مشمولة — بلا فاتورة للأبد».

هيكل الكود (الفعلي)

backend/src/integrations/
├── payments/
│   ├── payment-adapter.interface.ts
│   ├── cash.adapter.ts
│   ├── paymob.adapter.ts       # API حقيقية + HMAC
│   ├── invoice.adapter.ts      # cliq/shamcash/mtn/syriatel/zaincash — بلا API
│   └── payment-gateway.registry.ts
├── gemini/       # رؤية: وثائق + وجه + تحليل رسائل التحويل (P2)
└── otp/          # nabeh · kazumi + التوجيه حسب country pack

← السابق: 06-tenant-model · التالي: 08-data-model