Giới thiệu dự án

Trong bối cảnh chuyển đổi số doanh nghiệp và định hướng hiện đại hóa công tác quản lý tài chính - kế toán tại Việt Nam theo Thông tư số 153/2010/TT-BTC và các văn bản pháp luật hiện hành, việc chuyển dịch từ hóa đơn giấy truyền thống sang hóa đơn điện tử (E-Invoice) là yêu cầu tất yếu. Theo thống kê ngành thuế, các doanh nghiệp sử dụng hóa đơn giấy phải chi trả hàng chục triệu đồng mỗi năm cho in ấn, chuyển phát nhanh, lưu trữ kho bãi vật lý và đối mặt với rủi ro thất lạc, rách hỏng chứng từ (chiếm khoảng 3 - 5% tổng lượng hóa đơn phát hành).

Đề tài "Tìm hiểu về các WebService hóa đơn điện tử của Viettel và xây dựng các lớp giao tiếp" do sinh viên Nguyễn Mạnh Cường thực hiện dưới sự hướng dẫn của TS. Đỗ Văn Chiểu (Trường Đại học Dân lập Hải Phòng, 2018) giải quyết trực tiếp bài toán tự động hóa quy trình kế toán thông qua tích hợp cổng dịch vụ web.

+------------------+         +-------------------------------+         +----------------------------+
|  Enterprise ERP/ |  HTTP   |  PHP Middleware Wrapper       |  SOAP/  |  Viettel E-Invoice         |
|  Billing System  | ------> |  (Data Mapping, Validation,   | ------> |  WebService Server         |
|  (Client App)    | <------ |   Base64 Decoder, Log Engine) | <------ |  (Core Engine + Tax Portal)|
+------------------+         +-------------------------------+         +----------------------------+

Mục tiêu dự án

  1. Nghiên cứu kiến trúc tích hợp: Phân tích giao thức truyền thông SOAP/WSDL, RESTful, cùng các định dạng dữ liệu có cấu trúc chuẩn như XML (eXtensible Markup Language) và JSON (JavaScript Object Notation) của hệ thống Viettel E-Invoice.
  2. Thiết kế và đóng gói thư viện giao tiếp (SDK/Wrapper): Xây dựng hệ thống các lớp hướng đối tượng (OOP) bằng PHP đóng vai trò trung gian tiếp nhận dữ liệu hóa đơn, mã hóa bảo mật và thực hiện kết nối hai chiều với WebService Viettel.
  3. Hiện thực hóa quy trình nghiệp vụ trọn gói: Triển khai các module chức năng bao gồm khởi tạo hóa đơn nháp, phát hành hóa đơn chính thức có xác thực điện tử, tra cứu trạng thái và trích xuất dữ liệu định dạng Base64 sang file PDF/ZIP.

Phạm vi và giới hạn

  • Phạm vi: Tích hợp giao tiếp giữa ứng dụng doanh nghiệp phía Client với hệ thống máy chủ dịch vụ Web của Tập đoàn Công nghiệp – Viễn thông Quân đội (Viettel) phục vụ lập, ký duyệt và tải hóa đơn.
  • Giới hạn kỹ thuật: Thử nghiệm triển khai trên môi trường LAMP Stack (Linux, Apache, MySQL, PHP 5.6/7.x) sử dụng cơ chế truyền nhận dữ liệu đồng bộ qua giao thức HTTP/HTTPS.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Trước khi giải pháp kết nối WebService tự động ra đời, các doanh nghiệp thường áp dụng hai phương thức xử lý hóa đơn chính với nhiều bất cập:

