PAYNEX Описание Интеграция API (Swagger) API (ReDoc)

PAYNEX — документация по интеграции для мерчантов

P2P-процессинг депозитов и выплат. Вы (мерчант) создаёте заявки через API, клиент переводит деньги другому клиенту напрямую, мы матчим встречные потоки и подтверждаем перевод. Итог приходит вам вебхуком.


1. Авторизация

Каждый запрос к API — заголовок X-API-Key с вашим ключом.

X-API-Key: paynex_live_xxxxxxxxxxxxxxxxxxxx

Отдельно у вас есть api_secret — он НЕ передаётся в запросах, а используется только для проверки подписи входящих вебхуков (см. §6). Храните оба секрета на сервере.

Ошибки авторизации: 401 (нет/неверный ключ), 403 (мерчант отключён).


2. Создать депозит (Pay-In)

POST /api/v1/payments

Заголовки: X-API-Key, Content-Type: application/json, опц. Idempotency-Key.

Поле Тип Обяз. Описание
direction string да "payin"
amount_kopecks int да сумма в копейках (1..10^9)
currency string нет по умолч. "RUB"
payment_method string да "card" или "sbp"
merchant_player_id string да ваш ID клиента (напр. "user_42")
player_full_name string нет ФИО клиента из вашего KYC. Рекомендуется: включает анти-треугольник (сверку с ФИО на чеке)
merchant_payment_id string нет ваш ID транзакции для сверки
return_url string нет куда вернуть клиента после оплаты
webhook_url string нет URL вебхуков для этого платежа (иначе берётся дефолтный мерчанта)
external_metadata object нет любые ваши данные, вернём их в вебхуках без изменений
expires_in_seconds int нет TTL заявки, 60..21600, по умолч. 1800

Запрос:

curl -X POST https://<домен>/api/v1/payments \
  -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: dep-2026-06-20-0001" \
  -d '{
    "direction": "payin",
    "amount_kopecks": 500000,
    "currency": "RUB",
    "payment_method": "sbp",
    "merchant_player_id": "user_42",
    "player_full_name": "Иванов Иван Иванович",
    "merchant_payment_id": "order_98765"
  }'

Ответ 201:

{
  "payment_id": "de09a768-28ff-4b91-920e-3d6c27f4cfb6",
  "status": "matching",
  "direction": "payin",
  "amount_kopecks": 500000,
  "currency": "RUB",
  "payment_method": "sbp",
  "checkout_url": "https://<домен>/pay/Qc6CllN0...",
  "expires_at": "2026-06-20T08:27:28Z",
  "created_at": "2026-06-20T07:57:28Z",
  "merchant_payment_id": "order_98765"
}

Дальше: редиректните клиента на checkout_url. На этой странице он видит реквизиты получателя, переводит деньги и загружает чек. Вам ничего больше вызывать не нужно — финальный статус придёт вебхуком. Итог сверяйте по payment_id (или вашему merchant_payment_id).

⚠️ Сумма может быть округлена под шаг матчинга мерчанта. Тогда в вебхуке будет amount_kopecks (фактическая) и original_amount_kopecks (что вы запросили). Списывайте/ зачисляйте по фактической.


3. Создать выплату (Pay-Out)

POST /api/v1/payouts — здесь обязательны реквизиты получателя.

Общие поля: amount_kopecks, currency, payment_method (card/sbp), merchant_player_id, опц. merchant_payment_id, expires_in_seconds.

Запрос (СБП):

curl -X POST https://<домен>/api/v1/payouts \
  -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "amount_kopecks": 500000, "currency": "RUB", "payment_method": "sbp",
    "merchant_player_id": "user_42",
    "recipient_sbp_phone": "+7 999 123-45-67",
    "recipient_sbp_bank_code": "SBER"
  }'

Ответ 201 содержит payment_id, status, recipient_last4 (для визуальной сверки) и пр.


4. Жизненный цикл и статусы

pending → matching → awaiting_payment → awaiting_verification → completed
                                          ↘ failed / expired / cancelled
Статус Значение
pending заявка создана
matching ищем встречную заявку в очереди
awaiting_payment пара найдена, ждём перевод от отправителя
awaiting_verification чек загружен, идёт проверка (авто/оператор)
completed успех: перевод подтверждён
failed провал (поддельный чек, отказ оператора и т.п.)
expired истёк таймер ожидания
cancelled отменён мерчантом/оператором

Зачисляйте средства клиенту ТОЛЬКО по completed (приходит вебхуком). Статус awaiting_verification означает, что чек ещё проверяется (см. §7 про антифрод).


5. Idempotency-Key

Для POST /payments и POST /payouts передавайте заголовок Idempotency-Key (любая ваша уникальная строка на операцию). Повторный запрос с тем же ключом вернёт тот же ранее созданный платёж, без дублирования. Используйте при ретраях по таймауту сети.


6. Вебхуки (как получать результат)

Когда статус платежа меняется, мы шлём POST на ваш webhook_url с JSON-телом и подписью.

Заголовки:

Content-Type: application/json; charset=utf-8
X-Paynex-Event-Id:   <уникальный id события>
X-Paynex-Event-Type: payment.completed
X-Paynex-Timestamp:  1781162244
X-Paynex-Signature:  <hex HMAC-SHA256>

Тело:

{
  "event_id": "…",
  "event_type": "payment.completed",
  "created_at": "2026-06-20T08:00:00Z",
  "payment": {
    "id": "de09a768-…", "merchant_payment_id": "order_98765",
    "direction": "payin", "status": "completed",
    "amount_kopecks": 500000, "original_amount_kopecks": null,
    "remaining_kopecks": null, "currency": "RUB", "payment_method": "sbp",
    "external_metadata": {}, "expires_at": "…", "completed_at": "…", "created_at": "…"
  }
}

Типы событий: payment.created, payment.awaiting_payment, payment.completed, payment.failed, payment.expired, payment.cancelled.

Проверка подписи (ОБЯЗАТЕЛЬНО)

Подпись = HMAC_SHA256(api_secret, "{X-Paynex-Timestamp}.{сырое_тело_запроса}"). Сравнивайте с заголовком X-Paynex-Signature. Проверяйте, что timestamp не старше 5 минут (защита от replay). Тело берите как пришло, побайтово (не пересериализуйте).

import hmac, hashlib, time

def verify(api_secret: str, headers: dict, raw_body: bytes) -> bool:
    ts = headers["X-Paynex-Timestamp"]
    if abs(time.time() - int(ts)) > 300:          # старше 5 минут — отклоняем
        return False
    expected = hmac.new(
        api_secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, headers["X-Paynex-Signature"])

Идемпотентность и ретраи


7. Антифрод — что важно знать мерчанту

Чек о переводе технически невозможно на 100% отличить от хорошей подделки по самому файлу. Поэтому решение об одобрении опирается на поведение и историю, а не только на чек:


8. Лимиты и ошибки


9. Песочница (dev)