Kiểm soát đối soát
Bạn sẽ học được
- Ba nguồn cần đối soát: cổng thanh toán, ngân hàng, sổ cái.
- Phân loại chênh lệch: phí, hoàn tiền, thời điểm, lỗi thật.
- Viết truy vấn đối soát bằng
FULL OUTER JOIN. - Thiết kế sổ theo dõi ngoại lệ.
- Xây thói quen đối soát hằng ngày thay vì cuối tháng.
Khái niệm cốt lõi
Đối soát là quá trình chứng minh ba nguồn số liệu khớp nhau:
Cổng thanh toán (gross, phí, hoàn tiền)
↓
Sao kê ngân hàng (tiền thực vào)
↓
Sổ cái / kho dữ liệu (doanh thu, phải thu)Ba nguồn luôn lệch nhau ở một mức nào đó. Mục tiêu không phải "không có chênh lệch" mà là mọi chênh lệch đều được giải thích và ghi lại.
Ví dụ một ngày
| Khoản | Số tiền (triệu đồng) |
|---|---|
| Giao dịch gộp trên cổng | 1.000 |
| Phí cổng 2,5% | −25 |
| Hoàn tiền | −30 |
| Cổng chuyển về ngân hàng | 945 |
| Sao kê ngân hàng | 945 |
| Chênh lệch | 0 |
Nếu chỉ so "doanh thu 1.000" với "tiền vào 945", sẽ tưởng thiếu 55 triệu. Thực ra 25 triệu là phí và 30 triệu là hoàn tiền — cả hai đều hợp lệ.
Phân loại chênh lệch
| Loại | Ví dụ | Xử lý |
|---|---|---|
| Phí cổng | 2,5% mỗi giao dịch | Ghi nhận chi phí, không phải thiếu tiền |
| Hoàn tiền | Khách trả lại hàng | Giảm doanh thu, giảm tiền |
| Thời điểm | Cổng chuyển tiền T+1 | Chênh lệch tạm thời, tự khớp hôm sau |
| Tiền tệ | Thanh toán USD, hạch toán VND | Dùng tỷ giá ngày giao dịch |
| Lỗi thật | Giao dịch mất, ghi trùng | Điều tra, điều chỉnh |
| Gian lận | Chargeback | Tranh chấp, dự phòng |
Chỉ hai loại cuối cần hành động ngay. Bốn loại đầu là bình thường và phải được mô hình hoá, không phải "sửa" bằng tay mỗi tháng.
Truy vấn đối soát
WITH cong AS (
SELECT
gateway_txn_id AS ma,
SUM(amount) AS gross,
SUM(fee) AS phi,
SUM(refund_amount) AS hoan
FROM gateway_transactions
WHERE settled_date = CURRENT_DATE - 1
GROUP BY 1
),
ngan_hang AS (
SELECT
reference AS ma,
SUM(amount) AS tien_vao
FROM bank_statement
WHERE value_date = CURRENT_DATE - 1
GROUP BY 1
)
SELECT
COALESCE(c.ma, n.ma) AS ma,
c.gross,
c.phi,
c.hoan,
COALESCE(c.gross, 0) - COALESCE(c.phi, 0) - COALESCE(c.hoan, 0) AS du_kien,
n.tien_vao,
COALESCE(n.tien_vao, 0)
- (COALESCE(c.gross, 0) - COALESCE(c.phi, 0) - COALESCE(c.hoan, 0)) AS chenh_lech
FROM cong c
FULL OUTER JOIN ngan_hang n USING (ma)
WHERE COALESCE(n.tien_vao, 0)
- (COALESCE(c.gross, 0) - COALESCE(c.phi, 0) - COALESCE(c.hoan, 0)) <> 0
ORDER BY ABS(chenh_lech) DESC;Truy vấn chỉ trả về các dòng lệch — đó là danh sách việc cần làm. FULL OUTER JOIN bắt được cả hai chiều: giao dịch có trên cổng nhưng chưa về ngân hàng, và tiền về ngân hàng nhưng không có giao dịch tương ứng.
Đối soát với sổ cái
Bước thứ ba: sổ cái ghi doanh thu và phải thu. Đối soát ba chiều:
SELECT
(SELECT SUM(amount) FROM payments WHERE paid_at::date = CURRENT_DATE - 1) AS tien_thu_so_cai,
(SELECT SUM(tien_vao) FROM bank_statement WHERE value_date = CURRENT_DATE - 1) AS tien_vao_ngan_hang,
(SELECT SUM(gross - phi - hoan) FROM gateway_transactions WHERE settled_date = CURRENT_DATE - 1) AS du_kien_cong;Ba con số phải bằng nhau, trừ chênh lệch thời điểm đã biết. Nếu không, tìm nguồn nào sai trước khi điều chỉnh bất kỳ bên nào.
Nguyên tắc: không sửa số liệu để khớp. Nếu lệch, tìm nguyên nhân; chỉ điều chỉnh khi đã hiểu vì sao.
Sổ ngoại lệ
Mỗi chênh lệch chưa giải thích cần một dòng trong sổ ngoại lệ:
CREATE TABLE reconciliation_exceptions (
id bigserial PRIMARY KEY,
ngay date NOT NULL,
ma_giao_dich text,
so_tien numeric(14,2) NOT NULL,
loai text NOT NULL, -- 'phi' | 'hoan' | 'thoi_diem' | 'loi' | 'chargeback'
mo_ta text NOT NULL,
trang_thai text NOT NULL DEFAULT 'mo', -- 'mo' | 'da_xu_ly'
nguoi_xu_ly text,
xu_ly_luc timestamptz
);Mỗi tuần xem sổ này. Ngoại lệ tồn đọng quá 30 ngày là dấu hiệu quy trình đang hỏng, không phải "chuyện nhỏ".
Tần suất và dung sai
- Hằng ngày: đối soát cổng ↔ ngân hàng cho ngày hôm trước. Chênh lệch nhỏ dễ tìm hơn nhiều.
- Hằng tuần: đối soát sổ cái, xem ngoại lệ tồn đọng.
- Cuối tháng: khoá sổ, đối chiếu tổng với báo cáo tài chính.
Dung sai: với khối lượng lớn, cho phép sai số do làm tròn (ví dụ 1.000 đồng mỗi giao dịch). Nhưng dung sai phải được định nghĩa trước, không phải "thấy lệch nhỏ thì bỏ qua".
Lỗi thường gặp
- Đối soát mỗi tháng: hàng nghìn giao dịch, không tìm được nguyên nhân.
- So tổng doanh thu với tiền vào ngân hàng: bỏ phí và hoàn tiền, luôn thấy thiếu.
- Dùng
INNER JOIN: bỏ mất giao dịch chỉ có ở một bên — chính là các trường hợp cần tìm. - Điều chỉnh số liệu cho khớp: che mất lỗi thật.
- Bỏ qua T+1: chênh lệch thời điểm bị coi là lỗi.
- Không ghi ngoại lệ: cùng một vấn đề lặp lại mỗi tháng.
- Bỏ qua chargeback: mất tiền thật nhưng không được ghi nhận.
Thực hành
- Tính số tiền cổng phải chuyển về với gross 1.000, phí 2,5%, hoàn 30.
- Viết truy vấn
FULL OUTER JOINchỉ trả các dòng lệch. - Phân loại năm chênh lệch giả định vào bảng loại.
- Thiết kế cột cho sổ ngoại lệ.
- Viết quy trình xử lý một chargeback.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
| Ngân hàng thiếu so với doanh thu | Phí và hoàn tiền | Tính tiền ròng dự kiến |
| Lệch đúng một ngày | T+1 | Đối soát theo ngày quyết toán |
| Giao dịch mất tích | INNER JOIN | Dùng FULL OUTER JOIN |
| Chênh lệch lặp lại | Không ghi ngoại lệ | Sổ ngoại lệ, xử lý gốc |
| Số liệu bị sửa tay | Điều chỉnh để khớp | Tìm nguyên nhân trước |
| Cuối tháng mới phát hiện | Đối soát tháng | Chuyển sang hằng ngày |
Tóm tắt
- Ba nguồn: cổng, ngân hàng, sổ cái — phải khớp sau khi trừ phí và hoàn tiền.
- Phân loại chênh lệch trước khi xử lý.
FULL OUTER JOINlà công cụ đúng để tìm giao dịch lệch một bên.- Mọi chênh lệch chưa giải thích vào sổ ngoại lệ.
- Đối soát hằng ngày rẻ hơn nhiều so với đối soát cuối tháng.
Dùng ← → để chuyển bài