Để phục vụ cho công việc kinh doanh, mình đang sử dụng khá nhiều các ứng dụng mã nguồn mở để tiết kiệm chi phí vận hành:

  • Odoo: quản lý tồn kho, xuất nhập khẩu, kế toán,…
  • Paperless-ngx: quản lý hồ sơ, biên lai, hóa đơn điện tử
  • WordPress / Woocommerce: tạo blog / trang bán hàng e-commerce
  • Proxmox: quản lý máy ảo, container để cài đặt các ứng dụng web

Từ ngày dọn nhà qua Nhật, có thêm 1 ứng dụng đã nhanh chóng trở thành một phần không thể thiếu cho công ty mới của mình ở Nhật. Đó là Invoice Ninja – ứng dụng tạo và quản lý hóa đơn cho khách hàng. Mình đang sử dụng Invoice Ninja để nhận thanh toán từ khách hàng ở nhiều quốc gia khác nhau, thông qua cổng thanh toán Stripe.

Bài viết này sẽ hướng dẫn bạn cách cài đặt Invoice Ninja để sử dụng cho mục đích kinh doanh của mình

I. Invoice Ninja là gì?

Invoice Ninja là một phần mềm mã nguồn mở giúp bạn quản lý hóa đơn, báo giá, và các khoản thanh toán cho công việc kinh doanh. Nó được thiết kế phù hợp cho các doanh nghiệp nhỏ, freelancer cần một công cụ đơn giản nhưng mạnh mẽ để quản lý tài chính.

Các tính năng nổi bật của Invoice Ninja:

  • Tạo hóa đơn và báo giá chuyên nghiệp.
  • Tích hợp với các cổng thanh toán như Stripe, PayPal, …
  • Hỗ trợ theo dõi chi phí và quản lý dự án.
  • Có thể tự cài đặt lên máy chủ cá nhân để sử dụng miễn phí,

II. Cài đặt Invoice Ninja bằng Docker Compose

Bạn có thể cài đặt Invoice Ninja trực tiếp lên server, hoặc sử dụng Docker. Mình sẽ cài đặt thông qua Docker Compose cho nhanh gọn.

Yêu cầu máy chủ đã được cài đặt sẵn DockerDocker Compose.

1. Clone Invoice Ninja về server

SSH vào máy chủ và clone repo của Invoice Ninja về máy chủ

git clone https://github.com/invoiceninja/dockerfiles.git -b master invoice-ninja
cd invoice-ninjaCode language: Bash (bash)

File docker-compose.yml sẽ có nội dung tương tự như sau

version: '3.7'

services:
  server:
    image: nginx
    restart: always
    env_file: env
    volumes:
      # Vhost configuration
      #- ./config/caddy/Caddyfile:/etc/caddy/Caddyfiledocker-com
      - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
      - ./docker/app/public:/var/www/app/public:ro
    depends_on:
      - app
    # Run webserver nginx on port 80
    # Feel free to modify depending what port is already occupied
    ports:
      - "80:80"
      #- "443:443"
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 " #host and ip

  app:
    image: invoiceninja/invoiceninja:5
    env_file: env
    restart: always
    volumes:
      - ./config/hosts:/etc/hosts:ro
      - ./docker/app/public:/var/www/app/public:rw,delegated
      - ./docker/app/storage:/var/www/app/storage:rw,delegated
      - ./config/php/php.ini:/usr/local/etc/php/php.ini
      - ./config/php/php-cli.ini:/usr/local/etc/php/php-cli.ini

    depends_on:
      - db
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 " #host and ip

  db:
    image: mysql:8
#    When running on ARM64 use MariaDB instead of MySQL
#    image: mariadb:10.4
#    For auto DB backups comment out image and use the build block below
#    build:
#      context: ./config/mysql
    restart: always
    env_file: env
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw,delegated

      # remove comments for next 4 lines if you want auto sql backups
      #- ./docker/mysql/bak:/backups:rw
      #- ./config/mysql/backup-script:/etc/cron.daily/daily:ro
      #- ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro
      #- ./config/mysql/backup-script:/etc/cron.monthly/monthly:ro
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 " #host and ip

  # THIS IS ONLY A VALID CONFIGURATION FOR IN 4. DO NOT USE FOR IN 5.
  # cron:
  #   image: invoiceninja/invoiceninja:alpine-4
  #   volumes:
      # - ./docker/app/public:/var/www/app/public:rw,delegated
      # - ./docker/app/storage:/var/www/app/storage:rw,delegated
      # - ./docker/app/public/logo:/var/www/app/public/logo:rw,delegated
  #   entrypoint: |
  #     /bin/sh -c 'sh -s <<EOF
  #     trap "break;exit" SIGHUP SIGINT SIGTERM
  #     sleep 300s
  #     while /bin/true; do
  #       ./artisan ninja:send-invoices
  #       ./artisan ninja:send-reminders
  #       sleep 1d
  #     done
  #     EOF'
  #   networks:
  #     - invoiceninja
  #

