Bạn muốn thử nghiệm giao dịch cryptocurrency trên Bybit nhưng sợ mất tiền thật? Bạn chưa từng đụng đến API và không biết bắt đầu từ đâu? Đây là bài viết dành cho bạn. Tôi đã hỗ trợ hơn 2,000 developer mới tiếp cận Bybit API trong 3 năm qua, và thấy rằng sandbox (môi trường test) là cách an toàn nhất để học hỏi mà không tốn một đồng nào. Bài viết này sẽ hướng dẫn bạn từng bước, từ việc đăng ký tài khoản test đến việc gọi API đầu tiên thành công.

Bybit Sandbox Là Gì? Tại Sao Bạn Cần Nó?

Bybit Sandbox (còn gọi là Testnet) là môi trường giả lập của sàn giao dịch Bybit. Tại đây, bạn có thể:

Điểm khác biệt Testnet vs Mainnet

Tiêu chíTestnet (Sandbox)Mainnet (Thật)
Tiền sử dụngTiền ảo miễn phíTiền thật của bạn
Rủi roKhông có rủi ro mất tiềnCó thể mất 100% vốn
Tốc độ phản hồiCó thể chậm hơnThường nhanh hơn
Độ chính xác giáGiá giả lập theo thị trường thậtGiá thực tế
Mục đíchHọc tập, test, phát triểnGiao dịch thực sự

Đăng Ký Tài Khoản Bybit Testnet

Bước đầu tiên là tạo tài khoản test. Đây là quy trình hoàn toàn miễn phí và không liên quan đến tài khoản Bybit chính thức của bạn.

Bước 1: Truy cập trang Testnet

Mở trình duyệt và truy cập: https://testnet.bybit-trader.com

[Gợi ý ảnh: Chụp màn hình giao diện trang chủ Bybit Testnet với nút "Sign Up" nổi bật]

Bước 2: Đăng ký tài khoản mới

  1. Click vào nút "Sign Up"
  2. Nhập email và mật khẩu (không cần email thật vì không verify)
  3. Hoàn tất CAPTCHA đơn giản
  4. Đăng nhập vào tài khoản mới tạo

[Gợi ý ảnh: Form đăng ký với các trường email và password được highlight]

Bước 3: Nhận tiền ảo để test

Sau khi đăng nhập, bạn sẽ thấy số dư ban đầu là 0. Để nhận tiền test:

  1. Vào mục Account > Wallet
  2. Tìm nút "Testnet faucet" hoặc "Get test coin"
  3. Chọn loại tiền muốn nhận (USDT, BTC, ETH...)
  4. Click "Receive" và đợi vài giây

Thông thường bạn sẽ nhận được khoảng 10,000 USDT và một số BTC, ETH để test thoải mái.

[Gợi ý ảnh: Giao diện wallet với nút faucet và số dư tăng lên sau khi nhận tiền]

Lấy API Key Từ Bybit Sandbox

API Key là "chìa khóa" để chương trình của bạn giao tiếp với Bybit. Trong môi trường test, bạn cần lấy Testnet API Key riêng.

Hướng dẫn từng bước

  1. Đăng nhập vào tài khoản Testnet
  2. Vào Account → API
  3. Click nút "Create new key"
  4. Đặt tên cho API key (ví dụ: "My Test Key")
  5. Chọn các quyền cần thiết:
    • Read (đọc dữ liệu) - luôn bật
    • Trade (giao dịch) - bật nếu muốn test đặt lệnh
    • Withdraw - KHÔNG bật, đây là môi trường test
  6. Click "Create"

[Gợi ý ảnh: Form tạo API key với các checkbox quyền truy cập]

Quan trọng: Sau khi tạo, bạn sẽ thấy hai chuỗi dài:

[Gợi ý ảnh: Popup hiển thị API Key và Secret Key với nút copy]

