Autenticación

Todas las solicitudes API requieren autenticación HMAC-SHA256 mediante cabeceras HTTP. Obtenga sus credenciales en el panel → Tiendas.

Cabeceras requeridas

CabeceraDescripción
X-Api-KeyClave API de su tienda
X-TimestampTimestamp Unix actual (ventana ±5 min)
X-SignatureHMAC-SHA256 de timestamp + method + path + body firmado con API Secret

Ejemplo de firma

payload = "1700000000" + "POST" + "/api/v1/payment/create" + '{"amount":"100"}'
signature = HMAC-SHA256(payload, api_secret)
Cada tienda tiene su propia clave API. Una cuenta puede tener múltiples tiendas.

Crear pago

POST/api/v1/payment/createAuth Required

Crear un nuevo pago. Soporta cripto y conversión fiat→cripto.

Cuerpo de la solicitud (JSON)

ParámetroTipoDescripción
amount*stringMonto en cripto (ej. "100.00" USDT o "0.005" BTC)
order_idstringSu ID de pedido interno
fiat_amountstringMonto en fiat (sobrescribe amount)
fiat_currencystringMoneda fiat: USD, EUR, RUB, CNY, GBP
metadataobjectJSON arbitrario (devuelto en webhook)
La moneda se configura por tienda en el Panel (Configuración → Tiendas). Si acepta múltiples monedas, la API devuelve un payment_url con selección. Si solo hay una, el pago se crea inmediatamente.
Use fiat_amount + fiat_currency para auto-conversión desde fiat.

Respuesta — Moneda única

{
  "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-..."
  }
}

Respuesta — Múltiples monedas (selección requerida)

{
  "success": true,
  "data": {
    "payment_id": null,
    "status": "selecting",
    "amount": 100,
    "currencies": ["USDT_TRC20", "BTC", "ETH"],
    "payment_url": "https://soko.ai/pay/select?token=..."
  }
}
Importante: Siempre redirija al usuario a payment_url. Cuando payment_id es null, el usuario elegirá moneda primero.

Estado del pago

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

Respuesta

{
  "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"
  }
}

Estados de pago

EstadoDescripción
selectingEsperando selección de moneda
pendingEsperando pago
queuedTodos los slots USDT ocupados
confirmingTransacción detectada
completedPago confirmado
expiredPago expirado
overpaidRecibido más de lo esperado
underpaidRecibido menos de lo esperado

Lista de pagos

GET/api/v1/paymentsAuth Required

Lista paginada. Filtrar por status, currency, fechas.

Parámetros de consulta

ParámetroTipoDescripción
pageoptionalintegerNúmero de página (predeterminado: 1)
per_pageoptionalintegerResultados por página, 1-100 (predeterminado: 20)
statusoptionalstringFiltrar por estado
currencyoptionalstringFiltrar por moneda

Saldo del comerciante

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
    }
  }
}

Tipos de cambio Public

GET/api/v1/rates

Sin autenticación. Caché de 5 min.

Conversión

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
  }
}

Webhooks

Al cambiar el estado, enviamos POST a su webhook URL.

Cabeceras del webhook

EncabezadoDescripción
X-SignatureHMAC-SHA256 de timestamp + body firmado con Webhook Secret
X-TimestampTimestamp Unix

Cuerpo del webhook

{
  "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 }
}

Eventos

payment.completedPago confirmado
payment.confirmingTransacción detectada
payment.expiredPago expirado
payment.underpaidMenos de lo esperado
Siempre verifique la firma. Devuelva HTTP 200. Hasta 5 reintentos.

Verificación de firma (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...

Widget JavaScript

Integre un widget de pago. Solo HTML + JS.

Inicio rápido

<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>
El widget se abre como overlay iframe.

Acepte donaciones en criptomonedas en cualquier sitio web. Sin firmas API — solo su clave API de tienda.

Cómo funciona

Active las donaciones en la configuración de su tienda y añada el widget a su sitio. Los visitantes pueden donar en USDT, BTC o ETH. Cada donación crea un pago rastreable — visible en su Panel bajo ❤️ Donaciones.

Inicio rápido — Botón

Añade un botón "Donar" donde se coloca el script:

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

Barra superior

Muestra una barra fija de donación en la parte superior:

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

En línea

Renderiza el botón dentro de un elemento específico:

<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>

Atributos de personalización

ParámetroDescripción
data-store-keyClave API de tienda required
data-modebutton (predeterminado), topbar o inline
data-targetID del elemento para modo inline optional
data-textTexto personalizado (sobrescribe config. de tienda) optional
data-amountsMontos predefinidos, separados por comas: "5,10,25" optional
data-colorColor de acento, ej. "#e11d48" optional

Página de donación directa

También puede enlazar directamente a la página de donación sin widget:

https://soko.ai/donate/YOUR_STORE_API_KEY

API: Crear Donación

POST/donate/create Public

Cree una donación programáticamente. Sin firma requerida.

ParámetroDescripción
api_keyClave API de tienda required
fiat_amountMonto en fiat (ej. 10) required*
fiat_currencyCódigo de moneda fiat (ej. USD) optional, default: USD
amountMonto directo en cripto (alternativa a fiat) optional
currencyUSDT_TRC20, BTC o ETH required
donor_nameNombre del donante optional
donor_messageMensaje del donante (máx. 500 caracteres) optional
Las donaciones no activan webhooks. Monitoréelas en Panel → ❤️ Donaciones.

Manejo de errores

{
  "success": false,
  "error": "Description of what went wrong"
}
Código HTTPSignificado
200Éxito
400Solicitud incorrecta
401Auth faltante
403Firma inválida
404No encontrado
500Error del servidor

Ejemplos de código

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 日本語