E-invoice phát hành thất bại

Bạn bấm "Phát hành hoá đơn điện tử" từ payment, nhưng provider (VNPT/MISA/Viettel) trả lỗi. Hệ thống tự động retry 3 lần. Nếu vẫn fail, status chuyển `FAILED` — kế toán cần can thiệp: sửa thông tin BN, đổi provider, hoặc skip hoá đơn. CI-07 đảm bảo payment & cash KHÔNG bị ảnh hưởng dù e-invoice fail.

Ảnh minh hoạ
Luồng xử lý e-invoice fail: phát → lỗi → retry scheduler → FAILED → operator can thiệp

Bối cảnh

Sau khi BN thanh toán, kế toán bấm "Phát hành hoá đơn" từ Payment detail. Hệ thống liên hệ provider VNPT (hoặc MISA/Viettel). Lỗi xảy ra có thể là:

  • Timeout — provider chậm, hệ thống retry sau 10 giây.
  • Thông tin BN thiếu hoặc sai — tên, địa chỉ, MST/CCCD/passport không hợp lệ → provider reject.
  • Hết hạn certificate — chứng chỉ ký của phòng khám hết hạn (hạn 1-2 năm).
  • Vượt quota — provider sandbox/live có giới hạn số hoá đơn/tháng.
  • Lỗi provider tạm thời — server provider down, sẽ ok sau vài phút.

Diễn viên & quyền cần

Vai tròQuyền cầnTác vụ
Kế toáneinvoice.readXem status e-invoice, lỗi chi tiết
Kế toán / Quản lýeinvoice.manageRetry, cancel, sửa thông tin BN, đổi provider
Quản lý phòng khámeinvoice.manageKiểm tra cấu hình provider, update chứng chỉ

Quy trình từng bước

  1. Kiểm tra status hoá đơn: mở Payment detail → scroll xuống panel "E-invoice" → xem status (PENDING / RETRY / FAILED / ISSUED).
  2. Nếu status = PENDING hoặc RETRY: đợi scheduler tự động retry. Refresh trang sau 30 giây. Nếu vẫn pending sau 3 lần retry (≈ 1-2 phút), hệ thống chuyển FAILED.
  3. Nếu status = FAILED: click "Xem lỗi chi tiết" → đọc error message từ provider:
    • Nếu viết "Invalid buyer information": sửa thông tin BN → qua bước 5.
    • Nếu viết "Certificate expired": liên hệ provider để update chứng chỉ → qua bước 6.
    • Nếu viết "Quota exceeded": phòng khám cần upgrade gói provider hoặc chờ reset quota tháng sau.
    • Nếu viết "Server error" hoặc "Timeout": chờ provider khôi phục rồi retry (bước 7).
  4. Sửa thông tin BN (nếu lỗi buyer): quay lại Patient 360 → tab "Thông tin", sửa tên / địa chỉ / MST / CCCD cho đúng theo hóa đơn → lưu.
  5. Cập nhật chứng chỉ (nếu lỗi cert): quản lý phòng khám mở Settings → E-invoice → chọn provider (VNPT) → upload chứng chỉ mới từ provider. Test connection để kiểm tra.
  6. Retry phát hành: quay lại Payment → E-invoice panel → click "Phát hành lại" (Retry) → hệ thống enqueue lại job → scheduler xử lý trong 10 giây.
  7. Nếu vẫn fail lần thứ 6+: skip hoá đơn hoặc đổi provider. Click "Đổi provider" → chọn provider khác (MISA/Viettel) → test connection → retry phát hành.
  8. Hoặc Skip hoá đơn: nếu phòng khám chọn không phát hoá đơn cho lần này, click "Skip" → status chuyển `SKIPPED` → payment vẫn được giữ, không ảnh hưởng cash.

