SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-22

So sánh phần mềm xuất hóa đơn self-hosted

So sánh Invoice Ninja, InvoiceShelf, InvoicePlane, Kimai và ERPNext trên một VPS về hóa đơn định kỳ, thuế, cổng khách hàng, payment gateway và licence.

Nên chọn phần mềm xuất hóa đơn self-hosted nào?

Phần mềm xuất hóa đơn self-hosted trên một VPS thường chỉ còn 5 lựa chọn thực tế, và chúng không thay thế tương đương cho nhau. Invoice Ninja là sản phẩm hoàn thiện nhất: hóa đơn định kỳ, cổng khách hàng, payment gateway và các định dạng hóa đơn điện tử đều hoạt động ngay sau khi cài đặt. InvoiceShelf là lựa chọn nhẹ hơn và hoàn toàn open source. InvoicePlane là một ứng dụng PHP đơn giản, không cần điều phối nhiều thành phần. Kimai tính tiền theo số giờ đã theo dõi thay vì theo từng dòng hàng hóa. ERPNext là một hệ thống kế toán đầy đủ, đồng thời có thể in hóa đơn.

Hai vấn đề thường làm hỏng hệ thống xuất hóa đơn self-hosted hơn nhiều so với việc thiếu một tính năng. Vấn đề đầu tiên là email. Một hóa đơn nằm trong thư mục spam đồng nghĩa với một hóa đơn chưa được thanh toán, và không có gì báo cho bạn biết điều đó đã xảy ra. Vấn đề thứ hai là backup. Đây là database self-hosted duy nhất mà nếu mất dữ liệu, hậu quả trở thành vấn đề thuế chứ không chỉ là bất tiện.

Hãy đọc licence trước khi xem danh sách tính năng. Trong 5 lựa chọn này, 3 phần mềm dùng copyleft, 1 phần mềm dùng licence permissive, còn 1 phần mềm cho phép xem source nhưng đặt ra các giới hạn thực tế về cách bạn được phép sử dụng nó.

Năm lựa chọn và lựa chọn nào phù hợp với ai

Invoice Ninja

Một ứng dụng Laravel, hiện thuộc dòng v5. Tự host được miễn phí và không bị khóa tính năng: hóa đơn định kỳ, báo giá, dự án, theo dõi thời gian, chi phí, client portal và các payment gateway như Stripe và PayPal. Dự án tự mô tả là “ứng dụng lập hóa đơn, báo giá, quản lý dự án và theo dõi thời gian được xây dựng bằng Laravel, cung cấp mã nguồn”. Phần duy nhất phải trả phí là branding. Theo chính dự án: “Chúng tôi cung cấp license white-label với giá $40 mỗi năm để gỡ branding Invoice Ninja khỏi các phần hiển thị cho client”. Mức giá này được áp dụng tại thời điểm tháng 8 năm 2026.

Chọn ứng dụng này nếu bạn muốn sản phẩm đầy đủ tính năng nhất và chấp nhận chạy stack lớn nhất.

InvoiceShelf

Một fork của Crater, phát hành theo GNU Affero General Public License version 3 (AGPL-3.0). Ứng dụng hỗ trợ hóa đơn, báo giá, billing định kỳ, chi phí, thuế, nhiều currency, customer portal và nhiều công ty. Tính năng thanh toán và white-label được cung cấp trong các repository module chính thức riêng biệt. Cả hai đều dùng AGPL-3.0 và đều miễn phí. Thanh toán bằng thẻ chạy qua Stripe checkout.

Chọn ứng dụng này nếu bạn muốn một ứng dụng nhỏ, hoàn toàn open source và không cần ba mươi gateway.

InvoicePlane

Một ứng dụng PHP chạy trên CodeIgniter, phát hành theo MIT licence. Đây là lựa chọn duy nhất trong danh sách có thể cài bằng cách giải nén file vào web root. Không cần Docker và không có bước build bằng Node. PDF được tạo bằng mPDF, nên template dùng HTML và CSS. Client nhận một guest link để xem và thanh toán hóa đơn.

