الفوترة الإلكترونية في بنما من SAP Business One: ربط حقول NUC-JSON ورفض DGI

بقلم زين عباس, كودينوفا · آخر تحديث

الإجابة المختصرةلإصدار فاتورة إلكترونية بنمية من SAP Business One عبر مزوّد الاعتماد Digifact (PAC)، ترسل ملف NUC-JSON واحدًا لكل مستند: Header (DocType و IssuedDateTime و NumeroDF و CodigoSeguridad)، و Seller، و Buyer (TipoReceptor و RUC و DV و CodUbi)، و Items مع رمز ITBMS‏ 00/01/02/03 لنسب 0/7/10/15 %، و Payments. يحتوي SAP B1 أصلًا على معظم البيانات في OINV و INV1 و OCRD و OITM. تضيف بضعة حقول مستخدم (نوع المستلم، و DV، ورمز الموقع، و CPBS)، وتخزّن CUFE والبروتوكول ورابط QR التي تعود في الرد.

لإصدار فاتورة إلكترونية بنمية (Factura Electrónica، FE) من SAP Business One عبر مزوّد الاعتماد Digifact (PAC)، ترسل مستند NUC-JSON واحدًا لكل فاتورة أو إشعار دائن. معظم البيانات موجودة أصلًا في OINV و INV1 و OCRD و OITM. أما ما لا يوفره SAP B1 جاهزًا فهو نوع المستلم، ورقم التحقق من RUC ‏(DV)، ورمز الموقع (CodUbi)، ورمز الصنف CPBS، لذلك تصبح هذه حقول مستخدم. يرد مزوّد الاعتماد برمز CUFE وبروتوكول اعتماد ورابط QR، وتكتبها أنت مرة أخرى على المستند.

هذا الدليل هو الربط الذي أستخدمه في إضافتي لـ SAP Business One في بنما. اختُبر في 27 أكتوبر 2026 على شركة SAP B1 10 تعمل على SQL Server مقابل بيئة Digifact التجريبية: 34 سيناريو، من فاتورة مستهلك بنسبة 7 % إلى فاتورة من 105 أسطر، والتصدير، والمنطقة الحرة، والإشعارات الدائنة، والإلغاءات. للنظرة التجارية العامة، راجع الفوترة الإلكترونية في بنما لـ SAP Business One.

كيف يسير التدفق من SAP Business One إلى DGI؟

  1. يضيف المستخدم فاتورة مبيعات (الكائن 13) أو إشعارًا دائنًا للمبيعات (الكائن 14) في SAP B1 كالمعتاد.
  2. تقرأ الإضافة المستند، وتتحقق من قواعد DGI التي يمكن التحقق منها محليًا، وتبني ملف NUC-JSON.
  3. ترسل ملف JSON إلى Digifact ‏(/api/v2/transform/nuc_json، مع معاملات الاستعلام TAXID و FORMAT و USERNAME). يحوّله Digifact إلى XML بصيغة DGI، ويوقّعه، ويحصل على الاعتماد.
  4. يحمل الرد CUFE والبروتوكول وتاريخ الاعتماد ورابط QR. تكتبها الإضافة في حقول مستخدم على OINV/ORIN وترفق ملفي XML و PDF بالمستند.

قراران في التصميم وفّرا عليّ معظم المتاعب:

  • صف سجل واحد لكل مستند (جدول مستخدم، @FE_PA_DOC، مفتاحه 13-<DocEntry> أو 14-<DocEntry>). لا يمكن لجهازين يضيفان مستندات في الوقت نفسه أن يرسلا الفاتورة نفسها مرتين.
  • الاستعلام قبل إعادة الإرسال. إذا انتهت مهلة الإرسال، تسأل الإضافة Digifact أولًا ما إذا كان رقم NumeroDF هذا موجودًا بالفعل، ثم ترسل مجددًا فقط بعد ذلك. في الاختبار، الضغط على «Reintentar» (إعادة المحاولة) لفاتورة معتمدة بالفعل أعاد CUFE نفسه ولم يرسل شيئًا.

أي حقول SAP B1 تُربط بأي حقول NUC-JSON؟

صيغة NUC-JSON حساسة لحالة الأحرف: Buyer.TaxID يعمل، و buyer.taxid لا يعمل. كثير من القيم توضع في قوائم من كائنات { "Name": ..., "Value": ... } بدل خصائص عادية، وهذا أول ما يربك القادمين من FEL في غواتيمالا أو DTE في السلفادور.

