Профиль и лимиты мерчанта (My Merchant)
Self-service профиль мерчанта: лимиты сделок (min/max/daily), kill_switch, webhook URL — через кабинетный JWT
Профиль и лимиты мерчанта (My Merchant)
Пара self-service эндпоинтов личного кабинета (TD-UI-07): мерчант читает и
редактирует собственный профиль без админских прав. Stripe-аналогия —
GET/PATCH /v1/account.
Аутентификация. GET — dual-homed: кабинетный JWT
(Authorization: Bearer <access_token> из логина кабинета) или
HMAC-пара мерчанта (X-Merchant-Token / X-Timestamp / X-Signature,
скоуп — из подписанного токена). PATCH — только кабинетный JWT
(сервер-серверные мутации профиля по HMAC не поддерживаются). Путь — вне
merchant-префикса: /api/v1/p2p/my-merchant.
Получение профиля
GET /api/v1/p2p/my-merchant
Authorization: Bearer <access_token>Пример ответа (200 OK, живой ответ стейджа)
{
"merchant": {
"id": "3e52c59c-3013-4efa-a2db-70cef2adc7ab",
"name": "Merchant TC Sandbox",
"email": "merchanttc@syncra.money",
"status": "ACTIVE",
"kill_switch": false,
"balance_usdt": "95982",
"escrow_usdt": "0",
"trc20_address": "TCBYf3t6D2VshYVQLh55GGBDWTZvjQRoHd",
"trc20_usdt_balance": "0",
"trc20_trx_balance": "0",
"project_url": "",
"checkout_brand_name": "",
"success_redirect_url": "",
"fail_redirect_url": "",
"finance_chat_id": "",
"appeal_chat_id": "",
"ip_whitelist": [],
"api_token": "8102965ace9cbdcd88fb0fb857375c9b3d812327e8871a58d25a79a29d0cba7f",
"withdrawal_address": "",
"moderation_status": "APPROVED",
"api_version": "v2",
"webhook_url": "http://mock-merchant-e2e.syncra-stage.svc.cluster.local:18098/webhook",
"created_at": "2026-08-22T17:12:02Z",
"updated_at": "2026-08-23T18:58:54Z",
"kill_switch_reason": ""
},
"auto_withdrawal_mode": "AUTO_UP_TO_LIMIT",
"auto_withdrawal_effective_limit_usdt_cents": "10000000000"
}Ключевые поля
| Поле | Тип | Описание |
|---|---|---|
kill_switch | bool | Экстренная блокировка активности мерчанта. Переключается оператором платформы (admin-эндпоинты /disable//enable, недоступны HMAC/JWT-сессии мерчанта); сам мерчант видит статус в кабинете. |
kill_switch_reason | string | Причина включённого платформенного kill switch — её показывает баннер кабинета. Пустая строка при kill_switch=false или если оператор не указал причину. Read-only для мерчанта. |
deal_min_amount | int64 (optional) | Собственный минимум на сделку (минорные единицы, копейки). Отсутствует = минимума нет. |
deal_max_amount | int64 (optional) | Собственный максимум на сделку. Отсутствует = максимума нет. |
daily_deal_amount_limit | int64 (optional) | Дневной (UTC) cap объёма PayIn+PayOut. Отсутствует = cap не задан. |
api_token | string | Публичный токен API (ротируется через api-keys). |
auto_withdrawal_mode | string | Политика крипто-вывода: AUTO_UP_TO_LIMIT или MANUAL_ONLY (read-only). |
auto_withdrawal_effective_limit_usdt_cents | int64 | Порог автопроводки вывода в USDT-центах (0 = всё вручную). |
Поля лимитов (deal_min_amount / deal_max_amount /
daily_deal_amount_limit) появляются в ответе только когда заданы
(proto3 optional): после снятия лимита поле исчезает из JSON, а не
становится нулём.
Изменение профиля и лимитов
PATCH /api/v1/p2p/my-merchant
Authorization: Bearer <access_token>
Content-Type: application/jsonЧастичное обновление: передавайте только изменяемые поля. Мутируются
name, webhook_url, withdrawal_address, success_redirect_url,
fail_redirect_url, checkout_brand_name, finance_chat_id,
appeal_chat_id, ip_whitelist (JSON-массив строкой) и три лимита сделок.
Статус, балансы и комиссии через self-service не меняются (admin-only).
Семантика указателей (pointer semantics) для лимитов
Значения лимитов — int64 в минорных единицах (копейки):
| Передано в PATCH | Эффект |
|---|---|
| поле отсутствует | лимит не меняется |
0 | лимит снимается (NULL = нет лимита) |
> 0 | лимит устанавливается (например, "100000" = 1000,00 RUB) |
Пара min/max согласована: нельзя задать максимум ниже действующего минимума.
Пример запроса (установить минимум 1000,00 и дневной cap 100 000,00)
{
"deal_min_amount": "100000",
"daily_deal_amount_limit": "10000000"
}Пример ответа (200 OK)
Возвращается полный объект merchant (структура как в GET); установленные
лимиты видны в полях deal_min_amount / daily_deal_amount_limit.
Ошибки создания сделок при нарушении лимитов
Лимиты проверяются при POST /deals/payin и POST /deals/payout
(живые ответы стейджа; см. Коды ошибок):
400 INVALID_ARGUMENT — минимум/максимум
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "{\"code\":3,\"message\":\"deal amount is below the merchant minimum: 50000 is below the configured minimum 100000\",\"details\":[]}",
"instance": "/api/v1/p2p-engine"
}{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "{\"code\":3,\"message\":\"deal amount is above the merchant maximum: 150000 is above the configured maximum 100000\",\"details\":[]}",
"instance": "/api/v1/p2p-engine"
}400 FAILED_PRECONDITION — дневной объём
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "{\"code\":9,\"message\":\"merchant daily deal volume limit exceeded: today's volume 793921 + requested 150000 exceeds the configured daily cap 100000\",\"details\":[]}",
"instance": "/api/v1/p2p-engine"
}Дневной объём считается по UTC от того же UNION-набора, что и
обороты (без EXPIRED/SPAM_REJECTED/FAILED).
Связанные материалы
- Коды ошибок — канон
400для всех классов «неверное состояние». - Обороты сделок — как считается дневной объём.
- Callbacks — настройка
webhook_urlи подпись вебхуков.