Tự viết script tải hóa đơn từ trang thuế — vì sao thường thất bại
Nếu bạn có nền tảng lập trình và phải tải hóa đơn mua vào mỗi tháng, ý nghĩ đầu tiên là viết một script. Bài này nói về những gì bạn sẽ gặp — không phải để ngăn bạn, mà để bạn ước lượng đúng khối lượng việc.
- Phần dễ: đăng nhập và lấy danh sách
- Phần khó bắt đầu từ đây
- Ước lượng thực tế
- Khi nào tự viết là hợp lý
- Căn cứ
Phần dễ: đăng nhập và lấy danh sách#
Đăng nhập trả về một token, dùng token gọi endpoint tra cứu, nhận về JSON hoặc file Excel. Phần này làm trong một buổi.
Đây là lý do nhiều người tưởng cả bài toán chỉ mất một ngày.
1. Token hết hạn nhanh#
Token có thời hạn ngắn. Với một lần chạy vài phút thì không sao, nhưng khi bạn xử lý nhiều tháng hoặc nhiều công ty, token sẽ hết hạn giữa lúc chạy.
Script phải giải mã thời điểm hết hạn và tự đăng nhập lại, có khoảng đệm an toàn — chứ không phải chờ đến khi nhận lỗi rồi mới xử lý, vì lúc đó bạn đã mất dữ liệu của lần gọi đó.
2. Hai loại hóa đơn, hai đường dẫn khác nhau#
Hóa đơn điện tử thường và hóa đơn máy tính tiền nằm ở hai endpoint khác nhau. Bỏ sót một loại là bỏ sót dữ liệu, và bạn sẽ không nhận ra vì kết quả vẫn trả về bình thường.
3. Cấu trúc file Excel của hai loại không giống nhau#
Đây là chỗ gây lỗi âm thầm nhất, và nó tệ hơn vẻ ngoài: hai file chỉ trùng nhau ở 6 cột đầu (STT, ký hiệu mẫu số, ký hiệu hóa đơn, số hóa đơn, ngày lập, MST người bán). Từ cột thứ 8 trở đi cấu trúc đã khác nhau.
File hóa đơn thường có thêm địa chỉ người mua, tổng tiền phí, đơn vị tiền tệ và tỷ giá. File máy tính tiền có thêm địa chỉ người bán và căn cước công dân. Kết quả: hai cột trạng thái nằm ở R và S với hóa đơn thường, nhưng P và Q với hóa đơn máy tính tiền.
Nếu bạn đọc theo chỉ số cột cứng — và hầu hết script đều làm vậy — thì một trong hai loại sẽ đọc sai cột trạng thái. Kết quả: dữ liệu vào đủ, giá trị sai, không có lỗi nào được báo.
4. Chi tiết dòng hàng hóa là bài toán riêng#
Danh sách hóa đơn không chứa chi tiết hàng hóa dịch vụ. Muốn có, bạn phải gọi thêm một lần cho từng hóa đơn.
Với 300 hóa đơn một tháng là 300 lần gọi. Đây là chỗ mọi thứ trở nên phức tạp:
- Gọi tuần tự thì rất lâu
- Gọi song song nhiều luồng thì bị hệ thống giới hạn hoặc chặn
- Cần điều tiết tốc độ, và mức phù hợp khác nhau theo thời điểm trong ngày
5. Cần khả năng chạy lại phần đã lỗi#
Khi lần chạy thứ 200 lỗi giữa chừng, bạn cần chạy lại đúng 100 hóa đơn còn thiếu, không phải chạy lại từ đầu.
Nghĩa là phải có trạng thái lưu lại được: hóa đơn nào đã lấy chi tiết, hóa đơn nào chưa. Và phải phân biệt được "chưa lấy" với "đã lấy nhưng thực sự không có dòng hàng hóa nào" — hai trường hợp này rất dễ bị gộp thành một, và khi đã gộp thì hóa đơn đó không bao giờ được thử lại.
6. Trạng thái hóa đơn thay đổi theo thời gian#
Hóa đơn bạn tải tháng trước có thể đã bị hủy, thay thế hoặc điều chỉnh. Script chỉ ghi thêm dữ liệu mới sẽ giữ mãi trạng thái cũ.
Xử lý đúng: khi đồng bộ lại một kỳ, so trạng thái mới với trạng thái đã lưu, và lấy lại chi tiết của những hóa đơn đã đổi trạng thái. Xem thêm Hóa đơn bị hủy sau khi đã kê khai.
7. Chạy nền, không chạy trong request#
Đồng bộ một năm dữ liệu mất nhiều phút tới nhiều chục phút. Việc này phải chạy ở tiến trình nền có thể theo dõi được tiến độ, không thể chạy trong một request HTTP rồi chờ.
Ước lượng thực tế#
Bảng dưới là ước lượng theo kinh nghiệm, cho một người có nền tảng backend:
| Phần việc | Thời gian |
|---|---|
| Đăng nhập, lấy danh sách một tháng | 1 ngày |
| Xử lý token hết hạn, hai loại hóa đơn, hai cấu trúc file | 2–3 ngày |
| Lấy chi tiết dòng hàng hóa có điều tiết tốc độ và chạy lại được | 1–2 tuần |
| Theo dõi thay đổi trạng thái | 3–5 ngày |
| Chạy nền, theo dõi tiến độ, xử lý lỗi | 1 tuần |
Cộng lại là khoảng một tháng làm việc, cộng thêm bảo trì mỗi khi hệ thống của cơ quan thuế thay đổi.
Khi nào tự viết là hợp lý#
Tự viết hợp lý nếu bạn cần tích hợp sâu vào hệ thống nội bộ có sẵn, hoặc bạn có yêu cầu đặc thù mà không công cụ nào đáp ứng, và bạn có người duy trì nó lâu dài.
Không hợp lý nếu mục tiêu chỉ là có dữ liệu hóa đơn mỗi tháng. Khi đó bạn đang bỏ một tháng công sức cộng chi phí bảo trì vô hạn để giải một bài toán đã được giải.
eHoaDon xử lý toàn bộ các điểm ở trên. Bạn có thể xem cách tải hóa đơn mua vào từ cổng hóa đơn điện tử để so sánh với quy trình thủ công.
Căn cứ#
- Luật Quản lý thuế số 108/2025/QH15 (hiệu lực 01/7/2026, thay thế Luật 38/2019/QH14)
- Nghị định 254/2026/NĐ-CP (ban hành 30/6/2026, hiệu lực 01/7/2026) — thay thế Nghị định 123/2020/NĐ-CP và Nghị định 70/2025/NĐ-CP; Chương IV quy định cơ sở dữ liệu và cơ chế tra cứu thông tin hóa đơn điện tử
- Thông tư 91/2026/TT-BTC (hiệu lực 01/7/2026, thay thế Thông tư 32/2025/TT-BTC)
Quy định về thuế thay đổi thường xuyên — với quyết định có giá trị lớn, hãy đối chiếu lại văn bản đang hiệu lực tại thời điểm phát sinh.
Đừng tải hóa đơn thủ công nữa
eHoaDon đồng bộ hóa đơn mua vào từ Cục Thuế, lấy đầy đủ dòng hàng hóa và xuất Excel trong vài phút.
Dùng thử miễn phí