Điểm hạn chế là thanh toán. Tài liệu nêu rõ InvoicePlane 1.6 mặc định chỉ hỗ trợ Stripe, còn các provider khác đã bị gỡ trong phiên bản này. Requirements được công bố cho dòng 1.6 là PHP 8.0 đến 8.1 cùng MySQL 5.5 hoặc phiên bản MariaDB tương ứng. Hãy đọc ghi chú của release bạn tải xuống, vì dòng 1.7 vẫn đang được phát triển.

Chọn ứng dụng này nếu bạn dùng shared hosting hoặc VPS 512 MB.

Kimai

Một time tracker dùng AGPL-3.0, có thể tạo hóa đơn từ timesheet. Đây là lựa chọn phù hợp cho người tính phí theo giờ. Template hóa đơn được upload dưới dạng file DOCX, ODS hoặc XLSX. Tài liệu xác nhận đây là các format duy nhất được chấp nhận. Sau đó template được render thành PDF hoặc HTML. Bạn bố cục hóa đơn trong word processor thay vì viết CSS, cách này thường dễ hơn.

Kimai không có client portal và payment gateway, nên bạn phải gửi PDF qua email. Tính năng e-invoicing có cấu trúc là một store plugin trả phí tên E-Invoice Plus. Tại thời điểm tháng 8 năm 2026, plugin này có giá 99 EUR mỗi năm, chưa bao gồm VAT, cho một cài đặt self-hosted. Plugin hỗ trợ các profile EN16931, XRechnung, ZUGFeRD, Factur-X và Peppol.

Chọn ứng dụng này nếu hóa đơn là đầu ra của việc theo dõi thời gian.

ERPNext

GPL-3.0 và thuộc một nhóm phần mềm khác. Hóa đơn bán hàng chỉ là một loại document trong hệ thống kế toán đầy đủ, có chart of accounts, journal entries, stock và payroll. Đây là lựa chọn phù hợp khi việc lập hóa đơn không còn là toàn bộ công việc. Với một freelancer có tám client, đây là quá nhiều phần mềm. Việc triển khai ERPNext cũng là một dự án riêng, được trình bày trong chạy ERPNext trên VPS.

Hóa đơn định kỳ phụ thuộc vào một scheduler mà bạn không nhìn thấy

Invoice Ninja, InvoiceShelf, InvoicePlane và ERPNext đều có thể tạo hóa đơn định kỳ. Kimai không có tính năng hóa đơn định kỳ trong core, vì hóa đơn trong Kimai được tạo từ các bản ghi timesheet trong một khoảng thời gian.

Cách lỗi xảy ra giống nhau ở mọi ứng dụng dựa trên Laravel và thường không có dấu hiệu rõ ràng. Một scheduled task, php artisan schedule:run, tạo hóa đơn định kỳ. Một thành phần bên ngoài ứng dụng phải gọi task này mỗi phút. Nếu không có thành phần nào gọi, danh sách hóa đơn định kỳ vẫn hiển thị ngày gửi tiếp theo, rồi ngày đó cứ trôi qua. Không có hóa đơn nào được tạo. Không có lỗi nào được ghi vào log vì không có code nào chạy.

Sau khi tạo hóa đơn định kỳ đầu tiên, hãy đặt ngày gửi tiếp theo cách thời điểm hiện tại vài phút rồi chờ. Nếu không có hóa đơn nào xuất hiện, scheduler chưa chạy. Trong một Docker install, nguyên nhân thường là cron hoặc scheduler service trong file compose chưa khởi động hoặc đã thoát.

docker compose ps
docker compose logs --tail 50

Mọi service trong file phải báo trạng thái running. Service ở trạng thái exited là service bạn cần đọc log.

Đa tiền tệ và thuế: cần kiểm tra gì trước khi cam kết