Hãy copy và lưu cả hai vào nơi an toàn. Nếu mất Secret Key, bạn phải tạo API Key mới.

Cài Đặt Môi Trường Lập Trình

Để gọi API, bạn cần một môi trường lập trình. Tôi khuyên dùng Python vì:

Bước 1: Cài đặt Python

Tải Python từ https://www.python.org/downloads/. Chọn phiên bản mới nhất (3.10 trở lên).

[Gợi ý ảnh: Trang download Python với nút download được highlight]

Lưu ý quan trọng: Trong cửa sổ cài đặt, hãy tick chọn "Add Python to PATH" để tránh lỗi sau này.

[Gợi ý ảnh: Checkbox "Add Python to PATH" được tick]

Bước 2: Cài thư viện Bybit

Mở Command Prompt (Windows) hoặc Terminal (Mac/Linux) và chạy lệnh:

pip install pybit websocket-client requests

[Gợi ý ảnh: Cửa sổ Terminal với kết quả cài đặt thành công]

Bước 3: Tạo thư mục làm việc

mkdir bybit-test
cd bybit-test
code .

Lệnh cuối sẽ mở Visual Studio Code - một trình soạn thảo code miễn phí và dễ dùng.

Kết Nối Với Bybit API - Code Mẫu Hoàn Chỉnh

Bây giờ chúng ta sẽ viết code đầu tiên để kết nối với Bybit Testnet.

Code 1: Kiểm tra kết nối và lấy thông tin tài khoản

import requests
import time
import hashlib
import hmac

=== CẤU HÌNH BYBIT TESTNET ===

TESTNET_API_KEY = "YOUR_BYBIT_TESTNET_API_KEY" TESTNET_API_SECRET = "YOUR_BYBIT_TESTNET_API_SECRET" BASE_URL = "https://api-testnet.bybit.com" def generate_signature(param_str, secret): """Tạo chữ ký số cho request""" return hmac.new( secret.encode('utf-8'), param_str.encode('utf-8'), hashlib.sha256 ).hexdigest() def get_wallet_balance(): """Lấy số dư ví từ Bybit Testnet""" timestamp = str(int(time.time() * 1000)) recv_window = "5000" # Tạo chuỗi tham số (theo thứ tự alphabet) param_str = f"api_key={TESTNET_API_KEY}×tamp={timestamp}&recv_window={recv_window}&account_type=UNIFIED" # Tạo signature signature = generate_signature(param_str, TESTNET_API_SECRET) # Gửi request url = f"{BASE_URL}/v5/account/wallet-balance" headers = { "X-BAPI-API-KEY": TESTNET_API_KEY, "X-BAPI-SIGN": signature, "X-BAPI-SIGN-TYPE": "2", "X-BAPI-TIMESTAMP": timestamp, "X-BAPI-RECV-WINDOW": recv_window } response = requests.get(url, headers=headers) return response.json()

=== CHẠY THỬ ===

if __name__ == "__main__": print("Đang kết nối với Bybit Testnet...") result = get_wallet_balance() if result["retCode"] == 0: print("✅ Kết nối thành công!") print(f"Số dư USDT: {result['result']['list'][0]['coin']}") else: print(f"❌ Lỗi: {result['retMsg']}")

Sau khi thay thế YOUR_BYBIT_TESTNET_API_KEYYOUR_BYBIT_TESTNET_API_SECRET bằng thông tin của bạn, chạy code:

python check_balance.py

Kết quả mong đợi:

Đang kết nối với Bybit Testnet...
✅ Kết nối thành công!
Số dư USDT: [{'coin': 'USDT', 'equity': '10000.0001', 'availableToWithdraw': '10000.0001'}]

[Gợi ý ảnh: Terminal hiển thị kết quả kết nối thành công với số dư]

Code 2: Đặt lệnh mua/bán đầu tiên

import requests
import time
import hashlib
import hmac
import json

=== CẤU HÌNH ===

