API оплаты и интеграция с игровым сервером (RAGE MP)

Сайт (api.liverp.ru) хранит платежи и чеки. Игровой сервер (:63222) проверяет аккаунт и начисляет валюту.

Общий секрет: GAME_SERVER_API_KEY (Bearer). На сайте дополнительно GAME_SERVER_API_URL (например http://144.31.107.67:63222).

---

Проверка игрока с сайта (форма доната)

POST {BACKEND_PUBLIC_URL}/api/v1/payments/check-player — публичный, без Bearer. Backend проксирует на игровой …/users/server/check.

{ "gameId": "12345" }

Ответ: { "data": { "exists": true, "gameId": "12345", "nickname": "Имя Фамилия" } }.

---

Сайт → игровой сервер

Проверка игрока (перед созданием оплаты)

POST {GAME_SERVER_API_URL}/api/v1/users/server/check

{ "gameId": "12345" }
ОтветЗначение
exists: trueигрок есть, в ответе nickname
exists: falseсайт вернёт 404 «Игрок с таким ID не найден»

Начисление после оплаты (ResultURL Robokassa)

POST {GAME_SERVER_API_URL}/api/v1/payments/server/approve

{
  "gameId": "12345",
  "amount": 500,
  "invId": 42
}
ПолеОбязательноеНазначение
gameIdдаID персонажа — по нему зачисляется баланс
amountдасумма в ₽
invIdнетдля логов / сверки

Игра зачисляет донат сразу на аккаунт (без локальной таблицы платежей). Идемпотентность — на сайте: Payment.creditStatus (pending → crediting → credited / failed). Повторный ResultURL при credited не вызывает approve. Каждую минуту backend ретраит SUCCESS с pending/failed (и зависший crediting старше 2 мин) через services/paymentCredit.ts, пока не станет credited.

Ответ: { "data": { "success": true, "gameId", "amount", "creditedAmount", "balance", "invId", "status": "credited" } }.

На сайте: pending → credited / failed (+ авто-retry).

---

Игровой сервер → сайт (создать платёж)

POST {BACKEND_PUBLIC_URL}/api/v1/payments/server/create

Authorization: Bearer <GAME_SERVER_API_KEY>
Content-Type: application/json
ПолеТипОбязательноеОграничения
amountnumberда49 – 1 000 000 (₽)
gameIdstringдатолько цифры, 1–6 символов (ID персонажа)
emailstringнетдля фискального чека
{
  "amount": 500,
  "gameId": "12345",
  "email": "player@example.com"
}

Ответ 200:

{
  "data": {
    "paymentUrl": "https://auth.robokassa.ru/Merchant/Index.aspx?...",
    "invId": 42,
    "nickname": "Имя Фамилия"
  }
}

Перед созданием сайт вызывает check на игровом сервере.

КодПричина
400валидация тела
401неверный Bearer
404игрок не найден
500 / 502ошибка backend / игрового API

---

Зафиксировать возврат (после отмены в ЛК Robokassa)

Деньги — в кабинете Robokassa. Затем:

POST {BACKEND_PUBLIC_URL}/api/v1/payments/{invId}/refund

Authorization: Bearer <GAME_SERVER_API_KEY>
Content-Type: application/json

Тело опционально: { "amount": 500 } (по умолчанию полная сумма).

Ответ: ok, invId, refundAmount, receiptId, receiptStatus. Статус платежа → REFUNDED + чек CloudKassir IncomeReturn.

КодПричина
400неверная сумма
401нет Bearer
404платёж не найден
409уже REFUNDED или не SUCCESS

---

Важно