مقارنة برامج الفوترة المستضافة ذاتياً على VPS
قارن Invoice Ninja وInvoiceShelf وInvoicePlane وKimai وERPNext على VPS واحد: الفوترة المتكررة والضرائب وبوابة العملاء والدفع والتراخيص.
ما برنامج الفوترة المستضاف ذاتياً الذي ينبغي أن تختاره؟
تنحصر خيارات برامج الفوترة المستضافة ذاتياً الواقعية على VPS واحد في خمسة خيارات، وهي ليست بدائل متقاربة. يُعد Invoice Ninja المنتج الأكثر اكتمالاً: تعمل الفواتير المتكررة، وبوابة العملاء، وبوابات الدفع، وتنسيقات الفوترة الإلكترونية منذ اليوم الذي تثبّته فيه. أما InvoiceShelf فهو الخيار الأخف والمفتوح المصدر بالكامل. وInvoicePlane تطبيق PHP بسيط لا يحتاج إلى تنسيق مكونات متعددة. بينما يحسب Kimai الساعات المتتبعة بدلاً من بنود الفاتورة. أما ERPNext فهو نظام محاسبة متكامل يطبع الفواتير أيضاً.
هناك مشكلتان تتسببان في فشل إعداد الفوترة المستضافة ذاتياً أكثر بكثير من نقص أي ميزة. الأولى هي البريد الإلكتروني. الفاتورة الموجودة في مجلد البريد العشوائي هي فاتورة غير مدفوعة، ولا توجد وسيلة تخبرك بأن ذلك حدث. والثانية هي النسخ الاحتياطية. هذه هي قاعدة البيانات المستضافة ذاتياً التي يتحول فقدانها إلى مشكلة ضريبية بدلاً من مجرد إزعاج.
اقرأ الترخيص قبل أن تقرأ قائمة الميزات. ثلاثة من هذه الخيارات الخمسة تستخدم تراخيص copyleft، وواحد يستخدم ترخيصاً متساهلاً، وواحد متاح مصدره مع قيود فعلية على ما يمكنك فعله به.
الخيارات الخمسة، ولمن يناسب كل خيار
Invoice Ninja
تطبيق Laravel، وهو حالياً ضمن السلسلة v5. الاستضافة الذاتية مجانية ومفتوحة بالكامل: الفواتير المتكررة، وعروض الأسعار، والمشاريع، وتتبع الوقت، والمصروفات، وبوابة العملاء، وبوابات الدفع، ومنها Stripe وPayPal. يصف المشروع نفسه بأنه «تطبيق للفواتير وعروض الأسعار والمشاريع وتتبع الوقت، ومتاح مصدره، ومبني باستخدام Laravel». العنصر المدفوع الوحيد هو إزالة العلامة التجارية. ووفقاً للمشروع نفسه: «نوفّر ترخيص white-label بسعر $40 سنوياً لإزالة العلامة التجارية لـ Invoice Ninja من الأجزاء الموجّهة إلى العملاء في التطبيق». هذا السعر سارٍ حتى August 2026.
اختره إذا كنت تريد المنتج الأكثر اكتمالاً وتقبل بتشغيل أكبر حزمة برمجية.
InvoiceShelf
فرع من Crater، ومرخّص بموجب GNU Affero General Public License version 3 (AGPL-3.0). يغطي الفواتير، والتقديرات، والفوترة المتكررة، والمصروفات، والضرائب، وتعدد العملات، وبوابة العملاء، وتعدد الشركات. توجد المدفوعات وإزالة العلامة التجارية في مستودعين رسميين منفصلين للوحدات، وكلاهما مرخّص بموجب AGPL-3.0 ومجاني. تُنفّذ مدفوعات البطاقات عبر Stripe checkout.
اختره إذا كنت تريد تطبيقاً صغيراً ومفتوح المصدر بالكامل، ولا تحتاج إلى thirty بوابة دفع.
InvoicePlane
تطبيق PHP مبني على CodeIgniter، ومرخّص بموجب MIT licence، وهو الخيار الوحيد هنا الذي يُثبّت بفك ضغط الملفات داخل web root. لا يحتاج إلى Docker أو خطوة بناء باستخدام Node. تُنشأ ملفات PDF باستخدام mPDF، لذلك تكون القوالب بصيغة HTML وCSS. يحصل العملاء على guest link لعرض الفاتورة ودفعها.
المشكلة هي المدفوعات. توضّح الوثائق صراحةً أن InvoicePlane 1.6 يدعم Stripe فقط تلقائياً، وأن المزوّدين الآخرين أُزيلوا في ذلك الإصدار. تتطلب الإصدارات المنشورة من السلسلة 1.6 استخدام PHP 8.0 إلى 8.1 مع MySQL 5.5 أو إصدار MariaDB المطابق. اقرأ الملاحظات الخاصة بأي إصدار تنزّله، لأن السلسلة 1.7 ما زالت قيد التطوير.
اختره إذا كنت تستخدم shared hosting أو VPS بسعة 512 MB.
Kimai
أداة لتتبع الوقت، مرخّصة بموجب AGPL-3.0، وتُنشئ الفواتير من جداول الساعات. وهي الخيار المناسب لمن يفوتر مقابل الساعات. تُرفع قوالب الفواتير بصيغة DOCX أو ODS أو XLSX، وتؤكد الوثائق أن هذه هي الصيغ المقبولة الوحيدة، ثم تُحوّل إلى PDF أو HTML. تنسّق فاتورتك في معالج نصوص بدلاً من كتابة CSS، وهو ما يجده معظم المستخدمين أسهل.
لا تحتوي Kimai على بوابة عملاء أو بوابة دفع، لذلك ترسل ملف PDF عبر البريد الإلكتروني. الفوترة الإلكترونية المنظّمة متاحة في إضافة متجر مدفوعة باسم E-Invoice Plus، بسعر 99 EUR سنوياً، باستثناء VAT، لعملية تثبيت ذاتية الاستضافة حتى August 2026. وتشمل الإضافة ملفات EN16931 وXRechnung وZUGFeRD وFactur-X وPeppol.
اختره إذا كانت الفاتورة ناتجاً عن الوقت الذي تتبعه.
ERPNext
مرخّص بموجب GPL-3.0، وينتمي إلى فئة مختلفة من البرامج. فاتورة المبيعات نوع مستند واحد داخل نظام محاسبة كامل يضم دليل الحسابات، وقيود اليومية، والمخزون، وكشوف الرواتب. وهو الخيار المناسب عندما لا تعود الفوترة المهمة الوحيدة. أما بالنسبة إلى مستقل واحد لديه eight عملاء، فهو برنامج أكبر بكثير من الحاجة. ويُعد تشغيله مشروعاً بحد ذاته، وقد غطّيناه في تشغيل ERPNext على VPS.
تعتمد الفواتير المتكررة على مجدول لا يمكنك رؤيته
ينشئ كل من Invoice Ninja وInvoiceShelf وInvoicePlane وERPNext فواتير متكررة. لا يوفّر Kimai ميزة الفواتير المتكررة في النواة، لأن الفاتورة فيه تُنشأ من قيود جدول الساعات لفترة زمنية.
يحدث الفشل بالطريقة نفسها في كل تطبيق مبني على Laravel، ويحدث من دون إشعار. ينشئ مهمة مجدولة الفواتير المتكررة، php artisan schedule:run، ويجب على مكوّن خارج التطبيق استدعاؤها كل دقيقة. إذا لم يستدعها أي مكوّن، فستظل قائمة الفواتير المتكررة تعرض تاريخ الإرسال التالي، ويمر ذلك التاريخ ببساطة. لن تظهر أي فاتورة. ولن يُسجَّل أي خطأ، لأن أي تعليمات برمجية لم تُنفَّذ.
لذلك، بعد إنشاء أول فاتورة متكررة، اضبط تاريخ الإرسال التالي على بضع دقائق من الوقت الحالي وانتظر. إذا لم تصل أي فاتورة، فالمجدول لا يعمل. في تثبيت Docker، يعني ذلك عادةً أن خدمة cron أو خدمة المجدول في ملف compose لم تبدأ، أو أنها توقفت.
docker compose ps
docker compose logs --tail 50يجب أن تعرض كل خدمة في الملف الحالة running. أما الخدمة التي تكون في الحالة exited فهي الخدمة التي تحتاج إلى قراءة سجلاتها.
العملات المتعددة والضرائب: ما الذي يجب التحقق منه قبل الالتزام
تذكر قوائم الميزات «العملات المتعددة»، وقد تعني بذلك أموراً مختلفة جداً. نفّذ هذه الاختبارات الأربعة على نسخة تجريبية، باستخدام أرقام فعلية من نشاطك التجاري، لأن المحاسب سيكتشف الخطأ هنا بدلاً منك.
- هل تحفظ الفاتورة سعر الصرف المطبّق في تاريخ إصدارها؟ يجب أن تفعل ذلك. إذا كان التطبيق يعيد حساب الإجماليات باستخدام سعر صرف مباشر، فستتغير تقارير الربع السابق كلما فتحتها، ولن تعود دفاترك متطابقة مع ما سبق أن قدّمته.
- هل تُطبَّق الضريبة على كل بند، أم على الفاتورة، أم على كليهما؟ يكون استخدام معدل واحد على مستوى الفاتورة مناسباً إلى أن يحتوي أحد البنود على نسبة ضريبة صفرية.
- هل يمكنك إدخال الأسعار شاملة للضريبة، وكذلك غير شاملة لها؟ يؤدي التحويل بعد ذلك إلى فروق تقريب مقدارها سنت واحد لكل بند، وتتراكم هذه الفروقات على مدار العام.
- ماذا يعرض المستند لعميل في بلد آخر لا يدين بضريبة القيمة المضافة؟ تحتاج إلى طباعة ملاحظة الإعفاء على الفاتورة، وليس الاكتفاء بعرض صفر في عمود الضريبة.
يتعامل Invoice Ninja وERPNext مع الحالات الأربع كلها. وتدرج InvoiceShelf الضرائب والعملات المتعددة ضمن ميزاتها. أما InvoicePlane وKimai فهما أبسط، لذلك اختبرهما باستخدام أكثر فواتيرك تعقيداً، لا أسهلها.
بوابة العميل وبوابات الدفع
بوابة العميل هي صفحة يطّلع فيها العميل على فواتيره، وينزّل ملفات PDF، ويدفع المستحقات. وتكمن أهميتها في أنها أكبر مما قد يبدو، لأن متابعة الدفع عبر البريد الإلكتروني تستهلك من وقتك أكثر مما استغرقه إنشاء الفاتورة.
يتفوق Invoice Ninja في هذا الجانب، إذ يوفّر بوابة متكاملة، وبوابات دفع متعددة، ووسائل دفع محفوظة، وفوترة تلقائية للفواتير المتكررة. يوفّر InvoiceShelf بوابة للعملاء، ويضيف الدفع عبر Stripe من خلال وحدة المدفوعات الخاصة به. يتيح InvoicePlane رابط ضيف لكل فاتورة، ويدعم Stripe. أما Kimai فلا يوفّر أياً من ذلك، لذلك يُرسل ملف PDF كمرفق.
هناك نقطة يختلط فهمها باستمرار. استضافة تطبيق الفوترة ذاتياً لا تعني الاحتفاظ بأرقام البطاقات. عند استخدام Stripe Checkout، يُعاد توجيه العميل إلى Stripe، ويدخل بيانات البطاقة هناك، ولا يرى VPS رقم البطاقة مطلقاً. ويظل نطاق التزاماتك وفق PCI (معيار أمان بيانات بطاقات الدفع) محدوداً تحديداً لأنك لم تنشئ نموذج الدفع بنفسك. إذا احتجت لاحقاً إلى أكثر من معالج دفع، أو أردت توجيه المدفوعات حسب البلد، فضع ذلك في طبقة منفصلة مثل تنسيق المدفوعات المستضاف ذاتياً باستخدام Hyperswitch.
جودة PDF، والقالب الذي ستنتهي إلى تعديله
ستعدّل القالب. كل إعداد افتراضي هنا يضع عنوانك في الموضع الخطأ في بلدك.
يعرض Invoice Ninja قوالب HTML وCSS بصيغة PDF باستخدام Chromium من دون واجهة رسومية والمضمّن داخل الصورة، ولذلك تكون الحاوية كبيرة. خصّص له قدراً كافياً من الذاكرة: فالمتصفح من دون واجهة رسومية هو أثقل عملية في الحزمة، لذا يكون VPS بسعة 1 GB محدوداً. يستخدم InvoicePlane مكتبة mPDF، وهي مكتبة PHP خالصة وخفيفة، لكن ذلك يأتي على حساب تجاهل بعض خصائص CSS الحديثة. أما Kimai فيتبع النهج المعاكس، إذ يطلب منك تحميل ملف DOCX أو ODS، بحيث ينفّذ شخص لم يكتب ورقة أنماط من قبل تخطيط الملف في LibreOffice أو Word.
إذا كان تصميم الفاتورة مهماً لك ولا تهتم بـCSS، فنهج Kimai هو الأنسب. وإذا أردت حفظ القالب في نظام للتحكم بالإصدارات وإمكانية مقارنة تغييراته، فاختر HTML.
هل تسمح لك الرخصة باستخدام البرنامج تجارياً؟
تسمح لك البرامج الخمسة بإصدار فواتير لعملائك. تظهر الاختلافات عندما تفعل أي شيء يتجاوز ذلك.
يخضع Invoice Ninja لرخصة Elastic License 2.0. هناك بندان مهمان.
لا يجوز لك توفير البرنامج إلى أطراف ثالثة كخدمة مستضافة أو مُدارة، إذا كانت الخدمة تتيح للمستخدمين الوصول إلى مجموعة كبيرة من ميزات البرنامج أو وظائفه.
لا يجوز لك نقل وظيفة مفتاح الترخيص في البرنامج أو تغييرها أو تعطيلها أو التحايل عليها.
لذلك، لا مشكلة في تشغيله لنشاطك التجاري، لكن لا يجوز تشغيل نُسخ للعملاء باعتباره منتجاً. والبند الثاني هو سبب كون إزالة العلامة التجارية رخصة بقيمة $40، وليست تعديلاً على الشفرة المصدرية.
يخضع InvoiceShelf وKimai وCrater لرخصة AGPL-3.0. الاستخدام التجاري مجاني، ولا توجد طبقة أعلى منك. ويتمثل الالتزام في القسم 13: إذا عدّلت الشفرة وسمحت لأشخاص آخرين باستخدام نسختك المعدّلة عبر الشبكة، فيجب أن تتيح لهم الشفرة المصدرية لتغييراتك. أما النسخة غير المعدّلة فتكون مشمولة أصلاً بالشفرة المصدرية العامة التي يوفرها المشروع الأصلي، لذلك لا يتعامل معظم مستضيفي الخدمات ذاتياً مع هذا الشرط.
يخضع InvoicePlane لرخصة MIT، وهي أخف الالتزامات في هذه المجموعة، مع أن ملف README يوضح أن الاسم والشعار يظلان ملكاً للمشروع.
يخضع ERPNext لرخصة GPL-3.0. يجب مشاركة التعديلات التي توزّعها، ولا يترتب أي التزام على تشغيله بشكل خاص.
هذا وصف لنص الرخصة، وليس استشارة قانونية.
هل ما يزال المشروع قيد الصيانة؟ تحقّق من سجل الالتزامات
كان Crater تطبيق الفوترة مفتوح المصدر الشائع لعدة سنوات، وما تزال أدلة كثيرة توصي به. لم يتضمن الفرع الافتراضي أي التزام منذ 741 يوماً.
The data behind this chart
[
{
"label": "ERPNext",
"commit_gap": 0
},
{
"label": "Invoice Ninja",
"commit_gap": 1
},
{
"label": "Kimai",
"commit_gap": 1
},
{
"label": "InvoicePlane",
"commit_gap": 3
},
{
"label": "InvoiceShelf",
"commit_gap": 4
},
{
"label": "Crater",
"commit_gap": 741
}
]من بين المشاريع البالغ عددها 6 في تلك المجموعة، تضمّن خمسة منها التزاماً خلال الأسبوع الماضي. يُعد InvoiceShelf المشروع المتفرع الذي واصل تطوير Crater، بموجب ترخيص AGPL-3.0 نفسه وبنموذج البيانات نفسه، لذا فإن الانتقال إليه هو ترحيل للبيانات وليس إعادة كتابة. ثبّت InvoiceShelf بدلاً من Crater.
تثبيت كل تطبيق على VPS
تعمل جميع التطبيقات باستثناء InvoicePlane بسهولة أكبر ضمن Docker Compose. إذا كان ذلك جديداً عليك، فابدأ بـإنشاء أول مكدس Docker Compose على VPS ثم عد إلى هنا.
يأتي Invoice Ninja مع مستودع compose خاص به.
git clone https://github.com/invoiceninja/dockerfiles.git
cd dockerfiles
docker run --rm -it invoiceninja/invoiceninja php artisan key:generate --showانسخ هذا المفتاح إلى ملف env في المستودع، وأضف أيضاً قيمة APP_URL الحقيقية. ثم اضبط الملكية وفقاً لما تتوقعه الصورة وابدأ التطبيق.
chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/app
docker compose up -dتطابق ملكية 1500:1500 المستخدم داخل الصورة. إذا تخطيت هذه الخطوة، فلن يتمكن التطبيق من الكتابة إلى ذاكرة التخزين المؤقت أو ملفات PDF التي ينشئها. في معالج الإعداد، أدخل db بوصفه مضيف قاعدة البيانات، لأن هذا هو اسم الخدمة على شبكة compose. يشير localhost هناك إلى حاوية التطبيق نفسها.
ينشر InvoiceShelf ملفات compose جاهزة، ملفاً واحداً لكل محرك قاعدة بيانات.
curl -fLO https://raw.githubusercontent.com/InvoiceShelf/docker/master/docker-compose.mysql.yml
mv docker-compose.mysql.yml docker-compose.ymlافتح هذا الملف قبل بدء التطبيق. كل كلمة مرور فيه هي قيمة نائبة، ويوضح الملف ذلك في تعليقاته. تكون APP_URL وSESSION_DOMAIN وSANCTUM_STATEFUL_DOMAINS مضبوطة افتراضياً على localhost، ويجب ضبط القيم الثلاث على اسم المضيف الحقيقي قبل تسجيل الدخول لأول مرة. ثم شغّل التطبيق.
docker compose up -dينشر التطبيق المنفذ 8090 على المضيف، ويخدم عبر المنفذ 8080 داخل الحاوية. ضع reverse proxy مع TLS (أمان طبقة النقل) أمامه قبل إرسال أي عميل واحد إليه.
ملف compose للإنتاج الخاص بـKimai، من توثيق المشروع
services:
sqldb:
image: mysql:8.3
volumes:
- mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=kimai
- MYSQL_USER=kimaiuser
- MYSQL_PASSWORD=kimaipassword
- MYSQL_ROOT_PASSWORD=changemeplease
command: --default-storage-engine innodb
restart: unless-stopped
healthcheck:
test: mysqladmin -uroot -p$$MYSQL_ROOT_PASSWORD ping -h 127.0.0.1 --silent
interval: 10s
timeout: 5s
retries: 12
start_period: 30s
kimai:
image: kimai/kimai2:stable
depends_on:
sqldb:
condition: service_healthy
restart: true
volumes:
- data:/opt/kimai/var/data
- plugins:/opt/kimai/var/plugins
ports:
- 8001:8001
environment:
- APP_SECRET=your-fantastic-long-random-and-ultra-secure-secret
- TRUSTED_HOSTS=kimai.example.com
- ADMINMAIL=admin@example.com
- ADMINPASS=changemeplease
- DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8mb4&serverVersion=8.3.0
restart: unless-stopped
volumes:
data:
mysql:
plugins:اضبط APP_SECRET على سلسلة عشوائية طويلة من اختيارك، واضبط TRUSTED_HOSTS على النطاق الذي ستستخدمه فعلياً. تنشئ ADMINMAIL وADMINPASS أول مسؤول عند الإقلاع الأول، لذلك غيّر كلمة المرور هذه من الواجهة بعد ذلك، ثم أزلها من الملف.
لا تحتوي InvoicePlane على حاوية. أنشئ قاعدة بيانات فارغة أولاً.
sudo mysql -e "CREATE DATABASE invoiceplane CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"نزّل الأرشيف من صفحة إصدارات المشروع، واستخرجه في جذر الويب، وانسخ ipconfig.php.example إلى ipconfig.php، واضبط عنوان URL داخله باتباع التعليقات الموجودة في الملف. ثم افتح https://your-domain.example/index.php/setup واتبع خطوات برنامج التثبيت.
لماذا تصل فاتورتك إلى مجلد الرسائل غير المرغوب فيها
هذا هو العطل الذي يكلّفك المال، وسيعرض التطبيق بكل بساطة أن الفاتورة أُرسلت.
لا ترسل رسائل الفواتير من عنوان IP الخاص بـVPS نفسه. لا يملك عنوان IP جديد في VPS أي سجل إرسال، ويعامل كبار مزوّدي الاستقبال افتراضياً أول رسالة واردة من عنوان غير معروف في نطاق استضافة على أنها مشبوهة. أرسل الرسائل عبر مرحّل SMTP (بروتوكول نقل البريد البسيط) على نطاق صادقت عليه. يتطلب تنفيذ ذلك من البداية إلى النهاية دليلاً مستقلاً، ويغطي إرسال البريد بشكل موثوق من تطبيق مستضاف ذاتياً إعداد المرحّل، وسجلات DNS، والاختبار.
يحدث معظم الخطأ في إعدادات الفوترة في عنوان From. يجب أن يكون العنوان على نطاق تملكه، وأن يوقّعه المرحّل باستخدام DKIM (البريد المعرّف بمفاتيح النطاق). قد يبدو وضع عنوان العميل في From تصرفاً مهذباً، لكنه يعرقل التسليم، لأن خادم الاستقبال يتحقق من أن نطاق From يطابق النطاق الذي صادق على الرسالة. يرفض Gmail عدم التطابق مباشرة:
550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policyأبقِ عنوانك في From، وضع عنوان العميل في Reply-To. تحقّق من السجلات المنشورة قبل إرسال أي رسالة فعلية.
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.comيجب أن يعرض الاستعلام الأول سجل SPF (إطار سياسة المرسل) الذي يحدد مرحّلك. ويجب أن يعرض الثاني سياسة DMARC (مصادقة الرسائل المستندة إلى النطاق والإبلاغ والمطابقة). يعتمد الثالث على selector الذي منحه لك المرحّل، وتعني النتيجة الفارغة أن سجل DKIM مفقود أو منشور تحت اسم غير صحيح، ولذلك سيفشل كل بريد ترسله في فحص التوقيع.
أرسل بعد ذلك فاتورة فعلية إلى حساب تملكه لدى مزوّد كبير، واقرأ الرؤوس الأولية. إن dkim=pass وspf=pass في رأس Authentication-Results هما الدليل الوحيد المعتمد. وتعني علامة "sent" في التطبيق فقط أنه سلّم الرسالة إلى المرحّل.
النسخ الاحتياطية: قاعدة البيانات الوحيدة التي لا يمكنك فقدانها
يعني فقدان خادم الوسائط تنزيل الملفات مرة أخرى. أما فقدان قاعدة بيانات الفواتير فيعني أنك لن تتمكن من إثبات ما فوّتَرته، وما دُفع لك، وما لا يزال مستحقاً لك. تعامل معها وفقاً لذلك.
انسخ أربعة أشياء احتياطياً. قاعدة البيانات. وحدة التخزين التي تحتوي على الشعارات وملفات PDF المُنشأة وإيصالات المصروفات. ملف بيئة التطبيق. وملفات PDF المُنشأة المحفوظة كملفات عادية، لأن ملف PDF يفتح بعد عشر سنوات حتى من دون التطبيق الذي أنشأه.
ملف البيئة أهم مما يتوقع كثيرون. يشفّر Laravel القيم الحساسة المخزنة، بما في ذلك بيانات اعتماد بوابة الدفع، باستخدام APP_KEY الموجود في ذلك الملف. إذا استعدت قاعدة البيانات إلى جانب مفتاح مُنشأ حديثاً، فلن تُفكّ هذه القيم. ستكون فواتيرك موجودة بالكامل، لكن إعدادات بوابة الدفع ستكون غير قابلة للقراءة.
يبدو تفريغ بيانات مكدس InvoiceShelf كما يلي. تعمل خدمة قاعدة البيانات الخاصة به على mariadb:10، لذلك تكون الأداة داخل الحاوية هي mariadb-dump.
docker compose exec -T database mariadb-dump \
--user=root --password=YOUR_ROOT_PASSWORD \
--single-transaction --databases invoiceshelf > invoiceshelf.sqlتأخذ --single-transaction لقطة متسقة لجداول InnoDB من دون قفلها، لذلك يواصل التطبيق تقديم الخدمة أثناء تشغيل التفريغ. وتمنع -T Docker من تخصيص طرفية، لأن ذلك قد يفسد الخرج المعاد توجيهه وينتج ملف تفريغ لا يمكن استيراده.
أرسل النسخة الاحتياطية خارج الخادم وفق جدول زمني باستخدام نسخ restic الاحتياطية المشفّرة إلى تخزين خارج الموقع، واضبط مدة الاحتفاظ بما يكفي لتغطية الفترة التي يحددها محاسبك.
ثم استعدها. شغّل التفريغ في حاوية مؤقتة، وسجّل الدخول، وافتح فاتورة الشهر الماضي. ما لم تفعل ذلك مرة واحدة، فلن تعرف ما إذا كانت النسخة الاحتياطية تعمل.
ما سيطلبه منك محاسبك
لا تعتمد على هذا الدليل للحصول على مشورة ضريبية. يوضّح ما يلي ما يستطيع هذا البرنامج إنتاجه، حتى تتمكن من أخذ القائمة إلى الشخص الذي يقدّم لك المشورة.
البيانات القابلة للتصدير. يجب أن تتمكن من تصدير فواتيرك ومدفوعاتك إلى CSV من الواجهة، من دون استخدام عميل قاعدة بيانات ومن دون فتح تذكرة دعم. تفريغ SQL نسخة احتياطية وليس عملية تصدير، لأن محاسبك لا يستطيع فتحه.
الترقيم غير القابل للتغيير. يجب أن تتسلسل أرقام الفواتير وألا يعاد استخدامها، من دون فجوات. يؤدي حذف فاتورة إلى ترك فجوة يتعين تفسيرها لاحقاً. استخدم الإلغاء أو الإشعار الدائن بدلاً من ذلك، فكل تطبيق هنا يدعم ذلك. يعتمد ما إذا كان الترقيم المتسلسل بلا فجوات مطلوباً منك على مكان تسجيلك، ومن المفيد الاستفسار عن ذلك مبكراً.
الاحتفاظ. احتفظ بتفريغات قاعدة البيانات وملفات PDF الناتجة طوال المدة التي تفرضها القواعد المطبقة عليك. ملف PDF هو المستند الذي أُرسل فعلياً، وهو السجل المهم إذا اعترض أحد في أي وقت على فاتورة.
سجل التغييرات. من المفيد أن تتمكن من إظهار من عدّل فاتورة ومتى عدّلها، ويختلف هذا الجانب أكثر من غيره بين هذه التطبيقات. يحتفظ Invoice Ninja بسجل نشاط لكل سجل.
أصبحت الفوترة الإلكترونية المهيكلة متطلباً فعلياً، لا ميزة إضافية اختيارية، في أجزاء من الاتحاد الأوروبي. ينشئ Invoice Ninja التنسيقات الشائعة، بما في ذلك ZUGFeRD وXRechnung وFacturae وFatturaPA والتنسيق العام EN16931. يمر التسليم عبر شبكة Peppol من نسخة مستضافة ذاتياً عبر نقطة الوصول الخاصة بـInvoice Ninja: تسجّل كيانك لديهم وتشتري أرصدة لكل عملية إرسال، ولذلك فهي خدمة مدفوعة اعتباراً من August 2026. ويوفّر Kimai التنسيقات نفسها عبر plugin مدفوع. أما التطبيقات الثلاثة الأخرى فلا تنتج أي فواتير إلكترونية مهيكلة حتى اليوم، وهذا هو السبب الأقوى لاختيار Invoice Ninja إذا كنت تصدر الفواتير داخل الاتحاد الأوروبي.
FAQ
هل أختار Crater أم InvoiceShelf؟
InvoiceShelf. لم يتضمن الفرع الافتراضي لـCrater أي commit منذ 741 يوماً حتى 21 August 2026، كما يوجّه issue tracker الخاص به المستخدمين إلى الـfork. يستخدم InvoiceShelf ترخيص AGPL-3.0 نفسه ونموذج البيانات نفسه، لذلك يكون الانتقال بينهما عملية ترحيل لقاعدة البيانات، وليس إعادة كتابة. أي دليل ما زال يوصي بـCrater كُتب قبل أن يتوقف المشروع عن النشاط.
هل يمكنني استخدام Invoice Ninja لنشاطي التجاري من دون دفع رسوم؟
نعم. يعمل Invoice Ninja المستضاف ذاتياً بكامل وظائفه من دون تكلفة بموجب Elastic License 2.0، بما في ذلك الفواتير المتكررة، وبوابة العملاء، وبوابات الدفع. هناك أمران يتطلبان الدفع. إزالة العلامة التجارية لـInvoice Ninja من الصفحات التي يراها العملاء تتطلب white-label licence، وتبلغ "$40 per year" وفقاً لعبارات المشروع نفسه حتى August 2026. ويُحاسب إرسال الفواتير الإلكترونية عبر شبكة Peppol بشكل منفصل. ما يمنعه الترخيص هو تشغيل البرنامج كخدمة مستضافة لأشخاص آخرين.
لماذا تصل رسائل الفواتير التي أرسلها إلى مجلد البريد العشوائي؟
يحدث ذلك في معظم الحالات لأن الرسالة غير موثّقة للنطاق الموجود في عنوان From. أرسل الرسالة عبر SMTP relay بدلاً من إرسالها من VPS نفسه، ثم انشر سجلات SPF وDMARC لنطاقك، وأضف سجل DKIM باستخدام selector الذي يزوّدك به الـrelay. أبقِ عنوانك في From، وضع عنوان العميل في Reply-To. يؤدي تعيين عنوان العميل باعتباره المرسل إلى جعل Gmail يرفض الرسالة مع 550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policy. أكّد إصلاح المشكلة بالعثور على dkim=pass وspf=pass في ترويسة Authentication-Results لرسالة اختبار.
أي خيار أختار إذا كنت أحاسب بالساعة؟
Kimai. فهو أداة لتتبّع الوقت أولاً، لذلك تُنشأ الفاتورة من إدخالات timesheet المعتمدة، وتمثل بنود الفاتورة العمل الذي سجّلته. القوالب عبارة عن ملفات DOCX أو ODS أو XLSX تصمّمها في معالج نصوص، وهذا أسهل من تعديل CSS. المقابل هو أن Kimai لا يوفّر بوابة عملاء ولا بوابة دفع، لذلك ترسل ملف PDF بالبريد وتتلقى الدفع عبر تحويل مصرفي. يتتبّع Invoice Ninja الوقت أيضاً ويوفّر بوابة، لذا اختره بدلاً من ذلك إذا كان الدفع بالبطاقة عبر الإنترنت أهم لك من تفاصيل timesheet.
ما الذي أحتاج إلى نسخ احتياطي له تحديداً؟
قاعدة البيانات، وstorage volume الذي يحتوي على الشعارات وملفات PDF المُنشأة، وملف البيئة، وملفات PDF المُصدّرة المحفوظة كملفات عادية. ملف البيئة هو العنصر الذي ينساه الناس: تشفّر تطبيقات Laravel مثل Invoice Ninja وInvoiceShelf بيانات الاعتماد المحفوظة باستخدام APP_KEY، لذلك يؤدي استعادة قاعدة البيانات بجانب مفتاح مُنشأ حديثاً إلى جعل إعدادات بوابة الدفع غير قابلة للقراءة. استعد كل شيء في instance مؤقتة مرة واحدة، ثم افتح فاتورة قديمة، فهذه هي الطريقة الوحيدة لمعرفة أن النسخة الاحتياطية تعمل.