الأخطاء
نموذج أخطاء Integration API (RFC 7807 problem+json) والدليل الكامل لرموز الحالة مع معناها وطريقة معالجتها.
عند فشل الطلب، تُعيد Integration API رمز حالة HTTP قياسيًا وجسمًا بصيغة
RFC 7807 application/problem+json:
{
"type": "https://integration.fatorly.com/errors/validation-failed",
"title": "Validation Failed",
"status": 422,
"detail": "2 business-rule violations",
"instance": "/v1/invoices",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"errors": [
{ "field": "lines[0].vatRate", "message": "VAT rate not permitted for category S" }
]
}
| الحقل | المعنى |
|---|---|
type | مُعرِّف ثابت قابل للقراءة الآلية. اعتمد عليه (أو على status) في منطق المعالجة — ولا تعتمد أبدًا على نص title أو detail لأنه قد يتغيّر. |
title | ملخّص قصير مقروء لفئة الخطأ. |
status | رمز حالة HTTP مكرَّرًا داخل الجسم. |
detail | ما الذي حدث في هذه الحالة تحديدًا (اختياري). |
instance | مسار الطلب الذي أنتج الخطأ (اختياري). |
traceId | مُعرِّف تتبّع — أرفقه عند التواصل مع الدعم (اختياري). |
errors | أخطاء تحقّق على مستوى الحقول، بكل من field وmessage (اختياري). |
دليل الأخطاء
جميع مُعرِّفات type تقع تحت https://integration.fatorly.com/errors/:
| الحالة | لاحقة type | المعنى | كيفية المعالجة |
|---|---|---|---|
| 400 Bad Request | bad-request | JSON مشوّه أو غير قابل للتحليل، أو حقل لا يجتاز التحقّق، أو غياب ترويسة Idempotency-Key المطلوبة (أو تجاوزها الطول المسموح). | راجع detail وerrors[]. أضِف ترويسة Idempotency-Key وصحّح أي حقول غير صالحة. |
| 401 Unauthorized | unauthorized | ترويسة X-Api-Key مفقودة أو المفتاح غير صالح أو مُلغًى. | أرسل مفتاحًا صالحًا في X-Api-Key. إن كان مُلغًى، أنشئ مفتاحًا جديدًا. |
| 402 Quota Exceeded | quota-exceeded | بلغت حصّتك الشهرية من المستندات. | انتظر إعادة تعيين الحصّة أو ارتقِ بخطتك. |
| 403 Forbidden | forbidden | المفتاح صالح لكنه لا يملك الصلاحية (scope) التي تتطلّبها نقطة النهاية (مثل invoices:write). | عدِّل صلاحيات المفتاح من الإعدادات ← مفاتيح API، أو استخدم مفتاحًا يملك الصلاحية. |
| 404 Not Found | not-found | نقطة النهاية أو المورد المُشار إليه غير موجود. | تحقّق من العنوان ومعرّف المورد ومن أن شركة المفتاح تملكه. |
| 409 Conflict | conflict | أُعيد استخدام Idempotency-Key مع جسم طلب مختلف، أو أن المستند في حالة لا تسمح بالعملية (مثل إلغاء فاتورة مُرسَلة). | استخدم مفتاحًا جديدًا للطلب الجديد، أو عالج تعارض حالة المستند. |
| 422 Validation Failed | validation-failed | فشل المستند في تحقّق PINT-AE (schematron). | اقرأ errors[] لمعرفة القواعد المخالفة وصحّح بيانات الفاتورة (مثل غياب exemptionReasonCode على سطر معفى). |
| 429 Too Many Requests | rate-limited | تجاوزتَ حد عدد الطلبات (افتراضيًا 100 طلب كل 10 ثوانٍ لكل شركة). | انتظر عدد الثواني الوارد في ترويسة Retry-After ثم أعد المحاولة. |
| 500 Internal Server Error | internal-error | خلل غير متوقَّع في المنصة. | أعد المحاولة مع تباطؤ تدريجي؛ وأبلغ عن traceId إن استمر الخطأ. |
| 502 Upstream Error | upstream-error | لم تستطع البوابة الحصول على استجابة صحيحة من خدمة عليا — طلبك نفسه كان سليمًا. | أعد المحاولة مع تباطؤ تدريجي. |
Note
الفرق بين 400 و422. يعني 400 أن الطلب نفسه مشوّه — JSON غير صالح أو ترويسة مفقودة أو حقل لا يجتاز التحقّق. أما 422 فيعني أن الطلب سليم البنية لكن الفاتورة الإلكترونية الناتجة لا تجتاز قواعد PINT-AE الإماراتية.
Note
الفرق بين 500 و502. يعني 502 أن طلبك سليم لكن خطوة عليا فشلت — من الآمن
إعادة المحاولة مع تباطؤ تدريجي. أما 500 فهو خلل غير متوقَّع؛ إن استمر تواصل مع
الدعم مزوِّدًا traceId.
حدود معدل الطلبات
الطلبات محدودة لكل شركة. استجابة 429 تحمل ترويستين:
Retry-After— عدد الثواني قبل إعادة المحاولة.X-RateLimit-Remaining— دائمًا0عند رفض الطلب.
التحقّق والحصّة
- ترويسة
Idempotency-Keyإلزامية في كلPOST(باستثناء…/validate)؛ وإغفالها هو السبب الأكثر شيوعًا لـ 400. راجع معرّف عدم التكرار. - يكون
exemptionReasonCodeمطلوبًا على أي سطر يكون فيهtaxCategoryCodeبقيمةE؛ وإغفاله يُطلق خطأ تحقّق. - يتعلّق 402 بخطتك لا بطلبك — فالطلب كان صالحًا. ولن تُجدي إعادة المحاولة حتى تُعاد الحصّة.
إخفاقات التسليم بعد الإرسال
الطلب POST /invoices/{id}/submit غير متزامن: يعيد 202 بالحالة Pending،
بينما يجري التحقّق من قواعد PINT-AE والتسليم عبر Peppol في الخلفية. إذا فشل أيّ
منهما تتحوّل حالة المستند إلى DeliveryFailed — أي أنّ نجاح 202 عند
الإرسال لا يضمن التسليم.
- اعرض كل المستندات الفاشلة عبر
GET /invoices/failed— يحمل كل عنصر الحقلsubmissionErrorمع السبب (فشل قاعدة PINT-AE أو خطأ تسليم عبر Peppol). - أو استعلم عن مستند واحد عبر
GET /invoices/{id}— عندما تكون حالتهDeliveryFailedيتضمّن الردّ نفس الحقلsubmissionError.
للمعالجة: صحّح البيانات عبر PUT /invoices/{id}، ثم تحقّق عبر
POST /invoices/{id}/validate حتى يعيد "valid": true، ثم أعد الإرسال عبر
POST /invoices/{id}/submit.
Note
يُجري POST /invoices/{id}/validate نفس الفحوص التي تجري في الخلفية عند
الإرسال دون حفظ أي شيء — يمكنك استدعاؤه كما تشاء أثناء تصحيح المستند، وهو
طلب POST الوحيد الذي لا يتطلّب ترويسة Idempotency-Key.
معالجة الأخطاء في الكود
- اعتمد في منطق المعالجة على مُعرِّف
type(أوstatus)، لا على نصtitleأوdetailأبدًا. - أعِد محاولة الأخطاء العابرة (429 و500 و502 وأخطاء الشبكة والمهل
المنتهية) مع تباطؤ تدريجي، وبنفس
Idempotency-Keyفي طلبات POST كي لا تُكرّر مستندًا أبدًا. - لا تُعِد محاولة 400/401/402/403/404/409/422 دون تفكير — فهذه تحتاج إلى إصلاح (تصحيح الحمولة أو المفتاح أو صلاحياته أو خطتك)، لا إلى محاولة أخرى.
- سجِّل قيمة
traceIdلأي خطأ 500/502 غير متوقَّع — يستطيع الدعم من خلالها الوصول إلى الطلب نفسه في سجلات المنصة.
ذات صلة
- المصادقة — معالجة أخطاء 401 و403.
- معرّف عدم التكرار — معالجة أخطاء 400 الناتجة عن المفتاح المفقود وأخطاء 409.