حقل NUC-JSONما هومصدره في SAP B1
Header.DocType01 فاتورة، 03 تصدير، 04/06 إشعار دائن، 05/07 إشعار مدين، 08، 09، 10نوع الكائن (13/14)، و DocSubType = 'DN' للإشعارات المدينة، إضافة إلى حقل مستخدم على المستند للأنواع 02/08/09/10
Header.IssuedDateTimeتاريخ ووقت الإصدار، 2026-10-27T14:23:00-05:00يؤخذ وقت الإرسال ويُخزَّن في حقل مستخدم (U_FE_FechaEmi). تحتاجه الإشعارات الدائنة لاحقًا
AdditionalIssueDocInfo ← NumeroDFالرقم الضريبي من 10 خانات، مكمَّل بالأصفار، ولا يُعاد ضبطه أبدًاعدّاد خاص لكل نقطة فوترة. لا تعِد استخدام DocNum دون تفكير إذا كانت لديك عدة سلاسل ترقيم
PtoFactDFنقطة الفوترة، 3 خانات، وليست 000إعداد في الإضافة
CodigoSeguridad9 أرقام عشوائية، جزء من CUFE، ولا تساوي NumeroDFيُولَّد لكل مستند
Seller.TaxID و TaxIDType و DigitoVerificadorRUC المُصدِر، 1 شخص طبيعي / 2 شخص اعتباري، و DVإعدادات في الإضافة (شركة واحدة، RUC واحد)
Seller.BranchInfo.Code0000 المقر الرئيسي، و0001 فما فوق للفروعإعداد في الإضافة
Buyer.TaxIDرقم RUC، أو CF للمستهلك النهائي (consumidor final)، أو EXTRANJEROOCRD.LicTradNum
TipoReceptor01 مكلَّف (contribuyente)، 02 مستهلك نهائي، 03 جهة حكومية، 04 أجنبيحقل مستخدم لشريك الأعمال U_FE_TipoRec
Buyer.TaxIDType / DigitoVerificadorشخص طبيعي أو اعتباري، و DV لرقم RUCحقلا مستخدم لشريك الأعمال U_FE_TipoRuc و U_FE_DV
CodUbiرمز المقاطعة-المنطقة-البلدية (corregimiento)حقل مستخدم لشريك الأعمال U_FE_CodUbi
Buyer.Name والبريد والهاتفاسم المستلم وبيانات الاتصالOCRD.CardName و E_Mail و Phone1
Items[].Description و Qtyنص السطر والكميةINV1.Dscription و Quantity
Items[].Priceسعر الوحدة قبل الخصمINV1.PriceBefDi
Discounts.Discount[].Amountالخصم لكل وحدة بالبالبوا، وليس نسبة مئويةPriceBefDi - Price
Codes ← CodCPBSabr / CodCPBScmpرمز السلع والخدمات CPBS (خانتان و4 خانات)حقل مستخدم للصنف U_FE_CPBS على OITM
Taxes.Tax[].CodeITBMS‏ 00 = 0 %، 01 = 7 %، 02 = 10 %، 03 = 15 %من INV1.VatPrcnt
Taxes.Tax[].Amountمبلغ ضريبة السطرINV1.VatSum (أو VatSumFrgn)
Totals.TotalItemإجمالي السطر شاملًا الضريبةLineTotal + VatSum
Paymentsالنوع 02 دون شروط ائتمان؛ ومع شروط ائتمان النوع 01 إضافة إلى سطر PLAZO بتاريخ الاستحقاقأيام OCTG لقيمة GroupNum، و DocDueDate

تفصيلتان من الاختبار لا توضحهما المواصفات:

  • مبالغ الأسطر، لا مبالغ الرأس. ابنِ كل إجمالي من الأسطر واجعل الرأس مجموعها. لم يظهر لدي أي عدم تطابق في الفواتير متعددة النسب (0 و7 و10 % في مستند واحد) ولا في فاتورة من 105 أسطر، بتقريب كل سطر إلى خانتين عشريتين أولًا ثم الجمع.
  • الشركات بعملة أجنبية. إذا لم تكن العملة المحلية للشركة هي الدولار الأمريكي، فإن DocTotal و LineTotal و VatSum تكون بالعملة المحلية. يجب أن تحمل الفاتورة الإلكترونية عملة المستند، فاقرأ DocTotalFC و TotalFrgn و VatSumFrgn بدلًا منها. كانت العملة المحلية لشركة الاختبار لدي الجنيه الإسترليني، وهكذا ظهرت المشكلة.

