Hóa đơn điện tử theo từng chuyến xe: kiến trúc hệ thống real-time cho đội taxi
Thông tư 32/2025/TT-BTC bắt buộc hóa đơn điện tử phải được phát hành ngay tại thời điểm kết thúc chuyến. Bài viết phân tích ba thách thức kỹ thuật thực tế và kiến trúc event-driven để giải quyết chúng — từ đồng hồ taxi cơ học đến hệ thống ký số và đối soát tự động.
Từ ngày 1/6/2025, Thông tư 32/2025/TT-BTC (thay thế Thông tư 78/2021) quy định rõ: hóa đơn điện tử cho dịch vụ vận tải hành khách phải được lập tại thời điểm kết thúc chuyến xe, không phải cuối ngày hay cuối ca. Công văn 6022/CT-CS ban hành tháng 12/2025 siết thêm yêu cầu: hóa đơn phải ghi rõ biển số xe và tuyến đường, không được để chung chung "phí vận tải". Với các đội taxi lớn vận hành hàng nghìn xe, đây không còn là bài toán nghiệp vụ — mà là bài toán kỹ thuật cần giải đúng từ đầu.
Ba thách thức kỹ thuật thực tế
**Thứ nhất: đồng hồ taxi cơ học không nói chuyện được với hệ thống CNTT.** Đồng hồ tính cước (taximeter) truyền thống chỉ biết đếm quãng đường và tính tiền — hoàn toàn không có API, không có kết nối mạng. Khi chuyến kết thúc, đồng hồ hiển thị một con số, lái xe thu tiền mặt, hành khách đi về. Không có event nào được phát ra để hệ thống invoice bắt được.
**Thứ hai: giá thực thanh toán không phải lúc nào cũng bằng số đồng hồ.** Với taxi công nghệ, giá hiển thị trên app có thể đã áp dụng voucher giảm giá, cashback từ ví điện tử, hoặc doanh nghiệp đặt xe cho nhân viên — lúc đó có hai chủ thể trả tiền, một hóa đơn sẽ không đủ. Với taxi truyền thống chạy hợp đồng doanh nghiệp, tài xế có thể tính theo giờ hoặc theo lộ trình cố định, không theo đồng hồ.
**Thứ ba: kết nối 4G không đảm bảo 100% uptime.** Xe taxi đi qua hầm, vùng ven đô, hoặc khu vực sóng yếu — tại thời điểm chuyến kết thúc, xe có thể không có mạng. Thông tư không cho phép "để sau rồi phát hành hóa đơn"; hóa đơn phải gắn với thời điểm kết thúc chuyến, dù gửi lên CQT muộn hơn vẫn ổn nếu có lý do hợp lệ.
Kiến trúc giải pháp: event-driven từ đầu đến cuối
Mấu chốt của kiến trúc này là coi "chuyến xe kết thúc" như một **event** — không phải như một transaction đồng bộ. Mọi xử lý tiếp theo (tạo hóa đơn, ký số, gửi CQT, giao hóa đơn cho khách) được pipeline hóa và xử lý bất đồng bộ, nhưng có đủ metadata để reconstruct đầy đủ khi cần.
Lớp thu thập sự kiện (Event Ingestion)
- **Taxi truyền thống**: gắn module IoT (ESP32 + modem 4G) vào cổng xung của đồng hồ tính cước. Mỗi khi lái xe bấm kết thúc chuyến, module bắt xung, đọc số tiền cuối từ cổng serial của đồng hồ (nếu hỗ trợ), kết hợp GPS để lấy tuyến đường, rồi publish event `trip_completed` lên message broker. Nếu không có 4G, lưu vào local flash memory và retry khi có mạng — đây là cơ chế **store-and-forward** đã chuẩn hóa cho IoT.
- **Taxi công nghệ (app-based)**: app hoặc dispatch server gọi webhook API khi chuyến kết thúc. Payload gồm: `trip_id`, `vehicle_plate`, `driver_id`, `start_location`, `end_location`, `fare_amount`, `payment_method`, `discount_applied`. Đơn giản hơn nhiều về mặt hardware, nhưng cần validation schema chặt để tránh dữ liệu thiếu field.
Lớp xử lý hóa đơn (Invoice Pipeline)
Event được đưa vào một Kafka topic (hoặc MQTT broker nếu dùng kiến trúc IoT thuần). Consumer service đảm nhận:
- **Invoice Builder**: map dữ liệu trip sang template HĐĐT theo đúng yêu cầu TT 32 — biển số xe, tuyến đường (địa chỉ đón + trả), thời điểm kết thúc chuyến, thuế VAT 10%. Với trường hợp có nhiều chủ thể trả tiền, service tách thành nhiều invoice object trước khi ký.
- **Idempotency guard**: dùng `trip_id` làm deduplication key. Nếu cùng một `trip_id` được nhận hai lần (retry từ module IoT bị mất kết nối), chỉ tạo một hóa đơn duy nhất.
- **Digital Signing**: gửi invoice payload đến HSM (Hardware Security Module) hoặc service ký số trên cloud để đính chữ ký điện tử theo chuẩn XML của Tổng cục Thuế.
Kết nối với Cơ quan Thuế (MTT Integration)
Hóa đơn đã ký được gửi lên Máy tính của Thuế (MTT) theo API của nhà cung cấp HĐĐT (VNPT, Viettel, hay nhà cung cấp đã được cấp phép). Với yêu cầu "tại thời điểm kết thúc chuyến", mục tiêu end-to-end latency từ `trip_completed` event đến hóa đơn được CQT xác nhận nên dưới **30 giây** — hoàn toàn khả thi khi pipeline đã được tối ưu.
Giao hóa đơn và đối soát
Sau khi CQT trả về mã xác nhận, hệ thống gửi hóa đơn đến hành khách qua SMS/Zalo/Email (PDF + XML). Song song, một module đối soát (reconciliation) so sánh trip ledger với hóa đơn đã phát hành theo ngày — tự động flag bất kỳ chuyến nào chưa có hóa đơn để xử lý thủ công.
Những điểm cần lưu ý khi triển khai
- **Không dùng API call đồng bộ trong luồng thanh toán**: nếu hệ thống HĐĐT chậm hoặc down, toàn bộ luồng thanh toán bị block. Event-driven giải quyết điều này — lái xe thu tiền và kết thúc chuyến bình thường, hóa đơn được xử lý bất đồng bộ trong nền.
- **Store-and-forward là bắt buộc, không phải optional**: module IoT trên xe phải có local buffer đủ lớn (tối thiểu 24h dữ liệu) và retry logic với exponential backoff. Khi xe về điểm tập kết có WiFi, buffer flush tự động.
- **Timestamp phải là thời điểm kết thúc chuyến, không phải thời điểm gửi hóa đơn**: log `trip_end_time` tại module IoT hoặc app trước khi có kết nối — đây là trường bắt buộc để hóa đơn hợp lệ theo TT 32.
- **Test với CQT sandbox trước khi production**: Tổng cục Thuế có môi trường test để validate schema HĐĐT. Chạy toàn bộ pipeline qua sandbox, kiểm tra phản hồi lỗi schema để vá trước khi go-live.
Tóm lại
Yêu cầu hóa đơn điện tử theo từng chuyến xe không phải là gánh nặng thêm — đây là cơ hội để chuẩn hóa luồng dữ liệu vận hành của đội xe. Một pipeline event-driven triển khai đúng không chỉ đáp ứng nghĩa vụ thuế, mà còn cho phép đội quản lý nhìn thấy toàn bộ hoạt động xe theo thời gian thực: doanh thu theo xe, theo tài xế, theo tuyến đường — thay vì chờ báo cáo cuối ngày. Tại lớp Development của KonexForge, đây là dạng Pilot Build chúng tôi triển khai trong 6–8 tuần cho các công ty taxi và đội xe doanh nghiệp.