# بوابة ناز المتصلة — Partner API v1

تظل روابط البوابة والدخول الموحد ثابتة. العربية افتراضية، وتُحفظ الإنجليزية في الحساب وملف `naz_locale` دون تغيير المسارات. تعديل اللغة يدمج التفضيل مع الملف ولا يمسح العنوان أو البيانات الأخرى. إنشاء الأعمال يبدأ من `/business/new` ويوثق الهوية ثم يعود مباشرة لطلب المنشأة ويفتح مساحتها بحالتها الحالية. إدخال سجل قائم لا يمنح صلاحية عليه.

## الربط والمزامنة

تقدم أي منشأة طلب اتصال، مع متجر اختياري ونطاق HTTPS ومسار واجهات وعناوين عودة وقدرات مطلوبة. تعتمد الإدارة الدخول الموحد والخدمات والاشتراكات والفواتير والمنتجات والطلبات كلّاً على حدة. لا تنشر اتصالات sandbox بيانات للعموم. إيقاف الاتصال أو المنشأة أو المتجر يوقف المعالجة. تدوير المفتاح يعيد الاتصال للاعتماد، وتظل مفاتيح الخوادم منفصلة عن هوية المستخدم.

الدخول الموحد يستخدم Authorization Code وPKCE S256 وstate وnonce وموافقات المستخدم وعناوين عودة مطابقة. تظل معرفات العملاء السابقين محفوظة؛ يحصل العميل الشريك الجديد على جمهور `naz-partner-api`. لا يفترض دعم سلة أو زد أو Shopify لاستقبال هوية خارجية دون إثبات القدرة الفعلية.

يُرسل الحدث إلى `POST /api/v1/partner/events` مع `X-Naz-Connection` وتوقيع `X-Naz-Signature: t=UNIX_SECONDS,v1=HEX`. حساب HMAC-SHA256 يشمل الوقت ثم نقطة ثم بايتات JSON الأصلية، بمفتاح الاتصال. نافذة الوقت ٣٠٠ ثانية؛ يعاد توقيع المحاولة بوقت جديد مع إبقاء معرف الحدث ومحتواه ثابتين. تكرار المعرف بمحتوى مختلف تعارض، والإصدار الأقدم لا يطبق.

غلاف الحدث: `version:1` و`id` فريد و`type` و`entityId` و`revision` متزايد و`occurredAt` و`data`. تدعم العقود المنتجات والخدمات والخطط والاشتراكات والفواتير وحالات التنفيذ واعتماد الاسترداد. التفاصيل في [مواصفة المصدر](partner-source.openapi.json)، وأمثلة الخادم في `sdk/typescript` و`sdk/php`.

تطبق البيانات الصحيحة آلياً بعد تفعيل الاتصال، ويُعزل المرفوض مع السبب. تصحيح الحدث المرفوض يكون بمعرف جديد ومراجعة أعلى. قبول HTTP لا يعني تطبيق البيانات؛ افحص `status` و`reason`. يرسل المصدر أحداثه من outbox دائم بعد اكتمال معاملته، بهدف ظهور التحديث خلال دقيقة. السحب الاحتياطي كل خمس دقائق بصفحات حتى ١٠٠ حدث، مع مطابقة يومية قابلة للاستكمال. لا يدل نقص صفحة على حذف، ولا يكسب استيراد فاتورة تاريخية نقاطاً.

## الأسعار والاشتراكات والفواتير

المصدر يحدد السعر والضريبة والمخزون ودورة الباقة ومزايا العقد وإصداره، ولا يعيد تحديث الكتالوج تسعير اشتراك قائم. تدعم الخطط فترة مخصصة بالأيام إضافة للشهر والسنة والدفعة الواحدة. لا تُختلق أسعار «يبدأ من»، ولا تترجم بيانات العميل أو التاجر تلقائياً.