ما حقول المستخدم التي تحتاجها في SAP Business One؟

المدخلات (يعبّئها المستخدم أو البيانات الرئيسية لشريك الأعمال): U_FE_TipoRec و U_FE_TipoRuc و U_FE_DV و U_FE_CodUbi على OCRD؛ و U_FE_CPBS على OITM؛ و U_FE_Incoterm و U_FE_PuertoEmb و U_FE_TipoDoc على المستند.

المخرجات (تكتبها الإضافة على OINV و ORIN): الحالة، و CUFE، والبروتوكول، وتاريخ الاعتماد، ورابط QR، و NumeroDF، وتاريخ/وقت الإصدار المرسل، ونص الخطأ، وعدد المحاولات، وسبب الإلغاء. يبلغ رابط QR نحو 560 حرفًا، لذلك يحتاج حقلًا من نوع memo، لا حقلًا أبجديًا رقميًا من 254 حرفًا.

كثير من العملاء لديهم بالفعل حقول خاصة لنوع RUC أو DV من حزمة توطين سابقة. تتيح شاشة الإعدادات لدي توجيه كل مفتاح إلى حقل موجود بدل إنشاء حقل مكرر. ومهما فعلت، أنشئ الحقول عبر DI API أو الواجهة، ولا تستخدم ALTER TABLE أبدًا.

قبل الإطلاق أشغّل هذا الفحص. يسرد البيانات الرئيسية التي سترفض قبل أن يصل أي شيء إلى مزوّد الاعتماد. نسخة SQL Server أولًا:

-- Customers that will fail: contribuyente/gobierno without RUC, DV or location code
SELECT C.CardCode, C.CardName, C.LicTradNum, C.U_FE_TipoRec, C.U_FE_DV, C.U_FE_CodUbi
FROM OCRD C
WHERE C.CardType = 'C'
  AND ISNULL(C.U_FE_TipoRec, '01') IN ('01', '03')
  AND (ISNULL(C.LicTradNum, '') = '' OR ISNULL(C.U_FE_DV, '') = '' OR ISNULL(C.U_FE_CodUbi, '') = '');

-- Items sold in the last 90 days without a CPBS code
SELECT DISTINCT L.ItemCode, I.ItemName
FROM INV1 L
INNER JOIN OINV H ON H.DocEntry = L.DocEntry
INNER JOIN OITM I ON I.ItemCode = L.ItemCode
WHERE H.DocDate >= DATEADD(DAY, -90, GETDATE())
  AND ISNULL(I.U_FE_CPBS, '') = '';

(الاستعلام الأول: العملاء الذين سيُرفضون، أي المكلَّفون أو الجهات الحكومية دون RUC أو DV أو رمز موقع. الثاني: الأصناف المباعة خلال آخر 90 يومًا دون رمز CPBS.)

نسخة SAP HANA (معرّفات مقتبسة، و IFNULL، و ADD_DAYS):

SELECT C."CardCode", C."CardName", C."LicTradNum", C."U_FE_TipoRec", C."U_FE_DV", C."U_FE_CodUbi"
FROM "OCRD" C
WHERE C."CardType" = 'C'
  AND IFNULL(C."U_FE_TipoRec", '01') IN ('01', '03')
  AND (IFNULL(C."LicTradNum", '') = '' OR IFNULL(C."U_FE_DV", '') = '' OR IFNULL(C."U_FE_CodUbi", '') = '');

SELECT DISTINCT L."ItemCode", I."ItemName"
FROM "INV1" L
INNER JOIN "OINV" H ON H."DocEntry" = L."DocEntry"
INNER JOIN "OITM" I ON I."ItemCode" = L."ItemCode"
WHERE H."DocDate" >= ADD_DAYS(CURRENT_DATE, -90)
  AND IFNULL(I."U_FE_CPBS", '') = '';

إذا كانت لديك استعلامات SQL Server فقط حاليًا، فإن محوّل SQL إلى HANA يتولى معظم تغييرات الصياغة.

