Skip to content

ADR-0002. Ghi sổ theo sự kiện; ghi nhận finance tại lúc thanh toán, không phải lúc checkout

FieldValue
StatusAccepted
Date2026-04-28
DecidersPhat Nguyen
Supersedes-

Bối cảnh

  • Finance không được nằm trên luồng quan trọng của quy trình checkout POS - một sự cố của finance không được phép chặn việc thu tiền.
  • Doanh thu chỉ có thật khi tiền thực sự về tài khoản. Ghi nhận tại lúc checkout (trước khi thanh toán) sẽ ghi nhận doanh thu cho cả những đơn về sau bị bỏ dở hoặc thanh toán thất bại.
  • Giá trị giá vốn (COGS) và tài sản tồn kho thuộc quyền của @nx/inventory, vốn chỉ biết được giá vốn sau khi xuất kho - finance không thể tự tính.
  • Tài khoản/danh mục thanh toán được chọn là một quyết định tại thời điểm phục vụ khách hàng, đi kèm trong payload thanh toán của sale (payment.attempt.finance), không biết được tại lúc checkout.

Quyết định

Chúng tôi sẽ để finance phản ứng theo Kafka event, không bao giờ gọi nó đồng bộ từ luồng checkout. Finance lắng nghe năm topic và ghi sổ các phiếu như một tác động phụ:

Sự kiện đầu vàoPhiếu
PAYMENT_SUCCESS (sale)RECEIPT trên tài khoản tại attempt.finance.source.id
PURCHASE_ORDER_RECEIVED (inventory)PAYMENT cho nhà cung cấp (+ vế tài sản tồn kho)
INVENTORY_ISSUED_FOR_SALE (inventory)ADJUSTMENT - DEBIT COGS / CREDIT INVENTORY
INVENTORY_ADJUSTED (inventory)ADJUSTMENT một dòng trên INVENTORY
MERCHANT CDC (commerce)đối soát tài khoản mặc định + tài khoản kiểm soát

Doanh thu được ghi nhận khi có PAYMENT_SUCCESS, không phải tại lúc checkout. Nếu payload thanh toán không mang theo tài khoản được chọn (attempt.finance.source.id), finance ghi log INFO rồi bỏ qua thay vì đoán.

Hệ quả

ƯuNhược
Sự cố finance không bao giờ chặn checkoutViệc ghi sổ là nhất quán cuối cùng, không đồng bộ
Doanh thu phản ánh tiền đã về tài khoản, không phải ý địnhCần idempotent cho cơ chế gửi ít nhất một lần (xem ADR-0003)
Ghi sổ giá vốn/tài sản dùng đúng giá vốn chính thống từ inventoryFinance phụ thuộc vào tính đầy đủ của payload từ thượng nguồn (account id)
Tách bạch rõ trách nhiệm giữa các serviceViệc gỡ lỗi trải qua nhiều service + broker

Các phương án đã cân nhắc

Phương ánƯuNhượcLý do loại bỏ
Gọi HTTP đồng bộ từ luồng checkout của saleĐơn giản, tức thìBuộc độ trễ/khả dụng của checkout phụ thuộc financeVi phạm nguyên tắc "finance nằm ngoài luồng quan trọng"
Ghi nhận tại lúc checkout (theo ý định)Tín hiệu sớm nhấtGhi nhận doanh thu cho cả đơn chưa trả/bỏ dởHạch toán sai
Finance tự tính giá vốnÍt event hơnFinance sẽ lặp lại logic tính giá vốn của inventoryGiá vốn thuộc phạm vi của inventory

Tham chiếu

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.