PRD: Vòng đời & phát hành hóa đơn
| Module | Thuế & Hóa đơn (CORE-10) | PRD ID | PRD-INV-001 |
| Status | Shipped | Owner | Nhóm Thuế & Hóa đơn |
| Date | 2026-04-13 | Version | v1.0 |
| Packages | @nx/invoice · @nx/taxation · @nx/iiapi · @nx/t-van | URD | INV · REQ · MOD |
TL;DR
Biến một thanh toán đã hoàn tất thành hóa đơn điện tử hợp pháp của Việt Nam - tự động đưa vào queue và phát hành qua một nhà cung cấp được ủy quyền, theo dõi qua suốt vòng đời kèm thử lại, nộp lên cơ quan thuế, và ghi vào một dấu vết kiểm toán không thể thay đổi. Với chủ doanh nghiệp và thu ngân, điều này có nghĩa là mỗi đơn đã thanh toán đều có thể trở thành một hóa đơn có số, tuân thủ; với người mua, đó là khả năng tự yêu cầu hóa đơn của mình từ QR trên hóa đơn bán hàng. Kết quả: một đơn đã thanh toán không còn dở dang về mặt pháp lý - nó kết thúc bằng một hóa đơn đã phát hành với khả năng truy vết đầy đủ.
1. Bối cảnh & Vấn đề
Một thanh toán đã hoàn tất chưa hoàn chỉnh về mặt pháp lý tại Việt Nam cho tới khi một hóa đơn điện tử có số được phát hành qua một nhà cung cấp hóa đơn điện tử được ủy quyền và (khi cần) được nộp lên cơ quan thuế. Module đã ghi nhận định danh thuế người bán, các nhóm thuế, và cấu hình hóa đơn, nhưng chưa có lối đi từ một đơn đã thanh toán đến một hóa đơn đã phát hành - chưa có engine nào tiêu thụ payment-success, điều khiển phát hành, theo dõi trạng thái, thử lại khi lỗi, hay giữ một dấu vết kiểm toán.
Bước tăng này dựng nên engine phát hành trên nền cấu hình đó: một package @nx/invoice biến payment-success thành một lần phát hành đưa vào queue, phát hành qua nhà cung cấp, theo dõi hóa đơn qua suốt vòng đời, và ghi mọi sự kiện một cách không thể thay đổi. Đường đi qua nhà cung cấp chạy qua iiapi (VNPAY / VNIS) như gateway phát hành duy nhất, kèm thu thập thông tin người mua và một luồng tự yêu cầu để hóa đơn có thể được yêu cầu tại quầy hoặc được người mua tự nhận.
2. Mục tiêu & Ngoài phạm vi
Mục tiêu
- Tự động đưa một hóa đơn vào queue để phát hành khi thanh toán thành công, phát hành nó qua nhà cung cấp, và ghi nhận số hóa đơn cùng mã cơ quan thuế.
- Theo dõi hóa đơn qua
pending → processing → success / failed / cancelledvới một policy thử lại đã cấu hình khi gặp lỗi. - Nộp các hóa đơn đã phát hành lên cơ quan thuế (CQT qua T-VAN) khi được bật và theo dõi trạng thái đã nộp.
- Ghi một mục dấu vết kiểm toán không thể thay đổi cho mọi sự kiện hóa đơn.
- Hỗ trợ điều chỉnh, thay thế, và hủy (kèm lý do) đối với một hóa đơn đã phát hành.
- Thu thập thông tin người mua (tên, mã số thuế, địa chỉ, email) và hỗ trợ người mua tự yêu cầu hóa đơn qua QR trên hóa đơn bán hàng với một token yêu cầu và hạn chót.
- Hỗ trợ bốn chế độ phát hành: thời gian thực khi thanh toán, thủ công tại quầy, theo lô có lịch, và người mua tự yêu cầu.
Ngoài phạm vi
- Nhiều nhà cung cấp hóa đơn ngoài bộ iiapi / T-VAN hiện tại.
- Kết xuất PDF của hóa đơn - do phía nhà cung cấp tạo, không nằm trong repository.
- Tính thuế suất tại thời điểm bán - thuộc về pricing engine.
- Tự động kê khai / nộp tờ khai thuế.
- Định danh thuế người bán, nhóm thuế, và cấu hình hóa đơn - thuộc Định danh thuế & nhóm thuế và tính năng cấu hình hóa đơn.
3. Success Metrics
| Metric | Mục tiêu / tín hiệu |
|---|---|
| Độ phủ phát hành | 100% các đơn đã thanh toán đủ điều kiện đưa một hóa đơn vào queue khi payment-success |
| Tỷ lệ phát hành thành công | Đã phát hành / đã đưa vào queue có xu hướng tăng; lỗi được thử lại theo policy trước khi thất bại cuối cùng |
| Tỷ lệ cơ quan thuế chấp nhận | Hóa đơn đã nộp được CQT chấp nhận (nơi đã bật nộp) |
| Tính đầy đủ của kiểm toán | Mọi thay đổi trạng thái đều có một mục dấu vết kiểm toán tương ứng không thể thay đổi; không có lỗ hổng |
| Chuyển đổi yêu cầu | Số lần người mua tự yêu cầu hoàn tất trước hạn chót so với số liên kết đã phát |
4. Personas & Use Cases
| Persona | Mục tiêu trong tính năng này |
|---|---|
| Owner | Đảm bảo mỗi giao dịch bán đều tạo ra một hóa đơn tuân thủ; điều chỉnh / thay thế / hủy khi cần |
| Thu ngân | Thu thập thông tin người mua và phát hành hóa đơn tại quầy |
| Người mua | Tự yêu cầu hóa đơn của mình từ QR trên hóa đơn bán hàng |
| Kế toán (hạ nguồn) | Dựa vào hóa đơn đã phát hành + dấu vết kiểm toán để báo cáo thuế |
Core scenarios: một thanh toán thành công → một hóa đơn được đưa vào queue và phát hành qua nhà cung cấp → số và mã cơ quan thuế của nó được ghi nhận → nó được nộp lên CQT và theo dõi → mọi sự kiện được ghi lại; hoặc thu ngân phát hành thủ công kèm thông tin người mua, hoặc người mua tự yêu cầu qua QR trên hóa đơn bán hàng trước một hạn chót.
5. User Stories
- Là owner, tôi muốn một hóa đơn được phát hành tự động khi thanh toán thành công, để mỗi giao dịch bán trở nên tuân thủ pháp luật mà không cần thao tác thủ công.
- Là owner, tôi muốn các lần phát hành thất bại được thử lại theo một policy đã cấu hình, để các lỗi tạm thời của nhà cung cấp không làm mất hóa đơn.
- Là owner, tôi muốn các hóa đơn đã phát hành được nộp lên cơ quan thuế và theo dõi, để tôi đáp ứng nghĩa vụ với CQT.
- Là owner, tôi muốn điều chỉnh, thay thế, hoặc hủy một hóa đơn đã phát hành kèm lý do, để tôi có thể sửa sai một cách hợp pháp.
- Là thu ngân, tôi muốn thu thập thông tin người mua và phát hành hóa đơn tại quầy, để người mua khi yêu cầu sẽ nhận được hóa đơn ngay tại chỗ.
- Là người mua, tôi muốn quét QR trên hóa đơn bán hàng và gửi thông tin của mình trước một hạn chót, để tôi có thể tự nhận hóa đơn.
- Là owner, tôi muốn mọi sự kiện hóa đơn nằm trong một dấu vết kiểm toán không thể thay đổi, để lịch sử hóa đơn có thể kiểm chứng được.
6. Functional Requirements
| # | Yêu cầu | URD ref |
|---|---|---|
| FR-1 | Tự động đưa một hóa đơn vào queue để phát hành khi thanh toán thành công | URD-INV-001 |
| FR-2 | Phát hành hóa đơn qua nhà cung cấp và ghi nhận số + mã cơ quan thuế của nó | URD-INV-002 |
| FR-3 | Theo dõi trạng thái hóa đơn pending → processing → success / failed / cancelled | URD-INV-003 |
| FR-4 | Thử lại một lần phát hành thất bại theo policy thử lại đã cấu hình | URD-INV-004 |
| FR-5 | Nộp hóa đơn đã phát hành lên cơ quan thuế (CQT qua T-VAN) khi được bật, và theo dõi trạng thái của nó | URD-INV-005 |
| FR-6 | Ghi một mục dấu vết kiểm toán không thể thay đổi cho mọi sự kiện hóa đơn | URD-INV-006 |
| FR-7 | Điều chỉnh một hóa đơn đã phát hành (bản sửa liên kết với bản gốc); thay thế hoặc hủy kèm lý do | URD-INV-007..008 |
| FR-8 | Xử lý webhook đến từ nhà cung cấp kèm xác thực chữ ký để cập nhật trạng thái | URD-INV-009 |
| FR-9 | Thu thập thông tin người mua (tên, mã số thuế, địa chỉ, email); thu ngân phát hành trực tiếp tại quầy | URD-REQ-001..002 |
| FR-10 | Người mua tự yêu cầu qua QR trên hóa đơn bán hàng với token yêu cầu + hạn chót; vòng đời yêu cầu pending → claimed / expired | URD-REQ-003..004 |
| FR-11 | Gửi hóa đơn / liên kết yêu cầu qua QR trên hóa đơn bán hàng, email, hoặc SMS | URD-REQ-005 |
| FR-12 | Hỗ trợ bốn chế độ phát hành: thời gian thực, thủ công, theo lô có lịch, người mua tự yêu cầu | URD-MOD-001..004 |
Toàn bộ nội dung yêu cầu và tiêu chí chấp nhận nằm trong URD Thuế & Hóa đơn. PRD này tham chiếu chúng thay vì nhắc lại.
7. Non-Functional Requirements
| Lĩnh vực | Yêu cầu |
|---|---|
| Toàn vẹn dữ liệu | Số hóa đơn + mã cơ quan thuế chỉ được ghi khi phát hành đã được xác nhận; các chuyển trạng thái nhất quán với dấu vết kiểm toán |
| Bất biến | Dấu vết kiểm toán chỉ ghi thêm; sửa chữa qua các mục điều chỉnh/thay thế, không bao giờ chỉnh sửa trực tiếp |
| Phạm vi & phân quyền | Mọi thao tác giới hạn theo merchant (x-merchant-id); phát hành/cấu hình kiểm soát bằng permission hóa đơn; credentials nhà cung cấp giới hạn cho owner |
| Độ tin cậy | Phát hành chạy qua một queue (Kafka + BullMQ) với xử lý idempotent và thử lại; webhook xác thực chữ ký |
| Bảo mật | Credentials nhà cung cấp lưu mã hóa; token yêu cầu là duy nhất và gắn với một invoice request duy nhất |
| i18n | Nhãn/trạng thái hiển thị cho người dùng là song ngữ ({ en, vi }) |
8. UX & Flows
Các màn hình chính: cấu hình hóa đơn / wizard onboarding, danh sách và chi tiết hóa đơn, phát hành thủ công / theo lô, và trang người mua tự yêu cầu truy cập từ QR trên hóa đơn bán hàng (dựa trên @nx/invoice; webhook nhà cung cấp cập nhật trạng thái một cách bất đồng bộ).
9. Data & Domain
| Entity | Vai trò |
|---|---|
Invoice | Hóa đơn đã phát hành - trạng thái, số, mã cơ quan thuế, liên kết tới đơn và thông tin người mua |
InvoiceRequest | Thu thập thông tin người mua + token yêu cầu/hạn chót, sinh ra một hóa đơn |
InvoiceAuditTracing | Dấu vết theo sự kiện không thể thay đổi của mọi thay đổi trạng thái hóa đơn |
MerchantInvoiceProfile / InvoiceProvider / InvoiceProviderConfig | Thiết lập hóa đơn của merchant, credentials nhà cung cấp, dải số + policy thử lại |
InvoiceConfigMapping | Định tuyến một kênh bán tới config nhà cung cấp sẽ phát hành hóa đơn cho kênh đó |
Chỉ ở mức khái niệm - schema đầy đủ và các bất biến nằm trong domain model invoice và domain model taxation.
10. Dependencies & Assumptions
Phụ thuộc vào
- Cấu hình hóa đơn (URD-CFG) - phải tồn tại một hồ sơ hóa đơn, nhà cung cấp đã kết nối, dải số, và định tuyến.
- Định danh thuế người bán (URD-TAX) - người bán (MST, tên, địa chỉ) in trên mỗi hóa đơn.
- Payment (
payment.success) - một thanh toán thành công là thứ kích hoạt phát hành tự động. - Orders - đơn bán cung cấp các dòng hàng và tổng để điền vào hóa đơn.
- Gateway nhà cung cấp (
@nx/iiapi,@nx/t-van) - kết nối phát hành và cơ quan thuế.
Giả định
- Merchant có một hồ sơ hóa đơn đang hoạt động với nhà cung cấp đã kết nối và một kênh đã định tuyến.
- Một policy thử lại và (nơi cần) việc nộp lên cơ quan thuế đã được cấu hình.
- Thông tin thuế người mua sẵn có tại thời điểm phát hành (thu tại quầy hoặc qua yêu cầu) khi cần hóa đơn VAT.
11. Risks & Open Questions
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Nhà cung cấp gián đoạn / lỗi tạm thời | Phát hành đưa vào queue kèm thử lại đã cấu hình; thất bại cuối cùng được ghi vào dấu vết kiểm toán |
| Phát hành trùng lặp khi sự kiện bị phát lại | Xử lý queue idempotent theo khóa của mỗi đơn/yêu cầu |
| Giả mạo webhook | Webhook đến từ nhà cung cấp được xác thực bằng chữ ký trước khi cập nhật trạng thái |
| Đảo ngược một hóa đơn đã phát hành | Điều chỉnh / thay thế / hủy đều mang lý do và liên kết tới bản gốc; không có gì bị xóa cứng |
| Bộ nhà cung cấp đơn lẻ (iiapi / T-VAN) | Chấp nhận cho bước tăng này; thêm nhà cung cấp là một phase sau |
12. Release Plan & Launch Criteria
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P1 (nền tảng) - xem danh mục tính năng URD |
| Rollout | Tất cả merchant có một hồ sơ hóa đơn đang hoạt động; kiểm soát bởi cấu hình hóa đơn |
| Migration | Không (entity mới; cấu hình hóa đơn và credentials nhà cung cấp thiết lập qua onboarding) |
| Tiêu chí ra mắt | payment-success → đưa vào queue → phát hành → ghi nhận số + mã cơ quan thuế, kiểm chứng đầu-cuối; thử lại khi lỗi đã kiểm chứng; nộp CQT có theo dõi; một mục dấu vết kiểm toán cho mỗi sự kiện; người mua tự yêu cầu đã kiểm chứng |
| Giám sát | Tỷ lệ phát hành thành công/thất bại, số lần thử lại, tỷ lệ CQT chấp nhận, độ trễ queue, lỗi webhook, chuyển đổi yêu cầu |
13. FAQ
Khi nào hóa đơn được phát hành? Mặc định là thời gian thực khi payment.success. Nó cũng có thể được phát hành thủ công bởi thu ngân, theo một lô có lịch, hoặc bởi người mua tự yêu cầu qua QR.
Điều gì xảy ra nếu nhà cung cấp từ chối phát hành? Hóa đơn được thử lại theo policy đã cấu hình; khi đã hết số lần thử lại, trạng thái là failed và lỗi được ghi vào dấu vết kiểm toán.
Một hóa đơn đã phát hành có thể bị thay đổi không? Không tại chỗ - nó có thể được điều chỉnh (một bản sửa liên kết với bản gốc), thay thế, hoặc hủy kèm lý do. Dấu vết kiểm toán vẫn không thể thay đổi.
Ai kết xuất PDF? Nhà cung cấp, không phải app. Việc kết xuất ở phía nhà cung cấp.
Người mua tự nhận hóa đơn của mình như thế nào? Họ quét QR trên hóa đơn bán hàng, mở liên kết yêu cầu trước hạn chót, và gửi thông tin người mua của mình; hóa đơn sau đó được phát hành với các chi tiết đó. Sau hạn chót, yêu cầu hết hạn.
Tính năng này có tính thuế suất không? Không - tính thuế suất tại thời điểm bán thuộc về pricing engine; bước tăng này phát hành hóa đơn từ dữ liệu đơn mà nó nhận được.
References
- URD: Thuế & Hóa đơn - Invoice Lifecycle · Invoice Request & Buyer Claim · Issuance Modes
- Phụ thuộc vào: Invoice Configuration · Tax Identity
- PRD liên quan: Định danh thuế & nhóm thuế · Tích hợp nhà cung cấp hóa đơn điện tử
- Module: Thuế & Hóa đơn - tổng quan + truy vết
- Developer: @nx/invoice · @nx/taxation · iiapi · t-van