كيف تشير الإشعارات الدائنة إلى الفاتورة الأصلية؟

الإشعار الدائن في SAP B1 المبني على فاتورة (RIN1.BaseType = 13 و BaseEntry = <DocEntry للفاتورة>) يصبح من نوع DGI 04. ويجب أن يحمل ثلاث قيم في AdditionalInfo: اسم المُصدِر (NombEmRef)، وتاريخ/وقت إصدار الفاتورة الإلكترونية الأصلية (FechaDFRef)، ورمز CUFE الخاص بها (CUFERef). لهذا يجب تخزين وقت الإصدار عند إرسال الفاتورة؛ فلا يمكنك إعادة بنائه لاحقًا من DocDate.

أما الإشعار الدائن دون مستند أساس، أو المبني على فاتورة سابقة لتاريخ إطلاقك، فهو إشعار عام من النوع 06 دون مرجع. يمكن معرفة الإشعارات الدائنة التي لها فاتورة أساس في جدول ORIN (الإشعار الدائن للمبيعات) وأسطره في RIN1.

قواعد DGI الأشد إيلامًا، وكلها أتحقق منها الآن في SAP قبل الإرسال:

قاعدة DGIماذا تعنيالفحص في SAP B1
1710يجب أن يكون للإشعار المستلم نفسه الذي للفاتورةخذ المشتري من ملف JSON الذي أُرسل للفاتورة، لا من البيانات الرئيسية لشريك الأعمال اليوم
1711الإشعار الدائن أكبر من الفاتورةقارن مع إجمالي فاتورة الأساس
1714إشعار صادر بعد أكثر من 180 يومًا من الفاتورةDocDate للإشعار مقابل الفاتورة
1717مجموع الإشعارات الدائنة يتجاوز الفاتورة + الإشعارات المدينةاجمع الإشعارات المعتمدة المرتبطة بالفعل عبر أسطر الأساس في RIN1/INV1
1718إشعار على فاتورة ملغاة (anulada)حالة فاتورة الأساس
1720الفاتورة المرجعية لا تحمل تاريخ/وقت إصدار مخزنًاالحقل FechaEmi للفاتورة

الإشعار الدائن على فاتورة أساس لم تُعتمد بعد ليس خطأً. تحتفظ به إضافتي حتى تحصل الفاتورة على CUFE ثم ترسله.

ما أسباب حالات الرفض الأكثر شيوعًا في فوترة بنما الإلكترونية؟

من اختبارات البيئة التجريبية، بالترتيب الذي واجهتها به:

  • مستلم حكومي (03) برقم RUC عادي. القاعدة 1604: يجب أن يكون رقم RUC في جدول DGI للجهات الحكومية (Tabla 30). إذا لم يكن العميل في تلك القائمة، فاستخدم نوع المستلم 01. بعد تصحيح RUC، اعتُمدت الفاتورة نفسها بمجرد إعادة محاولة بسيطة.
  • مستهلك نهائي برقم RUC لشخص اعتباري. القاعدة 1621: لا يمكن أن يكون RUC لشخص اعتباري (TaxIDType 2) من نوع المستلم 02.
  • تصدير أو عملية أجنبية دون INCOTERM. للنوعين 03 و10 ردّت البيئة التجريبية بأن شروط التسليم (CondEntr) مفقودة. ضع INCOTERM في حقل مستخدم على المستند وأرسله في AdditionalInfo.
  • الحرف < في وصف الصنف. عادت إحدى فواتير الاختبار برسالة «XSLT failed» بسبب < في نص السطر. حوّله إلى رمز هروب أو استبدله قبل الإرسال. أما ñ و á و & و " و > فقُبلت كلها، بما في ذلك عميل باسم «Compañía Ñandú & Hijos».
  • الخصم على مستوى المستند. لا مكان واضحًا لقيمة OINV.DiscSum في بنية الأصناف. تمنع إضافتي المستند الذي ما زال يحمل خصم رأس وتطلب خصومات على الأسطر بدلًا منه. ومشكلة خصم الرأس نفسها تشوّه تقارير المبيعات أيضًا، راجع لماذا لا تتطابق إجماليات المبيعات في SAP B1.

كيف تلغي (anular) فاتورة إلكترونية من SAP Business One؟

