Аутентификация

Все API-запросы требуют HMAC-SHA256 аутентификации через HTTP-заголовки. Получите ключи в личном кабинете → Магазины.

Обязательные заголовки

ЗаголовокОписание
X-Api-KeyAPI-ключ вашего магазина
X-TimestampТекущий Unix timestamp (окно ±5 мин)
X-SignatureHMAC-SHA256 от timestamp + method + path + body, подписанная API Secret

Пример подписи

payload = "1700000000" + "POST" + "/api/v1/payment/create" + '{"amount":"100"}'
signature = HMAC-SHA256(payload, api_secret)
Каждый магазин имеет свои API-ключ и секрет. Один аккаунт может содержать несколько магазинов.

Создание платежа

POST/api/v1/payment/createAuth Required

Создать новый платёж. Поддерживается указание суммы в крипто и конвертация из фиата.

Тело запроса (JSON)

ПараметрТипОписание
amount*stringСумма в крипто (напр. "100.00" USDT или "0.005" BTC)
order_idstringВаш внутренний ID заказа
fiat_amountstringСумма в фиате (заменяет amount)
fiat_currencystringФиатная валюта: USD, EUR, RUB, CNY, GBP
metadataobjectПроизвольный JSON (возвращается в вебхуке)
Принимаемая валюта настраивается для каждого магазина в Панели управления (Настройки → Магазины). Если магазин принимает несколько валют, API вернёт payment_url со страницей выбора. Если включена одна валюта — платёж создаётся сразу.
Используйте fiat_amount + fiat_currency для автоконвертации из фиата. Система получит текущий курс и рассчитает сумму в крипто.

Ответ — Одна валюта (прямой платёж)

{
  "success": true,
  "data": {
    "payment_id": "a1b2c3d4-...",
    "amount": "100.14",
    "currency": "USDT_TRC20",
    "pay_address": "TXyz...abc",
    "status": "pending",
    "expires_at": "2025-01-15T12:30:00Z",
    "payment_url": "https://soko.ai/pay/a1b2c3d4-..."
  }
}

Ответ — Несколько валют (требуется выбор)

{
  "success": true,
  "data": {
    "payment_id": null,
    "status": "selecting",
    "amount": 100,
    "currencies": ["USDT_TRC20", "BTC", "ETH"],
    "payment_url": "https://soko.ai/pay/select?token=..."
  }
}
Важно: Всегда перенаправляйте пользователя на payment_url независимо от типа ответа. Когда payment_id = null, пользователь сначала выберет валюту, затем платёж создастся автоматически.

Статус платежа

GET/api/v1/payment/{payment_id}Auth Required

Ответ

{
  "success": true,
  "data": {
    "payment_id": "a1b2c3d4-...",
    "order_id": "ORDER-123",
    "status": "completed",
    "amount_requested": 100.14,
    "amount_with_cents": 100.14,
    "amount_received": 100.14,
    "currency": "USDT_TRC20",
    "pay_address": "TXyz...abc",
    "tx_hash": "abc123...",
    "confirmations": 21,
    "confirmed_at": "2025-01-15T12:25:00Z",
    "expires_at": "2025-01-15T12:30:00Z",
    "created_at": "2025-01-15T12:00:00Z"
  }
}

Статусы платежей

СтатусОписание
selectingОжидание выбора валюты покупателем (несколько валют включено)
pendingОжидание оплаты. Показать QR / адрес покупателю
queuedВсе USDT-слоты заняты. Скоро перейдёт в pending
confirmingТранзакция обнаружена, ожидание подтверждений блокчейна
completedПлатёж подтверждён. Можно отправлять товар
expiredОплата не получена до истечения таймаута (по умолчанию 30 мин)
overpaidПолучено больше ожидаемого. Считается завершённым
underpaidПолучено меньше ожидаемого

Список платежей

GET/api/v1/paymentsAuth Required

Постраничный список платежей. Фильтрация по status, currency, датам from/to.

Параметры запроса

ПараметрТипОписание
pageoptionalintegerНомер страницы (по умолч.: 1)
per_pageoptionalintegerРезультатов на странице, 1-100 (по умолч.: 20)
statusoptionalstringФильтр по статусу
currencyoptionalstringФильтр по валюте

Баланс мерчанта

