Thực thi chuyển đổi
Thực thi chuyển đổi ngoại tệ theo báo giá FIRM đã lấy tại Lấy báo giá FX. quote_id là bắt buộc — không hỗ trợ chuyển đổi không qua báo giá.
Luồng xử lý
Cơ chế Idempotency
request_id là idempotency key. Nếu Merchant gửi lại request với cùng request_id (do timeout, retry), hệ thống không tạo lệnh mới mà trả lại kết quả của lệnh ban đầu.
Xử lý timeout:
- Timeout không rõ kết quả → (1) retry với cùng
request_id, hoặc (2) tra cứu qua Tra cứu lệnh chuyển đổi - Không được đổi
request_idkhi retry cho cùng một lệnh
Ràng buộc Quote
- Mỗi
quote_idchỉ thực thi thành công một lần → gửi quote đã dùng (vớirequest_idkhác) → mã 426 - Quote quá
expires_at→ mã 425, lấy báo giá mới - Quote phải thuộc đúng
merchant_codeđã lấy báo giá; sai → mã 425
Đường dẫn
- URL:
/api/v1/fx/convert - Method:
POST
Request
| Tham số | Loại dữ liệu | Bắt buộc | Mô tả |
|---|---|---|---|
| request_id | string(50) | Có | Mã duy nhất định danh request, đóng vai trò idempotency key. Xem mục 3 Giới thiệu |
| request_time | string(19) | Có | Xem mục 3 Giới thiệu |
| merchant_code | string(20) | Có | Xem mục 3 Giới thiệu |
| quote_id | string(50) | Có | Mã báo giá FIRM lấy từ Lấy báo giá FX, còn trong thời hạn hiệu lực (expires_at) |
| from_currency | string(3) | Có | Đồng tiền nguồn, phải khớp chính xác với báo giá |
| from_amount | decimal(18,2) | Có | Số tiền nguồn muốn chuyển đổi, phải khớp chính xác với from_amount trong báo giá |
Cơ chế đối chiếu số tiền (Cross-Check)
from_currency và from_amount là các trường xác nhận tường minh, bắt buộc khớp chính xác với giá trị trong báo giá.
Không khớp → mã 428, lệnh không được thực thi. Merchant muốn chuyển đổi số tiền khác → lấy báo giá FIRM mới.
Ví dụ Request
{
"request_id": "MERCHANT1234BK202606050002",
"request_time": "2026-06-05 10:15:45",
"merchant_code": "MERCHANT1234",
"quote_id": "FXQ0605A7K2M9XD41",
"from_currency": "USD",
"from_amount": 10000.00
}
Response
| Tham số | Loại dữ liệu | Bắt buộc | Mô tả |
|---|---|---|---|
| response_code | int(4) | Có | Mã kết quả. 200 = thành công (kiểm tra status trong data), mã khác = lỗi |
| response_message | string(200) | Có | Mô tả mã kết quả |
| merchant_code | string(20) | Có | Mã merchant |
| data | Object | Có | Chi tiết lệnh chuyển đổi (xem bảng dưới) |
Cấu trúc data
| Tham số | Loại dữ liệu | Mô tả |
|---|---|---|
| conversion_id | string(50) | Mã lệnh chuyển đổi do Baokim sinh, dùng để tra cứu và đối soát |
| origin_request_id | string(50) | request_id của lệnh gốc (bằng request_id gửi lên; hữu ích khi response từ cơ chế idempotency) |
| status | string(20) | Trạng thái lệnh: PROCESSING (đang xử lý), SUCCESS (thành công), FAILED (thất bại, không phát sinh biến động) |
| quote_id | string(50) | Mã báo giá đã thực thi |
| trade_type | string(4) | Loại hình giao dịch (SELL/BUY) |
| currency_pair | string(10) | Cặp tiền tệ chuẩn hóa (v í dụ USD/VND) |
| rate | decimal(18,4) | Tỷ giá đã thực thi (đúng bằng tỷ giá trong quote) |
| from_currency | string(3) | Đồng tiền nguồn |
| from_amount | decimal(18,2) | Số tiền nguồn đã trừ |
| to_currency | string(3) | Đồng tiền đích |
| to_amount | decimal(18,2) | Số tiền đích đã ghi có |
| created_at | string(19) | Thời điểm tạo lệnh (GMT+7), định dạng YYYY-MM-DD HH:MM:SS |
| completed_at | string(19) | Thời điểm hoàn tất. Null khi status = PROCESSING. |
Ví dụ Response
{
"response_code": 200,
"response_message": "Success",
"merchant_code": "MERCHANT1234",
"data": {
"conversion_id": "FXC202606051015450001",
"origin_request_id": "MERCHANT1234BK202606050002",
"status": "SUCCESS",
"quote_id": "FXQ0605A7K2M9XD41",
"trade_type": "SELL",
"currency_pair": "USD/VND",
"rate": 26450.0000,
"from_currency": "USD",
"from_amount": 10000.00,
"to_currency": "VND",
"to_amount": 264500000,
"created_at": "2026-06-05 10:15:45",
"completed_at": "2026-06-05 10:15:46"
}
}
Lưu ý
Timeout hoặc mất kết nối khi gọi API này không đồng nghĩa lệnh thất bại. Merchant xử lý theo cơ chế idempotency ở trên, không tự ý coi là FAILED. Sử dụng Tra cứu lệnh chuyển đổi để xác định kết quả cuối cùng.
Mã lỗi
| Mã Response | Thông báo Response | Mô tả |
|---|---|---|
| 200 | Success | Xem status trong data để biết kết quả lệnh |
| 101 | System Error | Lỗi không mong muốn phía Baokim |
| 110 | Merchant code invalid | merchant_code không xác định |
| 120 | Invalid signature | Header Signature không hợp lệ |
| 422 | Validation Error | Trường request thiếu hoặc không hợp lệ |
| 425 | Quote not found, expired, or does not belong to merchant | Quote hết expires_at, không tồn tại, hoặc không phải của merchant này |
| 426 | Quote already used | quote_id này đã được thực thi thành công trước đó (single-use) |
| 427 | Insufficient balance | Không đủ tiền để thực thi chuyển đổi |
| 428 | Amount/currency does not match quote | from_currency hoặc from_amount không khớp quote |
| 429 | Too many requests | Vượt quá giới hạn tỷ lệ cho Merchant |