يُرسل الإلغاء إلى نقطة CancelFePA لدى Digifact مع RUC المُصدِر، و CUFE، وسبب (Motivo)، والمستخدم. أمران قِستهما في بيئة الاختبار:

  1. مباشرة بعد الاعتماد يفشل الإلغاء بالرد {"Codigo":9019,"Anulado":false,"Mensaje":"Anulacion incorrecta. Verifique si el CUFE pertenece a una FE existente"}. وبعد ثلاث إلى ثماني دقائق قُبل الطلب نفسه. تعيد إضافتي المحاولة مرة كل دقيقة بدل عرض خطأ للمستخدم.
  2. الأسباب القصيرة تفشل بالرمز 9019 نفسه. عشرون حرفًا أو أقل رُفضت دائمًا، و25 حرفًا أو أكثر قُبلت دائمًا، رغم أن الورقة التقنية لـ DGI تسمح من 15 إلى 1000. أفرض حدًا أدنى من 25 حرفًا في النموذج.

في SAP B1، يجب أن يُلغي الأمر Data > Cancel (البيانات > إلغاء) على فاتورة معتمدة لدى DGI أولًا. إذا رفضت DGI، فامنع الإلغاء في SAP، وإلا سيعرض SAP الفاتورة ملغاة بينما تعتبرها DGI صالحة. أما الفاتورة التي لم تصل إلى DGI أبدًا فيمكن إلغاؤها في SAP مباشرة.

إذا كنت تبني هذا كإضافة بنفسك، فأنماط معالجة الأحداث والتغليف والترحيل عبر DI موجودة في دليل تطوير إضافات SAP Business One، وحقول الجداول المذكورة أعلاه موجودة في مرجع جداول SAP B1.

ما الذي لم يكتمل بعد؟

وضع الطوارئ (TipoEmision 02/04) والعملات غير الدولار الأمريكي ليسا في إضافتي بعد. اعتُمدت الإشعارات المدينة (05 و07) في البيئة التجريبية، لكن الشركة ذات التوطين البريطاني لا تستطيع ترحيلها من DI API (إذ يُرفض DocumentSubType = DN)، لذا اختبرها في شركة بتوطين بنما أو أمريكا اللاتينية.

إذا كنت تشغّل SAP Business One في بنما وتحتاج الفوترة الإلكترونية عبر Digifact، أخبرني عن إعداداتك. نفّذت النوع نفسه من التكامل لـ FEL في غواتيمالا، و DTE في السلفادور، و SRI في الإكوادور، و ZATCA في السعودية.

المصادر

خدمات ذات صلة

الأسئلة الشائعة

أسئلة شائعة

هل أحتاج إلى مزوّد اعتماد (PAC) لإصدار الفواتير الإلكترونية من SAP Business One في بنما؟

لتكامل مع نظام ERP، نعم من الناحية العملية. لا يتصل SAP Business One بـ DGI مباشرة. يذهب المستند إلى PAC ‏(Proveedor de Autorización Calificado)، الذي يتحقق منه ويعتمده ويمرّره إلى DGI. تستخدم إضافتي مزوّد Digifact وواجهة NUC-JSON البرمجية الخاصة به.

أي مستندات SAP Business One تصبح أي أنواع مستندات لدى DGI؟

فاتورة المبيعات من النوع 01 (أو 03 للتصدير، و08 للمنطقة الحرة zona franca، و09 للاسترداد reembolso، و10 للعملية الأجنبية operación extranjera عندما تحدده). والإشعار الدائن للمبيعات المبني على فاتورة إلكترونية من النوع 04؛ ودون فاتورة مرجعية يكون 06. والإشعارات المدينة 05 و07.

لماذا ترفض DGI إلغاء فاتورة أصدرتها للتو؟

في بيئة الاختبار لدى Digifact، أعاد CancelFePA الرمز 9019 لبضع دقائق بعد الاعتماد، وكذلك كلما كان السبب (Motivo) 20 حرفًا أو أقل. الانتظار نحو 3 دقائق وكتابة سبب من 25 حرفًا أو أكثر نجح في كل مرة.

جاهز للبدء؟

أخبرنا بما تحتاجه. ستحصل على إجابة تقنية واضحة ونطاق عمل محدد وسعر ثابت، عادةً خلال 24 ساعة.