networks:
  invoiceninja:Code language: YAML (yaml)

3. Thay thế nginx bằng Caddy

File docker-compose.yml đã được tích hợp Nginx làm Reverse Proxy. Bạn có thể xóa phần khai báo nginx nếu trên hệ thống đã có sẵn Reverse Proxy.

MÌnh không thích dùng nginx nên sẽ thay bằng caddy để làm Reverse Proxy. Đổi lại nội dung file docker-compose.yml như bên dưới

services:
  server:
    image: caddy:alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config
      - ./docker/app/public:/var/www/app/public:ro
    networks:
      - invoiceninja
    
  app:
    image: invoiceninja/invoiceninja:5
    container_name: invoiceninja
    env_file: env
    restart: always
    volumes:
      - ./config/hosts:/etc/hosts:ro
      - ./docker/app/public:/var/www/app/public:rw,delegated
      - ./docker/app/storage:/var/www/app/storage:rw,delegated
      - ./config/php/php.ini:/usr/local/etc/php/php.ini
      - ./config/php/php-cli.ini:/usr/local/etc/php/php-cli.ini
    depends_on:
      - db
    networks:
      - invoiceninja
   
  db:
    image: mariadb:10.4
    restart: always
    env_file: env
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw,delegated
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 " #host and ip

networks:
  invoiceninja:Code language: YAML (yaml)

Tạo thêm file Caddyfile với nội dung sau

invoice.thuanbui.me {
    root * /var/www/app/public
    php_fastcgi invoiceninja:9000
    encode zstd gzip
    file_server browse
}Code language: PHP (php)

Bạn cần thay thế invoice.thuanbui.me bằng tên miền bạn sử dụng để truy cập Invoice Ninja.

2. Tạo APP_KEY

Trước khi kích hoạt dịch vụ, cần phải tạo APP_KEY bằng lệnh sau

docker run --rm -it invoiceninja/invoiceninja php artisan key:generate --showCode language: Dockerfile (dockerfile)

Chờ vài phút để hệ thống xử lý, bạn sẽ nhận được kết quả trả về tương tự như bên dưới

base64:5fOFQtFaQcwFxQ2nAEwBdMUWzB5DcOGS7y+uvkL5W2c=

3. Cập nhật thông số env

Chỉnh sửa lại file env bằng lệnh

nano envCode language: Nginx (nginx)
  • APP_URL: nhập vào tên miền bạn sử dụng để truy cập Invoice Ninja
  • APP_KEY: nhập vào thông số đã APP_KEY vừa tạo ở trên
# IN application vars
APP_URL=https://invoice.thuanbui.me
APP_KEY=base64:5fOFQtFaQcwFxQ2nAEwBdMUWzB5DcOGS7y+uvkL5W2c=
APP_DEBUG=true
REQUIRE_HTTPS=false
PHANTOMJS_PDF_GENERATION=false
PDF_GENERATOR=snappdf
TRUSTED_PROXIES='*'Code language: PHP (php)

Cập nhật thêm thông số tài khoản admin và mật khẩu

# Create initial user
# Default to these values if empty
# IN_USER_EMAIL=admin@example.com
# IN_PASSWORD=changeme!
IN_USER_EMAIL=thuan@thuanbui.me
IN_PASSWORD=123456Code language: Bash (bash)

Ngoài ra, để Invoice Ninja có thể gửi email đến khách hàng, cần phải cấu hình thêm mục #Mail options, cần khai báo các thông số cần thiết tương tự như sau

# Mail options
MAIL_MAILER=smtp
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=apikey
MAIL_PASSWORD=SG.wPFD3423dffdsfdsfdsfdsfZxRjSi0T4T-Rn7UsSd2F_-5ySJUV_4
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@thuanbui.me
MAIL_FROM_NAME=ThuanBui
Code language: Bash (bash)