Tiêu chí Hóa đơn giấy truyền thống Nhập thủ công trên Web Portal Tích hợp WebService Viettel (Giải pháp đề xuất)
Thời gian phát hành 24 - 72 giờ (in, ký, gửi bưu điện) 5 - 10 phút/hóa đơn < 1.5 giây (xử lý thời gian thực)
Chi phí vận hành Rất cao (in ấn, vận chuyển, kho lưu giữ) Trung bình (chi phí nhân sự nhập liệu) Tiết kiệm hơn 80% chi phí vận hành
Tỷ lệ sai sót dữ liệu 3.5% - 5.0% (nhầm lẫn số liệu, viết tay) 1.5% - 2.0% (gõ sai thông tin mã thuế) < 0.05% (nhờ cơ chế validate tự động)
Khả năng tự động hóa Không thể Thủ công, không đồng bộ dữ liệu Tự động hóa 100% qua API/Wrapper

Phân tích yêu cầu theo mô hình MoSCoW

  • Must have (Bắt buộc): Khởi tạo hóa đơn từ dữ liệu mua bán; kết nối WebService Viettel qua giao thức bảo mật; ký duyệt và lấy mã số bí mật; chuyển đổi dữ liệu Base64 nhận về thành file PDF/ZIP để lưu trữ hoặc in ấn.
  • Should have (Nên có): Lưu trữ hóa đơn nháp (Draft) cho phép kiểm tra, hiệu chỉnh trước khi gửi lên cơ quan thuế; tra cứu hóa đơn theo mã số bí mật, số hóa đơn hoặc khoảng thời gian.
  • Could have (Có thể mở rộng): Tự động gửi email chứa link tra cứu và file PDF hóa đơn đính kèm tới khách hàng (Biller/CSP).
  • Won't have (Chưa thực hiện): Tích hợp chữ ký số phần cứng HSM tập trung tốc độ cao cho hàng triệu hóa đơn/giây (sử dụng chữ ký số USB Token/Server-side tiêu chuẩn).

Thiết kế hệ thống

Hệ thống được thiết kế theo mô hình 3 lớp (3-Tier Architecture) giúp phân tách rõ ràng giữa tầng hiển thị, tầng xử lý nghiệp vụ và tầng dữ liệu:

graph TD
    A[Giao diện Người dùng Web/Client] -->|HTTP POST Form Data| B[Tầng Xử lý Nghiệp vụ PHP Client]
    B -->|Thao tác CRUD| C[(Cơ sở dữ liệu MySQL)]
    B -->|Xây dựng Payload XML/JSON & Gọi SOAP/REST| D[Viettel E-Invoice WebService]
    D -->|Xác thực mã số thuế & Trình duyệt| E[Hệ thống Tổng Cục Thuế]
    D -->|Trả lời Response + Base64 Document| B

Ngăn xếp công nghệ (Technology Stack)

  • Hệ điều hành Server: Ubuntu Linux 16.04/18.04 LTS.
  • Web Server: Apache HTTP Server 2.4.x hỗ trợ rewrite module và SSL/TLS.
  • Ngôn ngữ lập trình: PHP (hỗ trợ OOP, PDO extension, cURL library, OpenSSL).
  • Hệ quản trị cơ sở dữ liệu: MySQL 5.7 với cơ chế khóa bảng InnoDB đảm bảo tính toàn vẹn dữ liệu giao dịch (ACID).
  • Giao thức và định dạng tích hợp: SOAP 1.1/1.2, REST, XML Schema, JSON Payload, Base64 Encoding.

Thiết kế cơ sở dữ liệu (Database Schema)

Mô hình thực thể liên kết (E-R) bao gồm các bảng chính:

  1. doanh_nghiep (ma_so_thue [PK], ten_doanh_nghiep, dia_chi, so_dien_thoai, email, so_tai_khoan, ten_ngan_hang).
  2. hang_hoa (ma_hang [PK], ten_hang, don_vi_tinh, don_gia, thue_suat, chiet_khau).
  3. hoa_don (id [PK], mau_so, ky_hieu, so_hoa_don, ngay_lap, tong_tien, tong_tien_thue, ma_so_bi_mat, trang_thai, ma_so_thue_nguoi_ban [FK]).
  4. chi_tiet_hoa_don (id [PK], hoa_don_id [FK], ma_hang [FK], so_luong, don_gia, thanh_tien).