تفرد الفاتورة بالاتصال ومعرف المصدر. تُحفظ بياناتها الخاصة مشفرة، ويرفض تغيير الأصل والمبالغ والهوية وبصمة المستند. إرفاق PDF أو XML يتطلب مساراً على المصدر وبصمة SHA-256. تنزيل الأصل يتحقق من صلاحية حساب المشتري والجلسة والبصمة. فواتير الفرد ترتبط بجواله الموثق ومعرف العميل لدى المصدر، وفواتير الأعمال بسجلها المعتمد. يُستبعد جوال موظف التواصل من مطابقة فاتورة المنشأة. تبقى المطابقة الملتبسة دون إسناد، دون مراجعة ملكية ثانية للمنشأة المعتمدة.

## الشراء والاسترداد والتسويات

السلة بعملة SAR ولمشترٍ واحد وبحد خمسة متاجر. يثبت كل مصدر السعر والضريبة والشحن والمخزون أولاً، ثم تنشأ دفعة Nalpay واحدة وطلبات مستقلة للبائعين. صلاحية العرض من دقيقة إلى ١٥ دقيقة. عند فشل مصدر تلغى جميع الحجوزات بواسطة `nazOrderId`، حتى لو ضاع رد الحجز؛ يجب أن يدعم المصدر الإلغاء الآمن بهذا المعرف.

الاشتراك والترقية عملية مستقلة عن سلة المنتجات. عرض الترقية من المصدر يحدد الفرق والمدة والضريبة وإصدار العقد. إثبات الدفع خادمي ويطابق المبلغ والعملة والرابط والعملية والحالة الحقيقية؛ صفحة العودة وحدها لا تكفي. الطلب المدفوع ينتظر التنفيذ دون خصم جديد. يعالج رفض التنفيذ النهائي والدفع المتأخر باسترداد موثق، دون رفع المبلغ لتجاوز حد Nalpay أو إضافة عمولة بيع.

تفصل الدفاتر المحصل والمستحق المعلق والمتاح والمحجوز والمسترد والمحوّل والمديونية. التسليم أو الاستلام أو تفعيل الخدمة يحرر فقط المتبقي بعد المرتجعات وحجوزاتها. النزاع يوقف السحب. يلزم حساب بنكي موثق ومعتمد مستقل للحوالة، وتغيير البنك يبطل الطلب القديم. إلغاء حجز التحويل يسدد المديونية أولاً. الحد الافتراضي ٢٥٠٬٠٠٠ هللة. لا يُفترض وجود تحويلات تجار آلية لدى Nalpay؛ توثق الإدارة الحوالة المنفذة فعلياً بعد المطابقة.

يوزع المرتجع الجزئي على النقد والنقاط تراكمياً وفق الدفع الأصلي، مع منع التكرار وتجاوز المحصل وعكس النقاط المكتسبة وفق القواعد السابقة. فواتير بيع التاجر مستقلة عن رسوم ناز، ولا تفرض نسبة ضريبة واحدة على الذهب والخدمات. الاسترداد المنفذ خارج المسار المعروف يوقف تسوية العملية وسحب البائع، ويظهر للمالية كاستثناء مطابقة يحتاج مستندات المصدر والمزود قبل أي قيد تصحيحي.

## الرسائل والتشغيل

تقنيات مزود بنية أساسية مستقل، يستخدم Bearer و`POST /v1/messages` وأرقاماً دولية دون علامة +. قبول المزود منفصل عن تأكيد التسليم. لا تحفظ رموز الدخول أو النصوص أو الأسرار في السجلات. لكل من الدخول والتنبيهات والحملات مسار أساسي واحتياطي؛ النتيجة المجهولة لا تعاد تلقائياً. اختبار المزود يرسل رمزاً عشوائياً لجوال الإداري الموثق نفسه؛ نجاح التحقق يفعل المسار ويوقف الرمز المؤقت.