Kết quả mong đợi

  • Nếu retry thành công: Status chuyển `ISSUED` → hoá đơn số được ghi lại (VD: HÓA ĐƠN: 2026-05-28-000001) → email gửi cho BN với PDF hoá đơn.
  • Nếu skip: Status chuyển `SKIPPED` → phiếu thu vẫn có, hoá đơn không phát.
  • Payment & Cash KHÔNG bị ảnh hưởng (CI-07): dù e-invoice fail hay skip, tiền BN thanh toán vẫn ghi nhận, outstanding vẫn được tính, cash balance vẫn đúng.
  • Doctor Earnings KHÔNG bị ảnh hưởng: earning chỉ phụ thuộc vào stage completion, không phụ thuộc e-invoice.
  • Phòng khám có thể phát lại hoá đơn sau bất cứ lúc nào (phía backend), nhưng cần khi payment còn `COMPLETED` (chưa cancel).

Khi nào hỏng & cách xử lý

Tình huốngDấu hiệuGiải pháp
Lỗi "Invalid buyer"Error message: "Thông tin người mua không hợp lệ"Sửa Patient 360 → thông tin BN (tên, địa chỉ, MST/CCCD) → retry.
Certificate hết hạnError: "Certificate expired" hoặc "Signature invalid"Quản lý vào Settings → E-invoice → upload cert mới từ provider → test → retry.
Hết quotaError: "Quota exceeded for this month"Liên hệ provider để nâng cấp gói. Hoặc skip hoá đơn, phát lại khi reset quota tháng sau.
Provider error (5xx)Error: "Server error" hoặc "Temporary failure"Chờ 5-10 phút cho provider khôi phục, rồi retry. Hoặc đổi sang provider khác.
Nút "Retry" bị disableButton grey outStatus không phải FAILED hoặc payment đã CANCELED. Hoặc thiếu quyền `einvoice.manage`.
Panel E-invoice không hiển thịKhông thấy E-invoice sectionKiểm tra: (1) payment đã COMPLETED, (2) e-invoice được enable ở Settings, (3) có provider config.

Dấu vết để lại (audit & branch ownership)

Khi phát hành hoặc retry e-invoice, DentIQ ghi lại:

  • EInvoiceIssueLog: ngày/giờ phát, provider, status (PENDING → RETRY → ISSUED/FAILED/SKIPPED), error message (nếu có).
  • EInvoiceAuditLog: người phát/retry/skip, thời gian, trạng thái cũ/mới, reason (nếu skip).
  • DocumentAuditLog: hoá đơn PDF được tải xuống / email → người, thời gian, quyền `einvoice.read` + `document.export` cần thiết.
  • Branch ownership (CI-01): e-invoice branch lấy từ payment branch (visit gốc), không phải active branch. Nếu user ở chi nhánh A phát hoá đơn của chi nhánh B, hệ thống vẫn ghi chi nhánh B.
  • Realtime event: phát `EINVOICE_STATUS_CHANGED` → client refresh payment detail, e-invoice list, dashboard invoice count.
Quan trọng (CI-07)

E-invoice là tài liệu pháp lý độc lập. Lỗi e-invoice KHÔNG ảnh hưởng payment, cash, revenue, hoặc doctor earning. Nếu phòng khám muốn thay đổi số tiền trên hoá đơn sau khi phát, phải lập hoá đơn điều chỉnh (cancel/adjust) từ provider — không thể sửa e-invoice lưu trữ.

Tip: Provider nào?

VNPT, MISA, Viettel là 3 provider phổ biến ở Việt Nam. Mỗi provider có endpoint, format request khác nhau. DentIQ hỗ trợ cả 3, cộng thêm Fake provider (cho test). Nếu một provider fail nhiều, thử đổi sang provider khác (có thể cùng account, khác provider).

Timeline retry tự động

Khi bấm "Phát hành" hoá đơn:

  • Lần 1 (ngay lập tức): status = PENDING → liên hệ provider.
  • Nếu fail: scheduler lên lịch retry sau ~10 giây, status = RETRY.
  • Lần 2 (sau ~10 giây): retry tự động.
  • Nếu fail lại: scheduler lên lịch lần 3, status = RETRY.
  • Lần 3 (sau ~20 giây tính từ lần 1): retry cuối cùng.
  • Nếu fail lần 3: status = FAILED → operator can thiệp (retry manual, skip, hoặc đổi provider).

Operator có thể bấm "Retry" bất cứ lúc nào khi status = FAILED (không cần chờ).