每位订阅用户都会获得一个拥有 $1,000 虚拟余额的专属模拟账户,由你的机器人进行交易。他们可以实时查看 PnL、回撤、胜率,无需承担真实资金风险——你也无需承担获客成本。
你的机器人专属模拟账户会以 🤖 БОТ 徽章出现在公开排行榜中。用户可以看到它在真实交易者中的 PnL 排名。点击该行,点按“Connect”即可立即订阅。
如果你的机器人使用任意 Binance 合约 SDK(binance-connector-python、python-binance、CCXT 等),只需将其 base_url 指向 https://api.buycrypt.com/fapi。HMAC、recvWindow、订单类型——完全一致。
当用户订阅时,我们会将新生成的 API key + secret 通过 POST 发送到你的 webhook URL——经 HMAC 签名,失败后按指数退避重试,并可从死信队列中恢复。你永远无需向用户索要凭证。
用户打开排行榜,你的机器人账户会在用户名旁显示 🤖 БОТ 标签及订阅者数量。他们点击该行。
在机器人的资料页面,他们会看到“连接模拟账户”。轻点一下即可为其创建一个全新的 $1,000 模拟账户,你的机器人随即开始交易。
用户会观察机器人在模拟账户上交易数天甚至数周。PnL、持仓、胜率——应用内实时可见。如果满意,他们会在 BuyCrypt 内输入真实的 Binance API 密钥,从模拟升级到实盘。
用户在 BuyCrypt 内添加真实的 Binance API 密钥。我们会以交付模拟密钥同样的方式将其发送到你的 webhook——同样的 subscription.created 事件,只是换成了他们的生产环境凭证。一次接入即可覆盖模拟与实盘两种流程。
注册一个普通的 BuyCrypt 账户——流程与普通用户完全相同。注册的那一刻,你就会获得一个带起始余额的免费模拟账户。无需申请表,无需审核排队。
直接在 BuyCrypt 移动应用内生成 API 密钥:我的资料 → API 密钥 → 点击你的模拟账户 → 生成。系统会显示一次全新的 apiKey + apiSecret——请复制到你的机器人中。然后将你现有的 Binance U 本位合约机器人指向 https://api.buycrypt.com/fapi,即可直接运行——相同的 HMAC、相同的接口、相同的订单类型。
一旦我们检测到你的模拟账户上出现 API 驱动的交易,你的账户就会被自动标记为机器人。你的模拟账户会以 🤖 БОТ 标签和公开资料的形式出现在排行榜中,方便其他用户发现并订阅。
当你准备好接收订阅者时,请在设置中为你的机器人资料添加一个 webhook URL。每当有用户订阅——无论是模拟账户还是真实 Binance 密钥——我们都会 POST 一个 subscription.created 事件,附带该用户账户的 API key + secret。保存 (userId, apiKey, apiSecret) 并开始代其交易。
大多数 Binance 合约 SDK 都支持自定义基础 URL。以下是一个典型 Python 机器人所需的全部改动:
# before — trading on real Binance from binance.um_futures import UMFutures client = UMFutures(key=API_KEY, secret=API_SECRET) # after — trading on a BuyCrypt user's demo from binance.um_futures import UMFutures client = UMFutures( key=API_KEY, secret=API_SECRET, base_url="https://api.buycrypt.com/fapi", # <- the only line that changes ) # everything below is identical to your existing code client.new_order(symbol="BTCUSDT", side="BUY", type="MARKET", quantity=0.01) client.account() client.cancel_open_orders(symbol="BTCUSDT")
CCXT、python-binance、Go 的 go-binance、JS 的 node-binance-api——都以相同方式工作。纯粹使用 requests.get(...).headers["X-MBX-APIKEY"] = key 的机器人同样可用;HMAC 签名规则完全一致(字节级相同)。
当 BuyCrypt 用户订阅你的机器人时,我们会在服务端为该用户生成专属的 API key + secret,并通过 HTTPS 以签名方式 POST 到你注册的 webhook URL。密钥永远不会返回给用户——只会发送给你。
TL;DR: sign up → tap «Generate API key» on your demo → generate a webhook secret → run one Python script → admin approves. ~5 minutes.
Open buycrypt.com/terminal (or the mobile app). Sign in via Google or phone. A $1,000 USDT demo account is created automatically — that's the sandbox your bot will trade on.
In the app: Profile → API Keys → tap your demo account → «Bot API keys» → Generate. A dialog shows the apiKey + apiSecret once — copy both, you can't recover the secret afterwards.
# what you'll save API_KEY = "3fc370a4ac94b9aa756e2a97842dc04c" API_SECRET = "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU"
Same shape as Binance — your existing USD-M Futures bot library reads it as a regular Binance key with base URL https://api.buycrypt.com/fapi.
A second secret, separate from API_SECRET. We use it to sign the events we POST to your webhook URL — so you can verify the request really came from us. You generate it on your side; we encrypt-store it but never reveal back:
# any of these works — pick one. Save the output. $ openssl rand -hex 32 # macOS / Linux $ python3 -c "import secrets; print(secrets.token_hex(32))" # cross-platform # sample output 8a31c2f4d5e6789abc01234567890def8a31c2f4d5e6789abc01234567890def
Drop your three secrets into one signed POST. Save this as register_bot.py and run it once. Works on any OS with Python 3.10+ and pip install requests:
import hmac, hashlib, time, urllib.parse, requests # ─── fill these in from steps 2 and 3 ───────────────────── API_KEY = "3fc370a4ac94b9aa756e2a97842dc04c" API_SECRET = "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU" WEBHOOK_SECRET = "8a31c2f4d5e6789abc01234567890def8a31c2f4d5e6789abc01234567890def" SLUG = "alpha-trader" # lowercase, [a-z0-9-], unique DISPLAY_NAME = "Alpha Trader" # shown to users in the bot list WEBHOOK_URL = "https://your-bot.example.com/buycrypt/hook" # MUST be HTTPS, public # ────────────────────────────────────────────────────────── params = { "slug": SLUG, "displayName": DISPLAY_NAME, "webhookUrl": WEBHOOK_URL, "webhookSecret": WEBHOOK_SECRET, "defaultLeverage": 10, "timestamp": int(time.time() * 1000), } qs = urllib.parse.urlencode(params) sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest() r = requests.post( "https://api.buycrypt.com/fapi/v1/bot/profiles", headers={ "X-MBX-APIKEY": API_KEY, "Content-Type": "application/x-www-form-urlencoded", }, data=qs + f"&signature={sig}", ) print(r.status_code, r.json())
Notice no demoKeyPairId — your API_KEY already points to the demo it was generated for. Need to register against a different demo? Generate a separate API key for it (step 2 again).
Expected output:
201 {
"botId": 42,
"slug": "alpha-trader",
"status": "PENDING_REVIEW",
"webhookUrl": "https://your-bot.example.com/buycrypt/hook",
"webhookStatus": "ACTIVE",
"webhookSecretAutoGenerated": false
}
Common errors:
{"code":-2010, "msg":"Slug already in use."} # pick another slug
{"code":-1102, "msg":"webhookSecret must be at least 32..."} # too short — use 32+ chars
{"code":-1022, "msg":"Signature for this request is not valid."} # API_SECRET wrong, or params order changed after signing
{"code":-1003, "msg":"Bot registration rate limit: 1 per hour..."} # wait it out
Bot lands in PENDING_REVIEW. Our admin sees your request immediately and approves it. To check status anytime:
import hmac, hashlib, time, urllib.parse, requests API_KEY = "3fc370a4..." API_SECRET = "3WJ86kV..." qs = urllib.parse.urlencode({"timestamp": int(time.time() * 1000)}) sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest() r = requests.get( f"https://api.buycrypt.com/fapi/v1/bot/profiles?{qs}&signature={sig}", headers={"X-MBX-APIKEY": API_KEY}, ) print(r.json()) # [{"botId":42, "status":"ACTIVE", ...}] when approved
Once "status":"ACTIVE": every time a user subscribes we POST to your webhookUrl with the per-subscriber API key your bot will trade with. The events shape and a copy-paste signature-verification snippet are right below this section.
Lost your webhook secret? Pick a new one and rotate (same signing pattern as registration):
params = {
"webhookSecret": NEW_SECRET, # or omit to get backend-generated
"timestamp": int(time.time() * 1000),
}
qs = urllib.parse.urlencode(params)
sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
requests.post(
"https://api.buycrypt.com/fapi/v1/bot/profiles/42/webhook/rotate-secret",
headers={"X-MBX-APIKEY": API_KEY,
"Content-Type": "application/x-www-form-urlencoded"},
data=qs + f"&signature={sig}",
)
Old secret invalid the second the new one saves. Rate limit: 10 rotations/hour per bot.
subscription.created —— 用户刚刚订阅POST https://your-bot.example.com/buycrypt/hook Content-Type: application/json User-Agent: BuyCrypt-Webhook/1.0 X-BuyCrypt-Event: subscription.created X-BuyCrypt-Delivery-Id: 7f3b2e8c-a4d1-4f12-93b8-0c1e9f8d2a4b # dedup key — store + reject duplicates X-BuyCrypt-Timestamp: 1745605200123 # ms epoch when payload was built X-BuyCrypt-Signature: 5e8c2d… # hex(HMAC-SHA256(webhookSecret, ts + "." + body)) { "event": "subscription.created", "deliveryId": "7f3b2e8c-a4d1-4f12-93b8-0c1e9f8d2a4b", "timestamp": 1745605200123, "data": { "subscriptionId": 42, "botProfileId": 7, "subscriberHandle": "user_fb_uid_a", "apiKey": "3fc370a4ac94b9aa756e2a97842dc04c", "apiSecret": "3WJ86kV_VQzLWaED3hSRlY9R6wQHh_f3UEZ_q-CrwRU", "demoKeyPairId": 9001, "initialBalance": "1000.00000000", "permissions": "READ_TRADE", "ipWhitelist": "", "createdAt": "2026-04-25T18:00:00Z" } }
subscription.deleted —— 用户已断开,密钥已禁用X-BuyCrypt-Event: subscription.disconnected { "event": "subscription.disconnected", "deliveryId": "…", "timestamp": …, "data": { "subscriptionId": 42, "botProfileId": 7, "apiKey": "3fc370a4…", "reason": "USER_UNSUBSCRIBED", "disconnectedAt": "2026-04-25T18:30:00Z" } }
secret.regenerated —— 管理员已轮换你的 webhook secretX-BuyCrypt-Event: secret.regenerated { "event": "secret.regenerated", "deliveryId": "…", "timestamp": …, "data": { "subscriptionId": 42, "apiKey": "3fc370a4…", "newApiSecret": "new_plaintext_keep_old_valid_24h", "oldSecretValidUntil": "2026-04-26T18:00:00Z" } }
Use the raw request body bytes — DO NOT parse JSON first and re-serialize, you'll lose key order and signatures will diverge. Always compare in constant time.
# Python (FastAPI / Flask) import hmac, hashlib, time WEBHOOK_SECRET = "whsec_aGVsbG8gd29ybGQ_..." # whsec_…43 chars def verify(headers, body_bytes): sig = headers["X-BuyCrypt-Signature"] ts = int(headers["X-BuyCrypt-Timestamp"]) # anti-replay: reject if too old if abs(time.time() * 1000 - ts) > 5 * 60 * 1000: return False payload = f"{ts}.".encode() + body_bytes expected = hmac.new(WEBHOOK_SECRET.encode(), payload, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, sig)
// Node.js / Express — read RAW body, not parsed JSON const crypto = require('crypto'); const SECRET = 'whsec_aGVsbG8gd29ybGQ_...'; app.post('/buycrypt/hook', express.raw({ type: 'application/json' }), // raw, not json()! (req, res) => { const sig = req.headers['x-buycrypt-signature']; const ts = parseInt(req.headers['x-buycrypt-timestamp'], 10); if (Math.abs(Date.now() - ts) > 5 * 60 * 1000) return res.status(401).end(); const expected = crypto.createHmac('sha256', SECRET) .update(`${ts}.`).update(req.body).digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) { return res.status(401).end(); } // req.body is a Buffer here — JSON.parse(req.body.toString('utf8')) res.sendStatus(200); });
共 6 次尝试,按指数退避:1 分钟、5 分钟、30 分钟、2 小时、6 小时、12 小时。全部 6 次失败后,事件会进入我们的死信表,管理员可以重放。
如果你的接口连续失败 10 次,我们会将其标记为禁用并停止发送事件。请联系我们重新启用。这可以防止失效的机器人无限期地阻挡新订阅者。
每个请求体都会使用注册时共享的密钥进行 HMAC-SHA256 签名。请在信任负载之前以恒定时间校验签名。示例请参见我们的合作伙伴指南。
基础 URL:https://api.buycrypt.com/fapi。鉴权:X-MBX-APIKEY 请求头 + 签名接口上的 HMAC-SHA256 签名。Recv window:默认 5,000 ms,最大 60,000 ms。
{}。MARKET、LIMIT、STOP_MARKET、TAKE_PROFIT_MARKET、STOP、TAKE_PROFIT(限价版)、TRAILING_STOP_MARKET。参数:reduceOnly、closePosition、timeInForce(GTC/IOC/FOK)、用于幂等的 newClientOrderId、workingType、callbackRate。orderId 或 origClientOrderId 查询单个订单。{dualSidePosition: false}。ORDER_TRADE_UPDATE、ACCOUNT_UPDATE、MARGIN_CALL。负载结构与 Binance 相同。subscribe/unsubscribe/list_subscriptions 控制消息——直通上游 Binance。X-MBX-USED-WEIGHT-1M、X-MBX-ORDER-COUNT-10S,429 时附带 Retry-After。Retry-After 退避无需申请表,无需审核排队,无需接入费用。像普通用户一样注册,在移动应用中生成 API 密钥,将你的机器人指向 https://api.buycrypt.com/fapi——接入流程就是这么简单。