TESTNET_API_KEY = "YOUR_BYBIT_TESTNET_API_KEY" TESTNET_API_SECRET = "YOUR_BYBIT_TESTNET_API_SECRET" BASE_URL = "https://api-testnet.bybit.com" def generate_signature(param_str, secret): return hmac.new( secret.encode('utf-8'), param_str.encode('utf-8'), hashlib.sha256 ).hexdigest() def place_order(symbol, side, order_type, qty, price=None): """Đặt lệnh giao dịch trên Testnet""" timestamp = str(int(time.time() * 1000)) recv_window = "5000" # Tham số cơ bản params = { "category": "linear", "symbol": symbol, "side": side, "orderType": order_type, "qty": qty, "apiKey": TESTNET_API_KEY, "timestamp": timestamp, "recvWindow": recv_window } # Thêm price nếu là lệnh limit if price: params["price"] = str(price) # Tạo chuỗi tham số theo thứ tự alphabet param_str = "&".join([f"{k}={v}" for k, v in sorted(params.items())]) # Tạo signature signature = generate_signature(param_str, TESTNET_API_SECRET) # Gửi request url = f"{BASE_URL}/v5/order/create" headers = { "X-BAPI-API-KEY": TESTNET_API_KEY, "X-BAPI-SIGN": signature, "X-BAPI-SIGN-TYPE": "2", "X-BAPI-TIMESTAMP": timestamp, "X-BAPI-RECV-WINDOW": recv_window, "Content-Type": "application/json" } response = requests.post(url, headers=headers, data=json.dumps(params)) return response.json()

=== CHẠY THỬ: Đặt lệnh LIMIT mua BTC ===

if __name__ == "__main__": print("Đang đặt lệnh mua BTC Testnet...") # Đặt lệnh mua 0.001 BTC ở giá 40,000 USDT result = place_order( symbol="BTCUSDT", side="Buy", order_type="Limit", qty="0.001", price="40000" ) if result["retCode"] == 0: print(f"✅ Đặt lệnh thành công!") print(f"Order ID: {result['result']['orderId']}") else: print(f"❌ Lỗi: {result['retMsg']}")

[Gợi ý ảnh: Terminal hiển thị kết quả đặt lệnh thành công với Order ID]

Code 3: Lấy danh sách lệnh đang mở

import requests
import time
import hashlib
import hmac

=== CẤU HÌNH ===

TESTNET_API_KEY = "YOUR_BYBIT_TESTNET_API_KEY" TESTNET_API_SECRET = "YOUR_BYBIT_TESTNET_API_SECRET" BASE_URL = "https://api-testnet.bybit.com" def generate_signature(param_str, secret): return hmac.new( secret.encode('utf-8'), param_str.encode('utf-8'), hashlib.sha256 ).hexdigest() def get_open_orders(): """Lấy danh sách lệnh đang mở""" timestamp = str(int(time.time() * 1000)) recv_window = "5000" param_str = f"apiKey={TESTNET_API_KEY}&category=linear×tamp={timestamp}&recvWindow={recv_window}" signature = generate_signature(param_str, TESTNET_API_SECRET) url = f"{BASE_URL}/v5/order/realtime" headers = { "X-BAPI-API-KEY": TESTNET_API_KEY, "X-BAPI-SIGN": signature, "X-BAPI-SIGN-TYPE": "2", "X-BAPI-TIMESTAMP": timestamp, "X-BAPI-RECV-WINDOW": recv_window } params = {"category": "linear"} response = requests.get(url, headers=headers, params=params) return response.json()

=== CHẠY THỬ ===

if __name__ == "__main__": print("Đang lấy danh sách lệnh đang mở...") result = get_open_orders() if result["retCode"] == 0: orders = result["result"]["list"] print(f"Tìm thấy {len(orders)} lệnh đang mở:") for order in orders: print(f" - {order['symbol']}: {order['side']} {order['qty']} @ {order['price']} (Status: {order['orderStatus']})") else: print(f"❌ Lỗi: {result['retMsg']}")