GET/api/v1/merchant/balanceAuth Required
{
  "success": true,
  "data": {
    "USDT_TRC20": {
      "available": 1250.50,
      "pending": 100.00,
      "total_received": 5000.00,
      "total_withdrawn": 3750.00,
      "total_commission": 75.00
    },
    "BTC": {
      "available": 0.05000000,
      "pending": 0.00100000,
      "total_received": 0.10000000,
      "total_withdrawn": 0.04900000,
      "total_commission": 0.00150000
    },
    "ETH": {
      "available": 1.25000000,
      "pending": 0.10000000,
      "total_received": 2.00000000,
      "total_withdrawn": 0.65000000,
      "total_commission": 0.03000000
    }
  }
}

Курсы валют Public

GET/api/v1/rates

Аутентификация не требуется. Кеш 5 минут.

Конвертация

GET /api/v1/rates?amount=5000&fiat=RUB&crypto=USDT_TRC20

{
  "success": true,
  "data": {
    "rates": {
      "btc": { "usd": 97500, "eur": 91200, "rub": 8775000 },
      "eth": { "usd": 3200, "eur": 2990, "rub": 288000 },
      "usdt": { "usd": 1.0001, "eur": 0.935, "rub": 90.5 }
    },
    "converted": 55.24
  }
}

Вебхуки

При изменении статуса платежа мы отправляем POST-запрос на ваш webhook URL с деталями платежа.

Заголовки вебхука

ЗаголовокОписание
X-SignatureHMAC-SHA256 от timestamp + body, подписанная вашим Webhook Secret
X-TimestampUnix timestamp вебхука

Тело вебхука

{
  "event": "payment.completed",
  "payment_id": "a1b2c3d4-...",
  "order_id": "ORDER-123",
  "amount": 100.14,
  "amount_received": 100.14,
  "currency": "USDT_TRC20",
  "tx_hash": "abc123...",
  "confirmed_at": "2025-01-15T12:25:00Z",
  "status": "completed",
  "metadata": { "user_id": 42 }
}

События

payment.completedПлатёж подтверждён (можно доставлять)
payment.confirmingТранзакция обнаружена, ожидание подтверждений
payment.expiredПлатёж истёк без получения средств
payment.underpaidПолучено меньше ожидаемого
Всегда проверяйте подпись вебхука перед обработкой. Верните HTTP 200 для подтверждения. Мы повторяем до 5 раз с экспоненциальной задержкой (1м, 5м, 30м, 2ч, 12ч).

Проверка подписи (PHP)

$timestamp = $_SERVER['HTTP_X_TIMESTAMP'];
$signature = $_SERVER['HTTP_X_SIGNATURE'];
$body = file_get_contents('php://input');

$expected = hash_hmac('sha256', $timestamp . $body, $webhookSecret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    die('Invalid signature');
}

$payload = json_decode($body, true);
// Process payment...

JavaScript-виджет

Встройте платёжный виджет на свой сайт. Бэкенд-интеграция не нужна — только HTML + JS.

Быстрый старт

<script src="https://soko.ai/widget.js"></script>
<script>
CryptoMerchant.init({ apiKey: 'YOUR_STORE_API_KEY' });

document.getElementById('pay-btn').addEventListener('click', function() {
    CryptoMerchant.pay({
        amount: 100.00,
        order_id: 'ORDER-123',

        // Or use fiat conversion:
        // fiat_amount: 5000,
        // fiat_currency: 'RUB',

        onSuccess: function(payment) {
            alert('Payment confirmed! TX: ' + payment.tx_hash);
        },
        onClose: function() {
            console.log('Widget closed');
        },
        onError: function(err) {
            console.error('Payment error:', err);
        }
    });
});
</script>

<button id="pay-btn">Pay with Crypto</button>
Виджет открывается как iframe-оверлей. Платёж создаётся на сервере, ваш API-ключ не раскрывается покупателям.

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

Как это работает

Включите донаты в настройках магазина, затем добавьте виджет на сайт. Посетители могут пожертвовать в USDT, BTC или ETH. Каждый донат создаёт отслеживаемый платёж — все донаты видны в панели ❤️ Донаты.

Быстрый старт — Кнопка

Добавляет кнопку «Donate» в место вставки скрипта:

<script src="https://soko.ai/donate-widget.js"
        data-store-key="YOUR_STORE_API_KEY"></script>

Верхняя панель

Фиксированная панель с призывом к донату в верхней части страницы:

<script src="https://soko.ai/donate-widget.js"
        data-store-key="YOUR_STORE_API_KEY"
        data-mode="topbar"></script>

