إنتقل إلى المحتوى الرئيسي

عروض النقاط

الخلفية​

يحتاج نموذج إهداء النقاط إلى قائمتين: باقات النقاط (العروض) والمناسبات. وعلى Shukah يقرأهما التطبيق عبر GET /maeda/point-offer وGET /maeda/point-occasion. وفي Locate الـ routes نفسهما، وroute جديد واحد يُرجع عرضًا واحدًا. والحقول هي نفسها عند Shukah. وثلاثة أمور تستحق العناية: أن id العرض والمناسبة سلسلة من 24 حرفًا بدل رقم، وأن Locate تحتاج token حيث كانت Shukah تجيب بدونه، وأن ?id= في Shukah يُرجع القائمة كلها.

الميزة​

العرض باقة نقاط يستطيع العميل شراءها ببطاقة أو الدفع لها بالنقاط، ليرسلها إلى عميل آخر. والمناسبة هي سبب الهدية، مثل Birthday. وفي نسخة التطبيق اللحظية بتاريخ 2026-02-26 تحدث الاستدعاءات في نموذج إرسال الهدية:

الاستدعاءأين في التطبيق
قائمة العروضعندما تظهر أداة اختيار مبلغ الهدية في نموذج إرسال الهدية.
عرض واحد (?id= في Shukah)في ملخص الهدية، وفي زر الدفع (checkout)، وفي أداة اختيار طريقة الدفع. يطلب التطبيق من Shukah ?id= ثم يلتقط العرض من القائمة المُرجَعة بنفسه.
قائمة المناسباتعندما تظهر أداة اختيار المناسبة في نموذج إرسال الهدية.
مناسبة واحدة (?id= في Shukah)في ملخص الهدية. الالتقاط نفسه من جانب العميل (client-side).

تدخل المعرّفات في الاستدعاءات اللاحقة. يرسل التطبيق id العرض بوصفه point_offer_id وid المناسبة بوصفه point_occasion_id عندما يطلب نص الرسالة (وصف طلب النقاط) وعندما ينشئ الطلب (إنشاء طلب نقاط).

كل هذه تحتاج إلى token في Locate، ولا يعمل على dev اليوم إلا token من Shukah: فقد حصل JWT من Locate على 401 Invalid or expired token على قائمتَي العروض والمناسبات في 2026-10-02، مع أن الـ token كليهما عملا على route الرصيد في 2026-10-01 (انظر Which tokens work). يمرّر order-v2 كل استدعاء إلى خدمة النقاط ويُرجع الإجابة دون تغيير.

المعرّفات: خزّنها وأعِد إرسالها ولا تحلّلها أبدًا. id العرض أو المناسبة هو سلسلة hex من 24 حرفًا لصفه في قاعدة البيانات. وهو مختلف في كل بيئة، لذا يجب على التطبيق قراءة المعرّفات من القائمة وألا يكتب أيًّا منها في الشيفرة. والعدد الصحيح من Shukah المُرسَل إلى Locate بدل معرّف يُرفض بـ 400. ويحوّل التطبيق المعرّفات إلى نص بالفعل (String(id)) ويقارنها كنصوص، وهذا يعمل مع المعرّفات الجديدة، لكن أنواع TypeScript لديه ما زالت تقول number.

قاعدة is_custom. is_custom هي 0 أو 1، وليست boolean أبدًا. وعندما تكون 1 (على dev: Thank وOther) يعرض التطبيق خانة لنص حر ويرسل ما كتبه العميل في occasion، بجانب معرّف المناسبة.

GET /api/v2/client/point-offers​

يستبدل ShukahGET /maeda/point-offer✅ تم الاستبدال
استبدال مباشر0 breaking · 4 للمراقبة
  • 🟡 id سلسلة hex من 24 حرفًا (في Shukah من 1 إلى 5)؛ ويستخدم التطبيق String(id) فيعمل؛ ومعرّف Shukah يعطي 400.
  • 🟡 تحتاج Locate إلى token؛ وأجابت Shukah بـ 200 بدونه؛ ويرسل التطبيق token دائمًا.
  • 🟡 يحصل JWT من Locate على 401 على dev؛ أرسل token من Shukah.
  • 🟡 العروض الخمسة متطابقة في point_amount وpurchased_point_amount وamount ("40.00" كسلسلة نصية) وorder.

