身份验证

所有 API 请求需要通过 HTTP 头进行 HMAC-SHA256 身份验证。在商户面板 → 商店中获取您的密钥。

必需的请求头

请求头说明
X-Api-Key您的商店 API 密钥
X-Timestamp当前 Unix 时间戳(±5分钟窗口)
X-Signaturetimestamp + method + path + body 的 HMAC-SHA256,使用 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(在 webhook 中返回)
接受的货币在面板中按商店配置(设置 → 商店)。如果商店接受多种货币,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_idnull 时,用户将先选择货币,然后自动创建支付。

支付状态

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等待支付。向客户显示二维码/地址
queued所有 USDT 分槽已占用。即将变为 pending
confirming检测到交易,等待区块链确认
completed支付已确认。可以安全发货
expired超时前未收到付款(默认30分钟)
overpaid收到金额超过预期。视为已完成
underpaid收到金额低于预期

支付列表

GET/api/v1/paymentsAuth Required

分页支付列表。按 statuscurrencyfrom/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
  }
}

Webhooks

当支付状态变化时,我们会向您的 webhook URL 发送包含支付详情的 POST 请求。

Webhook 请求头

头部描述
X-Signaturetimestamp + body 的 HMAC-SHA256,使用 Webhook Secret 签名
X-TimestampWebhook 的 Unix 时间戳

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

事件

payment.completed支付已确认(可以安全发货)
payment.confirming检测到交易,等待确认
payment.expired支付过期,未收到资金
payment.underpaid收到金额低于预期
处理前始终验证 webhook 签名。返回 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捐赠。每笔捐赠都会创建可追踪的付款——在仪表板的❤️ 捐赠中可见。

快速开始 — 按钮

在脚本位置添加"捐赠"按钮:

<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-key商店API密钥 required
data-modebutton(默认)、topbarinline
data-target内嵌模式的元素ID 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_key商店API密钥 required
fiat_amount法币金额(如 10required*
fiat_currency法币代码(如 USDoptional, default: USD
amount加密货币直接金额(法币的替代) optional
currencyUSDT_TRC20BTCETH required
donor_name捐赠者姓名 optional
donor_message捐赠者留言(最多500字符) optional
捐赠不会触发Webhook。请在仪表板 → ❤️ 捐赠中监控。

错误处理

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