Jeśli twój bot już mówi w API Binance USD-M Futures, zmień jeden base URL i działasz na BuyCrypt. Nasi użytkownicy odkrywają twojego bota w rankingu, testują go na darmowym koncie demo $1000 i przechodzą na prawdziwe klucze, gdy się przekonają.
Bez przepisywania kodu. Bez specyficznych dziwactw giełdy. To samo podpisywanie HMAC-SHA256, ten sam strumień WebSocket user-data, te same typy zleceń — owinięte wokół naszego silnika handlu demo, dzięki czemu użytkownicy mogą porównywać boty bez ryzykowania kapitału.
Każdy subskrybujący użytkownik otrzymuje własne konto demo z wirtualnym saldem $1000. Twój bot na nim handluje. Widzą PnL na żywo, drawdown, win rate. Zero ryzyka dla ich realnego kapitału — i zero kosztów pozyskania dla ciebie.
Konto demo twojego bota pojawia się w publicznym rankingu z odznaką 🤖 BOT. Użytkownicy widzą ranking PnL wśród prawdziwych traderów. Klikają wiersz, wciskają „Połącz” — natychmiastowa subskrypcja.
Jeśli twój bot korzysta z dowolnego SDK Binance Futures (binance-connector-python, python-binance, CCXT itd.), skieruj jego base_url na https://api.buycrypt.com/fapi. HMAC, recvWindow, typy zleceń — identyczne.
Gdy użytkownik subskrybuje, wysyłamy metodą POST świeżo wygenerowany klucz API + secret na twój URL webhooka — podpisany HMAC, ponawiany przy błędzie z exponential backoff, odzyskiwalny z kolejki dead-letter. Nigdy nie musisz prosić użytkownika o dane dostępowe.
Użytkownik otwiera ranking. Konto twojego bota pojawia się z chipem 🤖 BOT obok nazwy użytkownika, plus liczba subskrybentów. Klika wiersz.
Na stronie profilu bota widzi „Połącz z kontem demo”. Jedno kliknięcie tworzy dla nich nowe demo $1000 i twój bot zaczyna na nim handlować.
Użytkownik obserwuje, jak bot handluje na jego demo przez dni lub tygodnie. PnL, pozycje, win rate — wszystko na żywo w aplikacji. Jeśli mu się podoba, wprowadza swój prawdziwy klucz API Binance w BuyCrypt, aby przejść z demo na produkcję.
Użytkownik dodaje swój prawdziwy klucz API Binance w BuyCrypt. Dostarczamy go do twojego webhooka tak samo, jak dostarczyliśmy klucz demo — to samo zdarzenie subscription.created, tylko z jego danymi produkcyjnymi. Jedna integracja obsługuje zarówno demo, jak i przepływy na żywo.
Zarejestruj zwykłe konto BuyCrypt — ten sam proces co dla każdego użytkownika. W momencie rejestracji otrzymasz darmowe konto demo z saldem startowym. Bez formularza zgłoszeniowego, bez kolejki weryfikacji.
Wygeneruj klucze API bezpośrednio w aplikacji mobilnej BuyCrypt: Mój profil → Klucze API → dotknij swoje konto demo → Generuj. Otrzymasz świeży apiKey + apiSecret pokazany jednorazowo — skopiuj je do swojego bota. Następnie skieruj swojego istniejącego bota Binance USD-M Futures na https://api.buycrypt.com/fapi i po prostu działa — ten sam HMAC, te same endpointy, te same typy zleceń.
Gdy tylko wykryjemy handel sterowany przez API na twoim demo, twoje konto zostaje automatycznie oznaczone jako bot. Twoje demo pojawia się w rankingu z chipem 🤖 BOT i publicznym profilem, dzięki czemu inni użytkownicy mogą je odkryć i subskrybować.
Gdy będziesz gotowy przyjmować subskrybentów, dodaj URL webhooka do profilu bota w ustawieniach. Za każdym razem, gdy użytkownik subskrybuje — na demo lub z prawdziwymi kluczami Binance — wysyłamy metodą POST zdarzenie subscription.created z kluczem API + secret dla konta tego użytkownika. Zapisz (userId, apiKey, apiSecret) i zacznij handlować w ich imieniu.
Większość SDK Binance Futures akceptuje niestandardowy base URL. Oto cała zmiana, jakiej potrzebuje typowy bot w Pythonie:
# 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's go-binance, JS node-binance-api — wszystkie działają tak samo. Zwykłe boty requests.get(...).headers["X-MBX-APIKEY"] = key też działają; reguła podpisu HMAC jest bajt w bajt identyczna.
Gdy użytkownik BuyCrypt subskrybuje twojego bota, generujemy klucz API + secret po stronie serwera dla tego użytkownika i wysyłamy je metodą POST na twój zarejestrowany URL webhooka. Secret nigdy nie trafia do użytkownika — trafia tylko do ciebie, przez HTTPS, podpisany.
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 — użytkownik właśnie zasubskrybował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 — użytkownik odłączył się, klucz wyłączonyX-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 — administrator zmienił twój secret webhookaX-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 prób z exponential backoff: 1 min, 5 min, 30 min, 2 godz, 6 godz, 12 godz. Po niepowodzeniu wszystkich 6 zdarzenie trafia do naszej tabeli dead-letter i administrator może je odtworzyć.
Jeśli twój endpoint zawiedzie 10 razy z rzędu, oznaczamy go jako wyłączony i przestajemy wysyłać zdarzenia. Skontaktuj się z nami, aby ponownie go włączyć. Zapobiega to blokowaniu nowych subskrybentów przez martwego bota w nieskończoność.
Każde body jest podpisane HMAC-SHA256 secretem udostępnionym przy rejestracji. Zweryfikuj w czasie stałym, zanim zaufasz payloadowi. Przykłady w naszym przewodniku dla partnerów.
Base URL: https://api.buycrypt.com/fapi. Autoryzacja: nagłówek X-MBX-APIKEY + podpis HMAC-SHA256 na podpisanych endpointach. Recv window: domyślnie 5000 ms, maksymalnie 60000 ms.
{}.MARKET, LIMIT, STOP_MARKET, TAKE_PROFIT_MARKET, STOP, TAKE_PROFIT (wariant limit), TRAILING_STOP_MARKET. Flagi: reduceOnly, closePosition, timeInForce (GTC/IOC/FOK), newClientOrderId do idempotencji, workingType, callbackRate.orderId lub origClientOrderId.{dualSidePosition: false}.ORDER_TRADE_UPDATE, ACCOUNT_UPDATE, MARGIN_CALL. Ten sam kształt payloadu co Binance.subscribe/unsubscribe/list_subscriptions — przekazywane bezpośrednio do Binance.X-MBX-USED-WEIGHT-1M, X-MBX-ORDER-COUNT-10S, Retry-After przy 429.Retry-AfterBez formularza zgłoszeniowego, bez kolejki weryfikacji, bez opłat integracyjnych. Zarejestruj się jak każdy użytkownik, wygeneruj klucze API w aplikacji mobilnej, skieruj swojego bota na https://api.buycrypt.com/fapi — to całe wdrożenie.