الحملات للإدارة بصلاحية مستقلة، مع موافقة تسويقية وإلغاء اشتراك موقع واستبعاد وجدولة وحد مستلمين وحجز تكلفة محافظ. اضبط الحد الأقصى للمستلم ليشمل جميع أجزاء الرسالة ورسوم المزود، وضع سقف إنفاق لدى المزود أيضاً. تعالج رموز الدخول مباشرة، بينما تعمل الحملات في دفعات محدودة.

## حالة موصلَي البداية

تحتوي `connectors/php` على بوابة موقعة وسجل مراجعات وoutbox ومؤشر سحب دائم، وجداول إضافية مستقلة لا تعدل دفاتر المصدر. يقرأ موصل التسويق جداول الباقات الفعلية وأسعار فتراتها ومزاياها. يحتاج تصدير الاشتراكات ارتباطاً موثقاً بين مساحة العمل وسجل ناز المعتمد وفترة العقد الأصلية؛ لا تستنتج الفترة أو الخصم من السعر الحالي. يستخدم موصل كبيان محرك عرض المتجر وتسعير الذهب الموجودين، ويستقبل لقطات الفواتير الصادرة الأصلية. تكتمل المتغيرات والحذف الصريح من أحداث المصدر، ولا يُعلن دعم قدرة مالية غير منفذة.

تفعيل الإنتاج ينتظر تثبيت الربط لدى المصدرين واختبار هويتهما وحجز المخزون والفوترة وتنفيذ الطلب والاسترداد وعرض الترقية. مسار الدفع القديم الذي فُحص في التسويق يحدث اشتراك المستخدم بينما اشتراكات مساحات المنشآت منفصلة؛ لذلك لم يُستخدم لترقية الأعمال. لم تثبت فيه فوترة ضريبية أصلية أو سياسة فرق ترقية موثوقة. كذلك تنتظر الرسائل والدفع والمحافظ مفاتيحها الحقيقية واختبارات الحساب. وجود الإعدادات والعقود وحده لا يعني جاهزية أي من هذه الاتصالات للإنتاج.


---

## مرجع الوحدات السابقة والصلاحيات
# مرجع مطوري ناز — الإصدار 1

## الهوية الموحدة

Issuer: `https://sso.naz.sa/identity/realms/naz`.
Discovery: `/identity/realms/naz/.well-known/openid-configuration`.

استخدم Authorization Code مع PKCE S256 وstate وnonce. سجل لكل متجر عميلاً مستقلاً من لوحة التكاملات بعد اعتماد المتجر والتكامل وقدرة SSO. عناوين العودة HTTPS مطابقة لنطاق المتجر، دون wildcards أو query/fragment. تخزن أسرار العملاء في خادم المتجر فقط. لا تستخدم implicit flow أو password grant أو تمرر رمز ناز المؤقت إلى المتاجر.

الهوية `sub` مرجع دائم. لا تربط حسابين تلقائياً اعتماداً على الاسم أو رقم غير موثق. سلة وزد OAuth تجار، ولا يثبت ذلك دعمهما لدخول العميل بموفر خارجي. Shopify يحتاج حساب Plus وقدرة مثبتة. WooCommerce يحتاج إضافة موثقة على المتجر. الربط الخاص يستخدم OIDC القياسي.

الملف المركزي `GET /api/v1/partner/profile` يستقبل Bearer access token من عميل متجر معتمد؛ يتحقق من issuer والتوقيع وazp والحالة وموافقة العميل. أضف موافقة المشاركة من حساب العميل في ناز؛ النطاقات profile/phone/email/address/customer_sync. لا تعاد بيانات خارج النطاق. سحب الموافقة يمنع القراءة التالية. رموز الهوية قصيرة العمر، وإلغاء الجلسات يجب أن يطبق في كل منصة مرتبطة أيضاً.

## واجهات البوابة

معظم `/api/v1` تستخدم جلسة Cookie httpOnly: `__Host-naz_session`، وموافقة Origin، وهيدر `X-CSRF-Token` للكتابة. يؤخذ CSRF من `/api/v1/auth/me`. واجهات المتصفح المالية ليست مفاتيح تجار عامة. Bearer خاص بواجهة ملف الشريك أعلاه. مواصفة المسارات الفعلية في `/api/openapi.json`.

