Платежные пропуски (Passes)
Использование системы платежных пропусков для гарантированной маршрутизации платежей и управления комиссиями в Syncra V2
Платежные пропуски (Passes)
Механизм платежных пропусков (Passes) — это продвинутая функция платформы Syncra V2, позволяющая мерчантам резервировать определённые реквизиты (карты, номера телефонов для СБП, IBAN для международных переводов) для конкретных плательщиков на заданный период времени.
Это гарантирует успешное прохождение платежей от VIP-игроков, оптимизирует маршрутизацию и защищает реквизиты от перегрузок (Anti-Spam). Пропуск обходит стандартное каскадное маршрутизация — сделка с подходящим пропуском закрепляется за конкретным провайдером.
Создание платежного пропуска
POST /api/v1/p2p/merchant/passesПараметры запроса (JSON Body)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
amount | int64 | Да | Сумма бронирования в минимальных единицах валюты (единственное обязательное поле). |
currency_id | string(UUID) | Нет | UUID валюты; пусто = любая валюта. |
payment_method_id | string(UUID) | Нет | UUID конкретного метода оплаты; пусто = любой метод. Только UUID — слаг на pass-ветке не резолвится (в отличие от PayIn/PayOut-сделок). |
requisite_type | string | Нет | Тип реквизитов: BANK_CARD, SBP, E_WALLET, SIM или BANK_TRANSFER (IBAN, для международных рынков — Havale/SEPA/...); пусто = любой тип. Полный справочник — в Типы реквизитов. |
expires_at | string(RFC3339) | Нет | Время истечения срока действия пропуска. Опционально: пустое/отсутствующее значение означает, что пропуск никогда не истекает (expires_at = NULL). |
provider_id | string(UUID) | Нет | UUID конкретного провайдера (если требуется привязать). |
Пример запроса (с истечением)
{
"amount": 1000000,
"currency_id": "4ac148fe-19a3-45bb-b992-019fac55b72c",
"requisite_type": "BANK_CARD",
"expires_at": "2026-07-12T18:30:00Z"
}Пример запроса (бессрочный)
{
"amount": 1000000,
"currency_id": "4ac148fe-19a3-45bb-b992-019fac55b72c",
"requisite_type": "BANK_CARD"
}Если expires_at не передан или пустой — пропуск действует бессрочно (NULL
в базе). Это полезно для постоянных VIP-маршрутов. Чтобы ограничить срок
действия, передайте RFC3339-timestamp.
Пример ответа (200 OK)
{
"pass": {
"pass_id": "812d77a0-0d3a-4422-b91c-7cb052a21abc",
"status": "ACTIVE",
"amount": "1000000",
"currency_id": "4ac148fe-19a3-45bb-b992-019fac55b72c",
"payment_method_id": "",
"requisite_type": "BANK_CARD",
"expires_at": "2026-07-12T18:30:00Z"
}
}Статусы платежного пропуска
Пропуск проходит через двухфазный коммит (two-phase commit), который
предотвращает потерю пропуска при истечении сделки. Существует 4 канонических
состояния (доменный enum PassStatus):
| Статус | Описание | Переход |
|---|---|---|
ACTIVE | Пропуск создан, реквизиты зарезервированы, ожидает matching со сделкой. | → RESERVED (сделка закрепила пропуск) или → EXPIRED (TTL истёк). |
RESERVED | Сделка закрепила этот пропуск (claim), но ещё не завершена. Ни одна другая сделка не может сматчить ACTIVE пропуск, пока он RESERVED. | → USED (сделка успешно завершена) или → ACTIVE (сделка истекла/отменена — пропуск возвращается в пул через ReleasePass). |
USED | Сделка, закрепившая пропуск, успешно завершена. Терминальное состояние — пропуск не может быть переиспользован. | Терминальный. |
EXPIRED | TTL пропуска истёк до того, как он был потреблён. Терминальное состояние — проверяется guard-условием expires_at в запросе MatchActivePass. | Терминальный. |
Диаграмма переходов
┌─────────┐ MatchAndReserve ┌───────────┐
│ ACTIVE │ ─────────────────► │ RESERVED │
└─────────┘ └───────────┘
│ │ │
TTL │ ConfirmPass (deal done) │ │ ReleasePass
exceeded │ ▼ │ (deal expired/cancelled)
│ ┌─────────┐│
▼ │ USED ││
┌─────────┐ └─────────┘│
│ EXPIRED │ ▼
└─────────┘ (обратно в ACTIVE)Двухфазный коммит (защита от потери)
MatchAndReserve—ACTIVE → RESERVEDпри создании сделки.ConfirmPass—RESERVED → USEDпри успешном завершении сделки.ReleasePass—RESERVED → ACTIVEпри истечении/отмене сделки (черезPaymentTimeoutWorker).
Если сделка, удерживающая пропуск (RESERVED), истекает или отменяется —
пропуск не теряется, а возвращается в пул (ACTIVE) и снова доступен для
matching. Это гарантирует, что VIP-реквизиты не «зависают» на упавших сделках.
Конкурентное резервирование
Если две сделки одновременно пытаются зарезервировать один пропуск, выигрывает первая транзакция, а вторая получает ошибку (RFC 9457 problem+json):
HTTP/1.1 409 Conflict
{
"type": "about:blank",
"title": "Conflict",
"status": 409,
"detail": "{\"code\":10,\"message\":\"pass was concurrently reserved\",\"details\":[]}",
"instance": "/api/v1/p2p-engine"
}Этот конфликт безопасен для retry: повторите запрос с тем же idempotency_key
через короткую паузу (200–500 мс). См.
Retry-матрицу.
Связанные материалы
- Коды ошибок —
ABORTED,RESOURCE_EXHAUSTEDи retry-стратегии. - Сделки — matching сделок с пропусками.
- Справочник статусов — типы реквизитов и статусы сделок.