2026-05-07· 15 دقيقة قراءة· Developer

ZATCA المرحلة الثانية للمطورين: دليل الربط الفني الشامل

هذا الدليل موجَّه للمطورين الذين يبنون أنظمة فوترة في السوق السعودي. يغطي كل التفاصيل الفنية لربط نظامك مع منظومة ZATCA المرحلة الثانية، من توليد الـ CSR إلى إرسال أول فاتورة مُصفّاة (Cleared).

⚠️ متطلبات أساسية: فهم XML، X.509 certificates، ECDSA cryptography، REST APIs، وUBL 2.1 schema.

١. نظرة معمارية على المرحلة الثانية

المرحلة الثانية (Integration Phase) تتطلب اتصال نظامك مع ZATCA لحظياً عبر أحد مسارين:

٢. الدورة الكاملة لربط النظام

  1. توليد CSR (Certificate Signing Request) بمعايير ZATCA
  2. الحصول على OTP من بوابة Fatoora
  3. إرسال CSR + OTP لـ Compliance API → الحصول على CSID (Compliance CSID)
  4. إصدار 6 فواتير اختبارية متنوعة (Standard + Simplified + Credit + Debit Notes)
  5. طلب Production CSID من Onboarding API
  6. توقيع الفواتير الفعلية + إرسالها لـ Clearance/Reporting API

٣. توليد الـ CSR بالمعايير الصحيحة

ZATCA يفرض حقولاً محددة في الـ CSR. أي خطأ هنا يرفض الطلب من البداية:

# OpenSSL config مطلوب: zatca.cnf
[ req ]
distinguished_name = req_distinguished_name
prompt             = no
req_extensions     = v3_req

[ req_distinguished_name ]
C  = SA
OU = "Branch Name"          # اسم الفرع
O  = "Company Name"         # اسم المنشأة
CN = "COMMON NAME"          # اسم الجهاز/الكاشير

[ v3_req ]
basicConstraints = critical, CA:FALSE
keyUsage         = critical, digitalSignature
extendedKeyUsage = critical, clientAuth
subjectAltName   = dirName:san

[ san ]
SN = "1-Solution|2-Device|3-UUID"  # بصمة فريدة
UID = "310000000000003"             # الرقم الضريبي
title = "1100"                       # Invoice Type Code
registeredAddress = "Riyadh, ..."
businessCategory = "Restaurant"

# توليد المفتاح + CSR (لاحظ secp256k1)
openssl ecparam -name secp256k1 -genkey -noout -out privkey.pem
openssl req -new -sha256 -key privkey.pem -config zatca.cnf -out csr.pem

ملاحظة: ZATCA تُلزم باستخدام منحنى secp256k1 وليس secp256r1 (المنحنى الشهير في ECDSA).

٤. APIs الأساسية

APIEndpointالغرض
compliancePOST /complianceطلب Compliance CSID
compliance-invoicePOST /compliance/invoicesاختبار الفواتير الست
productionPOST /production/csidsطلب Production CSID
clearancePOST /invoices/clearance/singleتصفية فاتورة B2B
reportingPOST /invoices/reporting/singleإبلاغ فاتورة B2C

Sandbox: https://gw-fatoora.zatca.gov.sa/e-invoicing/developer-portal
Production: https://gw-fatoora.zatca.gov.sa/e-invoicing/core

٥. توقيع XML بـ ECDSA secp256k1

كل فاتورة XML يجب توقيعها بمعيار XAdES-B-B. خطوات التوقيع:

  1. حساب InvoiceHash = SHA-256 على XML بعد إزالة بعض الـ tags (UBLExtensions, Signature, AdditionalDocumentReference[QR]).
  2. توليد SignedProperties XML من القيم: SigningTime, CertDigest, IssuerName, SerialNumber.
  3. حساب SignedPropertiesHash = SHA-256(SignedProperties).
  4. إنشاء SignedInfo يحتوي الـ hashes.
  5. توقيع SignedInfo بـ ECDSA secp256k1 + المفتاح الخاص.
  6. حقن النتيجة في UBLExtensions/UBLExtension.
// PHP — توقيع SignedInfo
$key = openssl_pkey_get_private('file://privkey.pem');
$signature = '';
openssl_sign($signedInfoXml, $signature, $key, OPENSSL_ALGO_SHA256);

// تحويل DER → IEEE P1363 (ZATCA يطلب raw r||s)
$signature = derToP1363($signature);
$signatureB64 = base64_encode($signature);

٦. توليد QR Code (TLV - 9 tags)

QR في المرحلة الثانية يضم 9 حقول مشفّرة بـ Base64 على هيئة TLV:

Tag 1: Seller Name (UTF-8)
Tag 2: VAT Number
Tag 3: Timestamp (ISO 8601)
Tag 4: Invoice Total (with VAT)
Tag 5: VAT Total
Tag 6: Invoice Hash (SHA-256 base64)
Tag 7: Digital Signature (ECDSA)
Tag 8: Public Key (DER base64)
Tag 9: Signature of public key by ZATCA CA

# بنية كل tag: [tagNum:1byte][length:1byte][value:Nbytes]
// PHP — توليد QR base64
function tlv(int $tag, string $value): string {
    return chr($tag) . chr(strlen($value)) . $value;
}
$qr = tlv(1, $sellerName) . tlv(2, $vatNumber) . tlv(3, $timestamp)
     . tlv(4, $total) . tlv(5, $vat) . tlv(6, $invoiceHash)
     . tlv(7, $signature) . tlv(8, $publicKey) . tlv(9, $caSignature);
$qrB64 = base64_encode($qr);

٧. تسلسل الفواتير (ICV / PIH)

٨. التعامل مع الأخطاء الشائعة

❌ Error: BR-CO-15 / KSA-15

المجموع الإجمالي لا يطابق مجموع البنود + الضرائب.

الحل: تحقق من الـ rounding في حساب الإجماليات. ZATCA حساس لـ 2 decimals بالضبط.

❌ Error: HTTP 401 invalid certificate

الشهادة منتهية أو لا تطابق البيئة (Sandbox vs Production).

الحل: تأكد أنك لا تستخدم Compliance CSID مع Production endpoint أو العكس.

❌ Error: Hash mismatch

XML hash المحسوب لا يطابق الـ value في QR.

الحل: تأكد أن الـ canonicalization (C14N) صحيح، خاصة في handling الـ namespaces.

٩. أفضل الممارسات

١٠. POS SAAS API — اختصار الطريق

بناء كل الطبقة أعلاه يستغرق ٣-٦ أشهر لفريق متخصص. POS SAAS يوفر API جاهز يخفي كل التعقيدات:

POST /api/v1/sales
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "items": [{"product_id": 123, "qty": 2}],
  "customer_id": 45,
  "invoice_type": "standard"
}

// Response
{
  "sale_id": 1001,
  "invoice_number": "SINV-001-1001",
  "zatca_status": "cleared",
  "qr_base64": "AQ5T2VsbGVy...",
  "xml_hash": "..."
}

كل التعقيدات (CSR، CSID، توقيع XML، QR، ICV/PIH، retry) مُدارة تلقائياً. اقرأ توثيق API أو ابدأ تجربة مجانية.

مقالات ذات صلة