Подготовлено по задаче Александра (22.06.2026): разобрать их расширение (cs-skins.pro), наше расширение и всю серверную работу со Steam — и дать чёткий план, как объединить лучшее.
Наше расширение по возможностям уже мощнее их: оно и опрашивает Steam в браузере, и САМО создаёт трейд продавца, и биндит токен на сервер для подстраховки. Их расширение проще — только опрашивает и шлёт изменения по сокету, а трейд создаёт их сервер.
Наши реальные проблемы не в «у них есть что-то, чего нет у нас», а в надёжности: серверный токен протухает когда юзер офлайн; обновление по сокету заменено на опрос раз в 1.5 мин; service worker засыпает; refresh-токен часто пустой. Плюс была денежная дыра в отмене по таймауту — уже исправлена.
План ниже = взять у них надёжность (свежий токен + реалтайм по сокету), оставить наши преимущества (двойной детект клиент+сервер, авто-создание трейда), и закрыть офлайн-кейс «вырубился свет».
steamLoginSecure (часть после «||») и сам зовёт IEconService/GetTradeOffers (get_sent_offers).needs_confirmation (нужно ли мобильное подтверждение), но сами его НЕ делают.steamLoginSecure (access_token) И steamRefresh_steam (refresh_token) + steam_id. Refresh часто пустой на новой сессии.POST /extension/seller/steam-bind/tokens (access+refresh+steam_id). Ре-бинд когда сервер says «не healthy» — алярм check-steam-bind раз в 30 мин + побочно на sync (10 мин) / poll (1.5 мин).pollPendingTrades раз в 1.5 мин берёт /extension/deals/pending, проверяет каждый оффер через Steam API (4-слойный fallback), и при принятии (state 3/11) шлёт /extension/deals/{id}/report-trade-status. Есть ретрай (финансовый P1-фикс).createTradeOfferFromSession открывает Steam-вкладку и постит /tradeoffer/new/send — оффер создаётся из расширения, не вручную.| Механизм | Ключ | Видит P2P? | Что делает |
|---|---|---|---|
seller-steam:poll-trades (раз/мин) | токен продавца | ДА | видит принятие → ставит на 7-дн холд (PlaceDealOnEscrowHold) |
deals:poll-steam-trades (раз/5 мин) | платформенный STEAM_API_KEY | НЕТ | принят→холд, мёртв→отмена, таймаут (тут была дыра) |
deals:cancel-unsent (раз/мин) | — | — | отменяет «оплачено» без оффера через 15 мин |
deals:settle-escrow-holds (раз/час) | токен продавца (осн.) / ключ (fallback) | — | после холда: подтверждённо доставлено→выплата продавцу; мёртв→отмена; неясно→ждём |
seller-steam:refresh-tokens (раз/сутки) | refresh_token | — | обновляет access_token (GenerateAccessTokenForApp). Падает если refresh пустой/протух (401) |
Жизненный цикл сделки: created → paid → trade_sent → trade_accepted (холд 7д) → completed (или cancelled). Деньги покупателя висят в hold до завершения; продавцу выплачиваются только после подтверждённого холда. Сервер трейд не создаёт — только записывает trade_offer_id и валидирует, что оффер реально соответствует сделке.
| Их | Наше | |
|---|---|---|
| Свежесть токена | всегда свежий (из cookie каждый опрос) | серверный протухает офлайн; refresh часто пустой |
| Скорость детекта | реалтайм (websocket, ~сек) | опрос 1.5 мин (+SW засыпает) |
| Двойной детект (клиент+сервер) | только клиент | и клиент, и сервер |
| Авто-создание трейда | сервер (нет кнопки) | расширение (createTradeOfferFromSession) |
| Работа при офлайн-юзере | завязано на онлайн-браузер | сервер может, но токен протухает |
| Денежные дыры | ? | блайнд-отмена + гонка закрыты 22.06 |
steamRefresh_steam когда он появляется, чтобы серверный рефреш работал и токен жил дольше.Решение Александра (22.06): сервер сам создаёт и шлёт трейд по сессии продавца (кнопка «передать» уходит), а продавцу падает уведомление/алерт — «подтверди обмен в Steam Guard (в мобильном приложении)». Мобильное подтверждение делает продавец руками, мы его об этом уведомляем.
Что делаем:
Остаётся учесть бан-риск Steam (серверная отправка трейдов от имени игроков): лимиты на аккаунт, «человеческие» паузы между офферами, бэкофф при ошибках Steam. Заложим в реализацию.
deals:poll-steam-trades) для P2P бесполезен (слеп). Свести P2P-детект на seller-token поллер + клиентский report, а платформенный ключ оставить только там, где площадка реально участник.