Deposits Endpoints¶
Краткое содержание: Детальная документация Deposit endpoints — получение депозитного адреса через Crypto2B API, история депозитов, webhook-обработка депозитов. Полная интеграция с внешними провайдерами.
Обзор Endpoints¶
| Метод | Endpoint | Описание | Auth требуется | Интеграция |
|---|---|---|---|---|
| GET | /api/user/deposits/address |
Получить персональный депозитный адрес (Crypto2B) | ✅ Да | Crypto2B API |
| GET | /api/user/deposits |
История депозитов пользователя | ✅ Да | PostgreSQL |
| POST | /api/webhooks/crypto2b/deposit |
Webhook обработка депозитов (Crypto2B → Saga) | ❌ Нет | Crypto2B Webhook |
| GET | /api/deposits/status |
Публичный статус депозитов (без auth) | ❌ Нет | PostgreSQL |
GET /api/user/deposits/address¶
Получить персональный депозитный адрес для пользователя через Crypto2B API интеграцию.
Запрос¶
GET /api/user/deposits/address?currency=USDT&network=TRC20
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | User JWT токен (email-based) |
Query параметры:
| Параметр | Тип | Обязательно | Описание | По умолчанию |
|---|---|---|---|---|
currency |
string | ❌ Нет | Валюта: USDT, USDC |
USDT |
network |
string | ❌ Нет | Сеть: TRC20, ERC20, BEP20 |
TRC20 |
Ответ¶
Успех (200 OK):
{
"success": true,
"data": {
"address": "TAuepQSzmUrXFkGYjHuPTTTrj2kVdCfhpy",
"currency": "USDT",
"network": "TRC20",
"chainId": "TRON",
"crypto2bProvider": "crypto2b.com",
"crypto2bAddressId": "addr_c2b_abc123",
"isExternal": true,
"qrCode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...",
"contractAddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"minimumDeposit": "500.00",
"estimatedConfirmations": 1,
"memo": null,
"expiresAt": "2025-11-21T12:34:56Z"
},
"timestamp": "2025-11-14T12:34:56Z"
}
Поля ответа:
| Поле | Тип | Описание |
|---|---|---|
data.address |
string | Персональный депозитный адрес (генерируется Crypto2B) |
data.currency |
string | Валюта депозита (USDT, USDC) |
data.network |
string | Blockchain сеть (TRC20, ERC20, BEP20) |
data.chainId |
string | Chain ID или название сети |
data.crypto2bProvider |
string | Поставщик интеграции (crypto2b.com) |
data.crypto2bAddressId |
string | ID адреса в системе Crypto2B |
data.isExternal |
boolean | Внешняя интеграция (всегда true для Integration-Only) |
data.qrCode |
string | Base64 QR код для депозита |
data.contractAddress |
string | Contract address (для токенов) |
data.minimumDeposit |
string | Минимальная сумма депозита ($500 для MVP) |
data.estimatedConfirmations |
number | Требуемое количество confirmations |
data.expiresAt |
string | Срок действия адреса (optional) |
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 401 | TOKEN_EXPIRED |
JWT токен истёк |
| 400 | CURRENCY_NOT_SUPPORTED |
Валюта не поддерживается |
| 400 | NETWORK_NOT_SUPPORTED |
Сеть не поддерживается |
| 503 | CRYPTO2B_API_ERROR |
Ошибка интеграции с Crypto2B API |
| 429 | RATE_LIMIT_EXCEEDED |
Превышен лимит запросов на генерацию адресов |
Пример cURL¶
TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -X GET "https://app.saga.surf/api/user/deposits/address?currency=USDT&network=TRC20" \
-H "Authorization: Bearer $TOKEN"
Пример TypeScript¶
// Получить депозитный адрес через Crypto2B
async function getDepositAddress(currency: string = 'USDT', network: string = 'TRC20'): Promise<string> {
const response = await fetch(`/api/user/deposits/address?currency=${currency}&network=${network}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
const { data } = await response.json();
return data.address;
}
// Отобразить депозитную информацию с QR кодом
async function displayDepositInterface() {
const response = await fetch('/api/user/deposits/address?currency=USDT&network=TRC20', {
headers: { 'Authorization': `Bearer ${token}` }
});
const { data } = await response.json();
// Отобразить QR код
const qrImage = document.getElementById('deposit-qr');
qrImage.src = data.qrCode;
// Показать адрес для копирования
document.getElementById('deposit-address').textContent = data.address;
document.getElementById('min-deposit').textContent = `Min: $${data.minimumDeposit} ${data.currency}`;
// Показать информацию о провайдере
document.getElementById('provider-info').textContent = `Powered by ${data.crypto2bProvider}`;
// Инструкции для пользователей
document.getElementById('instructions').innerHTML = `
<p>🚨 ВАЖНО: Отправляйте ТОЛЬКО ${data.currency} через сеть ${data.network}</p>
<p>📱 Используйте любой криптокошелек для отправки средств</p>
<p>⚡ Минимальная сумма: $${data.minimumDeposit}</p>
<p>🕒 Обработка: до 2-4 часов после ${data.estimatedConfirmations} подтверждений</p>
`;
}
📜 GET /api/user/deposits¶
Получить постраничную историю депозитов для аутентифицированного пользователя.
Запрос¶
GET /api/user/deposits?page=1&limit=20&status=completed&sortBy=createdAt&orderBy=desc
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | User JWT токен |
Query параметры:
| Параметр | Тип | Обязательно | Описание | По умолчанию |
|---|---|---|---|---|
page |
number | ❌ Нет | Номер страницы (с 1) | 1 |
limit |
number | ❌ Нет | Элементов на странице (макс: 100) | 20 |
status |
string | ❌ Нет | Фильтр по статусу: pending, confirming, completed, failed |
Все статусы |
currency |
string | ❌ Нет | Фильтр по валюте: USDC, ETH |
Все валюты |
sortBy |
string | ❌ Нет | Поле сортировки: createdAt, amount, confirmations |
createdAt |
orderBy |
string | ❌ Нет | Порядок сортировки: asc, desc |
desc |
startDate |
string | ❌ Нет | Фильтр от даты (ISO 8601) | - |
endDate |
string | ❌ Нет | Фильтр до даты (ISO 8601) | - |
Ответ¶
Успех (200 OK):
{
"success": true,
"data": [
{
"id": "dep_abc123",
"userId": 42,
"amount": "1000.00",
"currency": "USDC",
"status": "completed",
"fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"toAddress": "0x9876543210abcdef0123456789abcdef01234567",
"txHash": "0xabcdef123456789...",
"blockNumber": 1234567,
"confirmations": 15,
"requiredConfirmations": 12,
"network": "TRON",
"chainId": "TRC20",
"gasUsed": null,
"gasFee": "0.005 ETH",
"createdAt": "2025-10-06T10:00:00Z",
"confirmedAt": "2025-10-06T10:03:00Z",
"metadata": {
"depositAddress": "0x9876543210abcdef0123456789abcdef01234567",
"derivationPath": "m/44'/60'/0'/0/5",
"contractAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3"
}
},
{
"id": "dep_def456",
"userId": 42,
"amount": "500.00",
"currency": "USDC",
"status": "confirming",
"fromAddress": "0x123456789abcdef0123456789abcdef012345678",
"toAddress": "0x9876543210abcdef0123456789abcdef01234567",
"txHash": "0xfedcba987654321...",
"blockNumber": 1234890,
"confirmations": 5,
"requiredConfirmations": 12,
"network": "TRON",
"chainId": "TRC20",
"createdAt": "2025-10-06T11:30:00Z",
"confirmedAt": null,
"metadata": {
"estimatedCompletionTime": "2025-10-06T11:40:00Z"
}
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 47,
"totalPages": 3,
"hasNext": true,
"hasPrevious": false
},
"summary": {
"totalDeposited": "15000.00",
"totalCompleted": "14500.00",
"totalPending": "500.00",
"currency": "USDC"
},
"timestamp": "2025-10-06T12:34:56Z"
}
Статусы депозитов:
| Статус | Описание | Финальный? |
|---|---|---|
pending |
Транзакция обнаружена, awaiting confirmations | ❌ Нет |
confirming |
Accumulating confirmations (< required) | ❌ Нет |
completed |
Успешно завершён (>= required confirmations) | ✅ Да |
failed |
Транзакция провалилась или reverted | ✅ Да |
Поля ответа:
| Поле | Тип | Описание |
|---|---|---|
data[].id |
string | Уникальный ID депозита |
data[].amount |
string | Сумма депозита (SafeDecimal) |
data[].status |
string | Текущий статус |
data[].txHash |
string | Blockchain transaction hash |
data[].confirmations |
number | Текущее количество confirmations |
data[].requiredConfirmations |
number | Требуемое количество confirmations |
data[].confirmedAt |
string | Timestamp завершения (если completed) |
summary.totalDeposited |
string | Общая сумма всех депозитов |
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 400 | INVALID_DATE_RANGE |
startDate > endDate |
| 401 | TOKEN_EXPIRED |
JWT токен истёк |
Пример cURL¶
TOKEN="eyJhbGciOiJIUzI1NiIs..."
# Получить все депозиты
curl -X GET "https://app.saga.surf/api/user/deposits?page=1&limit=20" \
-H "Authorization: Bearer $TOKEN"
# Получить только completed депозиты
curl -X GET "https://app.saga.surf/api/user/deposits?status=completed" \
-H "Authorization: Bearer $TOKEN"
Пример TypeScript¶
// Получить историю депозитов
const response = await fetch('/api/user/deposits?page=1&limit=20&status=completed', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const { data: deposits, summary } = await response.json();
console.log(`Всего депозитов: ${summary.totalDeposited} ${summary.currency}`);
deposits.forEach(deposit => {
const statusIcon = {
pending: '⏳',
confirming: '🔄',
completed: '✅',
failed: '❌'
}[deposit.status];
console.log(`${statusIcon} $${deposit.amount}: ${deposit.confirmations}/${deposit.requiredConfirmations} confirmations`);
});
POST /api/webhooks/crypto2b/deposit¶
Webhook обработка депозитов от Crypto2B (автоматическая обработка депозитов без пользовательского взаимодействия).
Запрос¶
POST /api/user/blockchain/deposit
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
{
"txHash": "0xabcdef123456789...",
"amount": "1000.00",
"currency": "USDC",
"fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0"
}
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | User JWT токен |
Content-Type |
application/json |
✅ Да | JSON payload |
Body параметры:
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
txHash |
string | ✅ Да | Blockchain transaction hash (0x...) |
amount |
string | ✅ Да | Сумма депозита (SafeDecimal format) |
currency |
string | ✅ Да | Валюта: USDC, ETH |
fromAddress |
string | ✅ Да | Адрес отправителя (user wallet) |
Ответ¶
Успех (201 Created):
{
"success": true,
"data": {
"id": "dep_xyz789",
"userId": 42,
"amount": "1000.00",
"currency": "USDC",
"status": "pending",
"fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"toAddress": "0x9876543210abcdef0123456789abcdef01234567",
"txHash": "0xabcdef123456789...",
"blockNumber": null,
"confirmations": 0,
"requiredConfirmations": 12,
"createdAt": "2025-10-06T12:00:00Z",
"estimatedCompletionTime": "2025-10-06T12:03:00Z"
},
"timestamp": "2025-10-06T12:00:00Z"
}
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 400 | INVALID_TX_HASH |
Некорректный формат transaction hash |
| 400 | INVALID_AMOUNT |
Сумма меньше минимальной или некорректный формат |
| 400 | DUPLICATE_DEPOSIT |
Deposit с таким txHash уже существует |
| 401 | TOKEN_EXPIRED |
JWT токен истёк |
| 503 | BLOCKCHAIN_ERROR |
Не удалось проверить транзакцию на blockchain |
Пример cURL¶
TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -X POST https://app.saga.surf/api/user/blockchain/deposit \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"txHash": "0xabcdef123456789...",
"amount": "1000.00",
"currency": "USDC",
"fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0"
}'
Пример TypeScript¶
// Создать blockchain deposit
async function createBlockchainDeposit(txHash: string, amount: string, currency: string, fromAddress: string) {
const response = await fetch('/api/user/blockchain/deposit', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
txHash,
amount,
currency,
fromAddress
})
});
const { data } = await response.json();
console.log(`Deposit ${data.id} создан, статус: ${data.status}`);
return data;
}
// Инструкции для пользователей (любой кошелек)
async function showDepositInstructions(depositAddress: string, amount: string) {
const instructions = `
📱 Как отправить депозит:
1. Откройте ваш криптокошелек (Binance, OKX, Trust Wallet, etc.)
2. Выберите "Отправить" или "Перевести"
3. Выберите USDT (TRC20) - обязательно TRC20!
4. Вставьте адрес: ${depositAddress}
5. Введите сумму: $${amount} USDT (минимум $500)
6. Подтвердите транзакцию
⚡ Комиссия сети ~$1 (TRON)
🕒 Обработка: 2-4 часа автоматически
📧 Уведомление придет на email при зачислении
`;
document.getElementById('wallet-instructions').textContent = instructions;
}
GET /api/blockchain/deposits¶
Публичный endpoint для получения статуса депозитов (без аутентификации).
Запрос¶
Query параметры:
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
address |
string | ❌ Нет | Фильтр по deposit адресу |
txHash |
string | ❌ Нет | Фильтр по transaction hash |
limit |
number | ❌ Нет | Элементов на странице (макс: 50) |
Ответ¶
Успех (200 OK):
{
"success": true,
"data": [
{
"address": "0x9876543210abcdef0123456789abcdef01234567",
"totalDeposits": 15,
"totalAmount": "15000.00",
"currency": "USDC",
"lastDepositAt": "2025-10-06T11:30:00Z"
}
],
"timestamp": "2025-10-06T12:34:56Z"
}
Примечание: Публичный endpoint возвращает агрегированную статистику без детальной информации о пользователях.
Пример cURL¶
# Получить публичный статус депозитов
curl -X GET "https://app.saga.surf/api/blockchain/deposits?address=0x9876543210abcdef0123456789abcdef01234567"
Распространённые сценарии использования¶
Отображение deposit интерфейса¶
// Deposit UI компонент
async function DepositInterface() {
// Получить депозитный адрес
const { data: depositInfo } = await fetch('/api/user/deposits/address?currency=USDC', {
headers: { 'Authorization': `Bearer ${token}` }
}).then(r => r.json());
return (
<div className="deposit-container">
<h2>Пополнить баланс USDC</h2>
<div className="deposit-address">
<p>Ваш персональный адрес для депозитов:</p>
<div className="address-box">
<code>{depositInfo.address}</code>
<button onClick={() => copyToClipboard(depositInfo.address)}>
Копировать
</button>
</div>
</div>
<div className="qr-code">
<img src={depositInfo.qrCode} alt="QR код депозита" />
</div>
<div className="deposit-info">
<p>Минимальная сумма: ${depositInfo.minimumDeposit} {depositInfo.currency}</p>
<p>Требуемых подтверждений: {depositInfo.estimatedConfirmations}</p>
<p>Сеть: {depositInfo.network} (Chain ID: {depositInfo.chainId})</p>
</div>
</div>
);
}
Мониторинг подтверждений депозита¶
// Real-time monitoring депозита
async function monitorDepositConfirmations(depositId: string) {
const interval = setInterval(async () => {
const response = await fetch(`/api/user/deposits`, {
headers: { 'Authorization': `Bearer ${token}` }
});
const { data: deposits } = await response.json();
const deposit = deposits.find(d => d.id === depositId);
if (!deposit) return;
console.log(`Confirmations: ${deposit.confirmations}/${deposit.requiredConfirmations}`);
if (deposit.status === 'completed') {
clearInterval(interval);
showNotification('Депозит успешно зачислен!', 'success');
} else if (deposit.status === 'failed') {
clearInterval(interval);
showNotification('Депозит провалился', 'error');
}
}, 10000); // Проверка каждые 10 секунд
}
История депозитов с pagination¶
// Постраничная история депозитов
function DepositHistory() {
const [deposits, setDeposits] = useState([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
async function loadDeposits() {
const response = await fetch(`/api/user/deposits?page=${page}&limit=20`, {
headers: { 'Authorization': `Bearer ${token}` }
});
const { data, pagination } = await response.json();
setDeposits(prev => [...prev, ...data]);
setHasMore(pagination.hasNext);
}
useEffect(() => {
loadDeposits();
}, [page]);
return (
<div className="deposit-history">
<h2>История депозитов</h2>
<table>
<thead>
<tr>
<th>Дата</th>
<th>Сумма</th>
<th>Статус</th>
<th>Confirmations</th>
<th>Tx Hash</th>
</tr>
</thead>
<tbody>
{deposits.map(dep => (
<tr key={dep.id}>
<td>{new Date(dep.createdAt).toLocaleDateString()}</td>
<td>${dep.amount} {dep.currency}</td>
<td><StatusBadge status={dep.status} /></td>
<td>{dep.confirmations}/{dep.requiredConfirmations}</td>
<td>
<a href={`https://explorer.saga.surf/tx/${dep.txHash}`} target="_blank">
{dep.txHash.substring(0, 10)}...
</a>
</td>
</tr>
))}
</tbody>
</table>
{hasMore && (
<button onClick={() => setPage(p => p + 1)}>
Загрузить ещё
</button>
)}
</div>
);
}
Связанная документация¶
Другие User Endpoints:
- Balance & Transactions - Баланс и транзакции
-
Withdrawals - Операции вывода
-
Integration-Only Architecture - Основные принципы
- Deposits Flow - Crypto2B интеграция
- Database Schema - crypto2b_transactions table
"Integration-Only принципы: внешние API для crypto операций, email mandatory для пользователей, single strategy MVP"
— Saga Development Team (Phase 2 API Updates)