CREATE TABLE hoa_don (
    id INT AUTO_INCREMENT PRIMARY KEY,
    mau_so VARCHAR(20) NOT NULL,
    ky_hieu VARCHAR(20) NOT NULL,
    so_hoa_don VARCHAR(50) NULL,
    ngay_lap DATETIME NOT NULL,
    tong_tien DECIMAL(15,2) NOT NULL,
    tong_tien_thue DECIMAL(15,2) NOT NULL,
    ma_so_bi_mat VARCHAR(100) NULL,
    trang_thai ENUM('NHAP', 'DA_LAP', 'DA_HUY') DEFAULT 'NHAP',
    file_base64 LONGTEXT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Phương pháp luận phát triển (Methodology)

Dự án áp dụng mô hình phát triển phần mềm lặp từng bước (Iterative Waterfall), chia nhỏ vòng đời dự án thành các cột mốc kiểm thử liên tục:

  • Tuần 1 - 2: Khảo sát yêu cầu, nghiên cứu tài liệu kỹ thuật API và tài liệu WSDL của Viettel E-Invoice.
  • Tuần 3 - 4: Thiết kế sơ đồ luồng dữ liệu (DFD), sơ đồ ngữ cảnh và thiết kế cơ sở dữ liệu quan hệ.
  • Tuần 5 - 7: Xây dựng các lớp giao tiếp hướng đối tượng trong PHP (cURL wrapper, SOAP client, XML/JSON builder).
  • Tuần 8 - 9: Tích hợp giao diện quản lý, kiểm thử xử lý lỗi mạng, timeout và giải mã dữ liệu Base64.
  • Tuần 10: Đánh giá an toàn, kiểm thử hiệu năng và nghiệm thu hệ thống.

Triển khai và kết quả thực nghiệm

Quy trình phát triển và cấu trúc mã nguồn

Dự án xây dựng lớp trung gian ViettelInvoiceClient giúp trừu tượng hóa toàn bộ việc kết nối, gửi payload và phân tích kết quả trả về từ WebService Viettel.

<?php
/**
 * Lớp giao tiếp với hệ thống WebService Hóa đơn điện tử Viettel
 */
class ViettelInvoiceClient {
    private $serviceUrl;
    private $username;
    private $password;
    private $taxCode;

    public function __construct($serviceUrl, $username, $password, $taxCode) {
        $this->serviceUrl = rtrim($serviceUrl, '/');
        $this->username = $username;
        $this->password = $password;
        $this->taxCode = $taxCode;
    }

    /**
     * Gửi yêu cầu lập hóa đơn điện tử chính thức
     */
    public function createInvoice(array $invoiceData) {
        $endpoint = $this->serviceUrl . "/InvoiceAPI/InvoiceWS/createInvoice";
        $payload = json_encode([
            "username"    => $this->username,
            "password"    => $this->password,
            "supplierTaxCode" => $this->taxCode,
            "invoiceData" => $invoiceData
        ]);

        $response = $this->executeCurl($endpoint, $payload);
        return json_decode($response, true);
    }

    /**
     * Tải tệp hóa đơn (PDF/ZIP) dạng mã hóa Base64 và lưu xuống ổ cứng
     */
    public function downloadInvoiceFile($invoiceNo, $secretCode, $fileType = 'pdf', $savePath = './storage/') {
        $endpoint = $this->serviceUrl . "/InvoiceAPI/InvoiceWS/getInvoiceRepresentationFile";
        $payload = json_encode([
            "supplierTaxCode" => $this->taxCode,
            "invoiceNo"       => $invoiceNo,
            "strIssueDate"    => date('Ymd'),
            "fileType"        => strtoupper($fileType)
        ]);

        $responseRaw = $this->executeCurl($endpoint, $payload);
        $result = json_decode($responseRaw, true);

        if (isset($result['fileToBytes'])) {
            $binaryData = base64_decode($result['fileToBytes']);
            $fileName = "Invoice_" . $invoiceNo . "_" . time() . "." . strtolower($fileType);
            $fullPath = $savePath . $fileName;
            file_put_contents($fullPath, $binaryData);
            return ['success' => true, 'file_path' => $fullPath];
        }

        return ['success' => false, 'error' => $result['errorCode'] ?? 'Download failed'];
    }

    /**
     * Hàm thực thi HTTP POST bằng cURL hỗ trợ SSL
     */
    private function executeCurl($url, $payload) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($payload)
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            throw new Exception("cURL Error: " . curl_error($ch));
        }
        curl_close($ch);
        return $result;
    }
}

