Платёжная платформа для онлайн-игрового проекта

Сайт, на котором игроки пополняют баланс и покупают цифровые товары, а покупки автоматически выдаются на игровом сервере. Без ручной обработки оплат и без двойных списаний.

Сдан заказчику
ТипЗаказная разработка
ПлатежиЮKassa
ВходSteam OpenID
Роль NKDLСайт, платёжная логика, плагин выдачи
Человек оплачивает покупку банковской картой на ноутбуке

Название проекта заказчика и скриншоты с его брендом не публикуем. Макет панели ниже собран на демо-данных.

Задача

Нужно было принимать оплату и выдавать покупки без участия администратора. Игрок платит на сайте, а товар должен появиться у него на игровом сервере, даже если в момент оплаты он не в игре.

Главные риски такой системы — деньги и доверие: двойное списание при повторном нажатии, зачисление неподтверждённого платежа, потерянная выдача после сбоя сервера. Каждый такой случай — это обращение в поддержку и потерянный клиент.

Решение

01

Вход через Steam

Игрок входит через Steam OpenID. Идентификатор берётся из проверенного ответа платформы, поэтому подменить получателя покупки нельзя.

02

Баланс и пополнение

Оплата через ЮKassa. Уведомлению от провайдера сайт не доверяет: он сам запрашивает статус платежа и сверяет сумму. Зачисление происходит ровно один раз.

03

Покупка одной транзакцией

Списание, заказ и задания на выдачу записываются вместе. Двойной клик не создаёт второе списание, суммы хранятся в копейках, цена фиксируется на время оформления.

04

Автоматическая выдача

Серверный плагин каждые 15 секунд забирает задания по HTTPS. Входящий доступ к игровому серверу не нужен. Если игрок не в сети, покупка ждёт его входа.

Как работает

От оплаты до выдачи

Каждый шаг проверяется на сервере. Браузер игрока не может изменить цену, получателя или сумму.

01

Вход

Steam OpenID, профиль с именем и аватаром.

02

Пополнение

Сумма от 100 до 10 000 ₽, переход на страницу ЮKassa.

03

Проверка

Сайт сам запрашивает статус платежа у провайдера и зачисляет сумму с бонусом.

04

Покупка

Выбор количества, финальная цена, списание с баланса одной транзакцией.

05

Выдача

Плагин выдаёт товар на сервере и подтверждает выдачу. Спорные случаи уходят на ручную проверку.

Панель владельца · заказы за деньДемо-данные
Пополнений подтверждено38
Заказов64
Выдано автоматически61
Ждут игрока или проверки3
ЗаказСуммаПлатёжВыдача
№ 5187 · набор × 2476 ₽Списано с балансаВыдано
Пополнение баланса2 500 ₽ + 125 ₽ бонусПодтверждено ЮKassa—
№ 5188 · привилегия на 30 дней358 ₽Списано с балансаЖдёт входа игрока
№ 5189 · набор × 1129 ₽Списано с балансаНа ручной проверке

Спорная выдача не повторяется автоматически: администратор видит её в панели и решает, выдать снова или вернуть деньги на баланс.

Для владельца

Панель управления. Товары, цены, состав наборов и скидки, история заказов, корректировки баланса с указанием причины, бесплатная выдача, возвраты и журнал всех действий администратора.

Акции без обмана. Предложения дня, персональная подборка со скидкой раз в час, бонус к пополнению +3% от 1 000 ₽ и +5% от 2 500 ₽. Скидки не складываются. Выдуманных счётчиков продаж и перезапускающихся таймеров нет.

Возвраты. Возврат, проведённый в кабинете ЮKassa, сайт учитывает сам и списывает с баланса возвращённую сумму вместе с долей бонуса.

Качество

01

35 автоматических тестов

Балансы, одновременные списания, повторные запросы, купоны, возвраты, права доступа, вход без корректной сессии, повторная выдача.

02

Фоновая сверка платежей

Раз в минуту сайт проверяет незавершённые пополнения, чтобы оплата не потерялась, если игрок закрыл вкладку.

03

Развёртывание

Docker и автоматический HTTPS. Секреты не хранятся в коде, база не публикуется наружу.

04

Журнал выдачи

Плагин записывает операцию до изменения инвентаря. Подтверждённые задания не исполняются повторно даже после сбоя.

Технологии

Node.jsSQLiteЮKassa APISteam OpenIDC# (серверный плагин)DockerCaddy
Обсудим задачу

Нужен приём платежей с автоматической выдачей?

Онлайн-сервисы, цифровые товары, подписки, доступы. Спроектируем платёжную логику так, чтобы деньги не терялись и не списывались дважды.