Danh sách tính năng ghi “đa tiền tệ” nhưng ý nghĩa thực tế có thể rất khác nhau. Hãy thực hiện 4 kiểm tra sau trên một instance demo, sử dụng số liệu thực từ doanh nghiệp của bạn. Sai sót ở đây thường do kế toán phát hiện, không phải bạn.

  1. Hóa đơn có lưu tỷ giá áp dụng vào ngày phát hành không? Bắt buộc phải có. Nếu ứng dụng tính lại tổng tiền theo tỷ giá hiện tại, báo cáo của quý trước sẽ thay đổi mỗi lần bạn mở, và sổ sách sẽ không còn khớp với số liệu bạn đã nộp.
  2. Thuế được áp dụng theo từng dòng hàng, theo hóa đơn hay cả hai? Một mức thuế duy nhất ở cấp hóa đơn chỉ phù hợp cho đến khi một dòng hàng được áp dụng thuế suất 0%.
  3. Bạn có thể nhập giá đã gồm thuế và giá chưa gồm thuế không? Việc chuyển đổi sau đó có thể tạo chênh lệch làm tròn một cent trên mỗi dòng, và các khoản chênh lệch này sẽ cộng dồn trong cả năm.
  4. Tài liệu hiển thị gì khi khách hàng ở một quốc gia khác không phải trả VAT? Trên hóa đơn phải in lý do miễn thuế, không chỉ hiển thị số 0 trong cột thuế.

Invoice Ninja và ERPNext đáp ứng cả 4 yêu cầu. InvoiceShelf liệt kê thuế và đa tiền tệ trong các tính năng. InvoicePlane và Kimai đơn giản hơn, vì vậy hãy kiểm thử chúng với hóa đơn phức tạp nhất của bạn thay vì hóa đơn dễ xử lý nhất.

Cổng khách hàng và payment gateway

Cổng khách hàng là nơi khách hàng xem hóa đơn, tải PDF và thanh toán. Phần này quan trọng hơn nhiều người nghĩ, vì việc đốc thúc thanh toán qua email tốn nhiều thời gian hơn cả việc tạo hóa đơn.

Invoice Ninja mạnh nhất ở phần này, với portal đầy đủ, nhiều gateway, phương thức thanh toán được lưu và tự động lập hóa đơn cho các hóa đơn định kỳ. InvoiceShelf có customer portal và thêm chức năng thanh toán Stripe thông qua module payments. InvoicePlane tạo guest link cho từng hóa đơn và hỗ trợ Stripe. Kimai không có cả hai tính năng này, nên PDF phải được gửi dưới dạng file đính kèm.

Có một điểm thường xuyên bị nhầm lẫn. Tự host ứng dụng lập hóa đơn không có nghĩa là bạn lưu số thẻ. Với Stripe checkout, khách hàng được chuyển hướng đến Stripe, nhập thông tin thẻ tại đó, và VPS của bạn không bao giờ thấy số thẻ. Phạm vi PCI (payment card industry) của bạn vẫn nhỏ chính vì bạn không tự xây dựng form thanh toán. Nếu sau này bạn cần nhiều hơn một processor hoặc muốn định tuyến thanh toán theo quốc gia, phần đó nên được xử lý ở một layer riêng, chẳng hạn điều phối thanh toán tự host với Hyperswitch.

Chất lượng PDF và template bạn sẽ chỉnh sửa

Bạn sẽ chỉnh sửa template. Mọi giá trị mặc định ở đây đều đặt địa chỉ của bạn sai vị trí đối với quốc gia của bạn.

Invoice Ninja render template HTML và CSS thành PDF bằng headless Chromium được tích hợp trong image, nên container khá lớn. Hãy dành đủ memory cho thành phần này: headless browser là process nặng nhất trong stack, vì vậy VPS 1 GB sẽ khá sát giới hạn. InvoicePlane dùng mPDF, vốn là PHP thuần và nhẹ, nhưng đổi lại sẽ bỏ qua một số CSS hiện đại. Kimai đi theo hướng ngược lại và yêu cầu bạn upload file DOCX hoặc ODS, nên layout được thực hiện trong LibreOffice hoặc Word bởi người chưa từng viết stylesheet.

