في تكامل الفوترة الإلكترونية مع منصة فاتورة، الرفض ليس حالة استثنائية نادرة بل نتيجة محتملة لكل طلب مقاصة أو إبلاغ. الفاتورة التي «تبدو» صحيحة في بيئتك قد تُرفض عند الإرسال لأن قاعدة تحقق واحدة لم تتحقق. هذا الدليل موجّه للمطوّر الذي يبني طبقة الإرسال: يشرح ماذا يعني أن تُرفض الفاتورة، وكيف تميّز الرفض عن القبول مع تحذير، وما أكثر أسباب الرفض شيوعاً، وكيف تتصرف بعد الرفض، وكيف تمنعه من الأساس عبر التحقق قبل الإرسال.
هذا المقال جزء من مركز المطوّرين ضمن الفاتورة الإلكترونية من قيود، وتحديداً ضمن مركز معالجة الأخطاء. يفترض أنك قرأت معالجة الأخطاء (Error Handling) في API وتعرف بنية استجابة الأخطاء العامة، إضافة إلى قواعد التحقق من الفاتورة التي تحدد متى تُرفض الفاتورة، والمقاصة (Clearance) في الفاتورة الإلكترونية التي تحكم المسار الكامل للفاتورة الضريبية بين الطرف الأول (B2B).
ماذا يعني أن تُرفض الفاتورة؟
عندما ترسل فاتورة إلى منصة فاتورة، تمر باختبار قواعد التحقق قبل أن تُختم. النتيجة تأخذ واحدة من ثلاث حالات: قبول نظيف، أو قبول مع تحذير، أو رفض. الرفض يعني أن الفاتورة فشلت في قاعدة تحقق من نوع خطأ (ERROR)، فلم تُختم ولم تصبح وثيقة ضريبية صالحة.
الإشارة الأوضح إلى الرفض في واجهة المقاصة هي قيمة الحقل clearanceStatus التي تساوي NOT_CLEARED. هذه القيمة تعني حرفياً: لم تُجرَ المقاصة، والفاتورة غير معترف بها لدى هيئة الزكاة والضريبة والجمارك (ZATCA). في واجهة الإبلاغ يقابلها الحقل reportingStatus بقيمة NOT_REPORTED، وفي كلتا الحالتين يصاحب الرفض رمز حالة HTTP من فئة 422 في الغالب.
القاعدة الجوهرية التي يجب أن يبنيها كل مطوّر في ذهنه: الفاتورة المرفوضة غير موجودة قانونياً. لا يجوز أن تسلّمها للعميل، ولا أن تحتسبها في إقرار ضريبة القيمة المضافة، ولا أن تعتبر العملية مكتملة. هي مسوّدة فاشلة حتى تُصحَّح وتُقبل من جديد.
الخطأ الأخطر هنا ليس الرفض نفسه، بل أن يمرّ الرفض دون أن يلتقطه نظامك. إذا عالج الكود الاستجابة الناجحة فقط وتجاهل قيمة clearanceStatus، ستظن أن الفاتورة صدرت بينما هي مرفوضة، ويكتشف العميل الفجوة بعد أسابيع عند مطابقة سجلاته مع الهيئة.
الفرق بين «مقبولة مع تحذير» و«مرفوضة»
أكثر سوء فهم يقع فيه المطوّرون هو الخلط بين الفاتورة المقبولة مع تحذير والفاتورة المرفوضة. الحالتان تحملان ملاحظات، لكن واحدة صالحة والأخرى لا. التمييز بينهما يحدد سلوك نظامك بالكامل.
| النتيجة | المعنى والإجراء |
|---|---|
| CLEARED | صالحة وتُسلَّم، لا إجراء |
| CLEARED بتحذير | صالحة مع ملاحظات تُصحَّح لاحقاً |
| NOT_CLEARED | مرفوضة: صحّح وأعد بمعرّف جديد |
الفاتورة المقبولة مع تحذير تكون قد اجتازت كل قواعد التحقق من نوع خطأ، لكنها أثارت قاعدة أو أكثر من نوع تحذير (WARNING). قيمة clearanceStatus فيها CLEARED، وتُختم وتصبح وثيقة صالحة يمكن تسليمها للعميل. التحذير ملاحظة لمراجعة لاحقة، لا يمنع الإصدار. غالباً يرافقها رمز HTTP من فئة 2xx، ويظهر مصفوفة warningMessages ممتلئة بينما تبقى errorMessages فارغة.
الفاتورة المرفوضة على العكس فشلت في قاعدة تحقق من نوع خطأ. قيمة clearanceStatus فيها NOT_CLEARED، ولم تُختم، ولا يجوز تسليمها. مصفوفة errorMessages تحمل سبب الرفض على الأقل، وقد تحمل أيضاً تحذيرات إضافية يجب ألا تشغلك عن الخطأ الأصلي.
الفرق العملي بسيط في الكود: لا تقرأ رمز HTTP وحده، واقرأ قيمة clearanceStatus دائماً. التحذيرات تُسجَّل وتُراجَع دورياً، أما الأخطاء فتوقف الإصدار وتفرض التصحيح وإعادة الإرسال. التعامل مع التحذير كأنه رفض يعطّل فواتير صالحة بلا داعٍ، والتعامل مع الرفض كأنه تحذير يسرّب فواتير فاشلة إلى العميل.
إليك مثالاً لاستجابة فاتورة مرفوضة (يرافقها رمز HTTP من فئة 422)، حيث ترى قيمة NOT_CLEARED وسبب الرفض داخل errorMessages:
لاحظ في هذه الاستجابة ثلاث إشارات متطابقة كلها تقول «مرفوضة»: قيمة status داخل validationResults تساوي ERROR، ومصفوفة errorMessages غير فارغة، وقيمة clearanceStatus تساوي NOT_CLEARED. منطقك يجب أن يعتمد على هذه الإشارات مجتمعة لا على واحدة منها فقط.
للترسيخ، إليك استجابة فاتورة مقبولة مع تحذير حتى تقارنها مباشرة باستجابة الرفض السابقة. لاحظ أن clearanceStatus هنا CLEARED رغم وجود رسالة، لأن الرسالة من نوع تحذير لا خطأ:
الفرق بين هذه الاستجابة واستجابة الرفض حرف واحد في المنطق: قيمة status هنا WARNING ومصفوفة errorMessages فارغة، فتمر الفاتورة. هناك status كان ERROR ومصفوفة الأخطاء ممتلئة، فتُرفض. اجعل شرط القبول في كودك صريحاً: تُقبل الفاتورة فقط حين تكون errorMessages فارغة وclearanceStatus تساوي CLEARED، وما عدا ذلك يُعامل رفضاً.
رموز حالة HTTP المصاحبة للرفض
قبل أن تصل إلى جسم الاستجابة، يعطيك رمز حالة HTTP الفئة العامة للنتيجة. في سياق الرفض تحديداً، التمييز بين الرموز يحدد هل تُعيد المحاولة أم لا. الخلط هنا مكلف: إعادة المحاولة على رفض بيانات تكرّر الفشل وتستهلك حد المعدل، وعدم إعادة المحاولة على خطأ خادم مؤقت يخسر فواتير صحيحة.
| الرمز | الدلالة في سياق الرفض | هل تُعيد المحاولة؟ |
|---|---|---|
| 400 Bad Request | غلاف الطلب نفسه مشوّه: JSON غير صالح أو حقل إلزامي مفقود في الطلب لا في الفاتورة. | لا. أصلح بنية الطلب أولاً. |
| 401 Unauthorized | فشل المصادقة: شهادة CSID منتهية أو الرمز المميز غير صالح. | لا قبل التجديد. جدّد بيانات الاعتماد ثم أرسل. |
| 422 Unprocessable Entity | الفاتورة فشلت في قاعدة تحقق. هذه الفئة الأكثر تكراراً للرفض الفعلي. | لا قبل التصحيح. اقرأ errorMessages وأصلح البيانات. |
| 429 Too Many Requests | تجاوزت حد المعدل. ليست رفضاً للفاتورة بل تقييد إرسال. | نعم لاحقاً. احترم ترويسة إعادة المحاولة. |
| 500 / 503 | خطأ خادم مؤقت لدى المنصة. الفاتورة قد تكون صحيحة. | نعم. أعد المحاولة بتراجع أسّي. |
الرمز الأهم في موضوع الرفض هو 422. يعني أن الطلب وصل سليماً بنيوياً لكن الفاتورة لم تجتز قواعد التحقق. هنا بالضبط تجد قيمة NOT_CLEARED وتفاصيل الخطأ في errorMessages. لا تُعد المحاولة على 422 بالبيانات نفسها أبداً، فالنتيجة ستكون رفضاً مطابقاً.
احذر فخاً شائعاً: لا تستنتج القبول من رمز 2xx وحده. في بعض المسارات قد يصل رمز نجاح على مستوى النقل بينما تحمل الفاتورة NOT_CLEARED في جسم الاستجابة. الحَكَم النهائي دائماً هو حقول جسم الاستجابة لا رمز HTTP. اقرأهما معاً، ورجّح جسم الاستجابة عند أي تعارض.
أكثر أسباب رفض الفاتورة شيوعاً
لا تُرفض الفواتير عشوائياً. الأغلبية الساحقة من حالات الرفض تعود إلى عدد محدود من الأسباب المتكررة. معرفتها مسبقاً تسمح لك بالتحقق منها قبل الإرسال وتقليل الرفض إلى حده الأدنى. الجدول التالي يلخص الفئات الأكثر تكراراً مع رمز القاعدة النموذجي والإصلاح المطلوب.
| سبب الرفض | رمز نموذجي | الإصلاح المطلوب |
|---|---|---|
| الإجمالي لا يطابق مجموع البنود | BR-CO-15 | أعد حساب إجمالي الفاتورة شامل الضريبة ليساوي مجموع صافي البنود زائد الضريبة. |
| إجمالي الضريبة لا يساوي مجموع ضرائب البنود | BR-KSA-EN16931-08 | تحقق من احتساب 15% على كل بند ثم اجمعها بدقة الأرقام نفسها. |
| رقم تسجيل ضريبة القيمة المضافة غير صالح | BR-KSA-39 | تأكد أن الرقم 15 خانة يبدأ وينتهي بالرقم 3 ويتبع صيغة الهيئة. |
| انكسار تسلسل التجزئة (hash) للفاتورة السابقة | BR-KSA-26 | أرسل الفواتير بالترتيب ولا تتخطّ فاتورة. أصلح قيمة PIH للفاتورة السابقة. |
| الختم المشفّر غير صالح أو شهادة CSID منتهية | BR-KSA-60 | جدّد شهادة CSID وتأكد من صلاحية المفتاح قبل التوقيع. |
| صيغة التاريخ أو المنطقة الزمنية غير مطابقة | BR-KSA-70 | استخدم صيغة الوقت المعتمدة بتوقيت المملكة كما تحددها الهيئة. |
| نوع الفاتورة لا يطابق محتواها | BR-KSA-08 | طابق رمز نوع الفاتورة (مبسّطة B2C أو ضريبية B2B) مع المسار الصحيح. |
أكثر هذه الأسباب شيوعاً على الإطلاق هو عدم تطابق المجاميع. يحدث غالباً بسبب اختلاف في تقريب الكسور العشرية بين نظامك وحساب المنصة، أو بسبب احتساب الخصم على مستوى الفاتورة دون تعديل مجاميع البنود. القاعدة الآمنة أن تحسب الضريبة على مستوى كل بند بدقة موحّدة، ثم تجمع الأرقام نفسها التي أرسلتها لا أرقاماً معاد تقريبها.
السبب الثاني الأكثر إزعاجاً هو انكسار تسلسل التجزئة. كل فاتورة تحمل تجزئة الفاتورة السابقة (Previous Invoice Hash) لتشكيل سلسلة متصلة. إذا أرسلت الفواتير خارج الترتيب، أو أعدت إرسال فاتورة قديمة، أو فقدت قيمة التجزئة، تنكسر السلسلة وتُرفض الفاتورة. الحل تنظيمي قبل أن يكون برمجياً: اجعل الإرسال متسلسلاً ومضموناً، واحفظ آخر تجزئة بأمان.
أما أخطاء المصادقة وشهادة CSID فتظهر عادةً بشكل جماعي: تنجح الفواتير ثم تبدأ كلها بالفشل دفعة واحدة. هذا مؤشر على انتهاء صلاحية الشهادة لا على خطأ في بيانات فاتورة بعينها. راقب تاريخ انتهاء الشهادة وجدّدها قبل الموعد بفترة كافية.
هناك أيضاً فئة رفض تتعلق بالختم المشفّر ورمز الاستجابة السريعة. الفاتورة الضريبية المبسّطة (B2C) تحمل رمز استجابة سريعة يتضمن بيانات الفاتورة وتوقيعها، وأي خلل في توليد هذا الرمز أو في الختم المشفّر ينتج رفضاً. السبب غالباً مكتبة توقيع غير محدّثة، أو ترتيب حقول مختلف عن المواصفة، أو ترميز خاطئ للبيانات. هذه أخطاء بنيوية تُكتشف مبكراً في بيئة الاختبار قبل الإنتاج، فلا تتعجّل النقل إلى الإنتاج قبل أن تجتاز فواتير تجريبية متنوعة.
انتبه أيضاً إلى أخطاء الترميز المحرفي في الحقول النصية العربية. اسم البائع أو وصف البند بترميز غير UTF-8 الصحيح قد يكسر التوقيع أو يفشل التحقق دون رسالة واضحة. وحّد الترميز في كل طبقات نظامك من قاعدة البيانات حتى جسم الطلب، واختبر الحقول العربية تحديداً لأنها أكثر عرضة لهذا النوع من الأعطال الصامتة.
القاعدة الجامعة لكل هذه الأسباب: الرفض دائماً مرتبط بقاعدة محددة لها رمز. لا تتعامل مع الرفض ككتلة غامضة، بل اقرأ الرمز والرسالة، وابنِ خريطة داخلية تربط كل رمز بإجراء تصحيح معروف. مع الوقت تتحول هذه الخريطة إلى أصل ثمين يقلّص زمن التشخيص من ساعات إلى دقائق.
ماذا تفعل بعد الرفض؟
الرفض ليس نهاية المسار بل بدايته. بعد أن تلتقط استجابة الرفض، نظامك مسؤول عن سلسلة خطوات واضحة تنتهي بفاتورة مقبولة. الترتيب مهم، وتخطّي أي خطوة يعيدك إلى رفض جديد.
رصد NOT_CLEARED
قراءة errorMessages
تصحيح البيانات
توليد ICV وUUID جديدين
إعادة الإرسال والتأكد من CLEARED
الخطوة الأولى: التقط الرفض وسجّله. خزّن الاستجابة كاملة بما فيها رموز الأخطاء ورسائلها ومعرّف الفاتورة. هذا السجل ضروري للتشخيص ولإثبات المحاولة عند الحاجة. لا تكتفِ بتسجيل «فشل»، بل احفظ التفاصيل القابلة للتنفيذ.
الخطوة الثانية: اقرأ errorMessages واعرض السبب بلغة مفهومة. المستخدم المحاسب لا يفهم رمز BR-KSA-EN16931-08، لكنه يفهم «إجمالي الضريبة لا يطابق مجموع ضرائب البنود». ترجم الرمز إلى رسالة واضحة تقوده إلى الإصلاح، ولا تعرض الرمز الخام وحده.
الخطوة الثالثة: صحّح بيانات الفاتورة فعلياً. لا تكتفِ بإعادة الإرسال على أمل أن تنجح، لأن الفاتورة بالبيانات نفسها ستُرفض مجدداً. عالج السبب الجذري: أعد حساب المجاميع، أو صحّح رقم التسجيل الضريبي، أو أصلح تسلسل التجزئة بحسب ما يخبرك به الخطأ.
الخطوة الرابعة، وهي الأهم والأكثر إهمالاً: ولّد معرّفاً جديداً للفاتورة عند إعادة الإرسال. الفاتورة المصحّحة وثيقة جديدة من منظور المنصة، لا تعديلاً على القديمة. يجب أن تحمل معرّف عدّاد جديداً (Invoice Counter Value) ومعرّف UUID جديداً، وأن تشير إلى التجزئة الصحيحة للفاتورة السابقة. إعادة إرسال الفاتورة بمعرّفها القديم تنتج رفضاً جديداً أو تكراراً يكسر التسلسل.
الخطوة الخامسة: أعد الإرسال وتحقق من النتيجة. لا تفترض النجاح، واقرأ قيمة clearanceStatus في الاستجابة الجديدة. إذا صارت CLEARED اكتملت العملية وخزّن الفاتورة المُصدّقة ورمز الاستجابة السريعة (QR). إذا بقيت NOT_CLEARED فالخطأ لم يُصحَّح بالكامل، ارجع إلى قراءة الرسائل من جديد.
المثال التالي يوضح الفكرة المحورية: نفس الفاتورة بعد التصحيح تُرسَل بمعرّفات جديدة، فتعيد المنصة قيمة CLEARED:
انتبه إلى أن الفاتورة المرفوضة الأصلية لا تُحذف من سجلاتك بل تبقى موثّقة كمحاولة فاشلة. هذا يحفظ مسار التدقيق ويجنّبك إعادة استخدام معرّفها بالخطأ. الفاتورة المقبولة الجديدة هي الوثيقة الوحيدة الصالحة للتسليم والإقرار.
الرفض بسبب التكرار وأهمية المعرّفات الفريدة
فئة من الرفض يغفل عنها المطوّرون كثيراً هي رفض التكرار. منصة فاتورة ترفض الفاتورة إذا حملت معرّفاً سبق استخدامه، لأن كل وثيقة ضريبية يجب أن تكون فريدة. هذا يحدث غالباً نتيجة منطق إعادة محاولة ساذج: يرسل الكود الفاتورة، تنقطع الشبكة قبل وصول الرد، فيعيد الإرسال بالمعرّف نفسه، فتُرفض الثانية كتكرار أو تكسر التسلسل.
المعرّفات الثلاثة التي تضمن التفرّد هي معرّف العدّاد (ICV) الذي يتزايد مع كل فاتورة، ومعرّف UUID الفريد عالمياً، وتجزئة الفاتورة السابقة (PIH) التي تربط الفاتورة بسابقتها. أي تكرار في الأولين أو خلل في الثالث ينتج رفضاً. القاعدة: لا تُعد استخدام معرّف بعد إرساله ولو فشل الطلب، إلا إذا تأكدت يقيناً أن المنصة لم تستلمه.
عالج انقطاع الشبكة بحذر. عندما لا يصلك رد، الفاتورة في حالة غير محسومة لا فاشلة. الحل الصحيح أن تستعلم عن حالة الفاتورة بمعرّفها قبل أي إعادة إرسال، فإذا تبيّن أنها وصلت ومُوقّعت لا تعيد إرسالها، وإذا لم تصل أرسلها بالمعرّف نفسه دون توليد جديد. التوليد الأعمى لمعرّف جديد عند كل انقطاع يكسر التسلسل ويولّد رفضاً متسلسلاً يصعب تتبعه.
خزّن حالة كل فاتورة محلياً بثلاث قيم على الأقل: «قيد الإرسال»، و«مقبولة»، و«مرفوضة». الفاتورة «قيد الإرسال» التي لم يصلها رد تُعالَج بالاستعلام لا بإعادة الإرسال. هذا التمييز يحميك من ازدواج الفواتير ومن الرفض الناتج عنه.
كيف تمنع الرفض قبل أن يحدث؟
أفضل معالجة للرفض أن تمنعه قبل أن تصل الفاتورة إلى المنصة. منصة فاتورة تطبّق المنطق نفسه الذي يمكنك تطبيقه محلياً، فكل قاعدة تحقق تفشل عندها كان بإمكانك التقاطها قبل الإرسال. التحقق المسبق يوفّر طلبات الشبكة، ويسرّع التجربة، ويقلّل الرفض إلى الحالات النادرة فعلاً.
تطابق المجاميع مع البنود
صلاحية الأرقام الضريبية
اكتمال الحقول الإلزامية
سلامة سلسلة التجزئة (ICV/PIH)
ابدأ بالتحقق الحسابي محلياً. قبل أن ترسل، تأكد أن مجموع صافي البنود زائد الضريبة يساوي إجمالي الفاتورة بالقرش الواحد. هذا الفحص وحده يمنع أكثر أسباب الرفض شيوعاً. وحّد سياسة التقريب بين كل طبقات نظامك حتى لا تختلف الأرقام بين الحساب والإرسال.
تحقق بعدها من اكتمال الحقول الإلزامية وصحة صيغها. رقم تسجيل ضريبة القيمة المضافة من 15 خانة بالصيغة الصحيحة، والتاريخ بالمنطقة الزمنية المعتمدة، ونوع الفاتورة مطابق لمحتواها. هذه فحوصات بسيطة لكنها تلتقط شريحة كبيرة من حالات الرفض البنيوي.
راقب سلامة سلسلة التجزئة باستمرار. احتفظ بقيمة تجزئة آخر فاتورة مقبولة، واربطها بكل فاتورة جديدة قبل الإرسال، وامنع أي مسار يرسل فاتورة خارج الترتيب. سلسلة التجزئة المتماسكة شرط أساسي لقبول كل فاتورة لاحقة.
أخيراً، راقب صلاحية شهادة CSID قبل انتهائها بوقت كافٍ. اجعل النظام ينبّه عند اقتراب الانتهاء بدلاً من اكتشافه عبر موجة رفض جماعية. التجديد الاستباقي يحوّل مشكلة محتملة إلى مهمة صيانة روتينية.
التعامل مع حدود المعدل وإعادة المحاولة
ليست كل استجابة غير ناجحة رفضاً للفاتورة. رمز 429 يعني أنك تجاوزت حد المعدل المسموح للطلبات خلال نافذة زمنية، والفاتورة نفسها سليمة لم تُرفض. الفرق جوهري: لو عاملت 429 كرفض وصححت بيانات الفاتورة، تكون قد عالجت العرض الخاطئ. الصواب أن توقف الإرسال مؤقتاً ثم تعيد المحاولة بالبيانات نفسها.
طبّق منطق التراجع الأسّي مع 429 وأخطاء الخادم 5xx. ابدأ بفاصل قصير، ثم ضاعفه مع كل محاولة فاشلة حتى حد أعلى معقول، وأضف عشوائية بسيطة (jitter) تمنع تزامن المحاولات. احترم ترويسة إعادة المحاولة (Retry-After) إن وُجدت، فهي توجيه صريح من المنصة بموعد السماح. لا تتجاهلها وتعيد المحاولة فوراً، لأن ذلك يطيل فترة التقييد.
افصل صراحةً بين فئتين في منطق الإعادة. الفئة الأولى قابلة لإعادة المحاولة بالبيانات نفسها: 429 و5xx وانقطاع الشبكة، لأن الفاتورة صحيحة والمشكلة عابرة. الفئة الثانية ليست كذلك: 400 و401 و422، لأن إعادة الإرسال بلا تغيير تكرّر الفشل حتماً. خلط الفئتين هو أكثر خطأ يحوّل طبقة الإرسال إلى حلقة فاشلة تستهلك الموارد دون نتيجة.
اضبط حداً أقصى لعدد المحاولات. الفاتورة التي تفشل بعد عدد متفق عليه من المحاولات على خطأ خادم يجب أن تنتقل إلى طابور مراجعة يدوية، لا أن تظل في حلقة لا تنتهي. هذا يحمي نظامك من استنزاف الموارد ويضمن أن لا فاتورة تضيع بصمت.
تسجيل الرفض ومراقبته في الإنتاج
طبقة معالجة الرفض لا تكتمل دون مراقبة. سجّل لكل فاتورة مرفوضة: معرّفها، ورمز الخطأ، ورسالته، ورمز حالة HTTP، ووقت المحاولة، وعدد المحاولات. هذا السجل يحوّل الرفض من حدث غامض إلى بيانات قابلة للتحليل تكشف الأنماط المتكررة.
راقب نسبة الرفض كمؤشر صحة. ارتفاعها المفاجئ غالباً ليس مصادفة بل عَرَض لخلل واحد: شهادة CSID قاربت الانتهاء، أو تغيّر في حساب المجاميع بعد تحديث، أو انكسار في تسلسل التجزئة. النسبة المرتفعة تستدعي تشخيصاً فورياً قبل أن تتراكم الفواتير العالقة.
جمّع أسباب الرفض حسب رمز القاعدة. إذا تصدّر رمز واحد القائمة فهذا يدلّك على إصلاح واحد يحلّ شريحة كبيرة من الحالات دفعة واحدة. التحليل المجمّع أنجع بكثير من معالجة كل فاتورة على حدة، لأنه يهاجم السبب الجذري لا الأعراض.
أخيراً، اجعل الفواتير العالقة مرئية. الفاتورة التي رُفضت ولم تُصحَّح بعد يجب أن تظهر في طابور واضح مع سببها، لا أن تُدفن في سجل لا يُقرأ. الهدف أن يقاس الزمن بين الرفض والتصحيح، وأن لا تبقى فاتورة مرفوضة دون متابعة، لأن كل فاتورة عالقة فجوة محتملة في إقرار العميل لدى الهيئة.
دع قيود يتولّى التحقق والمقاصة والتعامل مع الرفض
يتحقق قيود من الفاتورة قبل إرسالها إلى منصة فاتورة، ويدير شهادة CSID والتوقيع والمقاصة الفورية تلقائياً، ويعرض أسباب الرفض بلغة واضحة دون أن تبني طبقة التحقق بنفسك.
خلاصة عملية للمطوّر
الرفض جزء طبيعي من تكامل الفوترة الإلكترونية، لا حالة طارئة. النظام الناضج يفترض احتمال الرفض في كل طلب، ويقرأ قيمة clearanceStatus دائماً، ويميّز القبول مع تحذير عن الرفض الفعلي. بهذا تتجنّب السيناريو الأسوأ: فاتورة مرفوضة تمرّ كأنها نجحت.
الفرق بين تكامل هشّ وتكامل صامد لا يظهر في المسار المثالي، بل في كيفية تصرّف النظام عند أول فاتورة تُرفض في الإنتاج. النظام الهشّ يتوقف أو يسرّب فاتورة فاشلة، والنظام الصامد يلتقط الرفض، ويترجمه للمستخدم، ويصحّحه، ويعيد الإرسال بمعرّفات جديدة، ويتأكد من القبول. هذه الدورة الكاملة هي ما يفصل بين شعور العميل بالثقة وشعوره بأن النظام يخذله عند الضغط.
تذكّر القواعد الأربع: لا تثق برمز HTTP وحده، اقرأ errorMessages واعرضها بلغة المستخدم، ولّد معرّفات جديدة عند إعادة الإرسال بعد التصحيح، وتحقق محلياً قبل الإرسال لتمنع الرفض من أصله. تطبيق هذه القواعد يحوّل طبقة الإرسال من نقطة هشاشة إلى مكوّن يصمد في الإنتاج. لمزيد من التفاصيل حول بنية الاستجابة العامة، راجع معالجة الأخطاء في API، ولفهم القواعد التي تحدد القبول من الرفض راجع قواعد التحقق من الفاتورة.