Tài liệu API

API Recharge

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í.

Endpoint chính
https://www.netpay.vn/api/rechargews

1. Tổng quan tích hợp

Endpoint chính https://www.netpay.vn/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.
  • Merchant và ví thanh toán phải đang hoạt động.
  • 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

topup và getstatus
md5(partner_key . partner_id . command . request_id)

Dùng cho các lệnh có request_id bắt buộc.

getbalance, productlist, feetopup
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.

canceltopup
md5(partner_key . partner_id . command)

Theo logic hiện tại, sign của lệnh hủy vẫn đang kiểm theo công thức này.

4. Chi tiết từng lệnh

1. Lệnh topup

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.
Ví dụ 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)"
}
Ví dụ response
{
    "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"
    }
}
2. Lệnh getstatus

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.
Ví dụ 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)"
}
Ví dụ response
{
    "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"
    }
}
3. Lệnh getbalance

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.
Ví dụ request
{
    "command": "getbalance",
    "partner_id": "YOUR_PARTNER_ID",
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "status": "success",
    "message": "Thành công",
    "data": {
        "balance": 1200000,
        "currency": "VND"
    }
}
4. Lệnh productlist

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.
Ví dụ request
{
    "command": "productlist",
    "partner_id": "YOUR_PARTNER_ID",
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "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"
                }
            ]
        }
    ]
}
5. Lệnh canceltopup

Yêu cầu hủy giao dịch recharge khi nghiệp vụ cho phép.

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(...) Theo logic hiện tại, sign kiểm theo md5(partner_key . partner_id . command).
Ví dụ request
{
    "command": "canceltopup",
    "partner_id": "YOUR_PARTNER_ID",
    "request_id": "TOPUP_20260403_001",
    "order_code": "RE240403001",
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "status": "success",
    "message": "Thành công",
    "data": {
        "request_id": "TOPUP_20260403_001",
        "order_code": "RE240403001",
        "status": "canceled"
    }
}
6. Lệnh feetopup

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.
Ví dụ request
{
    "command": "feetopup",
    "partner_id": "YOUR_PARTNER_ID",
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "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 có thể là chuỗi hoặc số nguyên tùy nhánh xử lý.
  • 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.

7. Code mẫu theo ngôn ngữ

PHP
<?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']
);
C#
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);
Java
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);
Node.js
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);
Python
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.
  • Nếu sản phẩm hỗ trợ mua số lượng, có thể truyền account_info.qty.
  • Lệnh canceltopup hiện vẫn đang kiểm sign mà không ghép request_id.

API liên quan

Callback nhà cung cấp
https://www.netpay.vn/api/rechargews/{provider}/callback

Endpoint dành cho nhà cung cấp callback về hệ thống, Merchant không cần gọi trực tiếp.

API Softcard

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.

Endpoint chính
https://www.netpay.vn/api/cardws

1. Tổng quan tích hợp

Endpoint chính https://www.netpay.vn/api/cardws
API danh sách sản phẩm https://www.netpay.vn/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.
  • Nếu bật checksign thì sign phải khớp công thức của từng lệnh.
  • IP gọi API phải nằm trong whitelist Merchant hoặc whitelist hệ thống.
  • Với buycard và redownload, request_id phải là mã riêng để tránh trùng đơn.
  • wallet_number phải là ví đúng Merchant và còn hoạt động.

3. Công thức tạo sign

buycard và redownload
md5(partner_key . partner_id . command . request_id)

Áp dụng cho các lệnh có request_id bắt buộc.

checkavailable và getbalance
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

1. Lệnh buycard

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 VND123456789 Ví thanh toán của Merchant.
sign Bắt buộc md5(...) Chữ ký xác thực request.
Ví dụ request
{
    "command": "buycard",
    "partner_id": "YOUR_PARTNER_ID",
    "request_id": "CARD_20260403_001",
    "service_code": "VIETTEL",
    "value": 100000,
    "qty": 2,
    "wallet_number": "VND123456789",
    "sign": "md5(partner_key . partner_id . command . request_id)"
}
Ví dụ response
{
    "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"
    }
}
2. Lệnh redownload

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.
Ví dụ request
{
    "command": "redownload",
    "partner_id": "YOUR_PARTNER_ID",
    "request_id": "CARD_20260403_001",
    "sign": "md5(partner_key . partner_id . command . request_id)"
}
Ví dụ response
{
    "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"
    }
}
3. Lệnh checkavailable

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.
Ví dụ request
{
    "command": "checkavailable",
    "partner_id": "YOUR_PARTNER_ID",
    "service_code": "VIETTEL",
    "value": 100000,
    "qty": 5,
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "stock_available": true,
    "VIETTEL-100000": "Còn hàng"
}
4. Lệnh getbalance

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 VND123456789 Ví cần lấy số dư.
sign Bắt buộc md5(...) Chữ ký xác thực request.
Ví dụ request
{
    "command": "getbalance",
    "partner_id": "YOUR_PARTNER_ID",
    "wallet_number": "VND123456789",
    "sign": "md5(partner_key . partner_id . command)"
}
Ví dụ response
{
    "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://www.netpay.vn/api/cardws/products?partner_id=YOUR_PARTNER_ID
Ví dụ response
[
    {
        "name": "Viettel",
        "slug": "viettel",
        "service_code": "VIETTEL",
        "image": "/uploads/softcard/viettel.png",
        "cardvalue": [
            {
                "service_code": "VIETTEL",
                "value": 100000,
                "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.

8. Code mẫu theo ngôn ngữ

PHP
<?php
$payload = [
    'command' => 'buycard',
    'partner_id' => 'YOUR_PARTNER_ID',
    'request_id' => 'CARD_20260403_001',
    'service_code' => 'VIETTEL',
    'value' => 100000,
    'qty' => 2,
    'wallet_number' => 'VND123456789',
];

$payload['sign'] = md5(
    $partnerKey . $payload['partner_id'] . $payload['command'] . $payload['request_id']
);
C#
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);
Java
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);
Node.js
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);
Python
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

API sản phẩm
https://www.netpay.vn/api/cardws/products?partner_id=YOUR_PARTNER_ID

Lấy danh sách sản phẩm Softcard và các mệnh giá theo service_code.

Callback nhà cung cấp
https://www.netpay.vn/api/cardws/{provider}/callback

Endpoint dành cho nhà cung cấp callback, Merchant không cần gọi trực tiếp.