Встроенный

Отрисовывает кнопку внутри указанного элемента:

<div id="crypto-donate"></div>
<script src="https://soko.ai/donate-widget.js"
        data-store-key="YOUR_STORE_API_KEY"
        data-mode="inline"
        data-target="crypto-donate"></script>

Атрибуты настройки

ПараметрОписание
data-store-keyAPI-ключ магазина required
data-modebutton (по умолч.), topbar или inline
data-targetID элемента для inline-режима optional
data-textСвой текст (переопределяет настройки магазина) optional
data-amountsПредустановленные суммы через запятую: "5,10,25" optional
data-colorЦвет акцента, напр. "#e11d48" optional

Прямая ссылка на донат

Можно дать прямую ссылку на страницу доната без виджета:

https://soko.ai/donate/YOUR_STORE_API_KEY

API: Создание доната

POST/donate/create Public

Создание доната программно. Подпись не требуется.

ПараметрОписание
api_keyAPI-ключ магазина required
fiat_amountСумма в фиате (напр. 10) required*
fiat_currencyКод фиатной валюты (напр. USD) optional, default: USD
amountСумма в крипте (альтернатива fiat) optional
currencyUSDT_TRC20, BTC или ETH required
donor_nameИмя донатера optional
donor_messageСообщение донатера (макс. 500 символов) optional
Донаты не вызывают вебхуки. Отслеживайте их в панели → ❤️ Донаты.

Обработка ошибок

{
  "success": false,
  "error": "Description of what went wrong"
}
HTTP-кодЗначение
200Успех
400Неверный запрос (невалидные параметры)
401Отсутствуют или просрочены заголовки авторизации
403Неверная подпись или заблокированный аккаунт
404Ресурс не найден
500Ошибка сервера

Примеры кода

PHP
Python
Node.js
cURL
<?php
$apiKey = 'your_api_key';
$apiSecret = 'your_api_secret';

$body = json_encode([
    'amount' => '100.00',
    'order_id' => 'ORDER-' . time(),
]);

$timestamp = (string) time();
$method = 'POST';
$path = '/api/v1/payment/create';

$signature = hash_hmac('sha256', $timestamp . $method . $path . $body, $apiSecret);

$ch = curl_init('https://soko.ai' . $path);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Api-Key: ' . $apiKey,
        'X-Timestamp: ' . $timestamp,
        'X-Signature: ' . $signature,
    ],
]);

$response = json_decode(curl_exec($ch), true);
echo $response['data']['payment_url'];
import hmac, hashlib, time, json, requests

API_KEY = 'your_api_key'
API_SECRET = 'your_api_secret'
BASE_URL = 'https://soko.ai'

body = json.dumps({
    'amount': '100.00',
    'order_id': f'ORDER-{int(time.time())}'
})

timestamp = str(int(time.time()))
method = 'POST'
path = '/api/v1/payment/create'

payload = f'{timestamp}{method}{path}{body}'
signature = hmac.new(API_SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()

r = requests.post(f'{BASE_URL}{path}', data=body, headers={
    'Content-Type': 'application/json',
    'X-Api-Key': API_KEY,
    'X-Timestamp': timestamp,
    'X-Signature': signature,
})

print(r.json()['data']['payment_url'])
const crypto = require('crypto');
const https = require('https');

const API_KEY = 'your_api_key';
const API_SECRET = 'your_api_secret';

const body = JSON.stringify({
    amount: '100.00',
    order_id: `ORDER-${Date.now()}`
});

const timestamp = Math.floor(Date.now() / 1000).toString();
const method = 'POST';
const path = '/api/v1/payment/create';

const signature = crypto
    .createHmac('sha256', API_SECRET)
    .update(timestamp + method + path + body)
    .digest('hex');

fetch('https://soko.ai' + path, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-Api-Key': API_KEY,
        'X-Timestamp': timestamp,
        'X-Signature': signature,
    },
    body
})
.then(r => r.json())
.then(data => console.log(data.data.payment_url));
# Generate signature first (bash):
TIMESTAMP=$(date +%s)
BODY='{"amount":"100.00","order_id":"ORDER-1"}'
PAYLOAD="${TIMESTAMP}POST/api/v1/payment/create${BODY}"
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "your_api_secret" | cut -d' ' -f2)

curl -X POST https://soko.ai/api/v1/payment/create \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: your_api_key" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -d "$BODY"
English Русский 中文 Español Deutsch Français Português 日本語