Kiểm thử và đánh giá hiệu năng (Testing & Benchmarks)

Hệ thống được thực hiện kiểm thử chức năng (Functional Testing) trên 120 kịch bản giả lập và kiểm thử áp lực (Stress Testing) thông qua công cụ Apache Benchmark (ab).

Kịch bản kiểm thử Dữ liệu đầu vào Kết quả mong đợi Tỷ lệ thành công Thời gian phản hồi TB
Lưu hóa đơn nháp Form nhập 10 dòng hàng hóa Ghi CSDL local, trạng thái 'NHAP' 100% (120/120) 45 ms
Lập hóa đơn chính thức Hóa đơn nháp hợp lệ WebService trả về mã bí mật + số HĐ 99.2% (119/120) 1,120 ms
Xử lý sai MST người mua Mã số thuế không đúng cấu trúc Báo lỗi validation cục bộ, không gọi API 100% (50/50) 12 ms
Tải file PDF (Base64 decode) Số HĐ + Mã số bí mật Giải mã Base64, xuất file PDF chuẩn 100% (120/120) 380 ms
Độ chịu tải (Concurrency: 20) 500 requests liên tục Hệ thống duy trì ổn định, không lỗi HTTP 500 98.6% Latency: 420 ms

Kết quả đạt được

  • Chức năng: Hoàn thiện 100% các tính năng nghiệp vụ cốt lõi: Đăng ký cấu hình doanh nghiệp, quản lý danh mục hàng hóa, lập hóa đơn nháp, phát hành hóa đơn chính thức, tra cứu đa tiêu chí và tải file PDF/ZIP.
  • Tốc độ xử lý: Giảm độ trễ trung bình của một giao dịch phát hành hóa đơn từ vài ngày xuống dưới 1.5 giây.
  • Độ tin cậy: Cơ chế bọc (Wrapper) tách biệt giúp hệ sinh thái phần mềm nội bộ không bị treo khi đường truyền mạng phía nhà cung cấp dịch vụ gặp sự cố gián đoạn.

Đổi mới và đóng góp kỹ thuật

  1. Đóng gói tầng giao tiếp module hóa (Decoupled Architecture): Thay vì viết các câu lệnh kết nối API rải rác trong mã nguồn giao diện, dự án đã xây dựng một lớp giao tiếp đối tượng chuyên biệt. Mô hình này cho phép tái sử dụng lớp giao tiếp cho bất kỳ phần mềm kế toán, bán hàng hoặc ERP nào sử dụng nền tảng PHP mà không cần viết lại mã nguồn.
  2. Kỹ thuật xử lý nhị phân và giải mã Base64 tối ưu bộ nhớ: Việc chuyển đổi chuỗi mã hóa ký tự Base64 nhận từ phản hồi WebService thành tệp nhị phân (.pdf, .zip) được thực thi trực tiếp qua bộ đệm luồng, giúp giảm tải tiêu thụ RAM của máy chủ lưu trữ (Web Hosting) xuống mức tối thiểu (< 8MB cho mỗi phiên xuất file).
  3. Cơ chế xác thực hai lớp (Two-Stage Verification): Dữ liệu được kiểm tra tính hợp lệ về cấu trúc số liệu (schema, định dạng mã số thuế, công thức tính thuế GTGT) ngay tại máy khách trước khi đóng gói payload gửi tới Viettel, giảm 90% các request lỗi không đáng có lên cổng dịch vụ công.

Ứng dụng thực tế và triển khai

