Получайте real-time уведомления о событиях через HTTP callbacks.
Укажите webhookUrl в профиле компании:
curl -X PATCH 'https://b2b.lumowallet.io/auth/company/profile' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"webhookUrl": "https://your-server.com/webhooks/lumo"
}'Webhooks отправляются как POST запросы:
POST /webhooks/lumo HTTP/1.1
Host: your-server.com
Content-Type: application/json
X-Lumo-Signature: 5d41402abc4b2a76b9719d911017c592
X-Lumo-Delivery-Id: 550e8400-e29b-41d4-a716-446655440000
{...payload...}| Заголовок | Описание |
|---|---|
X-Lumo-Signature | HMAC-SHA256 подпись тела запроса |
X-Lumo-Delivery-Id | Уникальный ID доставки |
Content-Type | application/json |
Всегда проверяйте подпись для защиты от подмены:
const crypto = require('crypto');
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(body))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// В обработчике webhook
app.post('/webhooks/lumo', (req, res) => {
const signature = req.headers['x-lumo-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Обработка события
handleEvent(req.body);
res.status(200).send('OK');
});import hmac
import hashlib
def verify_signature(body: str, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Изменение статуса ордера.
{
"event": "order.status_changed",
"orderId": "550e8400-e29b-41d4-a716-446655440000",
"walletOrderId": "660e8400-e29b-41d4-a716-446655440001",
"status": "success",
"amountUsdt": 52.63,
"amountRub": 5000.00,
"completedAt": "2026-03-10T12:00:45Z",
"failureReason": null,
"createdAt": "2026-03-10T12:00:00Z"
}Новый депозит обнаружен в сети.
{
"event": "deposit.created",
"depositId": "770e8400-e29b-41d4-a716-446655440002",
"txHash": "abc123...",
"walletAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"fromAddress": "TXyz...",
"amount": 100.00,
"tokenSymbol": "USDT",
"status": "new",
"createdAt": "2026-03-10T12:00:00Z",
"updatedAt": "2026-03-10T12:00:00Z"
}Депозит успешно зачислен.
{
"event": "deposit.completed",
"depositId": "770e8400-e29b-41d4-a716-446655440002",
"txHash": "abc123...",
"walletAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"amount": 100.00,
"status": "completed",
"sweepTxHash": "def456...",
"createdAt": "2026-03-10T12:00:00Z",
"updatedAt": "2026-03-10T12:00:30Z"
}AML-проверка не пройдена.
{
"event": "deposit.aml_failed",
"depositId": "770e8400-e29b-41d4-a716-446655440002",
"txHash": "abc123...",
"amount": 100.00,
"status": "aml_failed",
"amlCheckId": "check-123",
"amlResult": "high_risk",
"error": "Sanctioned address detected",
"createdAt": "2026-03-10T12:00:00Z"
}Для User Wallets — те же события, но с externalId:
{
"event": "deposit.completed",
"depositId": "880e8400-e29b-41d4-a716-446655440003",
"externalId": "user-12345",
"txHash": "ghi789...",
"walletAddress": "TUserWallet...",
"amount": 50.00,
"status": "completed",
"createdAt": "2026-03-10T12:05:00Z"
}При ошибке доставки (не-2xx ответ) — автоматические ретраи:
| Попытка | Задержка |
|---|---|
| 1 | Немедленно |
| 2 | 1 секунда |
| 3 | 2 секунды |
| 4 | 4 секунды |
Максимум 4 попытки. После этого webhook помечается как failed.
Отвечайте 200 OK как можно быстрее. Обрабатывайте событие асинхронно:
app.post('/webhooks/lumo', async (req, res) => {
// Сразу отвечаем
res.status(200).send('OK');
// Обрабатываем в фоне
setImmediate(() => {
processWebhook(req.body);
});
});Используйте X-Lumo-Delivery-Id для дедупликации:
const processedDeliveries = new Set();
function handleWebhook(deliveryId, payload) {
if (processedDeliveries.has(deliveryId)) {
return; // Уже обработано
}
processedDeliveries.add(deliveryId);
// Обработка...
}Логируйте все входящие webhooks для отладки:
console.log({
deliveryId: req.headers['x-lumo-delivery-id'],
event: req.body.event,
timestamp: new Date().toISOString()
});Используйте Mock-сервер для тестирования интеграции без реальных транзакций:
https://lumo.redocly.app/_mock/apis