| الإجراء | المسار |
|---|---|
| بدء OIDC / العودة | GET `/api/v1/auth/start` / `/auth/callback` |
| المستخدم / الخروج | GET `/api/v1/auth/me` / POST `/auth/logout` |
| اللوحة | GET `/api/v1/dashboard` |
| المنشآت / المتاجر / الخدمات / الخطط | POST `/api/v1/organizations`, `/stores`, `/services`, `/plans` |
| التفويضات | GET/POST `/api/v1/organizations/{id}/members` |
| الحساب البنكي | POST `/api/v1/organizations/{id}/bank`، `/bank/verify` |
| إعداد تكامل / عميل هوية | PATCH `/api/v1/integrations/{id}`، POST `/{id}/oidc` |
| الموافقات | GET/POST `/api/v1/consents`، DELETE `/consents/{id}` |
| الاشتراك | POST `/api/v1/subscriptions` |
| طلب تحويل | POST `/api/v1/stores/{id}/payouts` |

## النقاط والدفع

كل مبلغ بعملة SAR وبعدد صحيح من **الهللات**. لا ترسل كسوراً عشرية. قيمة 50 ريالاً =5000 هللة، وتحتاج 50000 نقطة. التقريب نصفاً للأعلى على الرسوم والضريبة، وتستخدم أجزاء داخلية من الألف للريال لحفظ التوازن. لا تقرأ الرصيد من الجهاز ولا تعدله مباشرة.

أرسل `Idempotency-Key` ثابتاً لكل إجراء منطقي وتكراراته. المفتاح نفسه مع جسم مختلف يرفض 409. الحجز POST `/redemptions/authorize` لصاحب النقاط، والتثبيت `/redemptions/{id}/capture` للكاشير المفوض، والإلغاء `/void`. مدة الحجز 15 دقيقة. التثبيت يستهلك FIFO ويضيف مستحق المتجر داخل معاملة واحدة.

POST `/commerce/orders` يحتاج storeId/personId/sourceRef/eligibleNetMinor/totalMinor/moneyPaidMinor/nazPaidMinor. لا يقبل من متصفح أو ملف استيراد كإثبات دفع؛ يجب وجود حدث مصدر موثق يطابق جميع الحقول في inbox. POST `/commerce/orders/{id}/refunds` يحتاج storeId/refundRef/refundedEligibleNetMinor **تراكمياً**. موصل المصدر المالي لا يعتمد قبل اختبارات توقيعه واسترجاع الطلب ومطابقة التسويات. لا توجد نقطة قابلة للصرف من بيانات «paid:true» يكتبها العميل.

Nalpay لا يستقبل PAN/CVV عبر ناز. الاشتراك ينشئ طلباً في outbox، ثم صفحة subscribe_url المستضافة؛ موافقة البطاقة تتم عند نال. الشهر 30 يوماً والسنة365 وفق عقد المزود. أي فشل شبكة يعاد بنفس المفتاح. webhook `/hooks/nalpay` يتحقق من Nalpay-Signature (t.body HMAC SHA256) والجسم الخام والتوقيت±300ثانية وNalpay-Delivery==event.id والبيئة، ويحفظ الحدث قبل200. العامل يسترجع المورد من Nalpay ويتحقق من القيمة والعملة والمرجع، ولا يعتمد متصفح النجاح. الأسرار API key وwhsec تحفظ مشفرة في حقول منفصلة. لا يدعم النظام افتراضياً تحويل مستحقات التجار عبر Nalpay.

## الاستيراد والمراجعة

POST `/sync-batches`: `{integrationId,records:[{sourceId,type,data}]}` حتى1000سجل/2MiB. يعيد البصمة وتقرير الأخطاء. الرفض لا ينشر أي سجل. الاعتماد POST `/sync-batches/{id}/approve` مع sourceHash، ثم النشر `/commit` بنفس البصمة. يعاد التحقق وقت النشر، وتفشل المعاملة كاملة عند الخطأ. `/reject` يمنع نشر الدفعة. لا توجد أرصدة افتتاحية أو إعادة احتساب نقاط من التاريخ.