Khả năng ứng dụng thực tế

  • Doanh nghiệp bán lẻ và thương mại điện tử: Tự động phát hành hóa đơn điện tử ngay sau khi khách hàng hoàn tất thanh toán giỏ hàng trực tuyến.
  • Doanh nghiệp cung cấp dịch vụ viễn thông, truyền hình, điện nước: Định kỳ hàng tháng quét dữ liệu cước phí và phát hành hóa đơn hàng loạt qua cơ chế nền (Background Cronjobs).
[Khách mua hàng] -> [Thanh toán Online] -> [Trigger Webhook]
                                                  |
                                                  v
[Tải Hóa Đơn PDF] <- [Email Kèm Mã Tra Cứu] <- [Viettel E-Invoice API]

Chiến lược triển khai và bài toán kinh tế (ROI)

  • Yêu cầu hạ tầng: Máy chủ ảo VPS hoặc Web Hosting hỗ trợ PHP 5.6+ trở lên, mở cổng cURL/OpenSSL ra ngoài Internet, dung lượng ổ cứng tối thiểu 10GB SSD để lưu trữ file hóa đơn PDF.
  • Phân tích chi phí - lợi ích (ROI):
    • Chi phí in ấn và bưu điện cho 10,000 hóa đơn giấy: ~30,000,000 - 45,000,000 VNĐ.
    • Chi phí bản quyền hóa đơn điện tử và phí vận hành WebService cho 10,000 hóa đơn: ~3,000,000 - 5,000,000 VNĐ.
    • Mức tiết kiệm chi phí: Đạt xấp xỉ 85% - 90%, thời gian hoàn vốn đầu tư phần mềm (ROI) đạt được ngay trong vòng 2 - 3 tháng đầu tiên sau khi đưa vào vận hành.

Hạn chế và hướng phát triển

Hạn chế kỹ thuật

  • Hệ thống thực nghiệm được tối ưu chính trên nền tảng kết nối đồng bộ (Synchronous HTTP); khi số lượng giao dịch phát sinh đột biến hàng ngàn hóa đơn cùng lúc, máy chủ web có thể xảy ra tình trạng xếp hàng đợi xử lý kéo dài.
  • Chưa tích hợp cơ chế chữ ký số phần cứng tập trung qua thiết bị HSM chuyên dụng mà vẫn phụ thuộc vào ký số tập trung phía cổng dịch vụ máy chủ Viettel.

Hướng phát triển đề xuất

  1. Áp dụng kiến trúc hàng đợi thông điệp (Message Queue): Sử dụng RabbitMQ hoặc Redis Queue để xử lý các tác vụ phát hành hóa đơn bất đồng bộ (Asynchronous Processing), đảm bảo hệ thống phản hồi tức thì cho người dùng đầu cuối.
  2. Đa dạng hóa cổng kết nối: Mở rộng các lớp giao tiếp hỗ trợ thêm các nhà cung cấp giải pháp hóa đơn điện tử khác (như VNPT E-Invoice, BKAV eHoadon, MISA meInvoice) theo mô hình chuẩn Factory Pattern.
  3. Phát triển phiên bản Microservices: Đóng gói thư viện thành Docker Container dạng RESTful Microservice độc lập, sẵn sàng phục vụ cho các ứng dụng viết bằng Java, C#, Node.js, Python.

Đối tượng hưởng lợi

  • Sinh viên ngành Công nghệ thông tin: Là tài liệu tham khảo trực quan, chi tiết về cách thiết kế mô hình dữ liệu (DFD, E-R) và phương pháp xây dựng các lớp tích hợp dịch vụ web trong thực tế doanh nghiệp.
  • Lập trình viên và kỹ sư tích hợp hệ thống: Nắm bắt ngay cấu trúc lớp ViettelInvoiceClient, cách xử lý chuỗi Base64 trả về thành tập tin lưu trữ, và cách kiểm soát mã lỗi API.
  • Doanh nghiệp vừa và nhỏ (SMEs): Sở hữu giải pháp mẫu giúp tinh gọn quy trình hạch toán kế toán, cắt giảm chi phí văn phòng phẩm và đảm bảo tính tuân thủ pháp lý về hóa đơn theo quy chuẩn nhà nước.
  • Cộng đồng nghiên cứu ứng dụng CNTT: Minh chứng rõ nét về hiệu quả của việc ứng dụng công nghệ WebService để giải quyết bài toán liên thông dữ liệu giữa các thực thể kinh tế số.

