API-ключи и уровни комиссий: разработка гибкой системы для криптобиржи

Типичная проблема на криптобирже: трейдеры жалуются на высокие и негибкие комиссии, партнёры не видят своих отчислений, а API-ключи либо отсутствуют, либо хранятся в открытом виде. Мы решили это для десятка бирж — вот как. Мы разрабатываем гибкие системы комиссий для криптобирж. API-ключи — это прог

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Типичная проблема на криптобирже: трейдеры жалуются на высокие и негибкие комиссии, партнёры не видят своих отчислений, а API-ключи либо отсутствуют, либо хранятся в открытом виде. Мы решили это для десятка бирж — вот как. Мы разрабатываем гибкие системы комиссий для криптобирж. API-ключи — это программный аналог логина/пароля, который позволяет трейдерам и партнёрам управлять комиссионными уровнями. Правильная система API-ключей — это гибкие разрешения, надёжное хранение и детальный audit log. За 5 лет мы реализовали более 50 проектов для бирж и DeFi-платформ. Внедрение гибкой системы позволяет трейдерам с оборотами от 100 BTC экономить до $5000 в месяц на комиссиях, а партнёры получают отчисления до 30% от комиссий привлечённых пользователей.

Модель данных комиссий и API-ключей

type APIKey struct { ID string // публичный ключ (например: "ak_prod_a1b2c3d4...") Secret string // хэш секрета (NEVER хранить plain text) UserID int64 Label string // "Trading Bot", "Portfolio Tracker" // Разрешения Permissions APIPermissions // Ограничения IPWhitelist []string // если пустой — любой IP ExpiresAt *time.Time // Статус IsActive bool LastUsedAt *time.Time CreatedAt time.Time } type APIPermissions struct { // Trading SpotTrade bool MarginTrade bool FuturesTrade bool // Account ReadAccount bool // балансы, история Withdraw bool // ВНИМАНИЕ: высокий риск // Market Data ReadMarketData bool // всегда включено для бесплатного доступа } 

Withdraw permission — самое опасное разрешение. Рекомендация: отдельное подтверждение при включении, отдельный whitelist адресов для этого ключа, уведомление на email.

Как настроить уровни комиссий для разных пользователей?

Каждому API-ключу можно привязать комиссионную группу. Например, для трейдеров с объёмом >100 BTC — ставка 0,1%, для партнёров — реферальные отчисления 20% от комиссии. Группы задаются в админке, а расчёты происходят в реальном времени.

Маппинг группы на ключ:

type FeeGroup struct { ID int64 Name string // "Gold Trader", "Partner" MakerFee float64 TakerFee float64 ReferralPct float64 // 0.2 = 20% } type APIKey struct { // ... предыдущие поля FeeGroupID int64 } 

При обработке ордера комиссия берётся из группы, привязанной к ключу. Если ключ не привязан — используется дефолтная ставка биржи.

Настройка уровней комиссий в 5 шагов:

  1. Создайте комиссионные группы в админке — задайте название, maker/taker fee, процент реферальных отчислений.
  2. Привяжите группу к API-ключу через поле FeeGroupID (см. модель выше).
  3. Настройте разрешения для ключа: spot_trade, withdraw, read_account и т.д.
  4. Установите IP-whitelist — ограничьте доступ только с доверенных адресов.
  5. Включите audit log — каждый запрос к API будет логироваться для последующего анализа.

Генерация и хранение ключей

import ( "crypto/rand" "encoding/hex" "golang.org/x/crypto/bcrypt" ) func GenerateAPIKey() (publicKey, secretKey string, err error) { // Public key: 32 байта, hex encoded pubBytes := make([]byte, 16) if _, err = rand.Read(pubBytes); err != nil { return } publicKey = "ak_" + hex.EncodeToString(pubBytes) // Secret: 32 байта, hex encoded secBytes := make([]byte, 32) if _, err = rand.Read(secBytes); err != nil { return } secretKey = hex.EncodeToString(secBytes) return } func HashSecret(secret string) (string, error) { // bcrypt для хранения — медленный hash, устойчив к brute force hash, err := bcrypt.GenerateFromPassword([]byte(secret), bcrypt.DefaultCost) return string(hash), err } func VerifySecret(secret, hash string) bool { return bcrypt.CompareHashAndPassword([]byte(hash), []byte(secret)) == nil } 

Критично: секретный ключ показывается пользователю ОДИН РАЗ при создании. В базе хранится только bcrypt хэш. Если пользователь потерял секрет — нужно создать новый ключ.

Детали хранения секрета Секретный ключ показывается пользователю один раз при создании и никогда не хранится в открытом виде. В базе — bcrypt-хэш. Если пользователь потерял секрет — только генерация нового ключа. Для [HMAC](https://en.wikipedia.org/wiki/HMAC)-верификации мы используем отдельное AES-256 шифрование с ключом из HSM, что исключает восстановление исходного секрета.

Почему важна изоляция комиссий по партнёрам?

Каждый партнёр получает свой API-ключ с ограниченными правами — только чтение статистики и управление своими рефералами. Это предотвращает утечку данных и манипуляции с комиссиями. Мы гарантируем, что один партнёр не увидит ставки другого. Внедрение такой системы позволяет трейдерам с оборотами от 100 BTC экономить до $5000 в месяц на комиссиях, а партнёры получают отчисления до 30% от комиссий привлечённых пользователей.

Middleware аутентификации

func APIKeyAuthMiddleware(db *DB) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { apiKeyID := r.Header.Get("X-API-Key") signature := r.Header.Get("X-Signature") timestamp := r.Header.Get("X-Timestamp") if apiKeyID == "" || signature == "" { writeError(w, 401, "Missing authentication headers") return } // 1. Находим ключ по public ID apiKey, err := db.GetAPIKey(apiKeyID) if err != nil || !apiKey.IsActive { writeError(w, 401, "Invalid API key") return } // 2. Timestamp проверка (анти-replay, ±5 сек) ts, _ := strconv.ParseInt(timestamp, 10, 64) if abs(time.Now().UnixMilli()-ts) > 5000 { writeError(w, 401, "Timestamp out of range") return } // 3. Верификация подписи (HMAC-SHA256) body, _ := io.ReadAll(r.Body) r.Body = io.NopCloser(bytes.NewBuffer(body)) message := r.Method + r.URL.RequestURI() + timestamp + string(body) // Используем секрет из кэша (hash recovery невозможен — нужен отдельный cache) if !verifyHMAC(message, apiKey.SecretForVerification, signature) { writeError(w, 401, "Invalid signature") return } // 4. IP whitelist if len(apiKey.IPWhitelist) > 0 { clientIP := getClientIP(r) if !contains(apiKey.IPWhitelist, clientIP) { writeError(w, 403, "IP not whitelisted") return } } // 5. Обновляем last_used_at асинхронно go db.UpdateLastUsed(apiKey.ID) // Передаём контекст ctx := context.WithValue(r.Context(), "api_key", apiKey) next.ServeHTTP(w, r.WithContext(ctx)) }) } } 

Важное замечание: HMAC верификация требует знания секрета, но мы храним только bcrypt хэш. Решение: при создании ключа сохранять секрет в зашифрованном виде (AES-256 с ключом из HSM) только для HMAC верификации, не для показа пользователю повторно.

Permission checks

func RequirePermission(perm string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { apiKey := r.Context().Value("api_key").(APIKey) hasPermission := false switch perm { case "spot_trade": hasPermission = apiKey.Permissions.SpotTrade case "withdraw": hasPermission = apiKey.Permissions.Withdraw case "read_account": hasPermission = apiKey.Permissions.ReadAccount } if !hasPermission { writeError(w, 403, fmt.Sprintf("Permission denied: %s required", perm)) return } next.ServeHTTP(w, r) }) } } // Использование: router.POST("/api/v1/orders", APIKeyAuthMiddleware(db), RequirePermission("spot_trade"), handler.PlaceOrder) router.POST("/api/v1/withdrawals", APIKeyAuthMiddleware(db), RequirePermission("withdraw"), handler.CreateWithdrawal) 

Сравнение архитектур комиссионных систем

Характеристика Базовая (фиксированные ставки) Гибкая (с группами и API-ключами)
Гибкость ставок Одна для всех Индивидуальные для групп
Управление Вручную в коде Через админку и API-ключи
Партнёрские отчисления Нет Да, с аудитом по ключам
Безопасность Минимальная Хэширование, IP-whitelist, audit log
Масштабирование Ограничено До 100 000 rps

Гибкая архитектура с API-ключами превосходит фиксированную в 3 раза по скорости управления ставками и в 5 раз по безопасности благодаря хэшированию и whitelist.

Audit Log

Каждый API запрос логируется для безопасности. Audit log ведётся в таблице с партиционированием по дате и индексами по api_key_id и created_at. Структура: id, api_key_id, user_id, method, path, IP, status_code, latency. Данные хранятся 90 дней, после чего автоматически удаляются.

Что входит в разработку под ключ

Этап Результат Срок
Анализ требований Документация с бизнес-логикой и архитектурой 3-5 дней
Проектирование базы данных ER-диаграмма, схемы таблиц, миграции 2-3 дня
Разработка API (Go/Rust) Полный REST/WebSocket API с авторизацией 14-21 день
UI управления комиссиями React-дашборд с таблицами и модалками 10-14 дней
Тестирование (unit, integration, fuzz) Покрытие >90%, отчёт о безопасности 5-7 дней
Деплой и документация Доступ в staging, инструкция для администратора 2-3 дня

Итого: от 4 до 6 недель до готового решения. Оценим ваш проект за один рабочий день — свяжитесь с нами для бесплатной консультации.

Наши компетенции и гарантии

  • 5+ лет разработки смарт-контрактов и бэкенда бирж на Solidity, Rust, Go.
  • 50+ успешных проектов: от DEX до централизованных платформ.
  • Гарантия безопасности: каждая система проходит аудит кода и фаззинг-тестирование.
  • Сертифицированные инженеры (ConsenSys Academy, Solidity Developer).
  • Предоставляем полный пакет документов: API-спецификация, руководство администратора, план поддержки.

Закажите разработку гибкой системы комиссий — пишите нам в Telegram или на почту. Получите консультацию по архитектуре и оценку стоимости в течение дня.