- product.data: name، description اختياري، url HTTPS اختياري، priceMinor صحيح>=0، currency="SAR"، sku اختياري.
- offer.data: name، description/url اختياريان، startsAt وendsAt بصيغة ISO، النهاية بعد البداية.
- customer.data: personId وconsentId لهوية موجودة وموافقة customer_sync نشطة تخص عميل التكامل. لا تنقل عنواناً أو جوالاً خاماً عبر دفعة العملاء ولا تدمج بالاسم.
- order: مرفوض في الاستيراد العام؛ مسار الأحداث المالية الموثقة مستقل.

مثال: `{"integrationId":"UUID","records":[{"sourceId":"sku-1","type":"product","data":{"name":"خاتم ذهب","priceMinor":500000,"currency":"SAR"}}]}`.

السجلات المنشورة تبقى مرتبطة بدفعتها ومصدرها؛ ظهور المتجر للعموم يحتاج أيضاً اعتماد المنشأة والمتجر وخيار النشر. النقاط المعلقة غير قابلة للصرف. لا تدعي المنصة اكتمال مزامنة مزود قبل مقارنة عدد السجلات، pagination، الحذف، أسعار/ضرائب وعملات، حالات الدفع والمرتجعات، ونتيجة replay كاملة.

## أخطاء وتشغيل

400 بيانات،401 جلسة/رمز،403 تفويض،409 تعارض/مخاطر/نسخة،429 حد محاولات،503 خدمة أو اعتماد غير جاهز. الاستجابة تحمل error.code وmessage وrequestId، دون أسرار. لا تسجل OTP أو Bearer أو cookies أو أجسام الإشعارات في سجلات HTTP.

البيئة المحلية منفصلة عن بيانات الإنتاج. قبل تفعيل موصل حقيقي ينشأ sandbox مستقل بقواعد وأسرار وأسماء شبكات مختلفة؛ لا تستخدم test keys داخل دفتر الإنتاج المالي. تجرى اختبارات التكرار والتزامن والمرتجعات وفشل الشبكة ثم اعتماد القدرة. لا تختبر خصماً أو تحويلاً مالياً حقيقياً دون إجراء تشغيلي معتمد.

## اختيار الحساب النشط

بعد الدخول، يوجه المستخدم إلى /accounts عند امتلاك أكثر من سياق. GET /api/v1/accounts يعيد الحساب الشخصي والمنشآت المفوضة وحساب الإدارة عند استحقاقه. POST /api/v1/accounts/select مع {accountId} يثبت الاختيار في الجلسة، ويدور CSRF ويعيد عنوان الوجهة. accountId إما personal أو admin أو org:UUID. لا يكفي is_admin في الهوية لتمرير عمليات الإدارة؛ يلزم اختيار حساب الإدارة. عضوية المنشأة تراجع مع كل طلب، وتمنع حسابات المنشآت الأخرى حتى يبدل المستخدم إليها.

أرسل X-Naz-Account بالقيمة النشطة في طلبات البوابة. يعاد account_changed/409 إذا استُخدمت نافذة قديمة بعد التبديل، وaccount_selection_required/409 قبل أول اختيار. الواجهة تنتقل إلى صفحة الاختيار وتبدأ قراءة جديدة؛ لا تعيد استخدام بيانات الحساب السابق. تغيير السياق لا يربط هويات جوال مختلفة تلقائياً. زر الخروج يسمح بالدخول برقم آخر.

## عضوية المحافظ والمتاجر

تفاصيل إصدار بطاقة Apple Wallet وGoogle Wallet ومتطلبات شهادات المُصدر في wallets.md. تعرض GET /api/v1/wallet/membership رقم العضوية وحالتي الجاهزية؛ POST /api/v1/wallet/google وPOST /api/v1/wallet/apple مقصوران على الحساب الشخصي مع CSRF. لا يمكن إصدار بطاقة قبل اعتماد المُصدر. الباركود للتعريف فقط ولا يجيز الاستبدال أو الدخول أو الدفع.