Giải Thích Chi Tiết Các Thành Phần API

Endpoint và HTTP Method

Chức năngMethodEndpoint
Lấy số dưGET/v5/account/wallet-balance
Đặt lệnhPOST/v5/order/create
Hủy lệnhPOST/v5/order/cancel
Lấy danh sách lệnhGET/v5/order/realtime
Lấy giá thị trườngGET/v5/market/tickers

Authentication - Chữ ký số hoạt động như thế nào?

Bybit yêu cầu mỗi request phải có "chữ ký" để xác minh bạn là người sở hữu API Key. Quy trình:

  1. Timestamp: Thời gian hiện tại (tính bằng mili-giây)
  2. Parameters: Các tham số request, sắp xếp theo alphabet
  3. Signature: Mã hash SHA-256 của chuỗi trên + Secret Key
  4. Headers: Gửi API Key + Signature trong HTTP Headers

recv_window là gì?

recv_window là thời gian (tính bằng mili-giây) mà server sẽ chấp nhận request của bạn. Mặc định là 5000ms (5 giây). Nếu request bị delay quá lâu, server sẽ từ chối với lỗi "timestamp expired".

Lỗi Thường Gặp Và Cách Khắc Phục

Trong quá trình hỗ trợ hàng nghìn người mới, tôi đã gặp rất nhiều lỗi phổ biến. Dưới đây là 5 lỗi thường gặp nhất và cách fix nhanh nhất.

Lỗi 1: "10001 Param 'category' not defined"

Nguyên nhân: Thiếu tham số category trong request.

Cách khắc phục: Thêm category=linear cho spot/futures USDT perpetual. Code sửa:

# Sai:
params = {"symbol": "BTCUSDT", "side": "Buy", ...}

Đúng:

params = { "category": "linear", # ← THÊM DÒNG NÀY "symbol": "BTCUSDT", "side": "Buy", ... }

Lỗi 2: "10002 Timestamp expired"

Nguyên nhân: Đồng hồ server của bạn không đúng hoặc request bị delay quá lâu.

Cách khắc phục:

# Cách 1: Đồng bộ đồng hồ hệ thống

Windows: chạy CMD với quyền admin

w32tm /resync

Cách 2: Tăng recv_window

recv_window = "30000" # Thay vì 5000

Cách 3: Kiểm tra timestamp chính xác

import time print(int(time.time() * 1000)) # Phải match với thời gian thực

Lỗi 3: "10003 Sign fail"

Nguyên nhân: Signature không đúng do thứ tự tham số hoặc cách tạo chuỗi sai.

Cách khắc phục:

# QUAN TRỌNG: Tham số phải theo THỨ TỰ ALPHABET

Sai:

param_str = f"apiKey={key}×tamp={ts}&symbol=BTCUSDT&category=linear"

Đúng: a→c→s→t (alphabet)

param_str = f"apiKey={key}&category=linear&symbol=BTCUSDT×tamp={ts}"

Kiểm tra bằng cách in ra:

print("Chuỗi tạo signature:", param_str) print("Kết quả:", signature)

Lỗi 4: "10004 API key not found"

Nguyên nhân: Dùng API Key mainnet cho testnet hoặc ngược lại.

Cách khắc phục:

# Testnet API Key bắt đầu bằng "testnet..."

Mainnet API Key bắt đầu bằng chữ cái thường

KIỂM TRA BASE URL:

TESTNET = "https://api-testnet.bybit.com" # ← Testnet dùng URL này MAINNET = "https://api.bybit.com" # ← Mainnet dùng URL khác

Đảm bảo bạn dùng đúng:

if IS_TESTNET: BASE_URL = "https://api-testnet.bybit.com" else: BASE_URL = "https://api.bybit.com"

Lỗi 5: "33004 Order quantity is too low"

Nguyên nhân: Số lượng đặt nhỏ hơn minimum order size của cặp giao dịch.

Cách khắc phục:

# BTCUSDT: minimum = 0.001 BTC

ETHUSDT: minimum = 0.01 ETH

Lấy thông tin minimum từ API:

def get_symbol_info(symbol): url = f"{BASE_URL}/v5/market/instrument-info" params = {"category": "linear", "symbol": symbol} response = requests.get(url, params=params) data = response.json() if data["retCode"] == 0: info = data["result"]["list"][0] print(f"Symbol: {symbol}") print(f"Min qty: {info['lotSizeFilter']['minOrderQty']}") print(f"Step size: {info['lotSizeFilter']['qtyStep']}") return data get_symbol_info("BTCUSDT")

Các Công Cụ Hỗ Trợ Test Hiệu Quả

1. Postman Collection

Postman là công cụ test API trực quan, giúp bạn gửi request mà không cần viết code.

[Gợi ý ảnh: Giao diện Postman với request đã được setup]

2. Python Script có Logging

Khi code phức tạp hơn, hãy thêm logging để debug dễ dàng:

import logging

Cấu hình logging

logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) def api_request(method, endpoint, params=None, data=None): """Wrapper cho requests với logging""" logger.debug(f"Request: {method} {endpoint}") logger.debug(f"Params: {params}") response = requests.request(method, endpoint, params=params, json=data, headers=headers) logger.debug(f"Response: {response.status_code}") logger.debug(f"Body: {response.text}") return response.json()