Sau khi hoàn thành, lưu lại (Ctrl + O) và thoát ra (Ctrl + X)

4. Chỉnh sửa permission

Để đảm bảo quyền thư mục được thiết lập chính xác khi container khởi động, cần sử dụng lệnh sau thiết lập đúng quyền truy cập cho thư mục Docker.

chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/appCode language: YAML (yaml)

3. Kích hoạt dịch vụ

Khởi động Invoice Ninja bằng lệnh

docker compose up -dCode language: Nginx (nginx)

Truy cập vào Invoice Ninja thông qua tên miền bạn đã cấu hình. Chúng ta sẽ bắt đầu phần cấu hình thông số ban đầu cho Invoice Ninja

III. Cấu hình Invoice Ninja

Bạn cần đăng nhập vào invoice Ninja bằng thông tin email và mật khẩu đã thiết lập trong file env

1. Thông tin công ty

Ở lần đăng nhập đầu tiên, chúng ta cần phải thiết lập tên công ty (Company Name), ngôn ngữ (Language) và tiền tệ (Currency)

Giao diện trang Dashboard của Invoice Ninja sẽ hiện ra như bên dưới

Truy cập thêm vào phần Setting / Company Details để khai báo thêm các thông tin liên quan: Website, Email, Địa chỉ,… Các thông tin này sẽ hiển thị trên các hóa đơn gửi cho khách hàng.

2. Kết nối với Stripe & PayPal

Invoice Ninja hỗ trợ kết nối với cổng thanh toán như StripePayPal giúp khách hàng có thẻ thanh toán trực tiếp từ các hóa đơn được tạo từ hệ thống.

Truy cập vào mục Settings > Payment Settings, chọn Add Gateway, chọn Stripe hoặc Paypal, sau đó nhập các thông tin cần thiết (API Keys) lấy từ tài khoản Stripe / Paypal của bạn


IV. Tạo hóa đơn và nhận thanh toán

1. Tạo hóa đơn mới

  1. Truy cập vào Invoices và chọn Create Invoice.
  2. Thêm thông tin khách hàng, dịch vụ/sản phẩm, thuế (nếu có).
  3. Tùy chỉnh hóa đơn theo ý muốn (logo, màu sắc, điều khoản).

Sau khi hoàn tất, nhấn nút Save để lưu lại invoice.

2. Gửi invoice cho khách hàng

Bạn có thể gửi invoice cho khách hàng bằng 2 cách:

  1. Bấm vào nút mũi tên bên cạch nút Save và chọn Email Invoice để gửi invoice qua email
  2. Right click vào dòng View in Portal, chọn Copy Link. Sau đó gửi link này cho khách hàng qua Zalo / Facebook / SMS/…

3. Nhận thanh toán

Khách hàng sau khi nhận invoice email / portal link có thể thanh toán bằng Stripe / Paypal (nếu bạn đã cấu hình). Sau khi thanh toán thành công, hóa đơn sẽ được tự động cập nhật trạng thái từ Sent thành Paid.


Invoice Ninja đã giúp mình tiết kiệm rất nhiều thời gian và công sức trong việc quản lý hóa đơn cho công ty. Nếu bạn đang tìm kiếm một công cụ quản lý hóa đơn và để nhận thanh toán từ khách hàng hãy thử cài đặt và sử dụng Invoice Ninja.

Chúc bạn thực hiện thành công!

Nếu bạn cần hỗ trợ thiết lập Invoice Ninja, tham khảo dịch vụ cài đặt Self-Hosting app của mình bên dưới nhé

Cài đặt Invoice Ninja

800,000 
(~ 4.904 JPY)

Nếu bạn cần hỗ trợ kỹ thuật miễn phí, vui lòng gửi câu hỏi trực tiếp ở phần Thảo luận bên dưới, mình sẽ trả lời trong thời gian sớm nhất.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *


Bạn cần hỗ trợ kỹ thuật chuyên sâu?

Khám phá các gói dịch vụ giúp bạn tối ưu công việc và vận hành hệ thống hiệu quả hơn. Từ chăm sóc website đến hỗ trợ kỹ thuật, mọi thứ đều linh hoạt và phù hợp với nhu cầu của bạn.