في حساب الشركة يضيف POST /api/v1/stores متجراً إلى organizationId النشط؛ يُرفض معرّف منشأة أخرى. إنشاء منشأة قانونية أخرى يبدأ من الحساب الشخصي أو الإدارة. الرموز المالية في الواجهة تستخدم SVG الريال الرسمي؛ تبقى عملة API هي SAR، والقيم هللات صحيحة.

## فئات العضوية والفريق

GET /api/v1/wallet/membership يعيد أيضاً membership={tier,next,tiers,qualifiedPoints,remainingPoints,progressBps}. نقاط التأهل من earned وpurchase_refunded فقط؛ لا ينقصها redeemed. الذهبية الافتراضية عند1000نقطة. PATCH /api/v1/settings/membership يقبل {tiers:[{id,name,minimumPoints,theme,benefits}]}؛ أول حد0، وحدود تصاعدية ومعرّفات فريدة، من فئتين إلى8فئات. التصميم محصور في classic/silver/gold/platinum/diamond. الواجهة تستدل على الجهاز محلياً لعرض المحفظة المناسبة، ولا تتخذ صلاحية من نوع الجهاز.

GET وPOST /api/v1/team وPATCH /api/v1/team/UUID لإدارة تفويضات الفريق، ومقصورة على المالك في سياق إدارة ناز. الإنشاء {name,phone,role}، والتعديل {name,role,enabled}؛ الدور admin أوviewer. العضو الجديد يرتبط بهوية مسجلة فقط بعد تحقق الجوال. تغيير الدور/الإيقاف يلغي الجلسات. auth/me يعرض platformRole وcanManageTeam وreadOnly؛ يمنع AuthGuard كتابة viewer من الخادم. الرمز المؤقت لا يعمم على أعضاء الفريق. تفاصيل النطاق في membership-and-team.md.


## صلاحيات فريق المنصة

توثيق الأدوار والصلاحيات التفصيلية في docs/team-permissions.md. يعيد auth/me الدور الفعلي وpermissions. عرض الصفحة والإجراء صلاحيتان مستقلتان. تغيير التفويض يلغي الجلسات. فريق المنصة مستقل عن أدوار المنشآت.


سجل نشاط الفريق: GET /api/v1/team/activity. يتطلب team.view وteam.activity في حساب الإدارة، مع مرشحات العضو والنوع والتاريخ بتوقيت الرياض وترقيم بالمؤشر. تفاصيل العقد وحدود السجلات السابقة في team-permissions.md.

## تصدير نشاط الفريق

`POST /api/v1/team/activity/export` يقبل `format` بقيمة `xlsx` أو `pdf`، ومرشحات `memberId` و`type` و`action` و`from` و`to` الاختيارية. يلزم حساب إدارة نشط وصلاحيات `team.view` و`team.activity` و`team.export`، مع Cookie جلسة و`X-CSRF-Token` و`X-Naz-Account: admin`. تاريخ النهاية شامل بتوقيت الرياض. الاستجابة 201 بملف، و`Content-Disposition: attachment`، و`X-Naz-Export-Count` و`X-Naz-Export-Id`. الحد 5000 حدث لـExcel و200 لـPDF؛ التجاوز يرجع 422 دون بتر. 429 عند الانشغال/فترة انتظار 15 ثانية، و503 عند تعذر الرسم. يسجل التصدير في التدقيق، ويعاد فحص الجلسة والصلاحيات قبل تسليم الملف.

أسعار باقات نظام التسويق شاملة للضريبة وفق تأكيد المالك. سياسة فرق الترقية أثناء مدة الاشتراك لم تُحدد بعد، ولا يُنفذ تحصيلها قبل تعريفها في المصدر واختبارها.
