Chuyển tới nội dung chính

Tổng quan

Tài liệu mô tả tích hợp giữa Baokim và CashPlus cho 2 nghiệp vụ:

  • Thu hộ: khách hàng chuyển tiền vào tài khoản ảo, Baokim thông báo giao dịch cho CashPlus.
  • Chia sẻ tiền: CashPlus đăng ký số tiền chia cho User, Merchant và CashPlus, sau đó gọi chi tiền cho từng người nhận. Baokim không tự chi tiền khi chưa có lệnh chi.

Môi trường​

Môi trường{env}{BASE_URL}
Test (sandbox)sanboxBaokim cung cấp khi bắt đầu tích hợp
ProductionliveBaokim cung cấp khi go-live

Phiên bản API chia sẻ tiền​

Luồng trong tài liệu này dùng /transaction/v2/*. API /transaction/v1/share-amount cũ (đăng ký xong Baokim tự chi) chạy song song trong giai đoạn chuyển và sẽ ngừng theo lịch Baokim thông báo trước.

  • Giao dịch đăng ký qua phiên bản nào thì xử lý theo phiên bản đó đến hết. Không dùng lẫn v1 và v2 cho cùng một giao dịch (mã 143).
  • Sau ngày ngừng v1, mọi API v1 trả 143.

{env} chỉ có trong URL nhóm API thu hộ (/collection/{env}/...). Các nhóm /transaction/... và /ats/... không có {env}, môi trường được phân biệt bằng {BASE_URL}.

Khóa công khai để verify chữ ký, domain ảnh mã QR ({QR_DOMAIN}), URL webhook thu hộ và URL webhook kết quả chi của CashPlus được trao đổi cùng thời điểm cho từng môi trường.

Thuật ngữ​

Thuật ngữÝ nghĩa
TransactionId / TransIdBkMã giao dịch thu hộ do Baokim sinh. Cùng một giá trị: TransIdBk trong webhook thu hộ, TransactionId trong các API chia sẻ tiền
NSố tiền khả dụng để chia của giao dịch thu hộ: TransAmount − TransFeeAmount. Nếu giao dịch được miễn phí thu hộ thì TransFeeAmount = 0 và N = TransAmount
U, M, PSố tiền chia cho User, Merchant và CashPlus, đăng ký một lần ở Đăng ký số tiền chia sẻ
ReceiverNgười nhận: 1 = User, 2 = Merchant, 3 = CashPlus
TypeHình thức chi: 1 = realtime, 2 = T+1
ReferenceIdMã lệnh chi do CashPlus sinh, duy nhất. Dùng để chống tạo lệnh trùng. (Trong response của webhook thu hộ, ReferenceId là mã giao dịch phía CashPlus — khác nghĩa)
TransIdPaymentMã lệnh chi do Baokim sinh. Không đổi trong suốt vòng đời lệnh
Lệnh hiệu lựcLệnh chi đang ở Status 0, 99 hoặc 200
Ngày TNgày Baokim nhận tiền của giao dịch thu hộ, giờ Việt Nam (GMT+7)
Cutoff23:50:59 ngày T, theo giờ hệ thống Baokim lúc nhận request
T+1Kỳ quyết toán của ngày T: ngày làm việc kế tiếp (giao dịch thứ Sáu, thứ Bảy, Chủ nhật quyết toán vào thứ Hai)
SourceNguồn lệnh: PARTNER = CashPlus gọi, AUTO = Baokim tự tạo sau cutoff (00:05 ngày T+1), MANUAL = Baokim chi tay

Luồng tích hợp​

BướcAPIGhi chú
1Webhook thu hộIsFull=0 khi chưa có tài khoản người trả, IsFull=1 khi đã có
2Đăng ký số tiền chia sẻ1 lần / TransactionId, trước cutoff. Chỉ ghi nhận số chia, không chuyển tiền
3, 4, 5Lệnh chiMỗi request một lệnh cho một người nhận, Amount bằng đúng số đã đăng ký. Các người nhận không chặn nhau
6Webhook kết quả chiKhi lệnh có kết quả cuối
*Tra cứu lệnh chiTheo ReferenceId (một lệnh) hoặc TransactionId (mọi lệnh của giao dịch)

Quy tắc chia và chi​

Đăng ký:

  • Mỗi giao dịch thu hộ đăng ký 1 lần, không sửa. U + M + P ≤ N.
  • Phần dư N − U − M − P không gọi chi được và được quyết toán về Merchant tại cutoff.

Lệnh chi:

  • Amount của lệnh phải bằng đúng số đã đăng ký cho người nhận đó.
  • Mỗi người nhận chỉ có 1 lệnh hiệu lực: chỉ gọi được khi người nhận chưa có lệnh ở Status 0, 99 hoặc 200.
  • Lệnh thất bại (Status=11) được gọi lại bằng lệnh mới (ReferenceId mới) trước cutoff, trừ khi Retryable=false.
  • Lệnh của người nhận này không chặn lệnh của người nhận khác. Ví dụ lệnh Merchant đang 99 thì CashPlus vẫn gọi chi User và CashPlus được.
ReceiverType hợp lệPhí chi
1 (User)Luôn 1 (realtime)Theo biểu phí realtime
2 (Merchant)Đúng Merchant.Type đã đăng kýRealtime: theo biểu phí, được miễn theo chính sách miễn phí. T+1: miễn phí
3 (CashPlus)Luôn 2 (T+1)Miễn phí

Cutoff 23:50:59 ngày T​

Từ 23:50:59 ngày T, Baokim không nhận đăng ký số tiền chia sẻ và lệnh chi mới cho các giao dịch thu hộ của ngày T (mã 141). Gọi lại một ReferenceId đã có và tra cứu vẫn dùng được.

Lúc 00:05 ngày T+1, Baokim tự tạo 1 lệnh T+1 về Merchant (Source = AUTO, không có ReferenceId, miễn phí) cho mỗi giao dịch thu hộ của ngày T, kể cả giao dịch nhận tiền sau cutoff, với số tiền:

Lệnh AUTO = N − Tổng Amount các lệnh hiệu lực của giao dịch, tính theo trạng thái lúc 23:50:59

Gồm: toàn bộ N nếu chưa đăng ký; phần của người nhận chưa được gọi chi; phần của lệnh thất bại; phần dư chưa chia. Bằng 0 thì không tạo. Lệnh AUTO nằm trong cùng kỳ quyết toán T+1 với các lệnh T+1 khác của ngày T, và có webhook kết quả chi như mọi lệnh.

  • Giao dịch nhận tiền từ 23:50:59 đến 23:59:59 ngày T: không nhận đăng ký, toàn bộ N về Merchant T+1.
  • Lệnh đang Status=99 lúc 23:50:59 không gộp vào lệnh AUTO (kể cả khi ra kết quả trước 00:05), mà chờ kết quả cuối:
    • 200: kết thúc.
    • 11: Baokim gửi webhook Status=11 của lệnh, rồi Baokim chi tay trong ngày làm việc kế tiếp:
      • Lệnh có Retryable=true: chi lại cho đúng người nhận (với User: dùng tài khoản của lệnh gốc).
      • Lệnh có Retryable=false (ví dụ lỗi tài khoản User), hoặc chi lại cho người nhận gốc không được: chi phần đó về Merchant.
      • Kết quả chi tay được báo qua webhook với Source = MANUAL, ReferenceId của lệnh gốc, TransIdPayment mới và Receiver là người thực nhận (có thể là 2 dù lệnh gốc là User).
  • Lệnh T+1 (Merchant Type=2, CashPlus, AUTO) thất bại khi Baokim quyết toán: Baokim gửi webhook Status=11 của lệnh, rồi chi tay lại cho đúng người nhận (Merchant, hoặc CashPlus với lệnh CashPlus) và báo kết quả qua webhook Source = MANUAL. Baokim không tự đưa lệnh này vào kỳ quyết toán sau.
  • Nên gọi API trước 23:45 để tránh request bị xử lý sau cutoff.

Gọi lại và xử lý lỗi​

Baokim không tự gọi lại lệnh chi thất bại. Baokim chỉ trả Status=11 khi chắc chắn tiền chưa ra; chưa chắc thì lệnh giữ Status=99.

Tình huốngCashPlus nên làm
Timeout / không nhận được response của lệnh chiGọi lại cùng ReferenceId hoặc tra cứu theo ReferenceId. Chỉ dùng ReferenceId mới khi tra cứu trả 137 và còn trước cutoff
Lệnh Status=99Chờ webhook hoặc tra cứu. Không gọi lệnh mới cho người nhận này (sẽ bị 134). Vẫn gọi chi cho người nhận khác
Lệnh Status=11, Retryable=trueGọi lệnh mới với ReferenceId mới trước cutoff. Không gọi → phần đó về Merchant T+1
Lệnh User Status=11, Retryable=false (lỗi tài khoản User)Không gọi lại (sẽ bị 119). Báo cho khách. Phần U về Merchant T+1
Bị 134Tra cứu lệnh cũ và xử lý theo Status thật của nó
Bị 141 (quá cutoff)Dừng, không gọi lại. Phần đó về Merchant T+1
Không đăng ký số tiền chia sẻ trước cutoffToàn bộ N về Merchant T+1. CashPlus nhận webhook của lệnh AUTO

Ví dụ​

Giao dịch thu hộ BK6AB9B10B92C04SZ, N = 14.010.

Kịch bản 1 — Chi đủ 3 bên

#Thao tácKết quả
1Đăng ký U = 7.000, M = 6.860, P = 150200, dư 0
2Lệnh chi Merchant 6.860 (Ref#1, Type 1)Status 200
3Lệnh chi User 7.000 (Ref#2)Status 200
4Lệnh chi CashPlus 150 (Ref#3, Type 2)Status 0 → webhook 200 sau kỳ T+1
5CutoffKhông tạo lệnh AUTO (đã chi đủ)

Kịch bản 2 — Không có tài khoản User, CashPlus không gọi chi phần mình

#Thao tácKết quả
1Đăng ký U = 7.000, M = 6.860, P = 150200
2Lệnh chi Merchant 6.860Status 200
3CutoffLệnh AUTO 7.150 về Merchant (U 7.000 + P 150) → webhook Source=AUTO

Kịch bản 3 — Lệnh User thất bại, CashPlus gọi lại

#Thao tácKết quả
1Lệnh chi User 7.000 (Ref#2)Status 11, Retryable=true
2Lệnh chi User 7.000 (Ref#4, ReferenceId mới)Status 200

Kịch bản 4 — Các lệnh bị chặn

#Thao tácKết quả
1Lệnh chi Merchant 6.860 (Ref#1)Status 99
2Lệnh chi Merchant 6.860 (Ref#5) khi Ref#1 còn 99Từ chối 134
3Lệnh chi User 5.000 (đăng ký 7.000)Từ chối 136
4Lệnh chi CashPlus 150 với Type=1Từ chối 107
5Lệnh chi User lúc 23:51Từ chối 141

Bảo mật​

Mọi request giữa Baokim và CashPlus đều được ký số. Xem Bảo mật.