بهترین نرمافزار فاکتوردهی self-hosted برای کسب و کار
مقایسه تخصصی Invoice Ninja، InvoiceShelf، InvoicePlane، Kimai و ERPNext. بررسی چالشهای ارسال ایمیل، پشتیبانگیری و تفاوت مجوزهای نرمافزاری برای میزبانی روی VPS شخصی.
کدام نرمافزار فاکتوردهی self-hosted را انتخاب کنیم؟
نرمافزارهای فاکتوردهی self-hosted به پنج گزینه واقعبینانه روی یک VPS محدود میشوند که جایگزینهای کاملاً متفاوتی برای یکدیگر هستند. Invoice Ninja کاملترین محصول است: فاکتورهای دورهای، پورتال مشتری، درگاههای پرداخت و فرمتهای فاکتور الکترونیکی همگی از همان روز نصب کار میکنند. InvoiceShelf گزینه سبکتر و کاملاً متنباز است. InvoicePlane یک برنامه ساده PHP است که نیاز به هیچگونه ارکستراسیون ندارد. Kimai به جای اقلام فاکتور، ساعات کاری ثبتشده را صورتحساب میکند. ERPNext یک سیستم حسابداری کامل است که قابلیت صدور فاکتور را نیز دارد.
دو مشکل، راهاندازی فاکتوردهی self-hosted را بسیار بیشتر از نبود یک قابلیت خاص با شکست مواجه میکنند. اولی ایمیل است. فاکتوری که در پوشه اسپم قرار بگیرد، فاکتوری پرداختنشده است و هیچچیز به شما اطلاع نمیدهد که این اتفاق افتاده است. دومی پشتیبانگیری (backup) است. این تنها پایگاهداده self-hosted است که از دست رفتن آن به جای یک دردسر ساده، به یک مشکل مالیاتی تبدیل میشود.
پیش از مطالعه لیست قابلیتها، مجوز (licence) نرمافزار را بخوانید. از این پنج مورد، سه مورد copyleft، یکی permissive و یکی source-available است که محدودیتهای واقعی برای نحوه استفاده شما دارد.
پنج گزینه موجود و مخاطب هر یک
Invoice Ninja
یک برنامه Laravel که در حال حاضر در نسخه v5 قرار دارد. میزبانی شخصی (self-hosting) آن رایگان و بدون محدودیت است: فاکتورهای دورهای، پیشفاکتورها، پروژهها، ردیابی زمان، هزینهها، پورتال مشتری و درگاههای پرداخت شامل Stripe و PayPal. این پروژه خود را «یک برنامه متنباز (source-available) برای فاکتور، پیشفاکتور، پروژه و ردیابی زمان ساختهشده با Laravel» معرفی میکند. تنها بخش پولی آن مربوط به برندینگ است. به گفته خود پروژه: «ما یک لایسنس white-label با قیمت 40 دلار در سال ارائه میدهیم تا برند Invoice Ninja از بخشهای در معرض دید مشتری حذف شود». این قیمت تا اوت 2026 معتبر است.
اگر کاملترین محصول را میخواهید و با اجرای یک stack بزرگ مشکلی ندارید، این گزینه را انتخاب کنید.
InvoiceShelf
یک فورک از Crater که تحت مجوز GNU Affero General Public License نسخه 3 (AGPL-3.0) منتشر شده است. این برنامه شامل فاکتورها، برآوردها، صورتحسابهای دورهای، هزینهها، مالیات، چندارزی، پورتال مشتری و قابلیت چندشرکتی است. پرداختها و قابلیت white-label در مخازن ماژول رسمی جداگانهای قرار دارند که هر دو تحت مجوز AGPL-3.0 و رایگان هستند. پرداخت با کارت از طریق Stripe checkout انجام میشود.
اگر یک برنامه کوچک و کاملاً متنباز میخواهید و به سی درگاه پرداخت نیاز ندارید، این گزینه را انتخاب کنید.
InvoicePlane
یک برنامه PHP مبتنی بر CodeIgniter که تحت مجوز MIT منتشر شده است و تنها گزینه در این لیست است که با استخراج فایلها در web root نصب میشود. بدون Docker و بدون مرحله build با Node. فایلهای PDF توسط mPDF تولید میشوند، بنابراین قالبها HTML و CSS هستند. مشتریان یک لینک مهمان برای مشاهده و پرداخت فاکتور دریافت میکنند.
نکته اصلی در مورد پرداختها است. مستندات بهصراحت بیان میکنند که InvoicePlane 1.6 بهصورت پیشفرض فقط از Stripe پشتیبانی میکند و سایر ارائهدهندگان در این نسخه حذف شدهاند. نیازمندیهای منتشرشده برای سری 1.6 شامل PHP 8.0 تا 8.1 و MySQL 5.5 یا MariaDB معادل آن است. یادداشتهای مربوط به هر نسخهای که دانلود میکنید را بخوانید، زیرا سری 1.7 همچنان در حال توسعه است.
اگر از هاست اشتراکی یا یک VPS با 512 مگابایت رم استفاده میکنید، این گزینه را انتخاب کنید.
Kimai
یک ابزار ردیابی زمان تحت مجوز AGPL-3.0 که از روی تایمشیتها فاکتور تولید میکند. این گزینه برای هر کسی که بر اساس ساعت کار میکند، بهترین پاسخ است. قالبهای فاکتور بهصورت فایلهای DOCX، ODS یا XLSX آپلود میشوند که طبق مستندات، تنها فرمتهای پذیرفتهشده هستند و به PDF یا HTML تبدیل میشوند. شما فاکتور خود را در یک نرمافزار واژهپرداز طراحی میکنید و نیازی به نوشتن CSS ندارید، که برای اکثر افراد سادهتر است.
Kimai فاقد پورتال مشتری و درگاه پرداخت است، بنابراین باید فایل PDF را ایمیل کنید. فاکتور الکترونیکی ساختاریافته یک افزونه پولی در فروشگاه به نام E-Invoice Plus است که تا اوت 2026 برای نصب شخصی، 99 یورو (بدون احتساب مالیات بر ارزش افزوده) در سال قیمتگذاری شده است و پروفایلهای EN16931، XRechnung، ZUGFeRD، Factur-X و Peppol را پوشش میدهد.
اگر فاکتور خروجیِ زمانِ ردیابیشده است، این گزینه را انتخاب کنید.
ERPNext
تحت مجوز GPL-3.0 و در دستهبندی متفاوتی از نرمافزار قرار دارد. فاکتور فروش تنها یک نوع سند در یک سیستم حسابداری کامل با نمودار حسابها، ثبتهای دفتر روزنامه، موجودی کالا و حقوق و دستمزد است. زمانی که فاکتوردهی دیگر تمام کار شما نباشد، این گزینه پاسخ مناسبی است. برای یک فریلنسر با هشت مشتری، این نرمافزار بسیار سنگین است. راهاندازی آن پروژهای مستقل است که در اجرای ERPNext روی یک VPS به آن پرداخته شده است.
فاکتورهای دورهای به یک زمانبند (scheduler) وابسته هستند که دیده نمیشود
برنامههای Invoice Ninja، InvoiceShelf، InvoicePlane و ERPNext همگی قابلیت ایجاد فاکتورهای دورهای را دارند. Kimai در هستهٔ خود چنین قابلیتی ندارد، زیرا در آنجا فاکتور بر اساس ورودیهای timesheet برای یک بازهٔ زمانی ساخته میشود.
حالت شکست در تمام برنامههای مبتنی بر Laravel یکسان و بیسروصدا است. فاکتورهای دورهای توسط یک وظیفهٔ زمانبندیشده به نام php artisan schedule:run ایجاد میشوند که باید توسط چیزی خارج از برنامه، هر دقیقه فراخوانی شود. اگر هیچچیز آن را فراخوانی نکند، لیست فاکتورهای دورهای همچنان تاریخ ارسال بعدی را نشان میدهد و آن تاریخ بهسادگی میگذرد. هیچ فاکتوری ایجاد نمیشود. هیچ خطایی هم ثبت نمیشود، زیرا کدی اجرا نشده است.
بنابراین پس از ایجاد اولین فاکتور دورهای، تاریخ ارسال بعدی آن را چند دقیقه جلوتر تنظیم کنید و منتظر بمانید. اگر چیزی ارسال نشد، یعنی زمانبند در حال اجرا نیست. در نصب Docker، این معمولاً به این معنی است که سرویس cron یا scheduler در فایل compose هرگز شروع نشده یا از کار افتاده است.
docker compose ps
docker compose logs --tail 50تمام سرویسهای موجود در فایل باید وضعیت running را گزارش کنند. سرویسی که در وضعیت exited قرار دارد، همان سرویسی است که باید لاگهای آن را بررسی کنید.
چندارزی و مالیات: مواردی که باید پیش از نهاییکردن بررسی کنید
لیست ویژگیها عبارت «چندارزی» (multi-currency) را ذکر میکنند، اما معانی بسیار متفاوتی از آن برداشت میشود. این چهار مورد را روی یک نمونه آزمایشی (demo instance) و با استفاده از اعداد واقعی کسبوکار خود تست کنید؛ چرا که اشتباه در این بخش، بهجای شما، توسط حسابدارتان کشف خواهد شد.
- آیا فاکتور، نرخ ارزِ اعمالشده در تاریخ صدور را ذخیره میکند؟ این الزامی است. اگر برنامه، مجموع مبالغ را بر اساس نرخ لحظهای (live rate) دوباره محاسبه کند، گزارشهای فصل گذشته با هر بار باز کردن تغییر میکنند و دفاتر حسابداری شما دیگر با آنچه قبلاً ثبت کردهاید، مطابقت نخواهند داشت.
- آیا مالیات بر اساس هر ردیف (line item)، کل فاکتور یا هر دو اعمال میشود؟ نرخ واحد برای کل فاکتور تا زمانی که یکی از ردیفها معاف از مالیات (zero-rated) نباشد، مشکلی ایجاد نمیکند.
- آیا میتوانید قیمتها را هم بهصورت «شامل مالیات» و هم «بدون مالیات» وارد کنید؟ تبدیل قیمتها پس از ثبت، باعث ایجاد اختلاف گرد کردن (rounding differences) به اندازه یک سنت در هر ردیف میشود و این سنتها در طول یک سال انباشته خواهند شد.
- سند برای مشتری در کشور دیگری که مشمول VAT نیست، چه چیزی را نشان میدهد؟ شما به یادداشت معافیت (exemption note) چاپشده روی فاکتور نیاز دارید، نه فقط یک عدد صفر در ستون مالیات.
نرمافزارهای Invoice Ninja و ERPNext هر چهار مورد را پوشش میدهند. InvoiceShelf مالیات و چندارزی را در لیست ویژگیهای خود دارد. InvoicePlane و Kimai سادهتر هستند، بنابراین آنها را با پیچیدهترین فاکتور خود تست کنید، نه سادهترین آنها.
پورتال مشتری و درگاههای پرداخت
پورتال مشتری صفحهای است که در آن مشتری فاکتورهای خود را مشاهده میکند، فایل PDF را دانلود کرده و پرداخت را انجام میدهد. اهمیت این موضوع بیش از آن چیزی است که به نظر میرسد، زیرا پیگیری پرداخت از طریق ایمیل، زمان بیشتری نسبت به صدور خودِ فاکتور از شما میگیرد.
نرمافزار Invoice Ninja در این زمینه قدرتمندترین گزینه است؛ این ابزار دارای یک پورتال کامل، درگاههای پرداخت متعدد، قابلیت ذخیرهسازی روشهای پرداخت و صدور خودکار صورتحساب برای فاکتورهای دورهای است. InvoiceShelf دارای پورتال مشتری است و از طریق ماژول پرداخت خود، امکان استفاده از Stripe checkout را نیز فراهم میکند. InvoicePlane برای هر فاکتور یک لینک مهمان ارائه میدهد و از Stripe پشتیبانی میکند. Kimai هیچکدام از این قابلیتها را ندارد، بنابراین فایل PDF باید به صورت پیوست ارسال شود.
یک نکته همواره باعث سردرگمی میشود. میزبانی شخصی (self-hosting) برنامهٔ صدور فاکتور به معنای نگهداری شماره کارتهای بانکی نیست. با استفاده از Stripe checkout، مشتری به سایت Stripe هدایت میشود، اطلاعات کارت را در آنجا وارد میکند و VPS شما هرگز آن شماره را نمیبیند. محدودهٔ مسئولیت PCI (استاندارد امنیت دادههای صنعت کارت پرداخت) شما دقیقاً به این دلیل کوچک باقی میماند که شما فرم پرداخت را نساختهاید. اگر بعداً به بیش از یک پردازشگر نیاز داشتید یا خواستید پرداختها را بر اساس کشور هدایت کنید، این کار در لایهٔ مجزایی مانند ارکستراسیون پرداخت به صورت self-hosted با Hyperswitch قرار میگیرد.
کیفیت PDF و قالبی که در نهایت ویرایش خواهید کرد
شما باید این قالب را ویرایش کنید. تمام تنظیمات پیشفرض در اینجا، آدرس شما را در مکان نادرستی برای کشور شما قرار میدهند.
Invoice Ninja برای تبدیل قالبهای HTML و CSS به PDF از یک نسخه headless از Chromium استفاده میکند که درون image بستهبندی شده است؛ به همین دلیل حجم container زیاد است. برای آن حافظه کافی در نظر بگیرید: مرورگر headless سنگینترین پردازش در این stack است، بنابراین یک VPS با 1 GB رم برای آن بسیار محدود است. InvoicePlane از mPDF استفاده میکند که کاملاً مبتنی بر PHP و سبک است، اما به قیمت نادیده گرفتن برخی ویژگیهای مدرن CSS. رویکرد Kimai متفاوت است و از شما میخواهد یک فایل DOCX یا ODS آپلود کنید؛ بنابراین طراحی توسط کسی انجام میشود که از LibreOffice یا Word استفاده میکند و هرگز استایلشیت (stylesheet) ننوشته است.
اگر طراحی فاکتور برای شما اهمیت دارد و CSS اهمیتی ندارد، رویکرد Kimai برنده است. اگر میخواهید قالب در سیستم کنترل نسخه (version control) باشد و بتوان تغییرات آن را با diff مقایسه کرد، HTML گزینه بهتری است.
آیا مجوز اجازه استفاده تجاری را میدهد؟
هر پنج مورد به شما اجازه میدهند برای مشتریان خود فاکتور صادر کنید. تفاوتها زمانی آشکار میشوند که فراتر از این کار انجام دهید.
نرمافزار Invoice Ninja تحت مجوز Elastic License 2.0 ارائه میشود. دو بند در اینجا اهمیت دارند:
شما نمیتوانید این نرمافزار را به عنوان یک سرویس میزبانیشده یا مدیریتشده در اختیار اشخاص ثالث قرار دهید، به طوری که آن سرویس به کاربران امکان دسترسی به مجموعه قابلتوجهی از ویژگیها یا عملکردهای نرمافزار را بدهد.
شما نمیتوانید قابلیت کلید مجوز در نرمافزار را جابهجا، تغییر، غیرفعال یا دور بزنید.
بنابراین، اجرای آن برای کسبوکار شخصی خودتان بلامانع است، اما اجرای نمونههای آن برای مشتریان به عنوان یک محصول مجاز نیست. بند دوم دلیل این است که حذف برندینگ مستلزم پرداخت هزینه 40 دلاری برای مجوز است و نه اعمال یک پچ روی سورسکد.
نرمافزارهای InvoiceShelf، Kimai و Crater تحت مجوز AGPL-3.0 هستند. استفاده تجاری از آنها رایگان است و هیچ سطح کاربری بالاتری نسبت به شما وجود ندارد. تعهد اصلی در بخش 13 ذکر شده است: اگر کد را تغییر دهید و به دیگران اجازه دهید از نسخه تغییریافته شما از طریق شبکه استفاده کنند، باید سورسکد تغییرات خود را به آنها ارائه دهید. یک نمونه بدون تغییر، پیشتر توسط سورسکد عمومی ارائهدهنده اصلی پوشش داده شده است، بنابراین اکثر کسانی که خودشان میزبانی (self-host) میکنند، هرگز با این مورد مواجه نمیشوند.
نرمافزار InvoicePlane تحت مجوز MIT است که سبکترین تعهد را در این گروه دارد، اگرچه در فایل README آن ذکر شده که نام و لوگو متعلق به پروژه باقی میمانند.
نرمافزار ERPNext تحت مجوز GPL-3.0 است. تغییراتی که توزیع میکنید باید به اشتراک گذاشته شوند، اما اجرای خصوصی آن هیچ تعهدی ایجاد نمیکند.
این شرحی بر متن مجوزهاست و به منزله مشاوره حقوقی نیست.
آیا این پروژه همچنان پشتیبانی میشود؟ لاگ commitها را بررسی کنید
Crater برای چندین سال یک برنامه متنباز محبوب برای صدور فاکتور بود و هنوز راهنماهای بسیاری آن را توصیه میکنند. شاخه پیشفرض (default branch) این پروژه برای 741 روز هیچ commit جدیدی نداشته است.
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 پروژهای که در آن بلوک قرار دارند، پنج مورد در هفته گذشته commit داشتهاند. InvoiceShelf فورکی است که کار Crater را با همان لایسنس AGPL-3.0 و همان مدل داده ادامه داده است؛ بنابراین انتقال به آن، یک مهاجرت داده محسوب میشود و نه بازنویسی کامل. به جای Crater، برنامه InvoiceShelf را نصب کنید.
نصب هر یک روی یک 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آن کلید را به همراه APP_URL واقعی خود در فایل env در مخزن کپی کنید. سپس مالکیت (ownership) مورد انتظار ایمیج را تنظیم کرده و آن را اجرا کنید.
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پیش از اجرا، آن فایل را باز کنید. تمام رمزهای عبور در آن صرفاً جاینگهدار (placeholder) هستند و خود فایل نیز در توضیحاتش به این موضوع اشاره کرده است. مقادیر APP_URL، SESSION_DOMAIN و SANCTUM_STATEFUL_DOMAINS همگی بهصورت پیشفرض localhost هستند و هر سه باید پیش از اولین ورود، با نام میزبان (hostname) واقعی شما تنظیم شوند. سپس آن را بالا بیاورید.
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;"آرشیو را از صفحه releases پروژه دانلود کنید، آن را در ریشه وب (web root) خود استخراج کنید، ipconfig.php.example را به ipconfig.php کپی کنید و با دنبال کردن توضیحات موجود در آن فایل، URL خود را تنظیم کنید. سپس https://your-domain.example/index.php/setup را باز کرده و مراحل نصب را دنبال کنید.
چرا فاکتور شما به پوشه اسپم میرود
این همان شکستی است که باعث ضرر مالی شما میشود، در حالی که برنامه با خوشحالی گزارش میدهد که فاکتور ارسال شده است.
ایمیلهای فاکتور را از آدرس IP خودِ VPS ارسال نکنید. یک IP جدید در VPS هیچ سابقه ارسالی ندارد و سرویسدهندههای بزرگ، اولین پیام از یک آدرس ناشناس در محدوده IPهای میزبانی را بهطور پیشفرض مشکوک تلقی میکنند. ارسال را از طریق یک SMTP (پروتکل انتقال ساده نامه) relay روی دامنهای که احراز هویت کردهاید انجام دهید. انجام این کار بهصورت کامل، خود یک راهنمای جداگانه است و ارسال مطمئن ایمیل از یک برنامه self-hosted به مباحث relay، رکوردهای DNS و تست کردن آن میپردازد.
آدرس From جایی است که اکثر تنظیمات صدور فاکتور در آن دچار مشکل میشوند. این آدرس باید روی دامنهای باشد که شما کنترل میکنید و relay شما آن را با 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 (چارچوب سیاست فرستنده) را برگرداند که relay شما را نام میبرد. دستور دوم باید یک سیاست DMARC (احراز هویت، گزارشدهی و انطباق پیام مبتنی بر دامنه) را برگرداند. دستور سوم به selectorای که relay به شما داده بستگی دارد؛ پاسخ خالی به این معناست که رکورد DKIM وجود ندارد یا با نام اشتباه منتشر شده است، بنابراین هر پیامی که ارسال میکنید در بررسی امضا شکست خواهد خورد.
سپس یک فاکتور واقعی به حسابی که در یک سرویسدهنده بزرگ دارید ارسال کنید و هدرهای خام (raw headers) را بخوانید. مقادیر dkim=pass و spf=pass در هدر Authentication-Results تنها مدرک معتبری است که اهمیت دارد. پرچم "sent" در خودِ برنامه فقط به این معناست که پیام به relay تحویل داده شده است.
پشتیبانگیری: تنها پایگاهدادهای که نباید از دست بدهید
از دست دادن یک سرور رسانهای به معنای دانلود مجدد فایلهاست. اما از دست دادن پایگاهداده صورتحسابها به این معناست که نمیتوانید نشان دهید چه چیزی را صورتحساب کردهاید، چه مبلغی دریافت کردهاید یا چه بدهیهایی باقی مانده است. با این موضوع متناسب با اهمیت آن برخورد کنید.
از چهار مورد پشتیبان تهیه کنید: پایگاهداده، volume ذخیرهسازی که شامل لوگوها، PDFهای تولیدشده و رسیدهای هزینه است، فایل environment برنامه، و در نهایت PDFهای نهایی که به عنوان فایلهای معمولی ذخیره شدهاند؛ چرا که یک فایل PDF حتی پس از 10 سال بدون برنامهای که آن را تولید کرده است، باز میشود.
اهمیت فایل environment بیش از آن چیزی است که تصور میشود. Laravel مقادیر حساس ذخیرهشده، از جمله اعتبارنامههای درگاه پرداخت را با استفاده از APP_KEY موجود در آن فایل رمزنگاری میکند. اگر پایگاهداده را در کنار یک کلید تازه تولیدشده بازیابی کنید، آن مقادیر رمزگشایی نخواهند شد. در این حالت، صورتحسابهای شما موجود هستند اما تنظیمات درگاه پرداخت غیرقابل خواندن خواهند بود.
یک خروجی (dump) از stack برنامه InvoiceShelf به این شکل است. سرویس پایگاهداده آن از mariadb:10 استفاده میکند، بنابراین ابزار موجود در داخل container برابر با mariadb-dump است.
docker compose exec -T database mariadb-dump \
--user=root --password=YOUR_ROOT_PASSWORD \
--single-transaction --databases invoiceshelf > invoiceshelf.sql--single-transaction یک snapshot منسجم از جداول InnoDB بدون قفل کردن آنها تهیه میکند، بنابراین برنامه در حین اجرای dump همچنان به سرویسدهی ادامه میدهد. -T از تخصیص ترمینال توسط Docker جلوگیری میکند؛ در غیر این صورت، خروجی تغییر مسیر داده شده (redirected) خراب شده و فایل dump حاصل غیرقابل import خواهد بود.
این فایل را طبق یک زمانبندی مشخص با استفاده از پشتیبانهای رمزنگاریشده restic در فضای ذخیرهسازی خارج از سایت از سرور خارج کنید و دوره نگهداری (retention) را به اندازهای طولانی تنظیم کنید که بازه زمانی مورد نظر حسابدارتان را پوشش دهد.
سپس آن را بازیابی کنید. dump را در یک container موقت بالا بیاورید، وارد شوید و صورتحساب ماه گذشته را باز کنید. تا زمانی که این کار را یک بار انجام ندادهاید، نمیدانید که آیا پشتیبانگیری واقعاً کار میکند یا خیر.
آنچه حسابدار شما درخواست خواهد کرد
از یک راهنما، مشاوره مالیاتی نگیرید. آنچه در ادامه میآید، قابلیتهای این نرمافزار است تا بتوانید این فهرست را به مشاور خود ارائه دهید.
دادههای قابل استخراج. شما باید بتوانید فاکتورها و پرداختهای خود را از طریق رابط کاربری به فرمت CSV استخراج کنید، بدون اینکه به کلاینت دیتابیس نیاز داشته باشید یا تیکت پشتیبانی باز کنید. یک SQL dump صرفاً یک نسخه پشتیبان است، نه یک خروجی قابل استفاده، زیرا حسابدار شما نمیتواند آن را باز کند.
شمارهگذاری غیرقابل تغییر. شماره فاکتورها باید به ترتیب باشند، هرگز دوباره استفاده نشوند و هیچ شکافی در آنها وجود نداشته باشد. حذف یک فاکتور باعث ایجاد شکافی میشود که بعداً باید برای آن توضیح ارائه دهید. بهجای حذف، از قابلیت لغو (Cancel) یا اعتبار (Credit) استفاده کنید که تمامی برنامههای معرفیشده در اینجا از آن پشتیبانی میکنند. اینکه آیا شمارهگذاری بدون شکاف برای شما الزامی است یا خیر، به محل ثبت کسبوکار شما بستگی دارد و بهتر است از همان ابتدا در این مورد پرسوجو کنید.
نگهداری. نسخههای پشتیبان دیتابیس و فایلهای PDF تولیدشده را تا زمانی که قوانین شما ایجاب میکند، نگهداری کنید. فایل PDF همان سندی است که در واقعیت ارسال شده است و در صورت بروز اختلاف بر سر یک فاکتور، این همان مدرکی است که اهمیت دارد.
تاریخچه تغییرات. امکان مشاهده اینکه چه کسی و در چه زمانی یک فاکتور را ویرایش کرده است، بسیار ارزشمند است و این قابلیت در میان این برنامهها تفاوت زیادی دارد. Invoice Ninja برای هر رکورد، یک لاگ فعالیت جداگانه نگهداری میکند.
صدور فاکتور الکترونیک ساختاریافته (Structured e-invoicing) در بخشهایی از اتحادیه اروپا به یک الزام واقعی تبدیل شده است، نه فقط یک قابلیت جانبی. Invoice Ninja فرمتهای رایج از جمله ZUGFeRD، XRechnung، Facturae، FatturaPA و فرمت عمومی EN16931 را تولید میکند. ارسال از طریق شبکه Peppol در یک نمونه self-hosted از طریق نقطه دسترسی اختصاصی Invoice Ninja انجام میشود: شما باید نهاد خود را نزد آنها ثبت کنید و برای هر ارسال اعتبار بخرید؛ بنابراین تا آگوست 2026، این یک سرویس پولی محسوب میشود. Kimai از طریق افزونه پولی خود به همین فرمتها دسترسی پیدا میکند. سه برنامه دیگر در حال حاضر هیچگونه فاکتور الکترونیک ساختاریافتهای تولید نمیکنند، که این مهمترین دلیل برای انتخاب Invoice Ninja در صورت صدور فاکتور در اتحادیه اروپا است.
FAQ
آیا باید Crater را نصب کنم یا InvoiceShelf را؟
InvoiceShelf را انتخاب کنید. شاخه پیشفرض Crater تا تاریخ 21 August 2026 به مدت 741 روز هیچ commit جدیدی نداشته است و سیستم ردیابی مشکلات (issue tracker) خود پروژه، کاربران را به سمت fork آن هدایت میکند. InvoiceShelf از همان مجوز AGPL-3.0 و همان مدل داده استفاده میکند، بنابراین انتقال بین این دو، یک مهاجرت دیتابیس ساده است و نه بازنویسی کامل. هر راهنمایی که همچنان Crater را توصیه میکند، پیش از توقف فعالیت این پروژه نوشته شده است.
آیا میتوانم از Invoice Ninja برای کسبوکار خودم بدون پرداخت هزینه استفاده کنم؟
بله. نسخه self-hosted نرمافزار Invoice Ninja تحت مجوز Elastic License 2.0 کاملاً کاربردی و رایگان است؛ این شامل فاکتورهای دورهای، پورتال مشتری و درگاههای پرداخت میشود. دو مورد هزینه دارند: حذف برند Invoice Ninja از صفحات مشتری نیازمند مجوز white-label است که طبق اعلام خود پروژه در آگوست 2026، هزینه آن "$40 per year" است. ارسال فاکتورهای الکترونیک از طریق شبکه Peppol نیز بهصورت جداگانه محاسبه میشود. آنچه این مجوز منع میکند، اجرای نرمافزار بهعنوان یک سرویس میزبانیشده (SaaS) برای دیگران است.
چرا ایمیلهای فاکتور من به پوشه اسپم میروند؟
تقریباً همیشه به این دلیل است که پیام برای دامنه موجود در آدرس From احراز هویت نشده است. بهجای ارسال مستقیم از طریق VPS، از یک SMTP relay استفاده کنید؛ سپس رکوردهای 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 است، آن را انتخاب کنید.
دقیقاً از چه چیزهایی باید نسخه پشتیبان تهیه کنم؟
دیتابیس، volume ذخیرهسازی که لوگوها و PDFهای تولیدشده را نگه میدارد، فایل environment و PDFهای نهایی که بهعنوان فایلهای ساده ذخیره شدهاند. فایل environment همان فایلی است که معمولاً فراموش میشود: برنامههای Laravel مانند Invoice Ninja و InvoiceShelf، اعتبارنامههای ذخیرهشده را با APP_KEY رمزنگاری میکنند؛ بنابراین اگر دیتابیس را در کنار یک کلید جدید بازیابی کنید، تنظیمات درگاه پرداخت شما غیرقابل خواندن خواهد بود. کل مجموعه را یکبار در یک نمونه آزمایشی (throwaway instance) بازیابی کنید و یک فاکتور قدیمی را باز کنید؛ چرا که این تنها راه اطمینان از صحت نسخه پشتیبان است.