Перейти к содержимому
Последнее обновление

Жизненный цикл ордера

Ордер проходит через несколько статусов от подтверждения котировки до завершения.

Диаграмма статусов

  prepare (котировка)
          │ accept
          ▼
      created ──────────────┐
          │                 │
          ▼                 │
     in_progress            │
       │      │             │
       ▼      ▼             ▼
   success   failed ◄───────┤
       │      │             │
       ▼      ▼             │
       disputed ◄───────────┘
       │      │
       ▼      ▼
   success   failed

Статусы

СтатусЧто значитСредства
createdОрдер создан после accept и передан в оплатуamountUsdt заморожен
in_progressИсполнитель взял ордерЗаморожен
successПлатёж выполнен, completedAt заполненСписан с баланса
failedПлатёж не выполнен, причина в failureReasonЗаморозка снята; если сумма уже была списана — возвращена
disputedПо ордеру открыт спорОстаются как были до спора

failed: частые значения failureReason

failureReasonЧто случилось
Order expiredОрдер не завершился к paymentUntil: 60 секунд после accept для nspk, 4 минуты для st00012 и gibdd_uin
expired_no_takerНикто из исполнителей не взял ордер
Dispute resolved: refundСпор решён возвратом
Dispute resolved: partial_refund (N)Спор решён частичным возвратом N USDT

Платёжная сторона может прислать и свою формулировку причины.

expired_no_taker и expired_by_system

Эти значения остались в перечислении статусов, но текущая версия API их ордерам не присваивает:

  • ордер, который никто не взял, становится failed с failureReason: expired_no_taker;
  • если исполнитель не подтвердил оплату вовремя, по ордеру автоматически открывается спор — ордер становится disputed.

Обработчик статусов всё равно лучше писать так, чтобы неизвестное значение не ломало интеграцию.

Переходы

ИзВКогда
createdin_progressИсполнитель взял ордер
createdfailedНикто не взял ордер, истёк срок или платёж отклонён
in_progresssuccess / failedПлатёж выполнен / не выполнен или истёк срок
created, in_progress, successdisputedСпор открыла платёжная сторона
success, faileddisputedВы открыли спор
disputedsuccess / failedСпор решён
failedsuccessПлатёж прошёл после истечения срока — сумма списывается с баланса

success — финальный статус, пока по ордеру не открыт спор. После решения спора ордер снова становится success или failed.

failed почти всегда финальный, но не гарантированно: если исполнитель успел оплатить уже после истечения paymentUntil (или подтверждение пришло с задержкой), ордер переходит из failed в success, сумма списывается с баланса и приходит вебхук order.status_changed со статусом success. Не считайте failed окончательным отказом для своего клиента без сверки — обработчик должен принимать success после failed.

Webhook

На переходы в success, failed и disputed приходит вебхук:

{
  "event": "order.status_changed",
  "orderId": "550e8400-e29b-41d4-a716-446655440000",
  "walletOrderId": "660e8400-e29b-41d4-a716-446655440001",
  "status": "success",
  "amountUsdt": 52.63,
  "amountRub": 5000,
  "completedAt": "2026-03-10T12:00:45.000Z",
  "failureReason": null,
  "createdAt": "2026-03-10T12:00:00.000Z"
}

Вебхука нет на created и in_progress. Когда спор открываете вы сами, вебхук может как прийти, так и нет — результат в любом случае приходит в ответе на запрос. Поля события — в разделе Webhooks.

Частичный возврат по ордеру

По уже исполненному ордеру платёжная сторона может вернуть часть суммы — пропорционально возвращённым рублям, в том числе решая так спор. Такой возврат зачисляется на баланс операцией order_partial_refund с referenceId ордера. Статус ордера при этом не меняется и вебхука нет: возврат видно только в истории баланса. Если возврат закрыл спор, ордер может так и остаться в статусе disputed.

Получение статуса

Один ордер

curl -X GET 'https://b2b.lumowallet.io/orders/{id}' \
  -H 'X-API-Key: YOUR_API_KEY'

Список ордеров

curl -X GET 'https://b2b.lumowallet.io/orders?status=success&limit=50' \
  -H 'X-API-Key: YOUR_API_KEY'

Ответ — { "orders": [...], "total": 128 }, новые сначала.

Параметры фильтрации:

  • search — поиск по идентификатору, см. ниже
  • status — фильтр по статусу
  • limit — количество записей (1-200, default 20)
  • offset — смещение для пагинации

Нужно право orders.read.

Поиск по вашему номеру заказа

curl -X GET 'https://b2b.lumowallet.io/orders?search=387057' \
  -H 'X-API-Key: YOUR_API_KEY'

search находит ордер по идентификатору, не требуя точного совпадения:

  • по вашему externalOrderId — достаточно части: запрос 387057 найдёт transaction_387057;
  • по нашему id ордера — целиком либо по первым символам;
  • полный UUID ищется точным совпадением, чтобы не цеплять чужие идентификаторы.

Запросы короче двух символов игнорируются. Тот же параметр работает и в списке диспутов — там он ищет по ордеру, к которому относится диспут.

Рекомендации

  1. Подписывайтесь на webhooks — не полагайтесь только на polling.
  2. Учитывайте paymentUntil — к этому времени (60 секунд после accept для nspk, 4 минуты для st00012 и gibdd_uin) ордер либо завершён, либо станет failed, либо по нему уже открыт спор.
  3. Обрабатывайте disputed — ордер может уйти в спор и без вашего участия, а затем вернуться в success или failed.
  4. Логируйте failureReason — для анализа ошибок.