doithe-sdk
v2.0.0
Published
SDK TypeScript cho các Cổng Đổi Thẻ Cào Việt Nam (TheSieuToc & Card2K)
Maintainers
Readme
DoiThe SDK 🚀
SDK TypeScript hiệu năng cao cho các Cổng Đổi Thẻ Cào Việt Nam.
Hỗ trợ:
- 🟢 Card2K / CardSwap Partner - Cổng đổi thẻ & mua thẻ (giống Nencer)
- 🟡 TheSieuToc - Cổng đổi thẻ cào
✨ Tính năng
- 🚀 Type-Safe: Fully typed với TypeScript
- 🛠 Multi-Gateway: Hỗ trợ cả Card2K và TheSieuToc
- 💎 Modern Design: Kiến trúc clean, dễ bảo trì
- 📦 Lightweight: Chỉ phụ thuộc axios
- 🔐 Secure: Tự động tạo chữ ký MD5
📦 Cài đặt
npm install doithe-sdkhoặc
yarn add doithe-sdk🟢 Card2K API (CardSwap Partner)
Cổng đổi thẻ cào & mua thẻ cào - Thiết kế giống cổng Nencer
🔧 Sandbox: https://sandbox.card2k.com/
Quick Start
1. Khởi tạo Client
import { Card2KClient, CARD2K_SANDBOX_URL } from 'doithe-sdk';
const client = new Card2KClient({
partnerId: 'YOUR_PARTNER_ID',
partnerKey: 'YOUR_PARTNER_KEY',
baseUrl: CARD2K_SANDBOX_URL, // Bỏ để dùng production
});2. Đổi Thẻ Cào (Card Exchange)
// Gửi thẻ lên hệ thống
const result = await client.submitCard({
telco: 'VIETTEL',
code: '1234567890123', // Mã thẻ (PIN)
serial: '10001234567890', // Serial
amount: 10000, // Mệnh giá khai báo
request_id: `REQ_${Date.now()}`,
});
console.log(result.status); // 99 = đang xử lý
console.log(result.message); // Gửi thẻ thành công, chờ xử lý
// Kiểm tra trạng thái thẻ
const status = await client.checkCardStatus({
telco: 'VIETTEL',
code: '1234567890123',
serial: '10001234567890',
amount: 10000,
request_id: result.request_id,
});Status Codes (Đổi thẻ):
| Code | Ý nghĩa | |------|---------| | 1 | Thẻ thành công đúng mệnh giá | | 2 | Thẻ thành công sai mệnh giá | | 3 | Thẻ lỗi | | 4 | Hệ thống bảo trì | | 99 | Thẻ chờ xử lý | | 100 | Gửi thẻ thất bại |
3. Mua Thẻ Cào (Buy Card)
// Lấy số dư tài khoản
const balance = await client.getBalance();
console.log(`Số dư: ${balance.balance} ${balance.currency_code}`);
// Lấy danh sách sản phẩm
const products = await client.getProducts();
// Kiểm tra tồn kho
const stock = await client.checkAvailable({
service_code: 'VIETTEL',
value: 10000,
qty: 1,
});
// Mua thẻ
if (stock.stock_available) {
const buyResult = await client.buyCard({
request_id: `BUY_${Date.now()}`,
service_code: 'VIETTEL',
value: 10000,
qty: 1,
});
if (buyResult.status === 1 && buyResult.data) {
buyResult.data.cards.forEach(card => {
console.log(`Serial: ${card.serial}`);
console.log(`Code: ${card.code}`);
});
}
}4. Lấy Phí/Chiết Khấu
const fees = await client.getFees();
// [{ telco: 'VIETTEL', value: '10000', fees: 9.8, penalty: 50 }, ...]5. Xử Lý Callback
Card2K gọi về endpoint của bạn qua GET method:
import { Card2KClient, Card2KCallbackData } from 'doithe-sdk';
// Express route
app.get('/card2k/callback', (req, res) => {
const data = req.query;
// Validate structure
if (!Card2KClient.isValidCallback(data)) {
return res.status(400).send('Invalid data');
}
const client = new Card2KClient({
partnerId: 'YOUR_PARTNER_ID',
partnerKey: 'YOUR_PARTNER_KEY',
});
// Verify signature: md5(partner_key + code + serial)
if (!client.verifyCallbackSign(data as Card2KCallbackData)) {
return res.status(400).send('Invalid signature');
}
const status = Number(data.status);
if (Card2KClient.isCardSuccess(status)) {
console.log(`✅ Thẻ thành công: ${data.amount} VND`);
// Cộng tiền cho user...
} else if (Card2KClient.isCardFailed(status)) {
console.log(`❌ Thẻ thất bại: ${data.message}`);
}
res.send('OK');
});Callback Parameters:
| Parameter | Mô tả | |-----------|-------| | status | Trạng thái (1, 2, 3, 99, 100) | | message | Thông báo | | request_id | Mã giao dịch của bạn | | declared_value | Mệnh giá khai báo | | card_value | Mệnh giá thực | | value | Mệnh giá tính tiền | | amount | Số tiền nhận được | | code | Mã thẻ | | serial | Serial | | telco | Loại thẻ | | trans_id | Mã giao dịch Card2K | | callback_sign | Chữ ký: md5(partner_key + code + serial) |
🟡 TheSieuToc API
Quick Start
1. Khởi tạo Client
import { TheSieuTocClient } from 'doithe-sdk';
const client = new TheSieuTocClient('YOUR_API_KEY');2. Gửi Thẻ
const result = await client.submitCard({
type: 'Viettel',
mathe: '1234567890123',
seri: '10001234567',
menhgia: 50000,
content: 'unique_order_id_123'
});
console.log(result.msg); // Thẻ đã gửi lên hệ thống chờ xử lý!3. Kiểm Tra Trạng Thái
const status = await client.checkCardStatus('unique_order_id_123');
console.log(status.msg); // Thẻ thành công4. Lấy Chiết Khấu
const discounts = await client.getDiscounts();
const viettel = discounts.find(d => d.card_type === 'Viettel');
console.log(viettel?.discount['50000']);5. Xử Lý Callback
import { TheSieuTocClient, CardCallbackData } from 'doithe-sdk';
app.post('/callback', (req, res) => {
const data = req.body as CardCallbackData;
if (TheSieuTocClient.isValidCallback(data)) {
if (data.status === 'thanhcong') {
console.log(`Card success: ${data.real_amount} VND`);
} else {
console.log(`Card failed: ${data.noidung}`);
}
res.send('OK');
} else {
res.status(400).send('Invalid data');
}
});📖 API Reference
Card2KClient
| Method | Mô tả |
|--------|-------|
| submitCard(data) | Gửi thẻ lên hệ thống |
| checkCardStatus(data) | Kiểm tra trạng thái thẻ |
| getFees() | Lấy danh sách phí/chiết khấu |
| buyCard(data) | Mua thẻ cào |
| getBalance() | Lấy số dư tài khoản |
| checkAvailable(data) | Kiểm tra tồn kho |
| getProducts() | Lấy danh sách sản phẩm |
| verifyCallbackSign(data) | Xác thực chữ ký callback |
TheSieuTocClient
| Method | Mô tả |
|--------|-------|
| submitCard(data) | Gửi thẻ lên hệ thống |
| checkCardStatus(requestId) | Kiểm tra trạng thái thẻ |
| getDiscounts(username?) | Lấy chiết khấu |
🎨 Constants & Types
// Card2K
import {
Card2KClient,
CARD2K_CARD_STATUS,
CARD2K_BUY_STATUS,
CARD2K_SANDBOX_URL,
} from 'doithe-sdk';
console.log(Card2KClient.getCardStatusMessage(99)); // Thẻ chờ xử lý
console.log(Card2KClient.getBuyStatusMessage(102)); // Số dư ví không đủ
// TheSieuToc
import {
TheSieuTocClient,
ERROR_CODES,
CHECK_STATUS_CODES
} from 'doithe-sdk';
console.log(TheSieuTocClient.getErrorMessage('54')); // Chưa Nhập API key🔧 Sandbox Testing (Card2K)
Kết quả thẻ trong môi trường sandbox được trả về tự động dựa trên 3 ký tự cuối của mã thẻ:
| Mã kết thúc | Kết quả |
|-------------|---------|
| 001 | Thẻ đúng |
| 002 | Thẻ đúng nhưng sai mệnh giá |
| Khác | Thẻ sai |
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by WangYi
