meita / zatca
PHP package to prepare, sign and send electronic invoices compliant with the ZATCA e‑invoicing regulations. It can be integrated into any PHP or Laravel project.
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/meita/zatca
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9.5
README
هذا الحزمة مكتوبة بلغة PHP وتهدف إلى تسهيل عملية إعداد، توقيع وإرسال الفواتير الإلكترونية وفقًا لمواصفات هيئة الزكاة والضريبة والجمارك (ZATCA) في المملكة العربية السعودية. يمكن استخدامها مع أي مشروع PHP، بما فى ذلك إطار عمل Laravel، وتوفر الأدوات اللازمة لتوليد الفاتورة بصيغة XML، حساب البصمة الرقمية (hash)، توقيعها باستخدام مفاتيح ECDSA، توليد رمز الإستجابة السريعة (QR) وترميزها، وأخيرًا إرسالها إلى بوابة فاتورة من خلال واجهات البرمجة الخاصة بمرحلة التصفية (Clearance) أو التبليغ (Reporting).
المزايا الرئيسية
- إنشاء نموذج فاتورة إلكترونية (بصيغة XML) يتوافق مع قاموس البيانات ومعايير ZATCA.
- توليد UUID، وربط الفواتير المتتالية عبر حقل
previousInvoiceHash. - حساب تجزئة الفاتورة باستخدام خوارزمية SHA‑256 وتوقيعها باستخدام مفتاح خاص من نوع ECDSA.
- توليد رمز الإستجابة السريعة (QR) وفق تنسيق TLV وترميزه Base64.
- إرسال الفواتير إلى واجهات البرمجة الخاصة ببوابة ZATCA (التصفية أو التبليغ) عبر بروتوكول HTTP Basic Auth.
- إمكانية ضبط عنوان الخادم (بيئة الإنتاج أو sandbox) وبيانات الاعتماد (CSID و secret).
- مهيأة للعمل ضمن أي تطبيق Laravel بفضل autoload بـ PSR‑4.
تنويه: هذه الحزمة للأغراض التعليمية وتعرض الخطوات الأساسية المطلوبة للتكامل مع ZATCA. يجب مراجعة المواصفات الرسمية ودمجها فى المشروع الفعلي، مع التأكد من توفير الأمن المناسب وإدارة المفاتيح السرية.
التركيب
يفضل تثبيت الحزمة عبر Composer. إذا كنت تستخدم هذه الحزمة داخل مشروعك مباشرة، يمكنك إضافتها كاعتماد محلي باستخدام المسار:
{
"repositories": [
{
"type": "path",
"url": "path/to/zatca-einvoice"
}
],
"require": {
"meita/zatca": "*"
}
}
ثم تشغيل:
composer require meita/zatca
الحزمة تمت تهيئتها بحيث يتم تحميل الأصناف ضمن مساحة الاسم Zatca\\.
الاستخدام السريع
1. التجهيز
قبل أن تتمكن من إرسال الفواتير، يجب الحصول على معرف ختم التشفير (CSID) والسر (secret) من بوابة المطورين التابعة لـ ZATCA. هذه العملية تشمل:
- إنشاء طلب توقيع شهادة (CSR) وتقديمه للحصول على CSID.
- إتمام الاختبارات عبر بيئة Integration Sandbox باستخدام Compliance CSID API.
- عند اجتياز الاختبارات، ستتلقى binarySecurityToken و secret تستخدمهما كبيانات مصادقة.
ضع ملف المفتاح الخاص (private_key.pem) والملف العام (certificate.crt) في مكان آمن بداخل مشروعك؛ حيث تستخدمهما الحزمة لتوقيع الفواتير.
2. تكوين العميل
use Zatca\ZatcaClient; use Zatca\Invoice; $client = new ZatcaClient([ // عنوان واجهة البرمجة؛ استخدم sandbox للتجارب أو production للإرسال الفعلي 'base_url' => 'https://sandbox.zatca.gov.sa/e-invoicing/core/v2', // معرف الختم الصادر (CSID) 'client_id' => 'YOUR_CSID_HERE', // السر المرتبط بالـ CSID 'secret' => 'YOUR_SECRET_HERE', // المسار إلى المفتاح الخاص لتوقيع الفاتورة 'private_key_path' => __DIR__ . '/keys/private_key.pem', // المسار إلى الشهادة العامة (اختياري في هذه النسخة) 'certificate_path' => __DIR__ . '/keys/certificate.crt', ]);
3. إنشاء الفاتورة
// البيانات المطلوبة للفاتورة، ويمكنك تخصيصها حسب احتياجاتك $data = [ 'uuid' => Invoice::generateUuid(), 'issue_date' => date('c'), // ISO 8601 timestamp 'seller_name' => 'شركة المثال للتجارة', 'seller_vat' => '123456789012345', 'invoice_total' => 115.00, 'vat_total' => 15.00, // في حال كانت هذه ليست أول فاتورة، أدخل Hash الفاتورة السابقة 'previous_hash' => null, // عناصر أخرى يمكن إضافتها فى ملف XML 'items' => [ [ 'name' => 'منتج 1', 'quantity' => 1, 'price' => 100.00, ], ], ]; $invoice = new Invoice($data); // يمكن تعديل العناصر بعد الإنشاء $invoice->setPreviousInvoiceHash('previousHashValue');
4. إرسال الفاتورة القياسية
// هذه الطريقة تقوم تلقائياً بإنشاء XML، احتساب hash وتوقيعه، بناء رمز QR، ثم إرسالها عبر واجهة التصفية $response = $client->sendStandardInvoice($invoice); if ($response['status'] === 'success') { // احفظ الفاتورة المختومة (response['invoice']) كما هو موضح فى مواصفات ZATCA file_put_contents('cleared_invoice.xml', base64_decode($response['invoice'])); } else { // عالج الأخطاء بناءً على رسالة الرفض أو التحذيرات var_dump($response['errors']); }
5. إرسال الفاتورة المبسطة
$response = $client->sendSimplifiedInvoice($invoice); // فى هذا النموذج، يجب أن تحتوى الفاتورة على الختم والرمز قبل الإرسال
هيكل الأصناف الأساسية
1. Zatca\Invoice
يمثل الفاتورة ويوفر طرقًا لتوليد UUID وتكوين بيانات الفاتورة وتحويلها إلى XML. يعتمد على DOMDocument لتوليد ملف UBL بسيط. يمكنك تعديل طريقة toXml() لتضمين حقول إضافية حسب القاموس الرسمي.
2. Zatca\Utilities\Signer
يحتوي على وظائف لحساب hash للفاتورة باستخدام خوارزمية SHA‑256 وفقًا لمعيار C14N11، وتوقيع الـ hash باستخدام المفتاح الخاص عبر openssl_sign. يستخدم خوارزمية ECDSA (اختيارية: يمكن استخدام RSA إذا كانت متطلباتك مختلفة).
3. Zatca\Utilities\QrCodeGenerator
يبني تمثيلًا نصيًا (Base64) لرمز الإستجابة السريعة وفقًا لمواصفات TLV. يتضمن حقول: اسم البائع، الرقم الضريبي، الطابع الزمني، إجمالى الفاتورة، إجمالى الضريبة، Hash الفاتورة، التوقيع الرقمي، والمفتاح العام. لا يتضمن إنشاء صورة QR؛ بل يُرجع سلسلة Base64 يمكن تحويلها لصورة عبر مكتبات خارجية (مثل endroid/qr-code).
4. Zatca\ZatcaClient
يُعد الواجهة الرئيسية للتعامل مع ZATCA. يوفر الطرق:
sendStandardInvoice(Invoice $invoice): array– يرسل الفاتورة القياسية للتصفية ويُرجع مصفوفة تحوى الحالة (successأوerror) والفاتورة المختمة أو الأخطاء.sendSimplifiedInvoice(Invoice $invoice): array– يرسل الفاتورة المبسطة للتبليغ. يجب أن يكون الـ invoice قد تم ختمه وتضمين QR.prepareSignedInvoice(Invoice $invoice): array– لإنشاء ملف XML، حساب الـhash، التوقيع، توليد QR وإرجاع جميع القيم الضرورية دون إرسالها؛ يمكن استخدامه فى سيناريوهات التبليغ.
تشغيل الاختبارات
يحتوي هذا المشروع على مجموعة من اختبارات PHPUnit للتأكد من صحة وحدات الكود الخاصة بالحزمة (توليد الـ UUID، بناء ملف XML، حساب الـ hash، التوقيع، إنشاء QR، والدمج فى العميل). لتشغيل الاختبارات:
-
تأكد من تثبيت اعتماديات التطوير (تشمل PHPUnit) باستخدام Composer:
composer install --dev
-
ثم قم بتشغيل الأمر التالي من جذر المشروع:
vendor/bin/phpunit
سترى ملخصًا بالاختبارات التى تم تنفيذها ونتائجها. يمكنك استخدام هذه الاختبارات كنقطة انطلاق لإضافة اختبارات أخرى حسب احتياجات مشروعك.
ملاحظات أمنية
- يجب تخزين المفتاح الخاص والـ secret فى أماكن آمنة وبصورة مشفرة وعدم مشاركتهما.
- لا تحتفظ بالسر فى مستودع الكود؛ استخدم متغيرات بيئة أو خدمات إدارة الأسرار.
- تأكد من استخدام اتصال
HTTPSعند إرسال الفواتير لحماية البيانات.
ترخيص
تم نشر هذه الحزمة تحت رخصة MIT. يمكنك استخدامها وتعديلها بحرية وفق شروط الرخصة.
المساهمة
مرحبًا بجميع المساهمات! إذا وجدت مشكلة أو ترغب فى إضافة ميزة جديدة، الرجاء فتح تذكرة أو إرسال طلب دمج (Pull Request).