Nếu một invoice có thiết kế đẹp là điều quan trọng với bạn còn CSS thì không, cách làm của Kimai phù hợp hơn. Nếu bạn muốn template nằm trong version control và có thể diff, HTML phù hợp hơn.

Giấy phép có cho phép bạn sử dụng phần mềm cho mục đích thương mại không?

Cả 5 phần mềm đều cho phép bạn lập hóa đơn cho khách hàng của mình. Khác biệt xuất hiện khi bạn làm thêm những việc khác.

Invoice Ninja sử dụng Elastic License 2.0. Có 2 điều khoản cần lưu ý.

Bạn không được cung cấp phần mềm cho bên thứ ba dưới dạng dịch vụ được host hoặc quản lý, trong đó dịch vụ cho phép người dùng truy cập vào một tập hợp đáng kể các tính năng hoặc chức năng của phần mềm.
Bạn không được di chuyển, thay đổi, vô hiệu hóa hoặc vượt qua cơ chế license key trong phần mềm.

Vì vậy, chạy phần mềm cho doanh nghiệp của bạn là được phép, nhưng chạy các instance cho khách hàng dưới dạng một sản phẩm thì không. Điều khoản thứ 2 là lý do việc gỡ branding có giá $40 cho license, thay vì chỉ là một patch cho source code.

InvoiceShelf, Kimai và Crater sử dụng AGPL-3.0. Bạn được phép sử dụng cho mục đích thương mại mà không phải trả phí, và không có cấp license cao hơn áp dụng cho bạn. Nghĩa vụ nằm ở section 13: nếu bạn sửa code rồi cho người khác sử dụng phiên bản đã sửa qua network, bạn phải cung cấp source code của các thay đổi đó. Một instance không bị sửa đã được source code công khai của upstream bao phủ, nên hầu hết self-hosting user không bao giờ phải xử lý việc này.

InvoicePlane sử dụng MIT, là license có ít nghĩa vụ nhất trong nhóm. Tuy nhiên, README của dự án lưu ý rằng tên và logo vẫn thuộc về project.

ERPNext sử dụng GPL-3.0. Các bản sửa đổi mà bạn phân phối phải được chia sẻ, còn việc chạy riêng tư không tạo ra nghĩa vụ nào.

Đây là phần mô tả nội dung license, không phải tư vấn pháp lý.

Dự án còn được duy trì không? Kiểm tra commit log

Crater từng là ứng dụng lập hóa đơn open source phổ biến trong nhiều năm, và nhiều hướng dẫn vẫn khuyến nghị dùng nó. Nhánh mặc định của dự án đã không có commit nào trong 741 ngày.

ChartGap since the last commit on the default branch, in days, checked 21 August 2026
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
  }
]

Trong 6 dự án ở khối đó, có 5 dự án có commit trong tuần qua. InvoiceShelf là fork tiếp tục phát triển từ Crater, dùng cùng giấy phép AGPL-3.0 và cùng data model, nên chuyển sang đây là một quy trình data migration thay vì phải viết lại. Hãy cài InvoiceShelf, không cài Crater.

Cài đặt từng ứng dụng trên VPS

Mọi ứng dụng ngoại trừ InvoicePlane đều dễ chạy nhất bằng Docker Compose. Nếu bạn chưa quen với Docker Compose, hãy bắt đầu bằng stack Docker Compose đầu tiên trên VPS rồi quay lại đây.

Invoice Ninja cung cấp repository compose riêng.

git clone https://github.com/invoiceninja/dockerfiles.git
cd dockerfiles
docker run --rm -it invoiceninja/invoiceninja php artisan key:generate --show

Chép key đó vào file env trong repository, cùng với APP_URL thực của bạn. Sau đó đặt ownership theo yêu cầu của image rồi khởi động ứng dụng.

chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/app
docker compose up -d

Ownership 1500:1500 khớp với user bên trong image. Nếu bỏ qua bước này, ứng dụng không thể ghi cache hoặc các file PDF được tạo. Trong setup wizard, nhập db làm database host vì đó là service name trên compose network. localhost ở đó trỏ đến chính application container.

