Fatorly
المطوّرون

الأخطاء

نموذج أخطاء 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 Requestbad-request‏JSON مشوّه أو غير قابل للتحليل، أو حقل لا يجتاز التحقّق، أو غياب ترويسة Idempotency-Key المطلوبة (أو تجاوزها الطول المسموح).راجع detail وerrors[]. أضِف ترويسة Idempotency-Key وصحّح أي حقول غير صالحة.
401 Unauthorizedunauthorizedترويسة X-Api-Key مفقودة أو المفتاح غير صالح أو مُلغًى.أرسل مفتاحًا صالحًا في X-Api-Key. إن كان مُلغًى، أنشئ مفتاحًا جديدًا.
402 Quota Exceededquota-exceededبلغت حصّتك الشهرية من المستندات.انتظر إعادة تعيين الحصّة أو ارتقِ بخطتك.
403 Forbiddenforbiddenالمفتاح صالح لكنه لا يملك الصلاحية (scope) التي تتطلّبها نقطة النهاية (مثل invoices:write).عدِّل صلاحيات المفتاح من الإعدادات ← مفاتيح API، أو استخدم مفتاحًا يملك الصلاحية.
404 Not Foundnot-foundنقطة النهاية أو المورد المُشار إليه غير موجود.تحقّق من العنوان ومعرّف المورد ومن أن شركة المفتاح تملكه.
409 Conflictconflictأُعيد استخدام Idempotency-Key مع جسم طلب مختلف، أو أن المستند في حالة لا تسمح بالعملية (مثل إلغاء فاتورة مُرسَلة).استخدم مفتاحًا جديدًا للطلب الجديد، أو عالج تعارض حالة المستند.
422 Validation Failedvalidation-failedفشل المستند في تحقّق PINT-AE‏ (schematron).اقرأ errors[] لمعرفة القواعد المخالفة وصحّح بيانات الفاتورة (مثل غياب exemptionReasonCode على سطر معفى).
429 Too Many Requestsrate-limitedتجاوزتَ حد عدد الطلبات (افتراضيًا 100 طلب كل 10 ثوانٍ لكل شركة).انتظر عدد الثواني الوارد في ترويسة Retry-After ثم أعد المحاولة.
500 Internal Server Errorinternal-errorخلل غير متوقَّع في المنصة.أعد المحاولة مع تباطؤ تدريجي؛ وأبلغ عن traceId إن استمر الخطأ.
502 Upstream Errorupstream-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 غير متوقَّع — يستطيع الدعم من خلالها الوصول إلى الطلب نفسه في سجلات المنصة.

ذات صلة

On this page