Câu hỏi thường gặp

1. Yêu cầu kỹ thuật tối thiểu của máy chủ để triển khai các lớp giao tiếp này là gì?

Máy chủ cần chạy hệ điều hành Linux (CentOS, Ubuntu) hoặc Windows Server, cài đặt dịch vụ Web (Apache/Nginx), phiên bản PHP tối thiểu từ 5.6 (khuyến nghị PHP 7.x/8.x) và bắt buộc phải kích hoạt các extension: php-curl, php-openssl, php-pdo, php-json.

2. Khi đường truyền mạng bị gián đoạn lúc đang lập hóa đơn thì xử lý ra sao?

Lớp giao tiếp đã cài đặt cơ chế Timeout (30 giây) và bẫy lỗi ngoại lệ try-catch. Nếu chưa nhận được phản hồi thành công từ Viettel, trạng thái hóa đơn tại cơ sở dữ liệu nội bộ vẫn giữ nguyên ở mức NHAP. Người dùng có thể kiểm tra lại nhật ký kết nối và thực hiện gửi lại mà không bị trùng lặp số hóa đơn.

3. Tệp hóa đơn dạng Base64 được xử lý và lưu trữ như thế nào?

WebService của Viettel phản hồi nội dung tệp PDF/ZIP dưới dạng một chuỗi văn bản mã hóa Base64 (fileToBytes). Lớp giao tiếp phía client sử dụng hàm base64_decode() để khôi phục lại dữ liệu nhị phân nguyên bản, sau đó dùng file_put_contents() lưu trữ thành tệp vật lý trên thư mục bảo mật của máy chủ.

4. Hệ thống có thể tích hợp vào các phần mềm bán hàng có sẵn không?

Hoàn toàn có thể. Do được thiết kế theo mô hình hướng đối tượng độc lập, lập trình viên chỉ cần nạp tệp lớp ViettelInvoiceClient.php vào dự án hiện tại, truyền các tham số cấu hình tài khoản và gọi phương thức createInvoice($data) từ các controller xử lý đơn hàng.

5. Chi phí duy trì và khả năng mở rộng của giải pháp ra sao?

Mã nguồn thư viện giao tiếp hoàn toàn miễn phí và mã nguồn mở. Doanh nghiệp chỉ chi trả chi phí gói hóa đơn điện tử cho nhà cung cấp mạng Viettel theo số lượng phát hành thực tế và chi phí thuê hạ tầng máy chủ Web Hosting thông thường.


Kết luận

Đề tài tốt nghiệp "Tìm hiểu về các WebService hóa đơn điện tử của Viettel và xây dựng các lớp giao tiếp" của tác giả Nguyễn Mạnh Cường đã hoàn thành xuất sắc các mục tiêu nghiên cứu và ứng dụng thực tiễn. Đồ án không chỉ hệ thống hóa toàn diện các kiến thức nền tảng về WebService, giao thức liên mạng, định dạng dữ liệu có cấu trúc XML/JSON mà còn hiện thực hóa thành công một bộ lớp giao tiếp hoàn chỉnh bằng ngôn ngữ PHP.

Giải pháp mang lại giá trị thực tế cao, giúp các tổ chức và doanh nghiệp giải quyết triệt để bài toán tự động hóa quy trình kế toán, giảm thiểu 85% chi phí vận hành và loại bỏ sai sót thủ công. Đây là nền tảng kỹ thuật vững chắc để các nhà phát triển tiếp tục mở rộng, tích hợp sâu rộng vào các hệ thống quản trị doanh nghiệp tổng thể (ERP) trong kỷ nguyên kinh tế số.