يُتجاهل المرشح ?id=؛ ولا يزال الاستدعاء يُرجع القائمة كلها.

الطلب (Request)​

الحقلالموضعالنوعمطلوبالقيودالوصف
AuthorizationheaderstringنعمBearer <token>: token من Shukah على dev اليوم. أما JWT من Locate فيحصل على 401 Invalid or expired token (التُقط على dev، 2026-10-02، على القائمتين): انظر Which tokens work.الـ token الخاص بالعميل نفسه.
idqueryanyلايُقبل ويُتجاهل: فالقائمة كلها تُرجَع دائمًا، كما يفعل ?id= في Shukah.يُبقى حتى يظل استدعاء Shukah القديم يعمل.
أي مفتاح query آخرquery—لايُقبل ويُتجاهل، مثل language.—

الاستجابة (Response)​

200 مع مصفوفة مجردة بالعروض النشطة. وقد تكون فارغة. ولا ترقيم للصفحات.

الحقلالنوعيقبل nullالصيغة / القيودالوصف
idstringلاسلسلة hex من 24 حرفًا، مثل "6a46104f3dd7b3dd6a261d90". وهي مختلفة في كل بيئة. وتُرسل Shukah عددًا صحيحًا.معرّف العرض. أعِد إرساله بوصفه point_offer_id.
point_amountnumberلارقم JSON.النقاط التي يحصل عليها المستلم.
purchased_point_amountnumberنعمnull عندما لا يكون للعرض سعر بالنقاط. وعلى dev هو أعلى من point_amount.النقاط التي يدفعها المرسِل عند الدفع بالنقاط.
amountstringلاخانتان عشريتان بالضبط، مثل "40.00".السعر بالريال (SAR) عند الدفع بالبطاقة.
[
{"id": "6a46104f3dd7b3dd6a261d90", "point_amount": 100, "purchased_point_amount": 110, "amount": "40.00"},
{"id": "6a46104f3dd7b3dd6a261d91", "point_amount": 200, "purchased_point_amount": 240, "amount": "60.00"},
{"id": "6a46104f3dd7b3dd6a261d94", "point_amount": 300, "purchased_point_amount": 360, "amount": "90.00"},
{"id": "6a46104f3dd7b3dd6a261d96", "point_amount": 400, "purchased_point_amount": 480, "amount": "120.00"},
{"id": "6a46104f3dd7b3dd6a261d98", "point_amount": 500, "purchased_point_amount": 600, "amount": "150.00"}
]

التُقط على dev، 2026-10-01 (العميل 356259): العروض الخمسة كلها.

يدفع المرسِل نقاطًا أكثر مما يحصل عليه المستلم: 110 مقابل 100، و240 مقابل 200، و360 مقابل 300، و480 مقابل 400، و600 مقابل 500. والعرض الذي قيمة purchased_point_amount فيه null لا يمكن الدفع له بالنقاط: فـ إنشاء طلب نقاط يجيب عنه بـ 400.

الترتيب. تأتي العروض مرتبة برقم تسلسلي يضبطه المسؤول، ثم بمعرّف Shukah، ثم بمعرّف الصف. وقد أُودع هذا الترتيب في 2026-10-01. وهل كان dev يشغّله وقت أخذ العينة: غير موثّق بعد.

الأخطاء​

