Tài liệu API
Hướng dẫn kết nối gửi thẻ cào
Tài liệu này dùng cho Merchant cần gửi thẻ, kiểm tra trạng thái giao dịch và lấy biểu phí theo tài khoản.
1. Tổng quan tích hợp
| Endpoint chính | https://hoangvistore.com/chargingws/v2 |
| API biểu phí | https://hoangvistore.com/chargingws/v2/getfee?partner_id=YOUR_PARTNER_ID |
| Method khuyến nghị | POST |
| Kiểu dữ liệu khuyến nghị | application/x-www-form-urlencoded hoặc JSON |
| Lệnh hỗ trợ | charging, check |
2. Điều kiện trước khi gọi API
- Bạn cần có partner_id và partner_key từ khu vực Merchant trước khi gọi API.
- Nếu Merchant bật IP whitelist thì request phải gửi từ đúng IP đã cấu hình.
- Với command charging, request_id phải là duy nhất theo từng partner_id.
- Với command check, hãy dùng lại đúng request_id của giao dịch đã gửi trước đó.
- Nên gửi telco, serial, code ở dạng sạch, đúng chuẩn để hệ thống xử lý nhanh và dễ đối soát.
3. Công thức tạo sign
md5(partner_key . code . command . partner_id . request_id . serial . telco)
Đây là công thức nên ưu tiên dùng khi gửi thẻ.
md5(partner_key . command . partner_id . request_id)
Phù hợp cho lệnh kiểm tra trạng thái giao dịch.
md5(partner_key . code . serial)
API vẫn hỗ trợ để tương thích ngược với client legacy.
4. Tham số cho lệnh charging
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | charging |
Lệnh gửi thẻ lên hệ thống. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | NAPTHE_20260403_001 |
Mã giao dịch phía bạn tự sinh và không được trùng. |
telco |
Bắt buộc | VIETTEL |
Mã nhà mạng. |
amount |
Bắt buộc | 100000 |
Mệnh giá bạn khai báo. |
serial |
Bắt buộc | 10006139342354 |
Serial của thẻ. |
code |
Bắt buộc | 114384960423544 |
Mã nạp hoặc PIN của thẻ. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
5. Tham số cho lệnh check
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | check |
Lệnh kiểm tra trạng thái giao dịch. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | NAPTHE_20260403_001 |
request_id đã dùng ở lệnh charging. |
sign |
Bắt buộc | md5(...) |
Khuyến nghị dùng md5(partner_key . command . partner_id . request_id). |
telco / serial / code |
Không bắt buộc | VIETTEL / 10006139342354 / 114384960423544 |
Có thể truyền thêm để tương thích ngược. |
6. Ví dụ payload
{
"command": "charging",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "NAPTHE_20260403_001",
"telco": "VIETTEL",
"amount": "100000",
"serial": "10006139342354",
"code": "114384960423544",
"sign": "md5(partner_key . code . command . partner_id . request_id . serial . telco)"
}
{
"command": "check",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "NAPTHE_20260403_001",
"sign": "md5(partner_key . command . partner_id . request_id)"
}
7. Cấu trúc phản hồi
trans_id |
ID giao dịch trong hệ thống. |
request_id |
Mã giao dịch phía Merchant gửi sang. |
amount |
Số tiền thực nhận về ví sau khi xử lý. |
value |
Mệnh giá thật được xác nhận. |
declared_value |
Mệnh giá Merchant khai báo lúc gửi thẻ. |
telco |
Nhà mạng của thẻ. |
serial |
Serial thẻ đã gửi. |
code |
Mã thẻ đã gửi. |
status |
Trạng thái thẻ hoặc mã lỗi API. |
callback_sign |
Chữ ký phản hồi: md5(partner_key . code . serial). |
message |
Mô tả trạng thái hoặc lỗi. |
8. Ví dụ response
{
"trans_id": 123456,
"request_id": "NAPTHE_20260403_001",
"amount": 0,
"value": 0,
"declared_value": "100000",
"telco": "VIETTEL",
"serial": "10006139342354",
"code": "114384960423544",
"status": 99,
"callback_sign": "md5(partner_key . code . serial)",
"message": "PENDING"
}
{
"trans_id": 123456,
"request_id": "NAPTHE_20260403_001",
"amount": 81000,
"value": 100000,
"declared_value": 100000,
"telco": "VIETTEL",
"serial": "10006139342354",
"code": "114384960423544",
"status": 1,
"callback_sign": "1d55e0d5f8b4e8f815a3efbb9f5c7b21",
"message": "VALID_CARD"
}
{
"status": 102,
"message": "Dữ liệu xác thực không hợp lệ hoặc chữ ký sign sai."
}
9. Trạng thái thẻ
| Status | Tên | Mô tả |
|---|---|---|
99 |
PENDING |
Thẻ đang chờ xử lý hoặc chờ nhà cung cấp trả kết quả. |
1 |
VALID_CARD |
Thẻ đúng, giao dịch thành công. |
2 |
CARD_WRONG_VALUE |
Thẻ đúng nhưng sai mệnh giá khai báo. |
3 |
INVALID_CARD |
Thẻ không hợp lệ hoặc dữ liệu thẻ sai. |
4 |
MAINTENANCE |
Nhà mạng hoặc cổng xử lý đang bảo trì. |
10. Mã lỗi ở mức request
100 |
Lỗi xử lý chung hoặc không thể tạo giao dịch. |
101 |
Không tìm thấy giao dịch khi gọi command check. |
102 |
Sai xác thực request, sai IP, sai sign hoặc dữ liệu đầu vào không hợp lệ. |
103 |
Có ngoại lệ trong quá trình xử lý request. |
104 |
Command không hợp lệ. Chỉ hỗ trợ charging và check. |
11. API biểu phí và mệnh giá hỗ trợ
Dùng endpoint sau để lấy biểu phí theo Merchant:
https://hoangvistore.com/chargingws/v2/getfee?partner_id=YOUR_PARTNER_ID
Không cần sign. Response là biểu phí theo nhóm giá của tài khoản (thành viên / đại lý / đối tác),
nhóm theo nhà mạng: {"VIETTEL":[{"telco":"VIETTEL","value":10000,"fees":17,"penalty":50}]}.
fees: % phí trừ trên mệnh giá thật; penalty: % phạt khi sai mệnh giá (tính trên mệnh giá nhỏ hơn).
Callback kết quả thẻ
Khi thẻ có kết quả cuối (status 1, 2, 3, 4), hệ thống gửi về Đường dẫn nhận dữ liệu
khai ở trang Kết nối API, đúng kiểu GET (tham số trên URL) hoặc POST (JSON) đã chọn. Nội dung giống response
của command check, kèm callback_sign = md5(partner_key . code . serial). Hãy kiểm tra chữ ký này
và chống xử lý trùng theo request_id trước khi cộng tiền.
Trả về HTTP 200 để xác nhận đã nhận. Lỗi hoặc quá 10 giây thì hệ thống gửi lại sau 1, 2, 5, 15, 30, 60 phút rồi dừng; khi đó dùng command check để đối soát.
Lưu ý tích hợp
- status trong response có thể là trạng thái thẻ hoặc mã lỗi ở mức request, nên cần đọc kèm message.
- sign luôn bắt buộc; sai sign, sai IP whitelist hoặc kết nối đang bị khoá đều trả status 102.
- request_id không được dùng lại; gửi trùng trả status 100.
- Nên gọi API getfee trước khi dựng form nạp thẻ phía frontend để lấy đúng biểu phí và mệnh giá hỗ trợ.
Nhà mạng đang hỗ trợ
VIETTELVINAPHONEMOBIFONEVNMOBIZINGGARENAVCOINSCOIN12. Code mẫu theo ngôn ngữ
<?php
$endpoint = 'https://hoangvistore.com/chargingws/v2';
$partnerId = 'YOUR_PARTNER_ID';
$partnerKey = 'YOUR_PARTNER_KEY';
$requestId = 'NAPTHE_20260403_001';
$payload = [
'command' => 'charging',
'partner_id' => $partnerId,
'request_id' => $requestId,
'telco' => 'VIETTEL',
'amount' => '100000',
'serial' => '10006139342354',
'code' => '114384960423544',
];
$payload['sign'] = md5(
$partnerKey .
$payload['code'] .
$payload['command'] .
$payload['partner_id'] .
$payload['request_id'] .
$payload['serial'] .
$payload['telco']
);
var sign = Md5(
partnerKey +
code +
"charging" +
partnerId +
requestId +
serial +
telco
);
var payload = new Dictionary<string, string>
{
["command"] = "charging",
["partner_id"] = partnerId,
["request_id"] = requestId,
["telco"] = telco,
["amount"] = "100000",
["serial"] = serial,
["code"] = code,
["sign"] = sign,
};
String sign = md5(
partnerKey + code + "charging" + partnerId + requestId + serial + telco
);
Map<String, String> payload = new LinkedHashMap<>();
payload.put("command", "charging");
payload.put("partner_id", partnerId);
payload.put("request_id", requestId);
payload.put("telco", telco);
payload.put("amount", "100000");
payload.put("serial", serial);
payload.put("code", code);
payload.put("sign", sign);
const sign = md5(
partnerKey + code + 'charging' + partnerId + requestId + serial + telco
);
const payload = {
command: 'charging',
partner_id: partnerId,
request_id: requestId,
telco,
amount: '100000',
serial,
code,
sign,
};
payload = {
"command": "charging",
"partner_id": partner_id,
"request_id": request_id,
"telco": telco,
"amount": "100000",
"serial": serial,
"code": code,
}
payload["sign"] = md5(
partner_key + code + "charging" + partner_id + request_id + serial + telco
)
Hướng dẫn nạp tiền dịch vụ
Tài liệu này dành cho Merchant cần topup dịch vụ, kiểm tra trạng thái, lấy số dư, danh sách sản phẩm và bảng phí.
1. Tổng quan tích hợp
| Endpoint chính | https://hoangvistore.com/api/rechargews |
| Method khuyến nghị | POST |
| Kiểu dữ liệu khuyến nghị | application/json |
| Lệnh hỗ trợ | topup, getstatus, getbalance, productlist, canceltopup, feetopup |
2. Điều kiện trước khi gọi API
- Bạn cần có partner_id và partner_key từ Merchant trước khi gọi API.
- Kết nối phải đang hoạt động (không bị quản trị viên khoá) và ví đủ số dư cho đơn topup.
- IP gửi request phải nằm trong whitelist được phép.
- Với lệnh topup, request_id phải là duy nhất để tránh tạo trùng giao dịch.
- Nên gọi productlist trước để biết đúng service_code và cấu trúc account_info cần truyền.
3. Công thức tạo sign
md5(partner_key . partner_id . command . request_id)
Dùng cho các lệnh có request_id bắt buộc.
md5(partner_key . partner_id . command)
Các lệnh này không dùng request_id trong bước xác thực sign.
md5(partner_key . partner_id . command)
Lệnh huỷ nhận cả md5(partner_key . partner_id . command . request_id).
4. Chi tiết từng lệnh
Tạo giao dịch nạp tiền dịch vụ cho tài khoản đích.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | topup |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | TOPUP_20260403_001 |
Mã giao dịch do phía bạn tự sinh. |
service_code |
Bắt buộc | VINA-DATA |
Mã dịch vụ lấy từ productlist. |
amount |
Bắt buộc | 100000 |
Giá trị cần nạp. |
account_info |
Bắt buộc | {"phone":"0987654321"} |
Thông tin tài khoản nhận nạp, tùy theo sản phẩm. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "topup",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "TOPUP_20260403_001",
"service_code": "VINA-DATA",
"amount": 100000,
"account_info": {
"phone": "0987654321"
},
"sign": "md5(partner_key . partner_id . command . request_id)"
}
{
"status": "success",
"message": "Thành công",
"data": {
"time": "2026-04-03 14:30:00",
"request_id": "TOPUP_20260403_001",
"account": {
"phone": "0987654321"
},
"order_code": "RE240403001",
"pay_amount": 95000,
"discount": 5,
"service_code": "VINA-DATA",
"amount": 100000,
"status": "pending"
}
}
Tra cứu trạng thái giao dịch recharge đã tạo trước đó.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | getstatus |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | TOPUP_20260403_001 |
request_id của giao dịch đã gửi. |
order_code |
Bắt buộc | RE240403001 |
Mã đơn hàng hệ thống trả về sau khi tạo giao dịch. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "getstatus",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "TOPUP_20260403_001",
"order_code": "RE240403001",
"sign": "md5(partner_key . partner_id . command . request_id)"
}
{
"status": "success",
"message": "Thành công",
"data": {
"account": {
"phone": "0987654321"
},
"request_value": 100000,
"amount": 100000,
"request_id": "TOPUP_20260403_001",
"order_code": "RE240403001",
"status": "completed"
}
}
Lấy số dư ví Merchant đang dùng để thanh toán recharge.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | getbalance |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
sign |
Bắt buộc | md5(...) |
Chữ ký không dùng request_id. |
{
"command": "getbalance",
"partner_id": "YOUR_PARTNER_ID",
"sign": "md5(partner_key . partner_id . command)"
}
{
"status": "success",
"message": "Thành công",
"data": {
"balance": 1200000,
"currency": "VND"
}
}
Lấy danh sách dịch vụ, mệnh giá, giá bán và các option nhập liệu.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | productlist |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
sign |
Bắt buộc | md5(...) |
Chữ ký không dùng request_id. |
{
"command": "productlist",
"partner_id": "YOUR_PARTNER_ID",
"sign": "md5(partner_key . partner_id . command)"
}
{
"status": "success",
"message": "Thành công",
"data": [
{
"name": "Nạp data VinaPhone",
"service_code": "VINA-DATA",
"items": [
{
"name": "Gói 100.000đ",
"value": 100000,
"price": 95000,
"discount": 5
}
],
"options": [
{
"key": "phone",
"name": "Số điện thoại",
"type": "text"
}
]
}
]
}
Tra khả năng huỷ đơn. Đơn đã chuyển sang nhà cung cấp thì không huỷ được (trả cancel_not_supported); đơn đã có kết quả trả order_finished. Đơn thất bại luôn được tự hoàn tiền về ví.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | canceltopup |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | TOPUP_20260403_001 |
request_id của giao dịch cần hủy. |
order_code |
Bắt buộc | RE240403001 |
Mã đơn hàng cần hủy. |
sign |
Bắt buộc | md5(...) |
md5(partner_key . partner_id . command), hoặc ghép thêm request_id. |
{
"command": "canceltopup",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "TOPUP_20260403_001",
"order_code": "RE240403001",
"sign": "md5(partner_key . partner_id . command)"
}
{
"status": "cancel_not_supported",
"message": "Đơn đã gửi sang nhà cung cấp nên không huỷ được. Đơn thất bại sẽ tự hoàn tiền về ví.",
"data": {
"request_id": "TOPUP_20260403_001",
"order_code": "RE240403001",
"status": "pending"
}
}
Lấy bảng giá và chiết khấu theo Merchant.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | feetopup |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
sign |
Bắt buộc | md5(...) |
Chữ ký không dùng request_id. |
{
"command": "feetopup",
"partner_id": "YOUR_PARTNER_ID",
"sign": "md5(partner_key . partner_id . command)"
}
{
"status": "success",
"message": "Thành công",
"data": [
{
"key": "VINA-DATA",
"value": 100000,
"price": 95000,
"discount": 5
}
]
}
5. Ghi chú về phản hồi
- Recharge API trả về khung JSON gồm status, message và data.
- Trường status là chuỗi, riêng lỗi sai IP trả số 114.
- data.status của đơn:
pendingđang xử lý,completedthành công,failedthất bại (đã hoàn tiền về ví). - Nên xử lý luồng nghiệp vụ theo status, không chỉ dựa vào message.
6. Trạng thái thường gặp
success |
Request hợp lệ và xử lý thành công. |
command_invalid |
Lệnh command không nằm trong danh sách hỗ trợ. |
wrong_post_data |
Thiếu hoặc sai dữ liệu đầu vào bắt buộc. |
product_not_found |
Không tìm thấy service_code tương ứng. |
account_info_not_correct |
account_info không đúng định dạng mong muốn. |
payment_fail |
Thanh toán ví thất bại. |
order_not_found |
Không tìm thấy đơn hàng cần tra cứu hoặc hủy. |
wrong_signature |
Sai chữ ký sign. |
114 |
IP gọi API không nằm trong whitelist cho phép. |
duplicate_request_id | request_id đã được dùng cho đơn khác. Dùng getstatus để tra cứu. |
topup_fail | Nhà cung cấp từ chối hoặc lỗi kết nối. Nếu đơn đã tạo thì tiền đã hoàn về ví, data kèm mã đơn. |
cancel_not_supported | Đơn đang xử lý, không huỷ được qua API. |
order_finished | Đơn đã có kết quả, không huỷ được. |
partner_not_found | partner_id không tồn tại. |
merchant_inactive | Kết nối đang bị khoá hoặc không có quyền dùng API topup. |
system_error | Lỗi hệ thống, thử lại sau. |
7. Code mẫu theo ngôn ngữ
<?php
$payload = [
'command' => 'topup',
'partner_id' => 'YOUR_PARTNER_ID',
'request_id' => 'TOPUP_20260403_001',
'service_code' => 'VINA-DATA',
'amount' => 100000,
'account_info' => ['phone' => '0987654321'],
];
$payload['sign'] = md5(
$partnerKey . $payload['partner_id'] . $payload['command'] . $payload['request_id']
);
var payload = new Dictionary<string, object>
{
["command"] = "topup",
["partner_id"] = partnerId,
["request_id"] = requestId,
["service_code"] = "VINA-DATA",
["amount"] = 100000,
["account_info"] = new Dictionary<string, object> { ["phone"] = "0987654321" },
};
payload["sign"] = Md5(partnerKey + partnerId + "topup" + requestId);
String sign = md5(partnerKey + partnerId + "topup" + requestId);
String payload = """
{
"command": "topup",
"partner_id": "%s",
"request_id": "%s",
"service_code": "VINA-DATA",
"amount": 100000,
"account_info": {"phone": "0987654321"},
"sign": "%s"
}
""".formatted(partnerId, requestId, sign);
const payload = {
command: 'topup',
partner_id: partnerId,
request_id: requestId,
service_code: 'VINA-DATA',
amount: 100000,
account_info: { phone: '0987654321' },
};
payload.sign = md5(partnerKey + partnerId + payload.command + requestId);
payload = {
"command": "topup",
"partner_id": partner_id,
"request_id": request_id,
"service_code": "VINA-DATA",
"amount": 100000,
"account_info": {"phone": "0987654321"},
}
payload["sign"] = md5(partner_key + partner_id + payload["command"] + request_id)
Lưu ý tích hợp
- Nên gọi productlist trước khi topup để xác định đúng service_code, mệnh giá và option đầu vào.
- Sau khi tạo đơn topup, status trong data thường là pending vì hệ thống còn gọi sang nhà cung cấp.
- Dịch vụ khách tự nhập số tiền có trường
amount_rule(min, max, step) trong productlist; amount gửi lên phải nằm trong hạn mức đó. - account_info chỉ nhận đúng các key trong
optionscủa productlist; thiếu key bắt buộc trả account_info_not_correct.
API liên quan
Khi đơn có kết quả cuối (completed / failed), hệ thống gửi về Đường dẫn nhận dữ liệu của kết nối
(GET hoặc POST JSON) nội dung giống data của getstatus, kèm
callback_sign = md5(partner_key . request_id . order_code). Trả HTTP 200 để xác nhận;
lỗi thì hệ thống gửi lại sau 1, 2, 5, 15, 30, 60 phút.
Hướng dẫn mua mã thẻ điện tử
Tài liệu này dùng để mua card, tải lại đơn đã mua, kiểm tra tồn kho, lấy số dư ví và danh sách sản phẩm.
1. Tổng quan tích hợp
| Endpoint chính | https://hoangvistore.com/api/cardws |
| API danh sách sản phẩm | https://hoangvistore.com/api/cardws/products?partner_id=YOUR_PARTNER_ID |
| Method | POST cho /api/cardws, GET cho /api/cardws/products |
| Kiểu dữ liệu khuyến nghị | application/json |
| Lệnh hỗ trợ | buycard, redownload, checkavailable, getbalance |
2. Điều kiện trước khi gọi API
- Merchant phải được cấp quyền dùng module Softcard và đang hoạt động.
- sign luôn bắt buộc và phải khớp công thức của từng lệnh.
- Nếu kết nối có khai IP whitelist thì request phải gửi từ đúng IP đó.
- Với buycard và redownload, request_id phải là mã riêng để tránh trùng đơn.
- wallet_number là số ví hiển thị ở trang Kết nối API (dạng
VND000000012), phải đúng ví của kết nối.
3. Công thức tạo sign
md5(partner_key . partner_id . command . request_id)
Áp dụng cho các lệnh có request_id bắt buộc.
md5(partner_key . partner_id . command)
Dùng cho các lệnh không cần request_id.
4. Chi tiết từng lệnh
Mua mã thẻ điện tử và nhận card ngay nếu hệ thống xử lý thành công.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | buycard |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | CARD_20260403_001 |
Mã giao dịch do phía bạn tự sinh. |
service_code |
Bắt buộc | VIETTEL |
Mã sản phẩm cần mua. |
value |
Bắt buộc | 100000 |
Mệnh giá thẻ. |
qty |
Bắt buộc | 2 |
Số lượng thẻ cần mua, phải là số nguyên dương. |
wallet_number |
Bắt buộc | VND000000012 |
Số ví của kết nối, xem ở trang Kết nối API. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "buycard",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "CARD_20260403_001",
"service_code": "VIETTEL",
"value": 100000,
"qty": 2,
"wallet_number": "VND000000012",
"sign": "md5(partner_key . partner_id . command . request_id)"
}
{
"status": 1,
"message": "Mua thẻ thành công",
"data": {
"cards": [
{
"name": "Thẻ Viettel 100.000",
"serial": "10006139342354",
"code": "114384960423544",
"expired": "2027-12-31"
}
],
"request_id": "CARD_20260403_001",
"order_code": "SC240403001"
}
}
Tải lại thông tin card của đơn hàng đã mua trước đó.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | redownload |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
request_id |
Bắt buộc | CARD_20260403_001 |
request_id đã dùng khi mua thẻ. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "redownload",
"partner_id": "YOUR_PARTNER_ID",
"request_id": "CARD_20260403_001",
"sign": "md5(partner_key . partner_id . command . request_id)"
}
{
"status": 1,
"message": "Mua thẻ thành công",
"data": {
"cards": [
{
"name": "Thẻ Viettel 100.000",
"serial": "10006139342354",
"code": "114384960423544",
"expired": "2027-12-31"
}
],
"request_id": "CARD_20260403_001",
"order_code": "SC240403001"
}
}
Kiểm tra tồn kho sản phẩm trước khi mua.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | checkavailable |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
service_code |
Bắt buộc | VIETTEL |
Mã sản phẩm cần kiểm tra. |
value |
Bắt buộc | 100000 |
Mệnh giá thẻ cần kiểm tra. |
qty |
Bắt buộc | 5 |
Số lượng muốn kiểm tra tồn kho. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "checkavailable",
"partner_id": "YOUR_PARTNER_ID",
"service_code": "VIETTEL",
"value": 100000,
"qty": 5,
"sign": "md5(partner_key . partner_id . command)"
}
{
"stock_available": true,
"VIETTEL-100000": "Còn hàng"
}
Lấy số dư của ví Merchant đang dùng để mua card.
| Trường | Bắt buộc | Ví dụ | Mô tả |
|---|---|---|---|
command |
Bắt buộc | getbalance |
Tên lệnh gọi API. |
partner_id |
Bắt buộc | YOUR_PARTNER_ID |
Mã Merchant của bạn. |
wallet_number |
Bắt buộc | VND000000012 |
Số ví của kết nối, xem ở trang Kết nối API. |
sign |
Bắt buộc | md5(...) |
Chữ ký xác thực request. |
{
"command": "getbalance",
"partner_id": "YOUR_PARTNER_ID",
"wallet_number": "VND000000012",
"sign": "md5(partner_key . partner_id . command)"
}
{
"balance": 2500000,
"currency_code": "VND"
}
5. API danh sách sản phẩm
Dùng endpoint sau để lấy danh sách sản phẩm và mệnh giá hỗ trợ:
https://hoangvistore.com/api/cardws/products?partner_id=YOUR_PARTNER_ID
[
{
"name": "Viettel",
"slug": "viettel",
"service_code": "VIETTEL",
"image": "/uploads/softcard/viettel.png",
"cardvalue": [
{
"service_code": "VIETTEL",
"value": 100000,
"price": 97000,
"id": 10
}
]
}
]
6. Ghi chú về phản hồi
- buycard và redownload trả về JSON theo khung status, message, data.
- checkavailable trả về JSON trực tiếp gồm stock_available và thông tin tồn kho.
- getbalance trả về JSON trực tiếp gồm balance và currency_code.
- API /api/cardws/products trả về mảng sản phẩm JSON trực tiếp.
7. Bảng mã trạng thái
1 |
Mua thẻ thành công hoặc tải lại card thành công. |
2 |
Đơn hàng đang chờ xử lý. |
3 |
Đơn hàng đã hủy và hoàn tiền. |
102 |
Số dư ví không đủ. |
109 |
request_id đã tồn tại. |
114 |
Merchant gọi sai IP đăng ký. |
116 |
Sai chữ ký sign. |
118 |
Sản phẩm đã hết. |
129 |
Đơn hàng không tồn tại. |
130 |
Lỗi lấy thẻ từ nguồn cung cấp. Tiền đã được hoàn về ví. |
113 | partner_id không tồn tại, kết nối đang bị khoá hoặc không có quyền dùng API mua thẻ. |
117 | Sai dữ liệu: thiếu request_id, qty ngoài 1–10, sai wallet_number, sai service_code/value hoặc command. |
8. Code mẫu theo ngôn ngữ
<?php
$payload = [
'command' => 'buycard',
'partner_id' => 'YOUR_PARTNER_ID',
'request_id' => 'CARD_20260403_001',
'service_code' => 'VIETTEL',
'value' => 100000,
'qty' => 2,
'wallet_number' => 'VND000000012',
];
$payload['sign'] = md5(
$partnerKey . $payload['partner_id'] . $payload['command'] . $payload['request_id']
);
var payload = new Dictionary<string, object>
{
["command"] = "buycard",
["partner_id"] = partnerId,
["request_id"] = requestId,
["service_code"] = "VIETTEL",
["value"] = 100000,
["qty"] = 2,
["wallet_number"] = walletNumber,
};
payload["sign"] = Md5(partnerKey + partnerId + "buycard" + requestId);
String sign = md5(partnerKey + partnerId + "buycard" + requestId);
String payload = """
{
"command": "buycard",
"partner_id": "%s",
"request_id": "%s",
"service_code": "VIETTEL",
"value": 100000,
"qty": 2,
"wallet_number": "%s",
"sign": "%s"
}
""".formatted(partnerId, requestId, walletNumber, sign);
const payload = {
command: 'buycard',
partner_id: partnerId,
request_id: requestId,
service_code: 'VIETTEL',
value: 100000,
qty: 2,
wallet_number: walletNumber,
};
payload.sign = md5(partnerKey + partnerId + payload.command + requestId);
payload = {
"command": "buycard",
"partner_id": partner_id,
"request_id": request_id,
"service_code": "VIETTEL",
"value": 100000,
"qty": 2,
"wallet_number": wallet_number,
}
payload["sign"] = md5(partner_key + partner_id + payload["command"] + request_id)
Lưu ý tích hợp
- Nên gọi API products trước để lấy đúng service_code và mệnh giá hợp lệ.
- buycard sẽ trừ tiền ví Merchant rồi cố gắng lấy card ngay từ hệ thống hoặc nhà cung cấp.
- redownload chỉ nên dùng khi request_id cũ đã mua thành công.
- checkavailable thường được dùng để kiểm tra tồn kho trước khi cho phép đặt mua số lượng lớn.
API liên quan
Lấy danh sách sản phẩm Softcard và các mệnh giá theo service_code.
buycard trả thẻ ngay trong response, không có callback. Mất kết nối giữa chừng thì gọi redownload với cùng request_id để lấy lại thẻ (không trừ tiền thêm).