InvoiceShelf cung cấp các file compose sẵn dùng, mỗi file dành cho một database engine.

curl -fLO https://raw.githubusercontent.com/InvoiceShelf/docker/master/docker-compose.mysql.yml
mv docker-compose.mysql.yml docker-compose.yml

Mở file đó trước khi khởi động. Mọi password trong file đều là placeholder và các comment trong file cũng ghi rõ điều này. APP_URL, SESSION_DOMAINSANCTUM_STATEFUL_DOMAINS đều mặc định là localhost. Bạn phải đặt hostname thực cho cả ba trước lần đăng nhập đầu tiên. Sau đó khởi động stack.

docker compose up -d

Ứng dụng publish port 8090 trên host và serve port 8080 bên trong container. Hãy đặt reverse proxy có TLS (bảo mật tầng truyền tải) phía trước ứng dụng trước khi cho bất kỳ client nào kết nối.

File compose production của Kimai theo tài liệu của project
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:

Đặt APP_SECRET thành một chuỗi ngẫu nhiên dài do bạn tự tạo và đặt TRUSTED_HOSTS thành domain bạn sẽ thực sự sử dụng. ADMINMAILADMINPASS tạo administrator đầu tiên trong lần boot đầu tiên. Sau đó đổi password này trong giao diện và xóa các giá trị đó khỏi file.

InvoicePlane không có container. Trước tiên hãy tạo một database trống.

sudo mysql -e "CREATE DATABASE invoiceplane CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

Tải archive từ trang releases của project, giải nén vào web root, copy ipconfig.php.example thành ipconfig.php, rồi đặt URL bên trong file đó theo các comment trong file. Sau đó mở https://your-domain.example/index.php/setup và thực hiện lần lượt các bước trong installer.

Vì sao hóa đơn của bạn rơi vào thư mục spam

Đây là lỗi khiến bạn mất tiền, trong khi ứng dụng vẫn báo hóa đơn đã được gửi.

Không gửi email hóa đơn từ chính địa chỉ IP của VPS. IP mới của VPS chưa có lịch sử gửi mail, và các hệ thống nhận mail lớn mặc định xem message đầu tiên từ một địa chỉ chưa xác định trong dải IP hosting là đáng ngờ. Hãy gửi qua một relay SMTP (simple mail transfer protocol) trên domain mà bạn đã xác thực. Quy trình này cần một hướng dẫn riêng, còn gửi mail ổn định từ ứng dụng tự host trình bày về relay, các bản ghi DNS và cách kiểm thử.

Địa chỉ From là nơi phần lớn cấu hình gửi hóa đơn gặp lỗi. Địa chỉ này phải thuộc một domain bạn kiểm soát và phải là domain mà relay của bạn ký bằng DKIM (domainkeys identified mail). Đặt địa chỉ của khách hàng vào From có vẻ lịch sự nhưng sẽ làm hỏng khả năng gửi mail, vì server nhận mail kiểm tra domain trong From có khớp với domain đã xác thực message hay không. Gmail từ chối ngay khi phát hiện không khớp:

550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policy

Giữ địa chỉ của bạn trong From và đặt địa chỉ khách hàng vào Reply-To. Kiểm tra các bản ghi đã công bố trước khi gửi mail thật.

dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com

Lệnh đầu tiên phải trả về một bản ghi SPF (sender policy framework) có tên relay của bạn. Lệnh thứ hai phải trả về một policy DMARC (domain-based message authentication, reporting and conformance). Lệnh thứ ba phụ thuộc vào selector mà relay cung cấp. Kết quả trống có nghĩa là bản ghi DKIM bị thiếu hoặc được công bố dưới tên sai. Khi đó mọi message bạn gửi đều sẽ không vượt qua bước kiểm tra chữ ký.

Tiếp theo, gửi một hóa đơn thật đến tài khoản của bạn tại một nhà cung cấp lớn và đọc raw headers. dkim=passspf=pass trong header Authentication-Results là bằng chứng duy nhất có giá trị. Cờ "sent" của ứng dụng chỉ có nghĩa là ứng dụng đã chuyển message cho relay.

