آخر تحديث: فبراير 2026 – راجع دائماً إشعار منشأتك من بوابة الهيئة للتأكد من تاريخ موجتك.
إذا كنت تدير متجر إلكتروني على Shopify وتبيع في السعودية، فأنت الآن أمام استحقاق تقني مهم: الامتثال لمتطلبات المرحلة الثانية من الفوترة الإلكترونية. الغرامات قد تصل إلى 50,000 ريال في حالات عدم الامتثال.
Shopify منصة عالمية، بينما ZATCA نظام محلي بمتطلبات صارمة تشمل التوقيع الرقمي، XML UBL 2.1، وسلسلة Hash. في هذا المقال راح نشرح كل شيء عن ربط Shopify مع ZATCA في المرحلة الثانية بوضوح.
📌 هذا الدليل موجه لـ:
- ✅ أصحاب متاجر Shopify في السعودية
- ✅ مطوري تطبيقات Shopify
- ✅ فرق التقنية في شركات التجارة الإلكترونية
- ✅ مدراء المنتجات الرقمية
- ✅ مزودي حلول الدفع والأنظمة المحاسبية
- ✅ استشاريي ERP والتكامل
مستوى المقال: متوسط إلى متقدم (يحتوي على تفاصيل تقنية وأمثلة برمجية)
⚡ للمطورين: النقاط التقنية الحرجة
- ✅ UTF-8 encoding إلزامي
- ✅ UUID فريد لكل فاتورة
- ✅ QR Code بصيغة TLV + Base64
- ✅ Compliance CSID → Production CSID
- ✅ مراقبة انتهاء صلاحية الشهادة
- ✅ SHA-256 hash chain (أول فاتورة = "0")
- ✅ Webhook: orders/paid أو fulfillments/create
- ✅ إعادة حساب VAT قبل الإرسال
- ✅ Retry logic مع exponential backoff
- ✅ حفظ invoice_hash للفاتورة التالية
فهم أنواع الفواتير (مهم جداً!)
أول خطأ يقع فيه التجار: يعتقدون أن كل الفواتير نفس الشيء. الحقيقة أن في نوعين مختلفين تماماً في المرحلة الثانية من الفوترة الإلكترونية:
الفاتورة الضريبية (B2B) - للمنشآت
- تحتاج موافقة من الهيئة قبل ما ترسلها للعميل (هذا اسمه Clearance)
- لازم يكون فيها الرقم الضريبي للمشتري
- الإرسال لازم يكون فوري في نفس اللحظة (Real-time)
- ما تقدر تصدرها بدون موافقة النظام
الفاتورة المبسطة (B2C) - للأفراد
- ترسلها للعميل مباشرة
- بعدين تبلغ الهيئة خلال 24 ساعة (هذا اسمه Reporting)
- ما تحتاج رقم ضريبي من المشتري
- لازم يكون فيها QR Code إلزامي
ليش هذا مهم؟ لأن طريقة ربط Shopify مع ZATCA المرحلة الثانية مختلفة تماماً حسب نوع الفاتورة. لو اخترت الحل الخطأ أو الـ webhook الخطأ، راح تفشل الفواتير.
الجدول الزمني للالتزام
هيئة الزكاة تطبق المرحلة الثانية على شكل موجات تدريجية حسب الإيرادات السنوية:
| نطاق الإيرادات السنوية | حالة الالتزام |
|---|---|
| أكثر من 3 مليون ريال | ✅ تم التطبيق (موجات سابقة) |
| 750,000 - 3 مليون ريال | ⚠️ موجات متوقعة في 2026 |
| أقل من 750,000 ريال | ⏳ موجات قادمة |
📌 تنويه مهم: نطاقات الإيرادات وتواريخ الموجات تعلن رسمياً من الهيئة بشكل دوري. الجدول أعلاه يعكس الاتجاه العام المتوقع. راجع دائماً الإشعار الرسمي المرسل لمنشأتك من بوابة الهيئة.
Shopify مقابل المنصات المحلية
قبل ما تقرر، شوف هالمقارنة السريعة:
| المنصة | التكامل مع ZATCA | سهولة الإعداد | الأفضل لـ |
|---|---|---|---|
| سلة | تكامل مدمج | ⭐⭐⭐⭐⭐ سهل جداً | السوق المحلي فقط |
| زيد | دعم محلي مباشر | ⭐⭐⭐⭐⭐ سهل جداً | المتاجر الصغيرة والمتوسطة |
| Shopify | تطبيقات خارجية أو Middleware | ⭐⭐⭐ متوسط | التوسع الدولي + مرونة عالية |
الخلاصة: إذا سوقك محلي 100% وما عندك فريق تقني، المنصات المحلية أسهل. لكن إذا تبي توسع دولي ومرونة، Shopify يستاهل الجهد الإضافي.
طرق ربط Shopify مع ZATCA
الخيار الأول: تطبيق جاهز (الأسهل)
في عدة تطبيقات تدعم التكامل مباشرة:
- QuiXcel ZATCA Connector - يوفر أكثر من 150 فحص توافق تلقائي
- Marmin ZATCA Invoice - يدعم B2B و B2C مع تخصيص PDF
- Qoyod Connector - يربط مع نظام قيود المحاسبي (يحتاج اشتراك مسبق)
المميزات:
- ✅ إعداد سريع (بدون برمجة)
- ✅ تحديثات تلقائية
- ✅ دعم فني من المزود
العيوب:
- ❌ اشتراك شهري مستمر
- ❌ مرونة محدودة في التخصيص
- ❌ اعتماد كامل على التطبيق
الخيار الثاني: Middleware مخصص (للاحترافيين)
تسوي خادم وسيط يقوم بالمهام التالية:
- استقبال إشعار (Webhook) من Shopify
- تحويل بيانات الطلب إلى XML UBL 2.1
- توقيع الفاتورة بالشهادة الرقمية (CSID)
- إرسالها للهيئة (Clearance أو Reporting)
- حفظ البيانات في Shopify Metafields
المميزات:
- ✅ تحكم كامل
- ✅ تخصيص حسب احتياجاتك
- ✅ قابلية توسع عالية
- ✅ لا اعتماد على طرف ثالث
العيوب:
- ❌ يحتاج خبرة تقنية
- ❌ تكلفة تطوير أولية
- ❌ مسؤولية الصيانة عليك
القاعدة الذهبية: أرسل الفاتورة عند "التوريد أو الدفع أيهما أسبق"
- orders/paid → للدفع الإلكتروني (بطاقة، Apple Pay، إلخ)
- fulfillments/create → للدفع عند الاستلام (COD)
⚠️ مهم: استخدام الـ webhook الخطأ يسبب تأخير في الإبلاغ (قد يؤدي لعدم الامتثال) أو إرسال مبكر قبل التوريد الفعلي (يسبب رفض الفاتورة).
لو تبي تتعلم كيف تبني أنظمة أتمتة، شوف دليلنا الكامل عن n8n.
الخيار الثالث: عبر نظام محاسبي
بعض الأنظمة المحاسبية (مثل Qoyod وDaftra) تتكامل مع Shopify وتتولى الربط مع الهيئة.
الميزة: إدارة مالية شاملة (فواتير + مخزون + تقارير محاسبية)
العيب: تحتاج اشتراك في النظام المحاسبي (تكلفة إضافية) + اعتماد كامل على المزود
التكلفة الحقيقية للربط
| الحل | التكلفة الشهرية | تكلفة التطوير | الإجمالي السنوي (تقريبي) |
|---|---|---|---|
| تطبيق جاهز | 20–100 دولار أمريكي | صفر | $240 - $1,200 |
| Middleware مخصص | $20 - $50 (استضافة) | $500 - $3,000 | $740 - $3,600 (السنة الأولى) |
| نظام محاسبي | $30 - $150 | وقت الإعداد فقط | $360 - $1,800 |
💡 ملاحظة: الأسعار تقريبية. قارن بين المزودين واطلب عروض أسعار.
المتطلبات التقنية الأساسية
1. الشهادة الرقمية (Cryptographic Stamp Certificate)
كل متجر Shopify يعتبر EGS (Electronic Generation Solution) ويحتاج شهادة رقمية خاصة.
أنواع الشهادات:
- Compliance CSID - للاختبار في بيئة Sandbox فقط
- Production CSID - للتشغيل الفعلي وإصدار فواتير حقيقية
كيف تحصل عليها؟ من خلال عملية Onboarding عبر بوابة الهيئة (تولد CSR وترسله وتستلم الشهادة).
مهم: كل متجر Shopify يحتاج شهادة منفصلة. لو عندك 3 متاجر، تحتاج 3 شهادات.
الشهادة الرقمية لها تاريخ انتهاء صلاحية. إذا انتهت:
- ❌ سيتم رفض جميع الفواتير
- ❌ سيتوقف Clearance و Reporting
- ❌ سيتوقف إصدار الفواتير بالكامل
- ❌ قد يؤدي إلى غرامات عدم الامتثال
أفضل ممارسة:
- ✅ راقب تاريخ انتهاء الشهادة تلقائياً (Monitoring)
- ✅ جددها قبل 30 يوم على الأقل
- ✅ اضبط تنبيهات (Alerts) عند اقتراب الموعد
- ✅ لا تخزن الشهادة داخل الكود (استخدم Key Vault)
2. XML Encoding (مهم جداً!)
أي encoding آخر سيؤدي لرفض الفاتورة. تأكد أن كل ملف XML يبدأ بـ:
<?xml version="1.0" encoding="UTF-8"?> <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"> ... </Invoice>
3. سلسلة Hash (Invoice Hash Chain)
كل فاتورة جديدة لازم تحتوي على hash الفاتورة السابقة. هذا يمنع التلاعب ويضمن تسلسل الفواتير.
Hash الفاتورة الحالية = SHA-256(محتوى XML + Hash الفاتورة السابقة)
عند إصدار أول فاتورة في النظام (أو بعد إعادة التهيئة):
Previous Invoice Hash = "0"
هذا يسمح ببداية السلسلة بدون الاعتماد على فاتورة سابقة. بعد ذلك، كل فاتورة تستخدم hash الفاتورة السابقة.
المشكلة الشائعة: إذا فشلت فاتورة وسط السلسلة، راح ينكسر كامل التسلسل بعدها!
الحل: استخدم نظام Queue (مثل RabbitMQ أو Redis) لضمان عدم فقدان أي فاتورة والحفاظ على الترتيب.
4. معرف UUID الفريد (إلزامي)
كل فاتورة يجب أن تحتوي على UUID (Universally Unique Identifier) فريد يولد قبل إرسالها.
لماذا UUID مهم؟
- يستخدم كمرجع أساسي في Clearance و Reporting
- يجب أن يكون فريد عالمياً (لا يتكرر أبداً في أي نظام)
- يربط الفاتورة بين نظامك ونظام الهيئة
- يستخدم في الاستعلام عن حالة الفاتورة
كيف تولد UUID صحيح؟
// JavaScript/Node.js const uuid = crypto.randomUUID(); // مثال: "123e4567-e89b-12d3-a456-426614174000" // Python import uuid invoice_uuid = str(uuid.uuid4()) // PHP $uuid = \Ramsey\Uuid\Uuid::uuid4()->toString(); // C# using System; string uuid = Guid.NewGuid().ToString();
- ❌ لا تستخدم أرقام متسلسلة (1, 2, 3...)
- ❌ لا تستخدم Timestamp كـ UUID
- ❌ لا تستخدم رقم الطلب من Shopify
- ✅ يجب أن يكون عشوائي تماماً ومطابق لمعيار RFC 4122
5. معالجة Rounding Issues (مشكلة خفية وخطيرة)
هذي مشكلة تقنية كثير من الحلول تتجاهلها:
المشكلة: Shopify يحسب الضريبة بطريقة معينة، لكن أحياناً تطلع فروقات صغيرة (هللات) مقارنة بالمعادلة المعتمدة من ZATCA.
مثال واقعي:
المبلغ الأصلي: 57.50 ريال الضريبة حسب Shopify: 8.63 ريال (تقريب) الضريبة حسب ZATCA: 8.625 ريال (دقيق) الفرق: 0.005 ريال النتيجة: الهيئة ترفض الفاتورة! ❌
الحل الصحيح: أعد حساب VAT قبل إرسال XML باستخدام معادلة ZATCA:
VAT Amount = (Taxable Amount × 15%) مقرب لأقرب هللتين Total Amount = Taxable Amount + VAT Amount
ملاحظة تقنية: التقريب يجب أن يتم على مستوى إجمالي الفاتورة (Invoice Level Total) وليس على مستوى كل عنصر منفصل (Line Item) لتجنب تراكم الفروقات الصغيرة.
💡 للتجار: اسأل مزود الحل: "كيف تعالجون Rounding Issues؟" - إذا ما عنده جواب واضح، ابحث عن حل آخر.
6. الختم الرقمي (Cryptographic Stamp)
بعد ما ترسل الفاتورة، الهيئة ترجع لك "ختم رقمي" يثبت أن الفاتورة معتمدة. هذا الختم لازم:
- تحفظه في قاعدة البيانات
- تعرضه في الفاتورة للعميل
- تحتفظ فيه للمراجعة
7. تنسيق QR Code للفواتير المبسطة (B2C)
QR Code في ZATCA ليس مجرد نص عادي - بل بيانات مشفرة بصيغة TLV (Tag-Length-Value) ثم محولة إلى Base64.
هذا سبب رفض شائع جداً: استخدام QR Code عادي بدلاً من TLV.
البنية الإلزامية (5 حقول أساسية):
| Tag | الحقل | مثال على القيمة |
|---|---|---|
| 1 | اسم البائع | شركة المثال التجارية |
| 2 | الرقم الضريبي | 300000000000003 |
| 3 | تاريخ ووقت الفاتورة | 2026-02-15T14:30:00Z |
| 4 | إجمالي الفاتورة (مع الضريبة) | 115.00 |
| 5 | قيمة الضريبة | 15.00 |
خطوات توليد QR Code الصحيح:
الخطوة 1: بناء مصفوفة TLV من البيانات
Tag (1 byte) + Length (1 byte) + Value (variable)
الخطوة 2: دمج كل الحقول الـ 5 في مصفوفة واحدة
الخطوة 3: تحويل المصفوفة إلى Bytes
الخطوة 4: ترميز Bytes إلى Base64
الخطوة 5: توليد صورة QR من Base64 String النهائي
💡 نصيحة للمطورين: استخدم مكتبات جاهزة للتعامل مع TLV مثل:
• Python: python-tlv أو pytlv
• Node.js: node-tlv
• Java/C#: ابحث عن TLV encoder libraries
لا تحاول بناء TLV encoder يدوياً - احتمال الخطأ عالي جداً!
مثال تطبيق عملي (كود مبسط)
هذا مثال بسيط لفهم كيف يشتغل ربط Shopify مع ZATCA المرحلة الثانية تقنياً:
// استقبال Webhook من Shopify عند دفع الطلب
app.post('/webhooks/orders/paid', async (req, res) => {
const order = req.body;
// 1. توليد UUID فريد للفاتورة
const invoiceUUID = crypto.randomUUID();
// 2. تحويل البيانات لصيغة XML UBL 2.1 مع UTF-8
const xmlInvoice = await convertToUBL(order, {
uuid: invoiceUUID,
encoding: "UTF-8"
});
// 3. إعادة حساب VAT لتجنب Rounding Issues
const correctedXML = await recalculateVAT(xmlInvoice);
// 4. توقيع الفاتورة بالشهادة الرقمية
const signedInvoice = await signWithCSID(correctedXML);
// 5. إرسالها للهيئة (Clearance أو Reporting)
const response = await submitToZATCA(signedInvoice);
// 6. حفظ البيانات في Shopify Metafields
await updateOrderMetafields(order.id, {
zatca_uuid: invoiceUUID,
zatca_clearance_id: response.clearanceId,
zatca_qr: response.qrCode, // TLV + Base64
zatca_hash: response.invoiceHash // مهم للفاتورة التالية!
});
// 7. إرجاع نجاح
res.sendStatus(200);
});
📌 هذا مثال تبسيطي. التطبيق الفعلي يحتاج: معالجة أخطاء، إعادة محاولة، تشفير آمن، Queue management، وإدارة Hash Chain.
تخزين البيانات في Shopify
بعد استلام الرد من الهيئة، احفظ البيانات في Shopify Metafields:
| البيانات | Namespace | Key | لماذا مهم؟ |
|---|---|---|---|
| UUID | zatca | invoice_uuid | المعرف الفريد للفاتورة |
| Clearance ID | zatca | clearance_id | إثبات الموافقة من الهيئة |
| Invoice Hash | zatca | invoice_hash | حرج! تحتاجه للفاتورة التالية |
| QR Code | zatca | qr_code_base64 | TLV مشفر - للطباعة على PDF |
| تاريخ الختم | zatca | clearance_timestamp | وقت الموافقة (للمراجعة) |
بعد كذا تقدر تعرض هذه البيانات في إيميل التأكيد وفاتورة PDF.
الأخطاء الشائعة وحلولها
| الخطأ | السبب | الحل |
|---|---|---|
| XML Validation Error | بنية XML غير متوافقة مع UBL 2.1 | استخدم مكتبة معتمدة واختبر في Sandbox |
| Encoding Error | استخدام encoding غير UTF-8 | تأكد من <?xml encoding="UTF-8"?> |
| Invalid UUID | استخدام رقم تسلسلي بدلاً من UUID | استخدم crypto.randomUUID() أو uuid.uuid4() |
| QR Code Rejected | استخدام نص عادي بدلاً من TLV | استخدم TLV encoder ثم Base64 |
| Hash Mismatch | Hash الفاتورة السابقة غير صحيح | احفظ hash كل فاتورة بشكل آمن |
| Rounding Error | فرق في حساب VAT | أعد حساب VAT باستخدام معادلة ZATCA |
| Certificate Expired | انتهت صلاحية CSID | جدد الشهادة قبل 30 يوم |
| API Timeout | بطء استجابة من خوادم الهيئة | أضف Retry Logic مع Exponential Backoff |
Checklist قبل التشغيل
الشهادات والأمان:
- ☐ حصلت على Compliance CSID واختبرت في Sandbox
- ☐ حصلت على Production CSID للتشغيل الفعلي
- ☐ الشهادة غير منتهية (راقب تاريخ الانتهاء)
- ☐ المفاتيح الخاصة مخزنة بأمان (Key Vault، مو في الكود!)
- ☐ في آلية تنبيه لتجديد الشهادة
التقنيات:
- ☐ XML بصيغة UBL 2.1 و UTF-8
- ☐ توليد UUID فريد لكل فاتورة (مو رقم تسلسلي)
- ☐ QR Code بصيغة TLV + Base64 (مو نص عادي)
- ☐ تم حل مشكلة Rounding Issues
- ☐ Hash Chain يشتغل بشكل صحيح (أول فاتورة = "0")
- ☐ Webhook صحيح (orders/paid أو fulfillments/create)
- ☐ في Retry Logic عند فشل الإرسال
- ☐ تحفظ invoice_hash لكل فاتورة
الجاهزية:
- ☐ اختبرت في بيئة Sandbox
- ☐ جربت B2B و B2C
- ☐ اختبرت QR Code يقرأ صح
- ☐ في Monitoring وتنبيهات
- ☐ عندك خطة نسخ احتياطي
هل Shopify يدعم المرحلة الثانية من ZATCA؟
نعم، ربط Shopify مع ZATCA المرحلة الثانية ممكن بالكامل، لكن يحتاج إعداد خارجي. بعكس المنصات المحلية التي توفر تكامل مدمج، Shopify يتطلب إما تطبيق جاهز (مثل QuiXcel أو Marmin) أو بناء Middleware مخصص يدعم Clearance و Reporting.
الميزة الأساسية لـ Shopify هي المرونة العالية والقدرة على التوسع الدولي، لكن هذا يأتي مع مسؤولية إعداد الربط التقني بشكل صحيح. المتطلبات الأساسية تشمل: توليد UUID فريد، QR Code بصيغة TLV، سلسلة Hash، وشهادة رقمية (CSID).
النجاح في ربط Shopify مع ZATCA يعتمد على فهم دقيق للفروقات بين B2B (Clearance) و B2C (Reporting)، ومعالجة التحديات التقنية مثل Rounding Issues والحفاظ على Hash Chain سليم.
أسئلة سريعة (FAQ)
هل يمكنني استخدام تطبيق واحد لعدة متاجر Shopify؟
لا. كل متجر Shopify يعتبر EGS مستقل ويحتاج شهادة رقمية منفصلة. لو عندك 3 متاجر، تحتاج 3 شهادات.
ماذا يحدث بالضبط إذا انتهت صلاحية الشهادة؟
يتوقف إصدار الفواتير فوراً. كل محاولة إرسال ستفشل. لذلك راقب تاريخ الانتهاء وجدد قبل 30 يوم على الأقل.
هل أحتاج مبرمج لكل تحديث في المتجر؟
مع التطبيقات الجاهزة: لا، التحديثات تلقائية. مع Middleware مخصص: قد تحتاج صيانة دورية حسب التعديلات.
كيف أعرف إذا كان الحل يعالج Rounding Issues؟
اسأل المزود مباشرة: "هل تعيدون حساب VAT قبل الإرسال؟" - إذا الجواب غير واضح أو "لا"، ابحث عن حل آخر.
لماذا QR Code يرفض رغم أنه يعمل عندي؟
السبب الأشهر: أنت تستخدم نص عادي بدلاً من TLV encoding. ZATCA تتطلب QR Code بصيغة TLV محول إلى Base64. استخدم مكتبة TLV encoder متخصصة لتجنب هذا الخطأ الشائع.
الخلاصة
ربط Shopify مع ZATCA في المرحلة الثانية ممكن وفعال، لكن يحتاج فهم دقيق للمتطلبات التقنية:
- ✅ فهم الفرق بين B2B (Clearance) و B2C (Reporting)
- ✅ توليد UUID فريد لكل فاتورة (مو رقم تسلسلي)
- ✅ استخدام QR Code بصيغة TLV (مو نص عادي)
- ✅ الحصول على الشهادات الرقمية ومراقبة انتهائها
- ✅ استخدام UTF-8 والتأكد من UBL 2.1
- ✅ معالجة Rounding Issues على مستوى الفاتورة
- ✅ بناء نظام Hash Chain قوي (أول فاتورة = "0")
- ✅ اختيار الـ Webhook الصحيح
- ✅ اختيار الحل المناسب لحجم عملك وميزانيتك
إذا نفذت الربط بشكل صحيح مع مراعاة كل هذه النقاط، Shopify يصير منصة قوية مع امتثال كامل للمرحلة الثانية.