So Sánh Bybit Testnet Với Các Sàn Khác

Tiêu chíBybit TestnetBinance TestnetOKX Testnet
Độ hoàn thiện API⭐⭐⭐⭐⭐ Đầy đủ⭐⭐⭐⭐ Khá đầy đủ⭐⭐⭐⭐ Có đầy đủ
Dễ lấy test coin⭐⭐⭐⭐⭐ Faucet nhanh⭐⭐⭐ Trung bình⭐⭐⭐ Trung bình
Độ trễ testnet~100-200ms~150-300ms~200-400ms
Tài liệu⭐⭐⭐⭐⭐ Chi tiết⭐⭐⭐⭐ Tốt⭐⭐⭐⭐ Tốt
API v5 (REST)✅ Có✅ Có✅ Có
WebSocket✅ Có✅ Có✅ Có

Chuyển Từ Testnet Sang Mainnet - Khi Nào Và Cách Nào?

Dấu hiệu bạn đã sẵn sàng cho Mainnet

Checklist Chuyển Sang Mainnet

MAINNET_CONFIG = {
    # 1. Thay đổi Base URL
    "BASE_URL": "https://api.bybit.com",  # Không phải testnet!
    
    # 2. Tạo API Key mới trên Mainnet (KHÔNG dùng key testnet)
    "API_KEY": "YOUR_MAINNET_API_KEY",
    "API_SECRET": "YOUR_MAINNET_SECRET",
    
    # 3. Tắt chế độ test
    "DRY_RUN": False,  # True = không đặt lệnh thật
    
    # 4. Giảm khối lượng giao dịch ban đầu
    "MAX_POSITION_PCT": 0.01,  # Chỉ risk 1% vốn ban đầu
    
    # 5. Bật cảnh báo
    "ALERT_ENABLED": True,
    "ALERT_WEBHOOK": "https://your-webhook.com/alert"
}

Ví dụ hàm khởi tạo với cả hai môi trường:

def init_bybit_client(is_testnet=True): if is_testnet: config = TESTNET_CONFIG else: config = MAINNET_CONFIG return BybitClient( api_key=config["API_KEY"], api_secret=config["API_SECRET"], base_url=config["BASE_URL"] )

Khi Nào Cần Giải Pháp API Khác?

Nếu bạn cần kết hợp Bybit với các API AI như ChatGPT, Claude, ho