Backup: cơ sở dữ liệu duy nhất bạn không thể để mất

Mất một media server chỉ có nghĩa là phải tải lại các file. Ngay cả photo server tự host như PhotoPrism hoặc Immich thường cũng đang giữ bản sao thứ hai của các file gốc vẫn còn trên điện thoại đã chụp chúng. Mất database lập hóa đơn nghĩa là bạn không thể chứng minh đã lập hóa đơn những gì, đã được thanh toán bao nhiêu, hoặc còn phải thu bao nhiêu. Hãy xử lý việc này tương ứng.

Hãy backup 4 thứ. Database. Storage volume chứa logo, PDF đã tạo và biên lai chi phí. File môi trường của ứng dụng. Và các PDF đã render được lưu dưới dạng file thông thường, vì một file PDF vẫn mở được sau 10 năm ngay cả khi không còn ứng dụng đã tạo ra nó.

File môi trường quan trọng hơn nhiều người nghĩ. Laravel mã hóa các giá trị nhạy cảm được lưu trữ, bao gồm credential của payment gateway, bằng APP_KEY trong file đó. Nếu restore database cùng một key vừa tạo mới thì các giá trị đó sẽ không giải mã được. Tất cả invoice vẫn còn, nhưng các thiết lập gateway không thể đọc được.

Dump từ stack InvoiceShelf có dạng như sau. Database service của nó chạy mariadb:10, nên tool bên trong container là mariadb-dump.

docker compose exec -T database mariadb-dump \
  --user=root --password=YOUR_ROOT_PASSWORD \
  --single-transaction --databases invoiceshelf > invoiceshelf.sql

--single-transaction tạo snapshot nhất quán của các bảng InnoDB mà không lock chúng, nên ứng dụng vẫn tiếp tục phục vụ request trong khi dump chạy. -T ngăn Docker cấp một terminal, vì terminal đó có thể làm hỏng output được redirect và tạo ra file dump không thể import.

Hãy gửi bản backup ra khỏi server theo lịch bằng restic backup được mã hóa đến storage ngoài site, và đặt thời gian retention đủ dài để bao phủ khoảng thời gian mà kế toán của bạn yêu cầu.

Sau đó hãy restore nó. Khởi chạy dump trong một container tạm thời, đăng nhập và mở invoice của tháng trước. Nếu chưa làm việc này ít nhất một lần, bạn chưa biết backup có hoạt động hay không.

Những gì kế toán sẽ yêu cầu

Không nên lấy tư vấn thuế từ một tutorial. Nội dung dưới đây là những gì phần mềm này có thể tạo ra, để bạn có thể đưa danh sách này cho người tư vấn thuế hoặc kế toán của mình.

Dữ liệu có thể export. Bạn phải có thể export invoice và khoản thanh toán sang CSV từ giao diện, không cần database client và không cần mở ticket hỗ trợ. SQL dump là bản backup, không phải bản export, vì kế toán không thể mở trực tiếp tệp đó.

Đánh số bất biến. Số invoice nên chạy tuần tự và không bao giờ được dùng lại, không có khoảng trống. Xóa một invoice sẽ tạo ra một khoảng trống và bạn phải giải trình khoảng trống đó. Thay vào đó, hãy hủy hoặc lập credit note; mọi ứng dụng trong bài này đều hỗ trợ cách này. Việc bạn có bắt buộc phải đánh số không có khoảng trống hay không tùy nơi bạn đăng ký, nên hỏi sớm.

Lưu giữ. Giữ database dump và các PDF đã render trong khoảng thời gian mà quy định yêu cầu. PDF là tài liệu thực tế đã được gửi, và đó là artifact quan trọng nếu invoice bị tranh chấp.

Lịch sử thay đổi. Có thể cho biết ai đã sửa invoice và sửa vào thời điểm nào là một tính năng đáng có. Mức hỗ trợ khác nhau nhiều nhất giữa các ứng dụng này. Invoice Ninja lưu activity log theo từng record.

