#Кошелёк и остановка обмена
Статус: Доступно.
GET /walletи остановка обмена при отрицательном балансе (402 wallet_suspended).
Назначение: как кошелёк арендатора влияет на обмен по API, какие бывают состояния, что происходит с запросами и вебхуками при отрицательном балансе и как возобновить обмен.
#Содержание
- Состояния кошелька
- GET /wallet
- Что происходит при остановке обмена
- Вебхуки при остановке
- Неизвестное состояние
- Как возобновить обмен
- Уведомления арендатору
#Состояния кошелька
Кошелёк арендатора ведётся в рублях (RUB) на любой ячейке. Суммы передаются объектом {amount, currency}, где amount — строка с двумя знаками после запятой ("125.50", "-3.20").
state | Когда | exchange | Что с запросами |
|---|---|---|---|
ok | Средств достаточно | active | Всё работает |
low | Средств мало (ниже порога предупреждения) | active | Всё работает; пора пополнить |
negative | Остаток ниже нуля | suspended | Обмен остановлен |
blocked | Кошелёк заблокирован | suspended | Обмен остановлен |
unknown | Источник баланса не ответил | active | Чтение без списаний работает, платное закрыто (ниже) |
Ровно нулевой остаток не останавливает обмен. Платформа-владелец (служебный арендатор площадки) не тарифицируется и никогда не останавливается.
#GET /wallet
Область не нужна, платы нет. Маршрут работает и при остановленном обмене — именно здесь видно причину остановки и адрес пополнения.
curl -sS "$API_BASE_URL/wallet" -H "Authorization: Bearer $API_KEY"
{
"balance": { "amount": "-3.20", "currency": "RUB" },
"state": "negative",
"exchange": "suspended",
"topup_url": "https://formula-cream.pro/ru/promo/economics#wallet",
"daily_spend": null
}
| Поле | Описание |
|---|---|
balance | Остаток. null, если состояние неизвестно или арендатор не тарифицируется |
state | ok, low, negative, blocked, unknown |
exchange | active или suspended |
topup_url | Адрес кабинета, где пополняется кошелёк. Пополнение выполняет сотрудник арендатора с правом пополнения; по ключу API кошелёк пополнить нельзя |
daily_spend | Суточные траты интеграции; null, пока расход по интеграции не учитывается. Предел интеграции виден в GET /me (wallet.daily_spend) |
Тот же блок (balance, state, exchange, topup_url, daily_spend) приходит в поле wallet ответа GET /me.
#Что происходит при остановке обмена
Пока exchange = suspended, любой маршрут, кроме GET /me и GET /wallet, отвечает 402:
{
"type": "https://formula-cream.pro/developers/errors#wallet_suspended",
"title": "Wallet is suspended",
"status": 402,
"code": "wallet_suspended",
"detail": "Data exchange is suspended because the tenant wallet balance is negative or the wallet is blocked. Top up the wallet to resume.",
"topup_url": "https://formula-cream.pro/ru/promo/economics#wallet",
"balance": { "amount": "-3.20", "currency": "RUB" },
"request_id": "req_01J…"
}
Правила:
- Проверка идёт сразу после аутентификации: до проверки областей, предела частоты и чтения тела. Запрос ничего не создаёт — ни операции, ни записи в журнале идемпотентности, ни данных.
- Это относится и к чтению, и к записи: входящие данные (события, сообщения, лиды) в остановленный обмен не принимаются. Повторите запрос после пополнения с тем же
Idempotency-Key. - Автоматически повторять
402 wallet_suspendedв цикле не нужно: переключайтесь на проверкуGET /walletраз в минуту или дождитесь уведомления.
#Вебхуки при остановке
Исходящие вебхуки при остановленном обмене не отправляются и не теряются:
| Правило | Описание |
|---|---|
| Откладывание | Доставка сдвигается на 15 минут (next_attempt_at) и проверяется снова |
| Попытки | Счётчик attempt не растёт: остановка по вине кошелька не расходует восемь повторов |
| Возобновление | После пополнения отложенные доставки уходят автоматически, в порядке очереди |
| Срок хранения | События хранятся 30 суток. Если событие выйдет за этот срок до возобновления, его доставка закрывается как «мёртвое письмо» с причиной wallet_suspended; недостающее забирайте из API по идентификатору ресурса |
#Неизвестное состояние
Если платформа не смогла получить баланс (временный отказ источника), состояние — unknown, а не «остановлено»: ошибка чтения не должна ни останавливать обмен, ни скрывать долг.
- Маршруты без списаний (чтение) работают; в ответе есть заголовок
Wallet-State: unknown. - Платные операции закрыты:
503 upstream_unavailableсRetry-After. Повторите позже с тем жеIdempotency-Key. - Ответ «неизвестно» кэшируется на считанные секунды, поэтому возврат к обычной работе происходит быстро.
#Как возобновить обмен
- Откройте
topup_url(кабинет → Продвижение → Экономика → кошелёк) под сотрудником с правом пополнения и пополните кошелёк. Для арендатора с общим кошельком пополнение выполняется в ячейке-«доме» кошелька. - Платформа сбрасывает кэш состояния при зачислении. Состояние в API обновляется сразу на том сервере, где оплата была проведена, на остальных — не позже чем через 30 секунд.
- Проверьте
GET /wallet:exchangeсталactive. Отложенные вебхуки уйдут сами.
#Уведомления арендатору
При смене состояния обмена арендатор получает сообщение в собственные привязанные каналы (телеграм сотрудников арендатора; чат площадки не используется):
- «Обмен остановлен» — при переходе в
suspended, со ссылкой на пополнение; - «Обмен возобновлён» — при возвращении в
active.
Сообщение уходит один раз на смену состояния, без повторов, на языке арендатора (русский, английский, индонезийский). Состояние unknown уведомлений не вызывает.
#Коды ошибок
| Код | HTTP | Когда |
|---|---|---|
wallet_suspended | 402 | Обмен остановлен |
upstream_unavailable | 503 | Состояние кошелька неизвестно, платная операция закрыта |
См. каталог и платные операции.