S
docs.syncra.money
API ReferenceMerchant API

Платежные пропуски (Passes)

Использование системы платежных пропусков для гарантированной маршрутизации платежей и управления комиссиями в Syncra V2

Платежные пропуски (Passes)

Механизм платежных пропусков (Passes) — это продвинутая функция платформы Syncra V2, позволяющая мерчантам резервировать определённые реквизиты (карты, номера телефонов для СБП, IBAN для международных переводов) для конкретных плательщиков на заданный период времени.

Это гарантирует успешное прохождение платежей от VIP-игроков, оптимизирует маршрутизацию и защищает реквизиты от перегрузок (Anti-Spam). Пропуск обходит стандартное каскадное маршрутизация — сделка с подходящим пропуском закрепляется за конкретным провайдером.


Создание платежного пропуска

POST /api/v1/p2p/merchant/passes

Параметры запроса (JSON Body)

ПолеТипОбяз.Описание
amountint64ДаСумма бронирования в минимальных единицах валюты (единственное обязательное поле).
currency_idstring(UUID)НетUUID валюты; пусто = любая валюта.
payment_method_idstring(UUID)НетUUID конкретного метода оплаты; пусто = любой метод. Только UUID — слаг на pass-ветке не резолвится (в отличие от PayIn/PayOut-сделок).
requisite_typestringНетТип реквизитов: BANK_CARD, SBP, E_WALLET, SIM или BANK_TRANSFER (IBAN, для международных рынков — Havale/SEPA/...); пусто = любой тип. Полный справочник — в Типы реквизитов.
expires_atstring(RFC3339)НетВремя истечения срока действия пропуска. Опционально: пустое/отсутствующее значение означает, что пропуск никогда не истекает (expires_at = NULL).
provider_idstring(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Сделка, закрепившая пропуск, успешно завершена. Терминальное состояние — пропуск не может быть переиспользован.Терминальный.
EXPIREDTTL пропуска истёк до того, как он был потреблён. Терминальное состояние — проверяется guard-условием expires_at в запросе MatchActivePass.Терминальный.

Диаграмма переходов

        ┌─────────┐  MatchAndReserve   ┌───────────┐
        │ ACTIVE  │ ─────────────────► │ RESERVED  │
        └─────────┘                    └───────────┘
            │                            │       │
   TTL      │ ConfirmPass (deal done)    │       │ ReleasePass
   exceeded │                            ▼       │ (deal expired/cancelled)
            │                         ┌─────────┐│
            ▼                         │   USED  ││
        ┌─────────┐                   └─────────┘│
        │ EXPIRED │                              ▼
        └─────────┘                         (обратно в ACTIVE)

Двухфазный коммит (защита от потери)

  1. MatchAndReserveACTIVE → RESERVED при создании сделки.
  2. ConfirmPassRESERVED → USED при успешном завершении сделки.
  3. ReleasePassRESERVED → 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-матрицу.


Связанные материалы

On this page