الفاتورة الإلكترونية حالة 202: لماذا لم تُقبل فاتورتك بعد؟
TechnoVision
٢٤ سبتمبر ٢٠٢٦ · ٨ دقائق قراءة
أرسلت فاتورة إلى منظومة الفاتورة الإلكترونية التابعة لمصلحة الضرائب المصرية. رد الـ API برقم 202 Accepted. نظام الـ ERP لوّن الفاتورة بالأخضر. وبعد ثلاثة أيام يخبرك المحاسب أن الفاتورة تظهر على بوابة المصلحة بحالة Invalid (غير صالحة) وأن العميل لا يراها أصلاً.
لم تحدث مشكلة في الشبكة، ولم يتعطل شيء. المشكلة أبسط وأكثر شيوعاً: الرقم 202 لا يعني «تم القبول». الرقم 202 يعني «استلمنا الطرد». في هذا المقال نشرح ماذا يحدث فعلاً بعد الرد 202، ولماذا تتحول الفاتورة إلى Invalid بعد ساعات، وماذا تراجع عندما يحدث ذلك.
الإجابة المختصرة
واجهة برمجة منظومة الفاتورة الإلكترونية تعمل بشكل غير متزامن. عندما تستدعي Submit Documents تُجري المنظومة الحد الأدنى من الفحوصات فقط ثم ترد بـ 202 Accepted قبل اكتمال التحقق. وثائق الـ SDK تقول ذلك صراحة: الـ API يرد بـ 202 «لأن عملية التحقق لا تكون قد اكتملت عند إرجاع النتيجة».
إذن الرد 202 يخبرك بثلاثة أشياء فقط:
- الطلب الذي أرسلته مقروء من حيث البنية.
- بيانات الاعتماد (Client ID/Secret) مقبولة لهذا الممول.
- المستندات دخلت طابور التحقق الكامل.
ولا يخبرك أبداً أن الفاتورة صالحة، ولا أن العميل سيستلمها، ولا أنها أصبحت مستنداً ضريبياً معتمداً.
ماذا يعني «accepted» داخل الرد 202
حتى داخل الإرسالية الواحدة، يمكن أن يُقبل بعض المستندات ويُرفض بعضها فوراً. جسم الرد يحتوي على:
submissionUUID– معرّف الإرسالية كاملة.acceptedDocuments[]– لكل مستندuuidوlongIdوinternalId(وهو عادة رقم الفاتورة في أودو).rejectedDocuments[]– المستندات التي فشلت في الفحوصات الفورية مع كائن الخطأ.
المستند الموجود في acceptedDocuments حصل على UUID، لكنه لم يحصل على حكم بعد. الحكم يأتي لاحقاً.
دورة حياة المستند بعد 202
كل مستند تستلمه المصلحة يمر بحالة. واجهة Get Document Details تذكر خمس حالات:
| الحالة | المعنى | ما يجب أن تفعله |
|---|---|---|
| Submitted | تم الاستلام والتحقق الكامل ما زال جارياً | انتظر ثم استعلم أو استقبل الإشعار |
| Valid | اجتاز كل خطوات التحقق؛ الفاتورة الآن مستند ضريبي | خزّن الـ UUID والـ long ID واطبع مرجع المصلحة على الـ PDF |
| Invalid | فشل في خطوة أو أكثر | اقرأ validationResults وصحّح البيانات وأصدر مستنداً مصححاً |
| Rejected | العميل (المستلم) رفضها | تواصل مع العميل وأصدر إشعار خصم أو فاتورة جديدة حسب الحالة |
| Cancelled | أنت (المُصدر) ألغيتها | أصدر بديلاً إذا كانت عملية البيع ما زالت قائمة |
Valid وحدها تعني أن الفاتورة مقبولة. كل ما عداها عمل غير مكتمل.
المدة بين Submitted والحكم النهائي غير ثابتة. عملياً تكون دقائق غالباً، لكنها قد تطول في أوقات الضغط أو بعد صيانة المنظومة. لا تفترض أن المستند سليم لمجرد مرور عشر دقائق بهدوء.
لماذا تتحول المستندات إلى Invalid بعد 202
المرحلة غير المتزامنة تُشغّل «معادلة التحقق» كاملة. رد المستند غير الصالح يحتوي على validationResults وبداخلها قائمة validationSteps؛ لكل خطوة اسم وحالة، وإذا فشلت يظهر كائن الخطأ. هذه هي الخطوات الأكثر فشلاً عند مستخدمي أودو في مصر.
1. أكواد الأصناف غير المعتمدة بعد
كل سطر في الفاتورة يحتاج codeType بقيمة GS1 أو EGS مع itemCode. الخطوة تحمل اسماً مثل «GS1 code validator». الأسباب المعتادة:
- أنشأت كود EGS على البوابة لكن المصلحة لم تعتمده بعد. إرشادات GS1 مصر تذكر فترة اعتماد تصل إلى 15 يوماً لأكواد EGS؛ راجع إرشادات المصلحة الحالية لمعرفة التوقيت المعمول به اليوم.
- الكود معتمد لرقم تسجيل ضريبي آخر (شركة شقيقة أو فرع مسجل بشكل مستقل).
- الكود مكتوب في أودو ببادئة مختلفة أو بمسافة زائدة في نهايته.
الحل: ابحث عن الكود على بوابة المصلحة وتأكد أن حالته Approved لهذا الممول تحديداً، ثم صحّح المنتج في أودو وأعد الإصدار.
2. إجماليات لا تتطابق حتى خمس خانات عشرية
المصلحة تقارن الإجماليات بدقة خمس خانات عشرية. أودو يخزّن المبالغ بتقريب العملة (خانتان للجنيه) ويحسب الضريبة لكل سطر ثم لكل مجموعة. عند وجود خصم أو ضريبتين على السطر نفسه، قد يختلف مجموع salesTotal وnetTotal وtaxTotals وtotalAmount بمقدار 0.00001، فيفشل مدقق الحساب.
الحل: على مُنشئ المستند أن يعيد حساب إجماليات المصلحة من قيم السطور التي يرسلها فعلاً، لا أن ينسخ حقول أودو المقرّبة. إذا كنت تبني التكامل بنفسك، اختبر سطراً فيه خصم بنسبة مئوية وكمية 3 وسعر وحدة ينتهي بـ .33.
3. بيانات المستلم ناقصة فوق الحد القانوني
عندما يكون المستلم شخصاً طبيعياً (النوع P)، تكون بيانات الرقم القومي والاسم والعنوان اختيارية فقط إذا كان مبلغ الفاتورة أقل من الحد المعرّف قانوناً. فوق هذا الحد يجب إدخال الرقم القومي واسم المشتري. هذا الحد تغيّر عبر السنوات، لذلك راجع إرشادات المصلحة الحالية بدلاً من كتابة رقم ثابت في الكود.
الحل: اجعل نموذج العميل في أودو يطلب الرقم القومي عندما يتجاوز إجمالي الفاتورة الحد، وقبل ترحيل الفاتورة.
4. مشاكل التاريخ
حقل dateTimeIssued يجب أن يكون بتوقيت UTC ولا يجوز أن يكون في المستقبل. خادم أودو المضبوط على توقيت القاهرة والذي يرسل التوقيت المحلي كأنه UTC سينتج مستنداً مؤرخاً بساعتين أو ثلاث في المستقبل، فيفشل.
الحل: حوّل إلى UTC صراحة عند بناء المستند ولا تعتمد على المنطقة الزمنية الافتراضية للخادم.
5. عدم تطابق كود النشاط أو الفرع أو العنوان
كود النشاط activityCode يجب أن يكون أحد أكواد النشاط الضريبي المسجلة للممول، ورقم الفرع branchID يجب أن يطابق فرعاً مسجلاً لدى المصلحة. فرع جديد أُضيف في أودو ولم يُضف في ملف الممول سيفشل.
6. مشاكل التوقيع الإلكتروني
التوقيع من نوع CAdES-BES بشهادة على توكن USB أو HSM. الأعطال الشائعة: المحتوى الموقّع يتضمن حقولاً يجب استبعادها، أو انتهت صلاحية الشهادة، أو تم تعديل المستند بعد التوقيع (مثلاً خطوة تسلسل تعيد ترتيب المفاتيح). الخطأ يشير عادة إلى خطوة مدقق التوقيع.
أخطاء لا علاقة لها بالرقم 202 أصلاً
أحياناً تظهر المشكلة قبل أي رد 202. من المفيد تمييزها لأن حلها مختلف:
| HTTP | الكود | المعنى |
|---|---|---|
| 400 | BadStructure | الـ JSON لا يطابق المخطط |
| 400 | MaximumSizeExceeded | حجم الإرسالية أكبر من المسموح |
| 403 | IncorrectSubmitter | بيانات الاعتماد لا تخص هذا الممول أو الوسيط |
| 403 | Forbidden | ملف الممول مقيّد |
| 422 | DuplicateSubmission | إرسالية مطابقة أُرسلت مرة أخرى خلال عشر دقائق |
خطأ DuplicateSubmission يستحق وقفة: التكامل الذي يعيد المحاولة تلقائياً عند انقطاع الشبكة يسبب هذا الخطأ. السلوك الصحيح هو الاستعلام عن الإرسالية السابقة بـ submissionUUID قبل الإرسال مرة أخرى.
قائمة مراجعة للتعامل الصحيح مع 202 في أودو
سواء بنيت الموديول بنفسك أو اشتريته، يجب أن يفعل التكامل الآتي:
- خزّن
submissionUUIDوuuidكل مستند على الفاتورة لحظة استلام 202. - اجعل حالة الفاتورة «Submitted» وليس «Sent» أو «Done». المصطلح مهم للمحاسبين.
- استعلم عبر Get Document Details (أو استقبل إشعار المصلحة) حتى تصبح الحالة Valid أو Invalid أو Rejected أو Cancelled.
- اعرض
validationStepsعلى شاشة الفاتورة بلا تصفية. رسالة مثل «خطأ من المصلحة» لا تفيد؛ أما «GS1 code validator: الكود 6221234567890 غير موجود» فقابلة للتنفيذ. - امنع طباعة مرجع المصلحة على الـ PDF قبل أن تصبح الحالة Valid.
- لا تعد الإرسال تلقائياً عند انتهاء المهلة؛ ابحث عن الإرسالية الأصلية أولاً.
- احتفظ بالـ JSON الموقّع كما أُرسل بالضبط. عندما يسأل المحاسب «ماذا أرسلنا؟» تحتاج الإجابة.
كيف تتحقق من الحالة يدوياً الآن
إذا أردت أن تعرف فوراً هل فاتورة معينة مقبولة:
- سجّل الدخول إلى بوابة الفاتورة الإلكترونية (الإنتاج، أو preprod إذا كنت تختبر).
- افتح المستندات وابحث برقمك الداخلي (رقم الفاتورة في أودو) أو بالـ UUID.
- اقرأ عمود الحالة. إذا كانت Invalid افتح المستند واقرأ نتائج التحقق.
- إذا كان المستند Valid انسخ الـ UUID إلى أودو إن لم يفعل التكامل ذلك.
إصلاح مستند Invalid
المستند غير الصالح ليس مستنداً مقبولاً، لذلك لا تُلغيه بل تُصدر مستنداً مصححاً. التسلسل المعتاد في أودو:
- عالج السبب الجذري (كود المنتج، رقم العميل، معالجة التاريخ، الإجماليات).
- أعد توليد مستند المصلحة من الفاتورة المرحّلة نفسها. معظم التكاملات تسمح بإعادة إرسال المستند غير الصالح لأن المصلحة لم تقبله أصلاً كمستند ضريبي.
- أرسل مرة أخرى وتابع الحالة حتى Valid.
أما إذا كانت الفاتورة نفسها خاطئة (السعر، الكمية، العميل) فأصدر إشعار خصم وفاتورة جديدة في أودو حتى تتطابق دفاترك مع ما لدى المصلحة.
قبل الإرسال القادم، راجع قائمة الفحص قبل الإرسال.
أسئلة شائعة
هل الرد 202 يعني أن مصلحة الضرائب قبلت فاتورتي؟
لا. الرقم 202 يعني أن الإرسالية استُلمت ودخلت الطابور. الحكم يأتي لاحقاً بحالة Valid أو Invalid. المستندات بحالة Valid وحدها تُعد مقبولة.
كم تستغرق المصلحة للتحقق من الفاتورة؟
الـ SDK لا يلتزم بوقت محدد. عملياً تكون دقائق غالباً، لكن التأخير يحدث. استعلم عن حالة المستند أو استقبل إشعار المصلحة بدلاً من الافتراض.
لماذا فاتورتي Invalid بسبب أكواد الأصناف رغم أنني سجلتها؟
غالباً كود EGS ما زال في انتظار اعتماد المصلحة، أو اعتُمد تحت رقم تسجيل ضريبي مختلف. راجع حالة الكود على البوابة للممول الذي أصدر الفاتورة تحديداً.
هل يمكنني إعادة إرسال فاتورة Invalid؟
نعم. المستند غير الصالح لم يُقبل قط كمستند ضريبي، لذلك تصحح البيانات وترسل مجدداً. لا تُلغه؛ الإلغاء ينطبق على المستندات Valid.
إذا كنت تفضّل ألا تبني هذا بنفسك