E-invoice có cấu trúc đã trở thành yêu cầu thực tế thay vì tính năng bổ sung ở một số khu vực của EU. Invoice Ninja tạo được các format phổ biến, gồm ZUGFeRD và XRechnung, Facturae, FatturaPA và EN16931 tổng quát. Việc gửi qua network Peppol từ instance tự host sử dụng access point riêng của Invoice Ninja: bạn đăng ký entity của mình với họ và mua credit cho từng lần gửi, nên đây là dịch vụ có tính phí tính đến tháng 8 năm 2026. Kimai hỗ trợ các format tương tự thông qua paid plugin. Ba ứng dụng còn lại hiện không tạo được e-invoice có cấu trúc, và đây là lý do thuyết phục nhất để chọn Invoice Ninja nếu bạn xuất invoice trong EU.

FAQ

Tôi nên cài Crater hay InvoiceShelf?

InvoiceShelf. Nhánh mặc định của Crater không có commit nào trong 741 ngày tính đến 21 August 2026, và issue tracker của chính dự án này hướng người dùng đến fork. InvoiceShelf giữ nguyên giấy phép AGPL-3.0 và cùng data model, nên chuyển đổi giữa hai phần mềm là một lần database migration thay vì phải viết lại. Mọi hướng dẫn vẫn khuyên dùng Crater đều được viết trước khi dự án ngừng hoạt động.

Tôi có thể dùng Invoice Ninja cho doanh nghiệp của mình mà không phải trả phí không?

Có. Invoice Ninja self-hosted có đầy đủ chức năng và không mất phí theo Elastic License 2.0, gồm recurring invoice, client portal và payment gateway. Có 2 khoản phải trả. Xóa branding của Invoice Ninja khỏi các trang hiển thị cho client cần white-label licence, với giá "$40 per year" theo thông tin của chính dự án tính đến August 2026. Gửi e-invoice qua mạng Peppol được tính phí riêng theo mức sử dụng. Điều license cấm là chạy phần mềm dưới dạng hosted service cho người khác.

Tại sao email invoice của tôi vào thư mục spam?

Gần như luôn là vì message chưa được xác thực cho domain trong địa chỉ From. Hãy gửi qua SMTP relay thay vì gửi trực tiếp từ VPS, sau đó publish các record SPF và DMARC cho domain của bạn, rồi thêm record DKIM dưới selector do relay cung cấp. Giữ địa chỉ của bạn trong From và đặt địa chỉ của client vào Reply-To. Đặt địa chỉ của client làm sender khiến Gmail từ chối message với 550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policy. Xác nhận đã sửa bằng cách tìm dkim=passspf=pass trong header Authentication-Results của một message kiểm thử.

Tôi nên chọn phần mềm nào nếu tính phí theo giờ?

Kimai. Đây trước hết là một time tracker, nên invoice được tạo từ các mục timesheet đã được duyệt và line item là phần công việc bạn đã ghi nhận. Template là các file DOCX, ODS hoặc XLSX do bạn thiết kế trong word processor, dễ hơn chỉnh sửa CSS. Đổi lại, Kimai không có client portal và payment gateway, nên bạn gửi PDF qua email và nhận tiền bằng chuyển khoản. Invoice Ninja cũng theo dõi thời gian và có portal, nên hãy chọn phần mềm đó nếu thanh toán online bằng thẻ quan trọng hơn chi tiết timesheet.

Chính xác thì tôi cần backup những gì?

Database, storage volume chứa logo và PDF được tạo ra, environment file, cùng các PDF đã render được lưu dưới dạng file thông thường. Environment file là thứ mọi người thường bỏ sót: các ứng dụng Laravel như Invoice Ninja và InvoiceShelf mã hóa credential đã lưu bằng APP_KEY, nên nếu restore database cạnh một key mới được tạo thì các thiết lập payment gateway sẽ không thể đọc được. Hãy restore toàn bộ vào một instance tạm thời một lần và mở một invoice cũ, vì đó là cách duy nhất để biết backup hoạt động.

#invoicing#tự lưu trữ#small-business#Docker#accounting