Bỏ qua để đến nội dung
Beta · Đặc tả có thể còn thay đổi trước khi ra mắt chính thức. Tên miền API api.hensa.example là tạm thời. Xem thay đổi →

Đối soát

Mỗi giao dịch tiền vào có một trạng thái đối soát reconciliation:

Giá trị Nghĩa
matched Đã gắn với một yêu cầu thanh toán hoặc một mã đơn
pending Cần người xử lý – thường do khách ghi sai nội dung
unmatched Đã xác nhận không phải đơn (vd. tiền cá nhân, hoàn ứng)

Hensa tìm referenceCode (vd. LK7F3K9) trong nội dung chuyển khoản. Tìm thấy và đúng số tiền → matched và phát payment_request.paid. Không cần làm gì thêm.

Khi một giao dịch ở pending, gắn nó với đơn đúng bằng một trong ba cách:

# 1. Với một yêu cầu thanh toán của Hensa
curl -X POST https://api.hensa.example/v1/bank_transactions/btx_…/reconcile \
-H "Authorization: Bearer $HENSA_API_KEY" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" -d '{ "paymentRequestId": "prq_…" }'
# 2. Với mã đơn trong hệ thống của bạn
-d '{ "orderRef": "DH-1024" }'
# 3. Đánh dấu không phải đơn
-d '{ "notAnOrder": true }'

Nhân viên cửa hàng cũng làm được việc này trong Dashboard › Giao dịch › Cần khớp – kết quả như nhau.

Webhook là đường chính, nhưng mạng và máy chủ đều có lúc lỗi. Hãy chạy một tác vụ định kỳ (vd. 15 phút/lần) lấy giao dịch mới và đối chiếu với đơn của bạn:

let cursor = null
do {
const url = new URL('https://api.hensa.example/v1/bank_transactions')
url.searchParams.set('limit', '100')
if (cursor) url.searchParams.set('cursor', cursor)
const page = await (await fetch(url, { headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}` } })).json()
for (const tx of page.data) handle(tx)
cursor = page.nextCursor
} while (cursor)

Giao dịch nào bạn chưa ghi nhận → xử lý như vừa nhận webhook. Vì xử lý là chống trùng, chạy lại bao nhiêu lần cũng an toàn.