HTTPBodyمتى
401{"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}}لا يوجد header باسم Authorization، أو لا يبدأ بـ Bearer . التُقط على dev، 2026-10-01، دون token.
401الشكل نفسه، مع message بالقيمة Invalid or expired token أو auth service unreachable: <error text> أو auth response missing numeric client id.رفضت خدمة المصادقة الـ token، أو تعذّر الوصول إليها (فعطل خدمة المصادقة يبدو كـ token سيئ)، أو أجابت دون معرّف عميل. وقد التُقط Invalid or expired token على dev، 2026-10-02، مع JWT من Locate على القائمتين.
500{"success":false,"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}}أي فشل غير متوقع في خدمة النقاط، مثل خطأ في قاعدة البيانات. وتكون الرسالة AUTH_SERVICE_URL not set عندما تكون الخدمة مضبوطة خطأً. لم يُلتقط.
502{"success":false,"error":{"code":"POINT_SERVICE_UNAVAILABLE","message":"Point service unavailable: <error text>"}}تعذّر على order-v2 الوصول إلى خدمة النقاط. وهذا الـ body صادر عن order-v2، لا عن خدمة النقاط. لم يُلتقط.
504{"success":false,"error":{"code":"POINT_SERVICE_TIMEOUT","message":"Point service did not respond in time; the request outcome is unknown"}}لم تجب خدمة النقاط خلال 10 ثوانٍ. وهذا الـ body صادر عن order-v2. لم يُلتقط.

كل خطأ صادر عن خدمة النقاط له الغلاف (envelope) {"success":false,"error":{"code":"…","message":"…"}}.

جرّبه​

export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_TOKEN='<shukah-token>' # a Locate JWT gets 401 here today; see "Which tokens work" on Points wallet
curl -s "$ORDER_BASE_URL/api/v2/client/point-offers" -H "Authorization: Bearer $SHUKAH_TOKEN"

المتوقع: 200 والمصفوفة المبيّنة تحت «الاستجابة». استخدم token من Shukah على dev اليوم: فـ JWT من Locate يحصل على 401 Invalid or expired token (2026-10-02). وبلا token تحصل على 401 المبيّن تحت «الأخطاء».

الفروق عن Shukah​

العروض الخمسة متطابقة في point_amount وpurchased_point_amount وamount وترتيب المفاتيح في 2026-10-01 ومرة أخرى في 2026-10-02. ويختلف id فقط.

الجانبShukahLocateالأثر على التطبيق
URLGET $SHUKAH_BASE_URL/maeda/point-offerGET $ORDER_BASE_URL/api/v2/client/point-offersغيّر base URL والمسار.
الـ Tokenلا حاجة إليه: 200 دون token (التُقط على dev، 2026-10-01).مطلوب: 401 دون token (التُقط على dev، 2026-10-01). وtoken من Shukah فقط على dev اليوم: فـ JWT من Locate يحصل على 401 (2026-10-02).يرسل التطبيق token الخاص به مع كل استدعاء بالفعل، ويجب أن يُبقيه token من Shukah هنا. أما شاشة تعرض العروض قبل تسجيل الدخول فستفشل. وهل توجد شاشة كهذه: غير موثّق بعد.
idعدد صحيح من 1 إلى 5 (التُقط على dev، 2026-10-01).سلسلة من 24 حرفًا.يحوّل التطبيق المعرّفات إلى نص، لذا يعمل. أما أنواعه فتقول number. لا تخلط النوعين أبدًا: فLocate ترفض العدد الصحيح من Shukah.
?id=يُرجع القائمة كلها. ويلتقط التطبيق العرض بنفسه.يُقبل ويُتجاهل: القائمة كلها مجددًا.لا شيء: فالالتقاط من جانب العميل في التطبيق يعمل مع المعرّفات الجديدة.
purchased_point_amountرقم (التُقط على dev، 2026-10-01).رقم، أو null عندما لا يكون للعرض سعر بالنقاط.يعرّفه التطبيق كرقم وينسخه إلى costInPoints. ويجب التعامل مع null.
الترتيبغير موثّق بعد.برقم تسلسلي يضبطه المسؤول، ثم معرّف Shukah، ثم معرّف الصف.إذا كان التطبيق يعرض القائمة بترتيب الخادم، فقد يتغير الترتيب.
body الخطأغير موثّق بعد. الـ route عام (public)، فلا يوجد 401 للمقارنة.غلاف خدمة النقاط الوارد تحت «الأخطاء».يجب تغيير أي شيء يطابق نص الخطأ.

GET /api/v2/client/point-offers/:id​

endpoint جديد — لا يوجد ما يقابله في Shukah.

route جديد. ليس لدى Shukah route يُرجع عرضًا واحدًا: فـ ?id= عندها يُرجع القائمة كلها، ويلتقط التطبيق العرض من تلك القائمة بنفسه. ولا يستدعي التطبيق هذا الـ route اليوم.

الطلب (Request)​

الحقلالموضعالنوعمطلوبالقيودالوصف
AuthorizationheaderstringنعمBearer <token>: token من Shukah على dev اليوم. أما JWT من Locate فيحصل على 401 Invalid or expired token (التُقط على dev، 2026-10-02، على القائمتين): انظر Which tokens work.الـ token الخاص بالعميل نفسه.
idpathstringنعم24 حرف hex بالضبط (أحرف كبيرة أو صغيرة). والعدد الصحيح من Shukah يُرفض ولا يُبحث عنه.معرّف العرض من القائمة.
أي مفتاح queryquery—لايمرّره order-v2 وتتجاهله خدمة النقاط.—

الاستجابة (Response)​

200 مع كائن واحد، بشكل صف القائمة نفسه (id وpoint_amount و purchased_point_amount وamount؛ انظر القائمة).

{"id": "6a46104f3dd7b3dd6a261d90", "point_amount": 100, "purchased_point_amount": 110, "amount": "40.00"}

التُقط على dev، 2026-10-01 (العميل 356259): العرض الأول.

الأخطاء​

HTTPBodyمتى
400{"success":false,"error":{"code":"VALIDATION_ERROR","message":"point offer id must be a 24-character hex ObjectId"}}:id ليس 24 حرف hex. ولا يوجد مفتاح details. لم يُلتقط.
404{"success":false,"error":{"code":"NOT_FOUND","message":"point offer <id> not found or inactive"}}لا يوجد عرض بذلك المعرّف، أو هو غير نشط أو محذوف. والمعرّف المكوَّن من 24 حرف hex غير الموجود يعطي 404 لا 400. لم يُلتقط.
401{"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}}لا يوجد header باسم Authorization، أو لا يبدأ بـ Bearer . التُقط على dev، 2026-10-01، دون token.
401الشكل نفسه، مع message بالقيمة Invalid or expired token أو auth service unreachable: <error text> أو auth response missing numeric client id.رفضت خدمة المصادقة الـ token، أو تعذّر الوصول إليها (فعطل خدمة المصادقة يبدو كـ token سيئ)، أو أجابت دون معرّف عميل. وقد التُقط Invalid or expired token على dev، 2026-10-02، مع JWT من Locate على القائمتين.
500{"success":false,"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}}أي فشل غير متوقع في خدمة النقاط، مثل خطأ في قاعدة البيانات. وتكون الرسالة AUTH_SERVICE_URL not set عندما تكون الخدمة مضبوطة خطأً. لم يُلتقط.
502{"success":false,"error":{"code":"POINT_SERVICE_UNAVAILABLE","message":"Point service unavailable: <error text>"}}تعذّر على order-v2 الوصول إلى خدمة النقاط. وهذا الـ body صادر عن order-v2، لا عن خدمة النقاط. لم يُلتقط.
504{"success":false,"error":{"code":"POINT_SERVICE_TIMEOUT","message":"Point service did not respond in time; the request outcome is unknown"}}لم تجب خدمة النقاط خلال 10 ثوانٍ. وهذا الـ body صادر عن order-v2. لم يُلتقط.

جرّبه​

export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_TOKEN='<shukah-token>' # a Locate JWT gets 401 here today; see "Which tokens work" on Points wallet
export OFFER_ID='<id-from-the-offers-list>'
curl -s "$ORDER_BASE_URL/api/v2/client/point-offers/$OFFER_ID" -H "Authorization: Bearer $SHUKAH_TOKEN"

المتوقع: 200 والعرض المبيّن تحت «الاستجابة». والمعرّف الذي ليس 24 حرف hex يعطي 400 المبيّن تحت «الأخطاء». استخدم token من Shukah على dev اليوم: فهذا الـ route له فحص الـ token نفسه الخاص بالقائمتين.

GET /api/v2/client/point-occasions​

يستبدل ShukahGET /maeda/point-occasion✅ تم الاستبدال
استبدال مباشر0 breaking · 4 للمراقبة
  • 🟡 id سلسلة hex من 24 حرفًا (في Shukah من 1 إلى 7)؛ ويستخدم التطبيق String(id)؛ وإرسال معرّف Shukah إلى create في Locate يعطي 400.
  • 🟡 تحتاج Locate إلى token؛ وأجابت Shukah بـ 200 بدونه؛ ويرسل التطبيق token دائمًا.
  • 🟡 يحصل JWT من Locate على 401 على dev؛ أرسل token من Shukah.
  • 🟡 الصفوف السبعة متطابقة في occasion وoccasion_en وis_custom (رقم 0/1) وترتيب المفاتيح.

الطلب (Request)​

الحقلالموضعالنوعمطلوبالقيودالوصف
AuthorizationheaderstringنعمBearer <token>: token من Shukah على dev اليوم. أما JWT من Locate فيحصل على 401 Invalid or expired token (التُقط على dev، 2026-10-02، على القائمتين): انظر Which tokens work.الـ token الخاص بالعميل نفسه.
languagequerystringلابعد حذف المسافات وتحويل الأحرف إلى صغيرة، القيمة ar بالضبط تعطي التسمية العربية. وأي قيمة أخرى، بما فيها ar-SA وen-GB، أو غياب القيمة، تعطي الإنجليزية. ولا يكون خطأً أبدًا.لغة تسمية occasion.
idqueryanyلايُقبل ويُتجاهل: فالقائمة كلها تُرجَع.يُبقى حتى يظل استدعاء Shukah القديم يعمل.

يضيف التطبيق language=en-GB أو language=ar-SA إلى كل استدعاء، لذا فبقيم التطبيق نفسه تكون التسمية إنجليزية دائمًا. وهل هذا مقصود: غير موثّق بعد.

الاستجابة (Response)​

200 مع مصفوفة مجردة بالمناسبات النشطة. وقد تكون فارغة. ولا ترقيم للصفحات.

الحقلالنوعيقبل nullالصيغة / القيودالوصف
idstringلاسلسلة hex من 24 حرفًا. مختلفة في كل بيئة. وتُرسل Shukah عددًا صحيحًا.معرّف المناسبة. أعِد إرساله بوصفه point_occasion_id.
occasionstringلاالتسمية الإنجليزية، بعد حذف المسافات الزائدة. ومع language=ar التسمية العربية، أو الإنجليزية عندما لا توجد عربية.التسمية المعروضة.
occasion_enstringلاالتسمية الإنجليزية، بعد حذف المسافات الزائدة، دائمًا.التسمية الإنجليزية.
is_customintegerلا0 أو 1، وليست boolean أبدًا.1 تعني أن التطبيق يعرض خانة لنص حر.
[
{"id": "6a4610503dd7b3dd6a261dbf", "occasion": "Birthday", "occasion_en": "Birthday", "is_custom": 0},
{"id": "6a4610503dd7b3dd6a261dc0", "occasion": "Born", "occasion_en": "Born", "is_custom": 0},
{"id": "6a4610503dd7b3dd6a261dc1", "occasion": "Gift", "occasion_en": "Gift", "is_custom": 0},
{"id": "6a4610503dd7b3dd6a261dc3", "occasion": "Wedding", "occasion_en": "Wedding", "is_custom": 0},
{"id": "6a4610503dd7b3dd6a261dc5", "occasion": "Graduation", "occasion_en": "Graduation", "is_custom": 0},
{"id": "6a4610503dd7b3dd6a261dc6", "occasion": "Thank", "occasion_en": "Thank", "is_custom": 1},
{"id": "6a4610503dd7b3dd6a261dc7", "occasion": "Other", "occasion_en": "Other", "is_custom": 1}
]

التُقط على dev، 2026-10-01 (العميل 356259)، دون language: المناسبات السبع كلها.

في التطبيق مشكلة في الأنواع موجودة مع Shukah أيضًا: فهو يقرأ التسمية الإنجليزية بالاسم occasionEn، لكن الخادمين يرسلان occasion_en، لذا فإن nameEn في التطبيق هي undefined اليوم.

الأخطاء​

HTTPBodyمتى
401{"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}}لا يوجد header باسم Authorization، أو لا يبدأ بـ Bearer . التُقط على dev، 2026-10-01، دون token.
401الشكل نفسه، مع message بالقيمة Invalid or expired token أو auth service unreachable: <error text> أو auth response missing numeric client id.رفضت خدمة المصادقة الـ token، أو تعذّر الوصول إليها (فعطل خدمة المصادقة يبدو كـ token سيئ)، أو أجابت دون معرّف عميل. وقد التُقط Invalid or expired token على dev، 2026-10-02، مع JWT من Locate على القائمتين.
500{"success":false,"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}}أي فشل غير متوقع في خدمة النقاط، مثل خطأ في قاعدة البيانات. وتكون الرسالة AUTH_SERVICE_URL not set عندما تكون الخدمة مضبوطة خطأً. لم يُلتقط.
502{"success":false,"error":{"code":"POINT_SERVICE_UNAVAILABLE","message":"Point service unavailable: <error text>"}}تعذّر على order-v2 الوصول إلى خدمة النقاط. وهذا الـ body صادر عن order-v2، لا عن خدمة النقاط. لم يُلتقط.
504{"success":false,"error":{"code":"POINT_SERVICE_TIMEOUT","message":"Point service did not respond in time; the request outcome is unknown"}}لم تجب خدمة النقاط خلال 10 ثوانٍ. وهذا الـ body صادر عن order-v2. لم يُلتقط.

جرّبه​

export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_TOKEN='<shukah-token>' # a Locate JWT gets 401 here today; see "Which tokens work" on Points wallet
curl -s "$ORDER_BASE_URL/api/v2/client/point-occasions?language=en-GB" -H "Authorization: Bearer $SHUKAH_TOKEN"

المتوقع: 200 والمصفوفة المبيّنة تحت «الاستجابة». استخدم token من Shukah على dev اليوم: فـ JWT من Locate يحصل على 401 Invalid or expired token (2026-10-02). وبلا token تحصل على 401 المبيّن تحت «الأخطاء».

الفروق عن Shukah​

الصفوف السبعة متطابقة في occasion وoccasion_en وis_custom وترتيب المفاتيح في 2026-10-01 ومرة أخرى في 2026-10-02. ويختلف id فقط.

الجانبShukahLocateالأثر على التطبيق
URLGET $SHUKAH_BASE_URL/maeda/point-occasionGET $ORDER_BASE_URL/api/v2/client/point-occasionsغيّر base URL والمسار.
الـ Tokenلا حاجة إليه: 200 دون token (التُقط على dev، 2026-10-01).مطلوب: 401 دون token (التُقط على dev، 2026-10-01). وtoken من Shukah فقط على dev اليوم: فـ JWT من Locate يحصل على 401 (2026-10-02).يرسل التطبيق token الخاص به مع كل استدعاء بالفعل، ويجب أن يُبقيه token من Shukah هنا.
idعدد صحيح من 1 إلى 7 (التُقط على dev، 2026-10-01).سلسلة من 24 حرفًا.يحوّل التطبيق المعرّفات إلى نص، لذا يعمل. لا تخلط النوعين أبدًا.
?id=يُرجع القائمة كلها.يُقبل ويُتجاهل: القائمة كلها مجددًا.لا شيء: فالالتقاط من جانب العميل في التطبيق يعمل مع المعرّفات الجديدة.
تسمية occasionالنص الإنجليزي نفسه في occasion وoccasion_en (التُقط على dev، 2026-10-01).إنجليزية، أو عربية عندما تكون language هي ar بالضبط.يرسل التطبيق ar-SA، فلا يحصل على التسمية العربية أبدًا.
الترتيبغير موثّق بعد.برقم تسلسلي يضبطه المسؤول، ثم معرّف Shukah، ثم معرّف الصف.إذا كان التطبيق يعرض القائمة بترتيب الخادم، فقد يتغير الترتيب.
body الخطأغير موثّق بعد. الـ route عام (public)، فلا يوجد 401 للمقارنة.غلاف خدمة النقاط الوارد تحت «الأخطاء».يجب تغيير أي شيء يطابق نص الخطأ.

تنبيه​

  • معرّفات العروض والمناسبات سلاسل من 24 حرفًا تختلف بين البيئات: خزّنها وأعِد إرسالها ولا تحلّلها أبدًا، ولا ترسل عددًا صحيحًا من Shukah أبدًا.
  • تتطلب Locate token على الـ routes الثلاثة، بينما كانت قوائم Shukah عامة.
  • ما زال ?id= يُرجع القائمة كلها، لذا التقط العرض أو المناسبة من المصفوفة، أو استخدم GET /point-offers/:id.

التفاصيل (للـ backend)​

فُحص dev فقط، عبر order-v2 على https://dev.v2.api.order.locate.sa، والبادئة /api/v2/client. الـ hosts في UAT وproduction: غير موثّق بعد. في هذا القسم تعني OV2: المستودع locate-order-v2-api@d9e4e5f6 وتعني PS: المستودع locate-point-service@2c44ce3. وكيف يعمل الـ proxy وفحص الـ token وغلاف الأخطاء موصوف مرة واحدة، تحت كيف تعمل الاستدعاءات الممرَّرة.

الـ Routes والـ proxy​

route التطبيق (order-v2)route المصدر (خدمة النقاط)ما يُمرَّرالحد
GET /api/v2/client/point-offersGET /api/client/point-offersAuthorization والـ query كله10 ث
GET /api/v2/client/point-offers/:idGET /api/client/point-offers/<id>، مع تمرير المعرّف عبر encodeURIComponentAuthorization والـ query كله (تتجاهله خدمة النقاط)10 ث
GET /api/v2/client/point-occasionsGET /api/client/point-occasionsAuthorization والـ query كله، لذا تصل language10 ث

(OV2: src/modules/client/point/point.controller.ts:61-108، PS: services/api/src/routes/client.routes.ts:20-22، PS: services/api/src/handlers/client-point-offers.ts:12-23، PS: services/api/src/handlers/client-point-occasions.ts:12-14.)

ما تقرؤه خدمة النقاط​

  • العروض. صفوف point_offers بحالة status: 'active' وdeleted_at: null، مرتبة بحسب sequence، ثم shukah_id، ثم _id. ولا ترقيم للصفحات ولا حد. والعرض المنشأ في Locate بلا معرّف في Shukah يُسرد كأي عرض آخر (PS: services/api/src/services/point-settings.service.ts:10-25). وقد تغيّر الترتيب في 2026-10-01 (commit 105119c، دُمج 14:25 +07)، بينما ما زالت وثيقة التكامل تقول "ordered by shukah_id" (PS: docs/plans/2026-10-01-app-language-and-arabic-reason.md:6-8، PS: docs/integrations/2026-07-16-client-facing-point-apis.md:321-322). وأُخذت الالتقاطات نحو الساعة 17:19 +07. وهل كان ذلك الـ build على dev: غير موثّق بعد.
  • عرض واحد. المرشّح نفسه على _id. والعرض غير النشط أو المحذوف يعطي 404 (PS: services/api/src/services/point-settings.service.ts:29-34). وفحص المعرّف هو ^[0-9a-fA-F]{24}$ (PS: services/api/src/lib/object-id.ts:12-14، PS: services/api/src/handlers/client-point-offers.ts:16,19-23).
  • المناسبات. صفوف point_occasions بالمرشّح نفسه، ومرتبة بالطريقة نفسها (PS: services/api/src/services/point-settings.service.ts:38-42). وقاعدة language (ar بالضبط بعد حذف المسافات وتحويل الأحرف إلى صغيرة) صدرت في الـ commit نفسه 105119c (PS: services/api/src/handlers/client-point-occasions.ts:5-8، PS: docs/plans/2026-10-01-app-language-and-arabic-reason.md:10-17).
  • المعرّفات. المعرّفات هي قيم _id الخاصة بالصفوف نفسها، معروضة كـ hex من 24 حرفًا بأحرف صغيرة. وتُقبل الأحرف الكبيرة في الإدخال (PS: services/api/src/services/point-settings.mappers.ts:25-58). أما الأعداد الصحيحة التي تستخدمها Shukah فما زالت مخزَّنة في الصفوف باسم shukah_id، لكن routes العميل لم تعد تقبلها: فـ point_offer_id الذي ليس 24 حرف hex يفشل بالرسالة must be a 24-character hex ObjectId (فُحص بتشغيل محلي للـ schema، zod 3.25.76).
  • الـ query المسمّى ?id=. لا يقرأ الـ handler أي id؛ وتُرجع القائمة كلها، وهو ما تقول وثيقة خدمة النقاط إنه يطابق Shukah، "measured on dev 2026-09-21" (PS: services/api/src/handlers/client-point-offers.ts:7-11، PS: docs/integrations/2026-07-16-client-facing-point-apis.md:324-328).
  • is_custom. يكتب الـ mapper doc.is_custom ? 1 : 0 (PS: services/api/src/services/point-settings.mappers.ts:56). والمناسبة المخصصة (custom) هي الحالة الوحيدة التي يرسل فيها التطبيق نصًا حرًا في occasion مع المعرّف (PS: services/api/src/services/point-settings.service.ts:57-58).
  • التعديلات. تُغيَّر العروض والمناسبات عبر routes المسؤول تحت /api/admin/… بمفتاح خدمة، ولا يفعل ذلك التطبيق أبدًا (PS: services/api/src/routes/admin.routes.ts:34-44).

التطبيق​

تقول أنواع التطبيق id: number للعروض والمناسبات (mobile/locate-client@e960c3a: src/entities/points/model/types/pointGiftOption.server.ts:1-6، mobile/locate-client@e960c3a: src/entities/points/model/types/pointGiftOccasion.server.ts:1-6). وتحوّل الـ DTOs المعرّف إلى نص وتحسب cost بـ Number(amount) وcostInPoints بـ purchased_point_amount وisCustom بـ String(is_custom) === '1' (mobile/locate-client@e960c3a: src/entities/points/model/api/dto/points.dto.ts:104-136). وتُرشّح دوال by-id المساعدة القائمة المُرجَعة بـ String(item.id) === request.id (mobile/locate-client@e960c3a: src/entities/points/model/api/services/points.service.ts:212-241,285-295). ويضيف interceptor اللغة language=en-GB أو language=ar-SA إلى كل استدعاء (mobile/locate-client@e960c3a: src/shared/api/interceptors/languageInterceptor.ts:5-15).

حيث تختلف الوثائق عن الشيفرة (القول للشيفرة)​

  • تقول وثيقة التكامل إن العروض مرتبة بحسب shukah_id مع _id لكسر التعادل (PS: docs/integrations/2026-07-16-client-facing-point-apis.md:321-322). أما الشيفرة فترتّب بحسب sequence أولًا.
  • 2026-10-02: قالت هذه الصفحة إن token من Shukah وJWT من Locate عملا كلاهما على هذه الـ routes. وفي 2026-10-02 حصل الـ JWT على 401 على قائمتَي العروض والمناسبات، وتستخدم استدعاءات «جرّبه» الآن token من Shukah (PS: services/api/src/services/client-auth.service.ts:22-29؛ انظر Which tokens work).

Sources​

  • locate-order-v2-api@d9e4e5f6: src/modules/client/point/point.controller.ts:61-108
  • locate-point-service@2c44ce3: services/api/src/routes/client.routes.ts:20-22، services/api/src/handlers/client-point-offers.ts:7-23، services/api/src/handlers/client-point-occasions.ts:5-14، services/api/src/services/point-settings.service.ts:10-42,57-58، services/api/src/services/point-settings.mappers.ts:25-58, services/api/src/lib/object-id.ts:12-14، services/api/src/routes/admin.routes.ts:34-44
  • وثائق locate-point-service@2c44ce3: docs/integrations/2026-07-16-client-facing-point-apis.md:321-328، docs/plans/2026-10-01-app-language-and-arabic-reason.md:6-17
  • نسخة الجوال اللحظية mobile/locate-client@e960c3a (الفرع development، 2026-02-26؛ شيفرة التطبيق نفسه، وليست من Locate): src/entities/points/model/api/services/points.service.ts:190-263,285-295، src/entities/points/model/api/dto/points.dto.ts:104-136، src/entities/points/model/types/pointGiftOption.server.ts:1-6، src/entities/points/model/types/pointGiftOccasion.server.ts:1-6، src/features/SelectPointGift/model/hooks/useSelectPointGiff.ts:16، src/features/SelectPointGiftOccasion/model/hooks/useSelectPointGiftOccasion.ts:10، src/widgets/SendPointGiftForm/ui/SendPointGiftForm/SendPointGiftForm.tsx:149-185، src/features/PointGiftSummary/ui/PointGiftSummary/PointGiftSummary.tsx:34-37، src/features/PointGiftsCheckoutButton/ui/PointGiftsCheckoutButton/PointGiftsCheckoutButton.tsx:33، src/features/SelectPointGiftPaymentMethod/model/hooks/useSelectPointGiftPaymentMethod.ts:52، src/shared/api/interceptors/languageInterceptor.ts:5-15
  • التقاطات dev، 2026-10-02 (parity audit): point-offer--shukah وpoint-offer--locate-st و point-offer--locate-jwt وpoint-occasion--shukah وpoint-occasion--locate-st و point-occasion--locate-jwt
  • التقاطات dev، 2026-10-01: locate-point-offers وlocate-point-offers-again وlocate-point-offer و locate-point-occasions وlocate-point-occasions-again وshukah-point-offer و shukah-point-occasion وprobe-locate-point-offers وprobe-locate-point-offer و probe-locate-point-occasions وprobe-shukah-point-offer وprobe-shukah-point-occasion