> This is part 1 of 2 of the full documentation (pages 1–100 of 122).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.mmoweb.biz/llms-full.txt/1
> Page index: https://docs.mmoweb.biz/llms.txt

# Главная

Вводная информация по mmoweb

## **Что вам может предложить MmoWeb:**

Это полностью продуманный личный кабинет для пользователя.\
Мы учли все возможные желания пользователей, максимально упростили интерфейс. Однако, это не значит, что кабинет простой и в нем нет функций, отличающих его от других доступных CMS.\
Это означает, что интерфейс стал более интуитивным, при возросшем количестве функций и возможностей.\
\
**CMS MmoWeb** можно разделить на **2 раздела**:

1. Управление сайтом;
2. Управление кабинетом.

**Раздел \[Управление Сайтом]**&#x200B;\
CMS Сайта включает в себя необходимые для любого проекта модули, такие как:

* Мультиязычность;
* Статус серверов (информация о состоянии сервера на сайте);
* Последние темы с форума;
* Новости на сайте;
* Статистика игроков;
* Прямые трансляции;
* IBlock - для вывода любой информации в виде слайдеров итд;
* Статичные страницы для сайта и для кабинета.

Все модули управляются через встроенную админ панель в CMS MmoWeb, имеют легкую расширяемость в случае необходимости (через обращение в техподдержку).\
\
\
**Отдельного внимания заслуживает система шаблонизации сайта:**\
Теперь **ЛЮБОЙ ЖЕЛАЮЩИЙ МОЖЕТ АДАПТИРОВАТЬ СВОЙ ДИЗАЙН САМОСТОЯТЕЛЬНО**, прочитав документацию и посмотрев примеры в дефолтном шаблоне, поставляемом в комплекте.\
\
**Раздел \[Управление Кабинетом]**&#x200B;\
Максимально была переработана административная панель MmoWeb для управления кабинетом!\
Теперь она имеет приятный дизайн и продуманную структуру + поиск (потеряться не получится среди настроек).\
\
Вы можете максимально быстро поставить MmoWeb 4 версии:

**каждый шаг установки описан в документации** с примерами и картинками;

* установка начинается с регистрации и плавно переходит к созданию подключения логин-сервера затем гейм-сервера и проекта с дальнейшим подключением вновь созданных серверов к проекту.

Для тех, кто никогда не пользовался системой MmoWeb переход с вашей собственной CMS на MmoWeb будет, практически, безболезненным, все игровые аккаунты успешно подключатся к вновь созданным мастер-аккаунтам пользователя после подтверждения почты.\
\
Для тех, кто уже использует MmoWeb 3 или другие CMS, где имеются балансы и прочие накопительные системы **можно организовать миграцию** (через обращение в техподдержку), **без потери данных**.\
Подробнее можно узнать, обратившись по контактам.

## **Сколько это стоит?**&#x200B;

В MmoWeb 4 - очень гибкая ценовая политика.\
Минимальный ежемесячный платеж составляет **25$**, что, согласитесь, крайне невысокая сумма за стабильную CMS + практически, круглосуточную тех. поддержку.\
\
Так же в MmoWeb имеются плагины, покупая которые вы будете **расширять функционал** как админ панели, так и самого личного кабинета для пользователей.\
\
**Список плагинов:**

* Бонус-коды;
* Магазин + Услуги;
* Техническая поддержка для пользователей;
* Мультиаккаунт;
* Аналитика регистраций.
* Служба поддержки
* Внутриигровой рынок
* Игра Lucky Wheel
* Игра кейсы
* Промо игры
* Ежедневная награда
* Вывод денег
* Смена аккаунта UnitPay
* Метрика
* Реферальная система
* Stop Spam Email
* Подарочные коды
* Массовая выдача на склад

(Список плагинов будет пополняться!)\
\
Помимо всего прочего, если вам чего-то не хватает из выше указанных функций, **вы всегда можете заказать доработку**, в оговоренные сроки и сумму она будет реализована.

## **Плавно переходим к КАБИНЕТУ ДЛЯ ИГРОКОВ:**&#x200B;

* Регистрация мастер аккаунта `[опционально]`
  * Регистрация по почте
  * Регистрация по телефону
    * С созданием игрового аккаунта или без, с префиксом или без - решать вам.
* Авторизация `[опционально]`
  * По почте
  * По телефону
  * Через социальные сети
* Восстановление пароля `[опционально]`
  * По почте
  * По телефону
* Страницы не авторизованного пользователя. `[опционально]`
  * Магазин - с возможностью купить на персонажа или на личный склад в мастер аккаунте
  * Пожертвования - с возможностью купить на персонажа
  * Статистика игроков
* Страницы авторизованного
  * Главная
    * Отображение всех игровых аккаунтов с персонажами на них
    * Отображение информации по мастер аккаунту с быстрыми ссылками к настройкам
    * Отображение баланса
    * Отображение Склада
    * Отображение Системы скидок
    * \+ Доп. виджет от магазина с акциями по товаром
  * Рейтинг (статистика)
    * Топ ПВП
    * Топ ПК
    * Топ EXP
    * Топ Клан
    * Топ Клан ПВП
    * Топ Альянс
    * Замки
    * Клан холлы
    * Общая статистика
    * История онлайна
  * Магазин `[плагин]`
    * Отображение товаров
    * Отображение Услуг
  * Техническая поддержка
    * Список обращений
    * Интерфейс по созданию нового обращения
  * Игра Lucky Wheel `[плагин]`
    * Игра колесо фортуны
  * Игра кейсы`[плагин]`
    * Список кейсов
      * Отображение игры
  * Баланс
    * Форма пожертвования с расчетом всех бонусов к платежу. Доступные системы:
      * FreeKassa
      * G2A
      * Unitpay
      * PayU
      * PayPal
      * PayOp
      * PayMaster
      * Paymentwall
      * Pagseguro
      * PayGol
      * InterKassa
      * Enot.io
      * PrimePayments
      * Paysafecard
      * IPS-Payment
      * LiqPay
      * PayPalych
      * PayZe
      * MoneyTigo
      * Stripe
      * Tome
      * Binance
      * Portmone
      * HotSkins\
        `(Список будет расширяться)`
  * Настройки
    * Управление мастер аккаунтом
    * Управление мультиаккаунтом `[плагин]`
    * Скрытие игровых аккаунтов
    * Логи пользователя
    * Логи платежей
      * Инвойсы операции по платежам

## MMOWEB сервис состоит из 3 связанных подсистем:

1. Админ панель -  для управления вашими проектами и гейм-серверами.
2. REST API - взаимодействует с вашей игровой базой данных
3. Веб часть `(клиентская часть)` - это CMS, которую вы устанавливаете у себя на хостинге

   1. Публичная часть `(сайт)` - имеется дефолтный шаблон
   2. Личный кабинет - для игрока управление мастер аккаунтом
   3. Админ панель - управления сайтом

   <figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FrZ95WEImYdPGg5Guu3uI%2Fimage.png?alt=media&amp;token=a46f44fb-a99e-4acb-b544-a5cb28fa3bfe" alt=""><figcaption></figcaption></figure>

Ответы на часто задаваемые вопросы можно прочитать в разделе [FAQ](https://docs.mmoweb.biz/faq)


# Roadmap

Наши планы амбиции и все остальное

## Step-by-step guide

Stepper blocks let you break down a tutorial or guide into separate, but clearly linked steps. Each step can contain multiple different blocks, allowing you to add detailed information.

{% stepper %}
{% step %}

### Add a stepper block

To add a stepper block, hit `/` on an empty line or click the `+` on the left of the editor and select **Stepper** from the insert menu.
{% endstep %}

{% step %}

### Add some content

Once you’ve inserted your stepper block, you can start adding content to it — including code blocks, drawings, images and much more.
{% endstep %}

{% step %}

### Add more steps

Click the `+` below the step numbers or hit `Enter` twice to add another step to your stepper block. You can remove or change the style of the step header or step body if you wish.
{% endstep %}
{% endstepper %}


# Начало работ

От А до Я

Для использования сервиса MmoWeb вам необходимо пройти все этапы описанные ниже, ВАЖНО выполнять каждое действие поочередно и не нарушать их последовательность, тогда при установке и настройке не возникнет ни каких проблем и вопросов!

1. Регистрация [(перейти к описанию)](/nachalo-rabot/registraciya)
2. Первая оплата [(перейти к описанию)](/nachalo-rabot/pervaya-oplata)
3. Пополнение баланса [(перейти к описанию)](/nachalo-rabot/popolnenie-balansa)
4. Покупка тарифа [(перейти к описанию)](/nachalo-rabot/pokupka-tarifa)
5. **Настройка** [(разделы)](/nachalo-rabot/nastroika)
   1. Логин серверы [(перейти к описанию)](/nachalo-rabot/nastroika/login-servera)
   2. Гейм серверы [(перейти к описанию)](/nachalo-rabot/nastroika/geim-servera)
   3. Почтовые сервера [(перейти к описанию)](/nachalo-rabot/nastroika/pochtovye-servera)
   4. Проекты [(перейти к описанию)](/nachalo-rabot/nastroika/proekta)
   5. Платежная система [(разделы)](/nachalo-rabot/nastroika/platezhnaya-sistema)
      1. Подключение агрегаторов платежных систем [(перейти к описанию)](/nachalo-rabot/nastroika/platezhnaya-sistema/podklyuchenie-agrigatorov)
      2. Внутригровая валюта [(перейти к описанию)](/nachalo-rabot/nastroika/platezhnaya-sistema/vnutrigrovaya-valyuta)
      3. Бонус при платеже [(перейти к описанию)](/nachalo-rabot/nastroika/platezhnaya-sistema/bonus-pri-platezhe)
      4. Система скидок [(перейти к описанию)](/nachalo-rabot/nastroika/platezhnaya-sistema/sistema-skidok)
6. **Установка CMS** [(разделы)](/nachalo-rabot/ustanovka-cms)
   1. Скачать файлы кабинета [(перейти к описанию)](/nachalo-rabot/ustanovka-cms/1.-skachat-faily-kabineta)
   2. Запуск инсталлятора [(перейти к описанию)](/nachalo-rabot/ustanovka-cms/zapusk-ustanovshika)
   3. Проверка соединения с кабинетом [(перейти к описанию)](/nachalo-rabot/ustanovka-cms/proverka-soedineniya-s-kabinetom)
   4. Первая загрузка настроек в кабинет [(перейти к описанию)](/nachalo-rabot/ustanovka-cms/pervaya-zagruzka-nastroek-v-kabinetom)

Если у вас возникнут вопросы, пожалуйста, обращайтесь по контактам


# Регистрация

Создание аккаунта в админ панели mmoweb

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

Для этого следует выполнить несколько простых шагов:

* заполнить обязательные поля на форме регистрации:

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FtoiDiq0Pk5ySM7tYbtRE%2Fimage.png?alt=media&amp;token=67578664-be01-422d-b909-79fdedd04bf0" alt=""><figcaption></figcaption></figure>

| Название поля            | Комментарий                                                            |
| ------------------------ | ---------------------------------------------------------------------- |
| Имя команды (проекта)    | Название вашей игровой команды                                         |
| Платформа для игры       | Название платформы игрового проекта                                    |
| Ник                      | Ваш игровой ник                                                        |
| Логин                    | Логин - это ваш EMAIL адрес                                            |
| Пароль                   | Минимум 6 символов латиницы и цифр                                     |
| Я соглашаюсь с правилами | Установив эту галочку вы соглашаетесь с правилами работы в системе ММО |

**ВНИМАНИЕ!**&#x20;

После регистрации необходимо пополнить баланс аккаунта на **$50**&#x20;

Для пополнения баланса следуйте по ссылке из письма об успешной регистрации в системе ММО:

![Кликните на кнопку "Перейти к оплате 30$..." чтобы пополнить баланс на 30$.](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCIOG2yMcFiy_Jokhnh%2F-MCIOcqi8Yrj4qaewhZr%2F%D0%BE%D0%BF%D0%BB%D0%B0%D1%82%D0%B0.png?alt=media\&token=8a1ac09f-f1c1-4175-b3a0-69b0c267d021)

**Решение проблем:**

* **Неверно указан email при регистрации**

*В этом случае просто пройдите регистрацию повторно*

* **Не пришло письмо об успешной регистрации**

*Либо вы указали неверный email, либо письмо попало в папку спам.*

* **Не работает ссылка на оплату депозита в письме.**&#x20;

*В этом случае обратитесь в тех.поддержку, по контактам*&#x20;

* **Счет оплачен, но баланс не пополнился**

*В этом случае обратитесь в тех.поддержку, по контактам*&#x20;

*Укажите свой email*&#x20;


# Первая оплата

Внесение депозита

После успешной регистрации в системе ММО вы получите уведомление, содержащее ссылку на оплату первого депозита:

![Уведомление об успешной регистрации](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKtcYI2cyBV7NnjY2H%2F-MBKtdV1evPwmnF4jiOG%2Fimage.png?alt=media\&token=387d64d8-44fe-4774-9188-d903a389f767)

При переходе по ссылке на оплату вам будет предложено выполнить оплату одним из нескольких способов:

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FBLVruktwhtbbG6v7Gmuw%2Fimage.png?alt=media&amp;token=c9f86b4c-4432-468b-a414-87f537854d7a" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Возможно выбрать 5 дней бесплатно в этом случае панель будет активна и активированы все возможные плагины&#x20;
{% endhint %}

Возможные варианты оплаты:

* банковские карты;
* электронные деньги;
* оплата с баланса сотового телефона.

После успешной оплаты вы получите возможность авторизоваться в системе ММО по логину и паролю, указанными при регистрации.

**Разрешение проблем:**

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

* логин;
* номер вашей транзакции;
* текст ошибки или описание проблемы.


# Пополнение баланса

Пополнение баланса с помощью банковских карт или электронной наличности

Для пополнения баланса выполните следующие шаги:

1. Авторизуйтесь в панели управления
2. Перейдите на страницу пополнения баланса
3. В поле "Пополнить баланс на" укажите требуемую сумму:

![](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCr8bTDO9GEDpGZhSXD%2F-MCrA1kwvLCWPKFWqkh7%2Freplenish.png?alt=media\&token=e664d0a0-407b-4562-85e8-64615b8d5225)

4\. Нажмите кнопку "Далее"

Далее следуйте инструкции по оплате, аналогично первой оплате

После успешного пополнения баланса на вашем счету, в поле "Баланс" отразится совершенный платеж - ваш баланс увеличится на внесенную вами сумму платежа.

![](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCr8bTDO9GEDpGZhSXD%2F-MCrAmdtVaZWzwpeYrzi%2Fbalance.png?alt=media\&token=45b615c4-9626-494f-8795-4b7ba1a5d5b1)


# Покупка тарифа

Покупка тарифа

После успешной регистрации и пополнения баланса, на Вашем счете будет 30$

Для того, чтобы начать пользоваться личным кабинетом, вам необходимо выбрать тариф.

Далее, когда вы выбрали какой тариф вам подходит, удостоверьтесь, что средств на балансе достаточно для месячной оплаты тарифа.

**ВНИМАНИЕ! Если денег на балансе не достаточно, для оплаты выбранного тарифа (за период), то баланс необходимо пополнить. Для пополнения баланса следуйте инструкции по пополнению баланса:**[Пополнение баланса](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/HCYsBbhJ3hK8hAvmKAYL/nachalo-rabot/popolnenie-balansa)

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MCr9KzW17d9Qzo09pda" %}
[Пополнение баланса](/nachalo-rabot/popolnenie-balansa)
{% endcontent-ref %}

Теперь вы можете выбрать ваш тариф:

![Вид покупки тарифа](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBOPpPKrBPhHza99x5X%2F-MBOR9RzX9eBMallzcDY%2Fimage.png?alt=media\&token=3fefb950-bc27-49c8-a66a-e63ab512940d)

Для этого:

1. нажмите на кнопку "Выбрать (GetStarted)"
2. В открывшемся окне выберите период использования тарифа
3. Нажмите кнопку "КУПИТЬ"

![Форма покупки тарифа](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBORF3iL1Rdb_Fnxwxp%2F-MBORhCGciQGkWxNYrvl%2Fimage.png?alt=media\&token=c3dc0552-e0a1-4291-bdfd-4d11b11fdd15)

{% hint style="warning" %}
**ВНИМАНИЕ!**&#x20;

**При оплате тарифа более, чем на 3 месяца вы получаете скидку:**
{% endhint %}

| Период              | Скидка |
| ------------------- | ------ |
| От 3х до 5 месяцев  | 5%     |
| 5 месяцев           | 6%     |
| От 6х до 10 месяцев | 7%     |
| 10 месяцев          | 8%     |
| 11 месяцев          | 9%     |
| 12 месяцев          | 10%    |

После покупки тарифа у вас появится возможность выполнить подключение к настройке логин-сервера.


# Настройка

Первичная настройка проекта

Основные шаги настройки аккаунта ММО:[1. Логин серверы](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/rDS0NpaKpPEsCiTazUxO/nachalo-rabot/nastroika/login-servera)[2. Гейм серверы](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/rDS0NpaKpPEsCiTazUxO/nachalo-rabot/nastroika/geim-servera)

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKe0EnQ6pZSC8RmqG1" %}
[1. Логин серверы](/nachalo-rabot/nastroika/login-servera)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKe6mJWrLVCokdyOVJ" %}
[2. Гейм серверы](/nachalo-rabot/nastroika/geim-servera)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhfOnYZaJfdwIV3CH" %}
[3. Почтовые сервера](/nachalo-rabot/nastroika/pochtovye-servera)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKe99gObJlOeH1Pd7r" %}
[4. Проекты](/nachalo-rabot/nastroika/proekta)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhm259jJRbaqB3BKJ" %}
[5. Платежная система](/nachalo-rabot/nastroika/platezhnaya-sistema)
{% endcontent-ref %}


# 1. Логин серверы

Подключение к логину серверу

Создать подключение к логин серверу можно в разделе Проекты -> Логин серверы

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FVfj9NEo1jQssP0VqC5BA%2Fimage.png?alt=media&amp;token=cd4c271c-0c73-46cb-bb42-cad4414ba519" alt=""><figcaption></figcaption></figure>

1\. Нажмите на кнопку "Добавить логин-сервер"

2\. Выберите игровую платформу из числа доступных.

{% hint style="warning" %}
ВНИМАНИЕ! Если в числе доступных платформ нет нужной вам игровой платформы, сообщите об этом на контактные данные техподдержки
{% endhint %}

3\. После выбора игровой платформы заполните настройки логин-сервера:

Для заполнения будет доступно 3 вкладки: `Основные`, `База Данных` и `Порты`

**БАЗА ДАННЫХ**

Для подключения в базе данных логин-сервера заполните следующие поля:

|  №  | Название                 | Описание                                                     |
| :-: | ------------------------ | ------------------------------------------------------------ |
|  1  | Тип базы                 | Тип базы данных логин-сервера (зависит от поставщика сборки) |
|  2  | Host базы                | адрес базы, IP адрес где она расположена                     |
|  3  | Имя базы                 | Название базы                                                |
|  4  | Логин пользователя базы  | логин для авторизации в базе                                 |
|  5  | Пароль пользователя базы | Пароль для авторизации в базе                                |

**ПОРТЫ**

Укажите IP и порт для обращения к логин-серверу. Использование юзера root в mysql или sa в mssql не безопасно!

**4. Нажмите "SUBMIT".**

После заполнения всех данных и создания новый логин сервер появится в разделе "Логин сервера"

![Вид логин сервера](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKwsGVUL71c4u9Jj9Y%2F-MBKzxK5kpjSGMyCE-qG%2Fimage.png?alt=media\&token=ecc58a80-5f1b-44fe-b7f8-d2d6a6d063a6)

После появления вашего логин-сервера в списке серверов вы можете проверить доступность сервера из системы ММО.

Для этого нажмите на кнопку "Проверить соединение"

![Кнопка Проверить соединение.](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKwsGVUL71c4u9Jj9Y%2F-MBL-C8mhRQXbxbhhhOo%2Fimage.png?alt=media\&token=c9f34635-6b80-406f-80fd-1c52d9186cf1)

Откроется окно с информацией о статусе.

![Окно проверки соединения](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKwsGVUL71c4u9Jj9Y%2F-MBL-eghwIF8w5LS2lCx%2Fimage.png?alt=media\&token=b6bed3cb-c0c8-4367-a491-ac0df6b299f4)

Если все прошло успешно, в статусе будет OK&#x20;

Если будут ошибки, то будет показан текст ошибки.

Если в указанном выше окне будут сообщения об ошибках и вы не знаете, что с ними делать, обратитесь в техподдержку, с указанием своего аккаунта ММО и названия логин-серверa


# 2. Гейм серверы

Подключение к гейм серверу

Подключение гейм сервера аналогично созданию логин-сервера

Для создания подключения к игровому серверу необходимо:

1. Перейти на страницу: Проекты -> Игровые сервера
2. Нажать на кнопку "Добавить игровой сервер":

![](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FEXRYo5tBbB6cv4HKAOJp%2Fimage.png?alt=media\&token=e194dcd9-e1e0-4312-8d27-a20a8ae16932)

Заполнить все группы настроек:`Основные`, `База Данных`, `Порты`, `Рейтинг` и `Онлайн`

{% hint style="warning" %}
**ПРИМЕЧАНИЕ! На данном этапе важно правильно выбрать Тип сервера если Вашего типа сервера** **(сборки,  разработчика, команды) нет в данном списке вам необходимо связаться с Тех.Продержкой.**
{% endhint %}

**БАЗА ДАННЫХ**

Для подключения в базе данных логин-сервера заполните следующие поля:

|  №  | Название                 | Описание                                                        |
| :-: | ------------------------ | --------------------------------------------------------------- |
|  1  | Тип базы                 | Тип базы данных игрового сервера (зависит от поставщика сборки) |
|  2  | Host базы                | адрес базы, IP адрес где она расположена                        |
|  3  | Имя базы                 | Название базы                                                   |
|  4  | Логин пользователя базы  | логин для авторизации в базе                                    |
|  5  | Пароль пользователя базы | Пароль для авторизации в базе                                   |

**РЕЙТИНГ**

Для управления рейтингом игроков, команд, кланов и т.п.

**ОНЛАЙН**

Используется для отображения периода статистики в панели ММО

**После заполнения настроек нажмите "SUBMIT"**

После заполнения всех данных и создания новый гейм сервер появится в разделе "Игровые сервера"

После того, как игровой сервер появился в списке доступных игровых серверов вы можете проверить его доступность из ММО, для этого нажмите кнопку "Проверить соединение":

![Кнопка Проверить соединение.](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKwsGVUL71c4u9Jj9Y%2F-MBL-C8mhRQXbxbhhhOo%2Fimage.png?alt=media\&token=c9f34635-6b80-406f-80fd-1c52d9186cf1)

Откроется окно с информации о статусе.

Если все прошло успешно в статусе будет OK если будут ошибки, то будет показан текст ошибки.[<br>](https://docs.mmoweb.ru/nachalo-rabot/nastroika)

**Разрешение проблем**

Если в указанном выше окне будут сообщения об ошибках и вы не знаете, что с ними делать, обратитесь в техподдержку, с указанием своего аккаунта ММО и названия логин-сервера


# 3. Почтовые сервера

Создание почтового сервера SMTP

{% hint style="warning" %}
Почтовый сервер необходим каждому проекту.

[SMTP сервер](https://www.google.com/search?q=SMTP+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80\&oq=SMTP+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80) необходим для отправки почты пользователям. Например, при регистрации или восстановления пароля от мастер аккаунта.&#x20;

Это то без чего проект не может работать.
{% endhint %}

Варианты SMTP-серверов:

| Сервис                                                                    | Ограничения       | Цена                                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Google](https://www.hostinger.ru/rukovodstva/kak-ispolzovat-smtp-server) | 100 писем в сутки | Бесплатно                                                                                                                                                                                                                                                                                                   |
| Yandex                                                                    | 500 писем в сутки | Бесплатно                                                                                                                                                                                                                                                                                                   |
| SendPulse.com                                                             | 25000 в месяц     | Условно бесплатно                                                                                                                                                                                                                                                                                           |
| Mailgun.net                                                               | \~                | Платно                                                                                                                                                                                                                                                                                                      |
| Ваш хостинг                                                               | Неизвестно        | Условно бесплатно                                                                                                                                                                                                                                                                                           |
| [Заказать свой SMTP](https://t.me/Route179)                               | нет               | <p></p><p>1. Настройка smtp на сервере заказчика </p><ul><li><strong>50 EUR</strong></li></ul><p>2. Аренда сервера для отправки почты 30к писем в месяц </p><ul><li><strong>5 EUR</strong></li></ul><p>3. Аренда сервера для отправки почты 60к писем в месяц </p><ul><li><strong>10 EUR</strong></li></ul> |
|                                                                           |                   |                                                                                                                                                                                                                                                                                                             |

{% hint style="info" %}
Данный список является примером и не ограничивает вас в вариантах выбора smtp-сервера!

Мы рекомендуем Вам для долгострочных проектов заказывать свой SMTP, т.к. он имеет ряд приимушеств:

* отсутсвие ограничений на отправку;
* цена в месяц оплатой за VDS;
* минимальные шансы что Вашы письма попадут в спам.
  {% endhint %}

Создать почтового сервера (SMTP) можно в разделе Настройки ->  Настройка почтовых SMTP серверов для отправки писем.

![Форма создания подключения к SMTP](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLRRpLe0Nyena9UQPn%2F-MBLTaHttgGwtFuT3xiS%2Fimage.png?alt=media\&token=b25b5d54-f2d1-4975-892b-59117a21a1b2)

После создания SMTP он отобразится в списках Настройки почтовых SMTP серверов для отправки писем.&#x20;

![Вид списка SMTP серверов](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLRRpLe0Nyena9UQPn%2F-MBLV-GgIfEpxaOBIEd_%2Fimage.png?alt=media\&token=69413165-1971-41a0-9b2e-add0e8648341)

При создании проекта этот SMTP отобразится у вас в списке выбора **Почтового сервера \***

![Пример выбора ранее созданного почтового сервера](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLVD2WDZ5h1P8aZM0o%2F-MBLVhN2oLwjh7Y4lect%2Fimage.png?alt=media\&token=3a5c81b0-ddac-416d-b0bc-d1fceb5e2792)

Для работы с настроенным SMTP просто выберите его в списке "Почтовый сервер".


# 4. Проекты

Создание проекта

Добавить проект можно в разделе Проекты -> Проекты

![Кнопка создания нового проекта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLW3vm3aARdYChk9UH%2F-MBLYg6A8GmAIed2IJeT%2Fimage.png?alt=media\&token=793a3b47-6e8b-4961-867f-d6fc91893601)

Для настройки проекта будет доступно 5 вкладок: `Основные настройки`, `Сайт`, `Кабинет`, `Визуализация` и `Платежная система`

![Фрагмент настроек проекта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLW3vm3aARdYChk9UH%2F-MBLZNqXD-aq9zjYufB_%2Fimage.png?alt=media\&token=b8229e11-30bb-44ca-8e4a-f44a4f6aac54)

Далее заполняем по порядку.&#x20;

Практически, под каждым полем есть краткое описание к нему.&#x20;

### Ниже описаны поля, заполнение которых критически важно для работы проекта:

![Аддрес сайта необходимо заполнить строго по шаблону https://yousite.com/](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLW3vm3aARdYChk9UH%2F-MBL_623-S0CnPOYngsO%2Fimage.png?alt=media\&token=a6cc041c-5180-425c-9773-eb87c7c2eea1)

![Секретный ключ необходимо сгенерировать нажав кнопку "Сгенерировать новый ключ"](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLW3vm3aARdYChk9UH%2F-MBL_KlONB-dYiDSiPgI%2Fimage.png?alt=media\&token=8b88e8ab-dd02-4643-ae4d-c224b2b6e24b)

![Вам необходимо указать IP вашего хостинга](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLW3vm3aARdYChk9UH%2F-MBL_ZWLgnwCJGDKPRYI%2Fimage.png?alt=media\&token=c4153618-d826-4b42-a137-5061d064be06)

{% hint style="info" %}
Вам необходимо указать IP откуда будет происходить обращение к REST API, а именно -  указать IP вашего хостинга.

Узнать его можно у вашего хостера.

Если узнать ваш IP нет возможности, укажите \*.\*.\*.\* (КРАЙНЕ НЕ РЕКОМЕНДУЕТСЯ)!
{% endhint %}

**Платформы игр** - Выберите интересующую вас игру из списка

После появится вкладка игры, которую вы выбрали.

Далее, Вам необходимо выбрать ранее созданные игровые сервера в поле **Игровые сервера.**

**Теперь Вы можете настроить оставшиеся пункты.**

![Выбрать доступные языки](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLa0jEsmwLghlZZWB6%2F-MBLa8isseEKn8aMqfkc%2Fimage.png?alt=media\&token=17b45d65-6072-464e-8899-0a7fab82aca2)

![Выбрать методы регистрации](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLa0jEsmwLghlZZWB6%2F-MBLaIPInc8lqax5lBam%2Fimage.png?alt=media\&token=b244923c-fd9f-4323-a6ed-4715740a3a55)

Курс всегда устанавливается по отношению к доллару!

Теперь вы можете создать / сохранить проект.


# 5. Платежная система

Настройка способов приема платежей

Основные шаги настройки платежных систем (способов оплаты):[Подключение агрегаторов платежных систем](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/xV0PuBwK54HzY6Y26rmg/nachalo-rabot/nastroika/platezhnaya-sistema/podklyuchenie-agrigatorov)[Внутригровая валюта](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/xV0PuBwK54HzY6Y26rmg/nachalo-rabot/nastroika/platezhnaya-sistema/vnutrigrovaya-valyuta)[Бонус при платеже](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/xV0PuBwK54HzY6Y26rmg/nachalo-rabot/nastroika/platezhnaya-sistema/bonus-pri-platezhe)[Система скидок](https://app.gitbook.com/s/-MBKZbS5Cb7cxz5sHYKf-1508421016/~/changes/xV0PuBwK54HzY6Y26rmg/nachalo-rabot/nastroika/platezhnaya-sistema/sistema-skidok)

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhnj9cCIgT2LM4HDh" %}
[Подключение агрегаторов платежных систем](/nachalo-rabot/nastroika/platezhnaya-sistema/podklyuchenie-agrigatorov)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhqH9CZJu76uJw6Qe" %}
[Внутригровая валюта](/nachalo-rabot/nastroika/platezhnaya-sistema/vnutrigrovaya-valyuta)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhrWPIhj-Z1Wo8n4\_" %}
[Бонус при платеже](/nachalo-rabot/nastroika/platezhnaya-sistema/bonus-pri-platezhe)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKhsqOo2t6kPw1l8zc" %}
[Система скидок](/nachalo-rabot/nastroika/platezhnaya-sistema/sistema-skidok)
{% endcontent-ref %}

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/5IVKuNtpmNwlJBlG1bnR" %}
[Управления балансом](/nachalo-rabot/nastroika/platezhnaya-sistema/upravleniya-balansom)
{% endcontent-ref %}


# Подключение агрегаторов платежных систем

Настройка платежных систем

На текущий момент количество подключенных платежных агрегаторов достигло своего максимального значения. Увеличение количества платежных шлюзов может вызвать нестабильность в работе системы при загрузке настроек. После добавления новых платежных систем будет возникать постоянная необходимость расширения загрузочного пула. В связи с этим добавление новых платежных систем на бесплатной основе приостановлено. Если у вас есть острая необходимость подключения или уникальные условия для проекта - Стоимость добавления нового агрегатора будет составлять 150$.

Платежные системы находятся в Проекты -> [Проекты](https://mmoweb.biz/panel/project/project)&#x20;

1. Выберите нужный сайт и нажмите кнопку "редактировать"
2. Перейдите во вкладку `Платежная система`

![Кнопка Редактировать настройки проекта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLayJ5VUM6hYzQZyg-%2F-MBLbhldBLoeEk09Ueu2%2Fimage.png?alt=media\&token=1ddceb18-16c3-42e7-b70d-c2a9c35e0a3f)

Вам следует выбрать **Платежные шлюзы**

У каждой платежной системы свой набор настроек, характерный только для этой системы.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FbCY0UMdWYERleJwHXelX%2Fimage.png?alt=media&amp;token=d1a88811-b629-4e0d-9dc9-0909c07394b6" alt=""><figcaption></figcaption></figure>

В окне настроек добавлены комментарии к каждому полю.

Например, на скрине выше видно как под NextPay написано красным "Пополнения баланса" - это указывает на тип создаваемого магазина в этой системе.

После каждого изменения настроек проекта система ММО будет напоминать Вам о необходимости их загрузки. В этом случае вы увидите значок: `/!\`

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fv5aYL3seASDq2x2Q6LBr%2Fimage.png?alt=media&amp;token=d89a539c-3117-438c-8ae4-aba844f70528" alt=""><figcaption></figcaption></figure>


# Внутригровая валюта

Настройка покупки внутриигровой валюты из лк

**Создание внутриигровой валюты**

Валюта добавляется/создаётся в разделе Платежная система > [Внутригровая валюта](https://mmoweb.biz/panel/payment/in-game) > [Новая конфигурация](https://mmoweb.biz/panel/payment/in-game/add)

![Кнопка создания валюты](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLgVLmDy_vEoEDLBNy%2F-MBLhu2Mguuc2OLw4AzO%2Fimage.png?alt=media\&token=d1a5ef7a-91b3-494f-8de9-0966b0537afa)

При создании валюты есть 2 типа доставки условных единиц:

1. Доставка на персонажа - Условный CoL будет доставлен на персонажа
2. Доставка на аккаунт - Условный Point будет доставлен на счет аккаунта

Зависит от типа вашей сборки

![Пример выбора типа валюты](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLixMeJZTLuvC5woNf%2F-MBLmI0QH2GSNe3nlUSo%2Fimage.png?alt=media\&token=c2294847-6946-440d-906b-1bfc6eb64807)

После создания формы она отобразится в разделе Платежная система > [Внутригровая валюта](https://mmoweb.biz/panel/payment/in-game)

{% hint style="info" %}
Форма имеет подробные пояснения!

Единственное, что требует более понятного объяснения - это настройка покупки игровой валюты с передачей на персонажа.&#x20;
{% endhint %}

Курс валюты устанавливается по отношению к вашей валюте личного кабинета из настроек проекта!


# Бонус при платеже

Бонус при пополнении баланса

Система бонусов к платежам находится в разделе Платежная система > Система поощрения > [Бонус при платеже](https://mmoweb.biz/panel/payment/event)

![Кнопка создания бонуса](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLixMeJZTLuvC5woNf%2F-MBLo-r27JY1daBuhglx%2Fimage.png?alt=media\&token=b34b379f-fe22-434e-aab1-21dcab0de22c)

Для настройки будет доступно 2 вкладки: `Бонус система` и `Бонус предметы`

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FXHlPbYBi0YJ5fAu95VcU%2Fimage.png?alt=media&amp;token=0fdab80b-99f2-41ea-ba72-5f120c338b49" alt=""><figcaption></figcaption></figure>

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

{% hint style="info" %}
Пример!

Мы создали диапазон платежа от 0 до 99 условных единиц и от 100 до 200, получили 2 уровня.
{% endhint %}

![Пример уровней и диапозонов](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLixMeJZTLuvC5woNf%2F-MBLpbxXjuxKLB5GNlki%2Fimage.png?alt=media\&token=02a8be74-b95e-47aa-a1f8-7777cd472845)

Теперь переходим во вкладку `Бонус предметы`

![Пример создания бонуса ввиде предметов](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLixMeJZTLuvC5woNf%2F-MBLpw2AWcYLT-o8B7k2%2Fimage.png?alt=media\&token=8f4b696e-7309-46db-9da3-b930693d2c4f)

Создаём позиции в LvL.

Указываем уровень диапазона, в данном случае, в диапазоне от 0 до 99.

У нас начислится предмет с ID 57 в кол-во 1000шт.


# Система скидок

Накопительная система - скидка на покупку товаров в лк

Создать новую систему скидок можно в разделе:

Платежная система > Система поощрения > [Система скидок](https://mmoweb.biz/panel/payment/discount) > [Создать скидку](https://mmoweb.biz/panel/payment/discount/add)

![Форма системы скидок](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLr23itOS1GeE9IRrN%2F-MBLrTY4h5OIr2NkFb5G%2Fimage.png?alt=media\&token=b483c518-73d5-48f4-9f41-699f91675e69)

Скидка может распространяться как на весь проект, так и на определенный сервер на проекте.

Пользователю будет показана текшая скидка.

Скидка работает по принципу накопительной:

ведется учет суммарного доната на сервере;

скидка начисляется при попадании накопленого доната в диапазон скидки.

![Настройка диапозона скидки](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLr23itOS1GeE9IRrN%2F-MBLsAXLfY14sGgj-6Hx%2Fimage.png?alt=media\&token=bee70290-8c7d-4e21-9c28-9f065f75562e)

{% hint style="info" %}
Пример.

На скрине видно, что существует две позиции от 1000 до 2000 и от 2000 до 3000.

Если пользователь имеет суммарный баланс 1001, он попадет в первый диапазон и получит 5% скидку при покупке ранее выбранных разделов.
{% endhint %}

![Доступные разделы](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBLr23itOS1GeE9IRrN%2F-MBLshSyvqNIIrhve546%2Fimage.png?alt=media\&token=55e3bd07-0f81-46b8-82e8-a3dd3db1baf6)


# Управления балансом

Массовое начисление или списание баланса

Настройка позволяет управлять балансом выбранных МА. Имеет возможность начисления, списания или умножения баланса.&#x20;

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FSeUfOfPRFXd2tqUlBvhu%2Fimage.png?alt=media&amp;token=ae7b3617-5f28-45fc-9af7-d757ef291872" alt=""><figcaption></figcaption></figure>


# Установка CMS

Установка и настройка CMS файлов mmoweb


# 1. Скачать файлы кабинета

Скачивание копии клиента с GitHub

**Актуальную версию кабинета и последние обновления вы можете найти в нашем GitHub:**

<https://github.com/PlaygridDev/playgrid-client>

Вы всегда можете скачать последнюю версию в .zip архиве по ссылке:

[**MmoWeb 4 Client**](https://github.com/PlaygridDev/playgrid-client/archive/refs/heads/master.zip)&#x20;

![Скачивание архива в браузере](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBP9RfBXYn24JKGo2vf%2F-MBPB8brZRlrhRwAWrxv%2Fimage.png?alt=media\&token=9cec1e44-8fce-4f61-9b86-b09227338d2c)

**Теперь содержимое архива нужно распаковать на ваш хостинг в корень сайта.**

❗ **Минимальные требования к хостингу:**

* PHP 7.4.33
* Apache 2.4
* MySQL version > 5.6.5


# 2. Запуск инсталлятора

Установка таблиц в базу данных

Находим в корне сайта **install.php** и переходим на него в браузере <https://yousite.ru/install.php>

При первом запуске вы увидите поля для заполнения, **первым** и очень важным полем является `Api key`&#x20;

![Поле Api key в установке mmoweb](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYddIYiQ41VQkR3aWNt%2F-MYde2GlBN4U-bPVN9fe%2Fimage.png?alt=media\&token=8ceb499c-1112-451c-bb1d-2ebec11e728a)

Ключ находится в панели mmoweb.biz, в **блоке информации**, в поле **Секретный ключ группы:**<br>

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fy0JsR9l8J59xrvZYKK41%2Fimage.png?alt=media&amp;token=0f81283c-368d-4aa2-a33d-f1a7d4983c34" alt=""><figcaption></figcaption></figure>

Подключения к базе данных хостинга (MySql)

{% hint style="info" %}
База данных должна быть уже создана, при создании вам необходимо

* Имя базы
* Логин для подключения к базе
* Пароль от базы

Эти данные нам понадобятся для настройки.
{% endhint %}

![Настройки базы данных MySql на вашем хостинге сайта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYddIYiQ41VQkR3aWNt%2F-MYdeqjQxkZxSngIZeSb%2Fimage.png?alt=media\&token=a7cbf5bb-f49a-42e1-aef6-db5ed7e7b6ff)

### Настройка доступов к админ панели сайта

По умолчанию она расположена /admin

![Настройка логин пароля для админ панели сайта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYddIYiQ41VQkR3aWNt%2F-MYdfaJyAtCF6kI0h3d4%2Fimage.png?alt=media\&token=83be7f7f-11e1-4eff-875f-5e70c4c4c421)

### Запускаем установку

По завершению заполнению всех полей необходимо нажать кнопку **-> Install**

> Если при установке возникнут какие-то ошибки, скрипт вам их выведет нужно и будет их исправить и запустить повторно установку.

### Установка окончена

&#x20;Вы должны будите увидеть такую страницу.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F7RIq1hTLHzYC4ohUCp3T%2Fimage.png?alt=media&amp;token=37ddba3d-641c-4ce6-a553-50a5450c3e8f" alt=""><figcaption></figcaption></figure>

При повторном запуске скрипта вы получите сообщение&#x20;

{% hint style="info" %}

## MmoWeb v4 Installation

\
Installation is complete, remove "/Files/blocked\_install.txt" file to re-install!
{% endhint %}

Если будет необходимость снова установить вам нужно будет удалить файл /Files/blocked\_install.txt

Переходим к ознакомлению настроек скрытых в Config.php


# 3. Настройка конфига

Настройка конфига для подключения к базе данных

После того как мы установили MmoWeb мы можем ознакомиться с системными настройками:  нужно найти в корне сайта фаил Config.php&#x20;

![Фаил конфигурации](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBP9RfBXYn24JKGo2vf%2F-MBPELxkBuMd_Rzz2ILE%2Fimage.png?alt=media\&token=6b91a76f-0ed0-4201-8c27-33757953eed0)

Открыть его в текстовом редакторе, к примеру NotePad++.

> В этом конфиги мы можем видеть все ранее настроенные поля через установщик &#x20;

Апи ключ

```php
/**
* Это главный ключ группы он хранится в админ панеле
* This is the main key of the group it is stored in the admin panel.
*/
define('API_KEY',       "q08YmsGbX0lC)54U7ZJ1")
```

Подключения к базе данных

![Настройки базы данных](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBP9RfBXYn24JKGo2vf%2F-MBPEeQMjopInb7dhpJ-%2Fimage.png?alt=media\&token=211a7d03-53b1-4a7d-9898-bd4f4392c08e)

И настройки админ панели

![настройка доступа в админ панель](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBP9RfBXYn24JKGo2vf%2F-MBPFom3ZQkDPvBvpv4d%2Fimage.png?alt=media\&token=a817ef5c-45b2-4298-b71e-605f5f286261)

Для более детальной настройки доступов к админ панели предлагаю настроить ее в этом конфиги

| Ключ              | Значение                                                                                                                                      |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| ADMIN\_PANEL      | Активна ли панель true/false                                                                                                                  |
| ADMIN\_LOGIN      | Логин входа в админ панель                                                                                                                    |
| ADMIN\_PASSWORD   | Пароль для входа в админ панель                                                                                                               |
| TEMPLATE\_WYSIWYG | Использовать ли текстовый редактор true/false                                                                                                 |
| ADMIN\_URL        | путь к админ панели по умолчанию 'admin' вы можете его изменить на свой пример 'admintop' и админ панель будет доступна по адресу /admintop � |

{% hint style="warning" %}
Важно устоновить **Логин и Пароль** для входа в админ панель кабинета с максимальной сложностью для ввода, и ранее не использовавшаяся ни где.&#x20;

По умолчанию эти настройки стоят admin admin
{% endhint %}

> Админ панель сайта используется только для управления сайтом настройки рекламных меток создание новосте и прочего управления сайтом


# 4. Проверка соединения с кабинетом

Тестирование соединения API REST с кабинетом

Проверка соединения производится в панели [mmoweb.b](https://mmoweb.biz/panel)iz > Проекты > Проекты

У проекта, добавленного в панели ММО, есть кнопка **Проверить соединение**&#x20;

![Кнопка Проверить соединение](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBPUsVhO9YI1zxkh2xX%2F-MBPVvQtZbpbjiJ1SKOq%2Fimage.png?alt=media\&token=c5b83795-4860-4d93-b89e-5fb04bc48525)

После нажатия на кнопку "Проверить соединение" откроется окно с информацией о соединении:

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FDbhDwD0dL1o8FS3tTTc5%2Fimage.png?alt=media&amp;token=87360e33-357f-4cd4-8f5b-048d5a656f10" alt=""><figcaption></figcaption></figure>

В случае успеха на всех позициях будет статус OK.

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


# 5. Первая загрузка настроек в кабинет

Загрузка настроек в личный кабинет

Основные настройки личного кабинета хранятся и редактируются в панели mmoweb.biz

Загрузка их в личный кабинет происходит из панели mmoweb.biz

Практически при любых изменениях настроек в админ центре mmoweb.biz вам будет предложено загрузить настройки в личный кабинет.&#x20;

Об этом будет информировать красный значок в верхнем левом углу  <img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBPW_NS3VW4U2CFwRd-%2F-MBPXzRMbEp-_m9mVfDi%2Fimage.png?alt=media&amp;token=4aaefa10-70f5-43bf-b953-c014dfc3510e" alt="" data-size="original">, по нажатию на который будет открываться шторка с информацией:

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F0xMZ8pWhS3PU18p3dob7%2Fimage.png?alt=media&amp;token=fce5c444-0bf1-4225-a875-e7e9618dbd37" alt=""><figcaption></figcaption></figure>

По нажатию на <img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBPW_NS3VW4U2CFwRd-%2F-MBPYmCrtFPZmyevgqT9%2Fimage.png?alt=media&amp;token=65145501-0218-418a-bb51-b4e3c68549aa" alt="" data-size="original"> настройки будут отправлены в личный кабинет и сохранены.

![Сообщение об успешной загрузке настроек](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBPW_NS3VW4U2CFwRd-%2F-MBPZ5fTAuWmM-GhpIW-%2Fimage.png?alt=media\&token=f43d8f41-6cd2-4736-af63-653ae23f8e5d)

Личный кабинет готов к работе.


# Обновления

Как обновить личный кабинет

{% stepper %}
{% step %}

### [Узнайте как работают обновления](/obnovleniya/avtoobnovleniya/kak-rabotaet-avtoobnovlenie)

{% endstep %}

{% step %}

### [Проверьте требования системы](/obnovleniya/avtoobnovleniya/trebovaniya-sistemy)

{% endstep %}

{% step %}

### [Запустите обновление](/obnovleniya/avtoobnovleniya/zapusk-obnovleniya)

{% endstep %}
{% endstepper %}

{% hint style="info" %}
Хотите узнать больше? Начните изучение всей системы доставки обновлений со страницы [Введение](/obnovleniya/avtoobnovleniya)
{% endhint %}


# Что нового?

Регулярные обновления и последние новости от команды Playgrid

## 09.09.2026 — version 4.5.0

### Описание релиза

Версия **4.5.0** завершает основные работы над двухфакторной аутентификацией: добавлены коды восстановления, которые позволяют войти в мастер-аккаунт, даже если пользователь потерял доступ к устройству или к электронной почте. API v2 получило эндпоинты для работы с мастер-аккаунтами проекта, у платёжной системы Stripe появились настраиваемые адреса возврата после оплаты, а так-же исправлены запросы для Lucera.

### Список изменений

#### Коды восстановления 2FA

Добавлены коды восстановления — набор из 10 одноразовых кодов, любой из которых можно ввести вместо кода подтверждения. Это страховка на случай, если пользователь потерял телефон с приложением-аутентификатором, доступ к почте или к номеру, на который приходят коды.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F8XctnOCk5b7w8EkIwcIx%2Ffirefox_ESekIYfjxL.gif?alt=media&amp;token=c0446a79-b55d-453f-b3cb-1f27dc8ddf64" alt="" width="563"><figcaption><p>Получение кодов восстановления доступно двумя способами: при включении любого из методов 2FA и вручную по кнопке в настройках безопасности</p></figcaption></figure>

Коды выдаются автоматически при подключении первого метода 2FA, а также по кнопке «Создать коды» в настройках безопасности. Список показывается один раз — его можно сохранить в TXT-файл. В настройках безопасности видно, сколько кодов осталось. Новые коды можно создать в любой момент, подтвердив пароль мастер-аккаунта — старые коды при этом перестают действовать.

<div align="center"><figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FcgElIogvurRtKDatrNyQ%2Ffirefox_NsdqVQ35vA.gif?alt=media&amp;token=508e96bd-476e-4cc2-ac58-f925e22de880" alt="" width="563"><figcaption><p>При утере доступа к методу 2FA, пользователь может авторизоваться с помощью кода восстановления</p></figcaption></figure></div>

В окне подтверждения появилась ссылка «Нет доступа к устройству? Использовать код восстановления». Код подходит для любого метода 2FA и работает как при входе в личный кабинет, так и при отключении двухфакторной аутентификации. Каждый код можно использовать только один раз.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F39L75LSqJwfUKr4LcD8P%2Fimage.png?alt=media&amp;token=8e1342a3-4be3-4c84-9ddc-4d82bec4b85e" alt=""><figcaption><p>Конфиг находится в настройках проекта (вкладка Безопасность)</p></figcaption></figure>

Функция включается в настройках проекта, во вкладке «Безопасность», параметром «Коды восстановления 2FA» — по умолчанию она выключена. Создание кодов и каждое их использование фиксируются в логах пользователя, поэтому службе поддержки видно, когда и для какого действия был применён код. При сбросе 2FA мастер-аккаунта из админ-панели коды восстановления также аннулируются.

#### Новые эндпоинты API v2

Публичное API v2 получило два эндпоинта для работы с мастер-аккаунтами проекта:

* [Список мастер-аккаунтов](/rest-api/master-akkaunt/spisok-master-akkauntov) — постраничная выгрузка аккаунтов с фильтрами по дате регистрации и статусу, а также пакетным поиском по идентификаторам, адресам электронной почты и телефонам.
* [Получение мастер-аккаунта](/rest-api/master-akkaunt/poluchenie-master-akkaunta) — данные одного аккаунта по идентификатору, электронной почте или телефону.

Доступ выдаётся в настройках ключей API: в списке доступов ключа появились пункты «Список мастер аккаунтов (v2)» и «Получение мастер аккаунта (v2)». Ключ работает в рамках выбранного проекта. Так как эндпоинты возвращают персональные данные пользователей, рекомендуем завести для выгрузки отдельный ключ и выдать ему только эти права.

#### Success/Cancel URL для Stripe

В настройках Stripe появились поля **Success URL** и **Cancel URL** — теперь можно указать, куда возвращать пользователя после успешной оплаты и после её отмены.

Если поля не заполнены, поведение остаётся прежним — возврат на главную страницу. При способе расчёта стоимости «Price» Stripe поддерживает только адрес успешной оплаты.

#### Исправлены запросы для Lucera

Исправлены услуги смены цвета ника и титула персонажа, а также управление HWID-привязкой — ранее эти действия завершались ошибкой.

## 17.08.2026 — version 4.4.5

### Описание релиза

Версия **4.4.5** — патч-обновление, продолжающее линию безопасности релиза 4.4.0. Главное в этом обновлении — новый метод двухфакторной аутентификации через приложение-аутентификатор, который работает без писем и SMS. Также улучшено поведение метода подтверждения по телефону, у администраторов появилась возможность отключить 2FA мастер-аккаунта из панели управления, исправлена ошибка авторизации, связанная с проверкой пароля, и улучшена стабильность списания бонусных балансов.

### Список изменений

#### **2FA через приложение-аутентификатор**

Добавлен третий метод двухфакторной аутентификации — приложение-аутентификатор. Он работает наравне с E-Mail и телефоном и поддерживает популярные приложения-аутентификаторы, включая Google Authenticator.

Метод не использует письма и SMS, поэтому доступен всем пользователям — в том числе тем, кто не подтвердил электронную почту и не указал телефон. Это делает его универсальным способом защитить мастер-аккаунт, особенно в режиме «Обязательна для всех».

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fq2wQ9tjrZOvMGjbbPAZe%2Ffirefox_XX14tyB2Mn.gif?alt=media&amp;token=d33f4060-686c-428e-ac61-ce7d333ba44a" alt="" width="563"><figcaption></figcaption></figure>

Подключение занимает несколько шагов: в настройках личного кабинета, во вкладке «Безопасность», нужно выбрать метод «аутентификатор», отсканировать QR-код в приложении и ввести код подтверждения. После этого при входе в личный кабинет и при подтверждении важных действий код берётся из приложения.

Метод можно использовать вместе с остальными: если у пользователя подключены и E-Mail, и аутентификатор, при подтверждении он выбирает удобный способ.

#### **Метод подтверждения по телефону**

Исправлено отображение метода подтверждения по телефону: теперь он предлагается только если в настройках проекта включена авторизация через телефон.

#### **Отключение 2FA мастер-аккаунта из админ-панели**

В профиле мастер-аккаунта появился блок **2FA**: видно, включена ли у пользователя двухфакторная аутентификация и какие методы подключены, а также доступно её отключение.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FD1p51ZoOMUkSm2Oc3Fx9%2Ffirefox_iRnbY8snGU.gif?alt=media&amp;token=10957cdc-3f51-46e0-9206-6bab49078145" alt=""><figcaption></figcaption></figure>

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

#### **Списание бонусного баланса**

Улучшена стабильность списания в плагине Bonus Balance — устранено повторное списание бонусов при сгорании начислений с истёкшим сроком.

## 29.07.2026 — version 4.4.0

### Описание релиза

Версия **4.4.0** — одно из крупнейших обновлений безопасности MMOWeb. В этом релизе мы сосредоточились на защите мастер- и игровых аккаунтов, расширили возможности контроля регистрации пользователей и добавили новые инструменты для администраторов проектов. Обновление включает двухфакторную аутентификацию, гибкие политики паролей, защиту от временных почтовых сервисов и алиасов, ограничения доступа по IP, а также улучшенный процесс подтверждения электронной почты.

### Список изменений

#### &#x20;2FA для мастер-аккаунтов

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FD64lOh21wzLf0do58zI2%2Ffirefox_zvNkRdS868.gif?alt=media&amp;token=54c93ff0-a557-44e0-841e-67298bc37791" alt="" width="563"><figcaption></figcaption></figure>

Добавлена двухфакторная аутентификация для защиты мастер-аккаунтов. Доступно 2 способа аутентификации: через E-Mail, телефон. Так-же доступно 2 режима работы: по желанию, обязательна для всех.

При выборе режима «Обязательна для всех» пользователи, не подключившие 2FA, должны будут настроить её для продолжения работы с мастер-аккаунтом.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FjCXypjHplfqNjvja8aO8%2Fimage.png?alt=media&amp;token=b748054c-b338-48a0-a8e6-b6abfba95b50" alt=""><figcaption><p>Выбрать режим работы 2FA вы можете в настройках проекта, во вкладке безопасность</p></figcaption></figure>

#### Требования к паролям

Добавлены гибкие настройки требований к паролям для мастер- и игрового аккаунта.

Теперь для каждого типа аккаунта можно независимо настроить:

* минимальную длину пароля;
* максимальную длину пароля;
* обязательное наличие:
  * строчных букв;
  * заглавных букв;
  * цифр;
  * специальных символов.

Это позволяет привести политику паролей в соответствие с требованиями безопасности вашего проекта. Настройки применяются отдельно к мастер-аккаунтам и игровым аккаунтам, что дает возможность использовать разные уровни защиты для административных и игровых пользователей.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FofI6KSAE5njvnYUFMQEE%2Fimage.png?alt=media&amp;token=7b866d9b-dfb0-46bf-a93e-655ade75cc46" alt=""><figcaption><p>Параметры требования к паролям доступны в настройках проекта, во вкладке безопасность </p></figcaption></figure>

#### Блокировка временных Email

Обновлен плагин блокировки временных e-mail адресов. Теперь для проверки используются внешние сервисы, что обеспечивает максимально полное покрытие базы временных доменов и позволяет оперативно блокировать новые одноразовые почтовые сервисы без необходимости ручного добавления.

#### Блокировка почтовых алиасов

Добавлена возможность блокировать регистрацию и использование почтовых алиасов.

Почтовые алиасы позволяют создавать несколько адресов электронной почты для одного почтового ящика (например: `user@gmail.com`, `user+1@gmail.com`, `user+2@gmail.com`), что часто используется для повторной регистрации и обхода ограничений.

**Доступно три режима работы:**

* **Отключено** — алиасы считаются отдельными адресами.
* **Только для новых регистраций** — запрещает регистрацию новых аккаунтов с использованием алиасов, если основной адрес уже зарегистрирован. Рекомендуемый режим.
* **Для всех аккаунтов** — ограничение применяется как к новым, так и к существующим пользователям. Владельцам аккаунтов с почтовыми алиасами будет предложено изменить адрес электронной почты при следующем входе.

Функция помогает предотвратить создание нескольких аккаунтов с использованием одного почтового ящика и повышает эффективность защиты от злоупотреблений.

#### Блокировка IP-адресов, подсетей

Добавлена возможность полностью ограничить доступ к личному кабинету по IP-адресу.

Функция позволяет создавать правила блокировки для отдельных IP-адресов, диапазонов и подсетей. Пользователи, чей IP попадает под действие правила, не смогут получить доступ к личному кабинету, включая страницы авторизации, регистрации и восстановления доступа.

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

## 18.05.2026 — version 4.3.0

### Описание релиза

Мы начинаем развитие платформы по архитектурному подходу API First. Для нас это важный этап, который позволит быстрее развивать интеграции, автоматизацию и новые возможности личного кабинета в будущем. Фактически, это означает переход от CMS-first модели, где функциональность была ограничена возможностями личного кабинета, к подходу Entity API Management — более гибкой архитектуре, в которой API становится основой для управления всеми сущностями и сервисами платформы.

### Список изменений

* Реализован алгоритм позволяющий добавлять новые способы оплаты самостоятельно
  * [API v2 Payment документация](/rest-api/master-akkaunt)
* Реализован DataBus на основе BroadcastChannel API и бэкенд для него.
* Checkout v1 deprecated и будет удалён в следующих выпусках.
* Payment v2: createOrder, getMethods.
* Updater: переписан алгоритм сравнения файлов (теперь используется gitTree).
* Updater: проведена большая работа по стабилизации апдейтера, исправлены многие ошибки и непредвиденные состояния.
* Updater: улучшен UX для случаев, когда сайту не удалось отправить запрос о запуске процесса обновления. Если по какой-либо причине сайт не может связаться с API для уведомления о старте процесса, обновление не начнётся, а в админ-панели через 5 минут появится сообщение: «Connection timeout, check update log in Debug folder».
* Добавлены новые способы оплаты: Betatransfer, LiqPay, WayForPay.
  * Реализован алгоритм обработки частичной оплаты для Betatransfer
  * Добавили опциональные параметры "Описание заказа" для LiqPay, WayForPay
* Везде, где происходит пополнение, теперь используется API v2.
* Добавлена синхронизация баланса между вкладками при операциях списания.
* Выполнен отказ от localStorage как способа передачи данных между JS и бэкендом — теперь используется BroadcastChannel API.
* Реализована архитектура, позволяющая выбирать способ оплаты до перехода на страницу платёжной системы (пример реализации сделали для Betatransfer).
* Бонусный баланс: в списке балансов на странице просмотра мастер-аккаунта отображаются только сервера со статусом "Включен".
* Бонусный баланс: исправлена некорректная валидация входящих данных для срока действия начисляемых бонусов
* Ключи сторонних приложений: исправлен баг при котором во время сохранения записывался пустой Application Token

## version 4.2.1

{% hint style="info" icon="book-blank" %}
Скоро мы перенесем все обновления сюда, а пока можете найти предыдущие изменениях [здесь](https://mmoweb.biz/changelog)
{% endhint %}

## version 4.2.0

## version 4.1.5

## version 4.1.1

## Версия 4.1.0


# Исправление версии

Рекомендуется выполнить всем для подключения к стабильному каналу обновлений и исправления компонента автообновлений

{% hint style="info" %}
Компонент автообновлений был доработан и исправлен в версии 4.3.0

Мы рекомендуем выполнить процедуру обновления заново используя эту инструкцию
{% endhint %}

{% hint style="warning" %}
Перед выполнением обновления, узнайте [как работает процесс обновления](/obnovleniya#uznaite-kak-rabotayut-obnovleniya)

Рекомендуется сделать резервную копию корневой директории сайта перед любыми изменениями

Убедитесь, что вы сделали копии языковых локалей и кастомных шаблонов
{% endhint %}

1. Компонент автообновлений доступен для пользователей с оплаченым тарифом
2. [Скачайте свежий updater-патч](https://m.mmoweb.biz/mmoweb-updater-patch.zip)
3. Разархивируйте содержимое архива в корень сайта
4. После распаковки архива — загрузите конфиг проекта на сайт

   *Это необходимо, чтобы ваша CMS могла отправлять данные о прогрессе обновления на API*
5. Перейдите на страницу управления обновлениями

   <figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fhft0dniUT2uoHqoCf3F7%2Fgoto-updates.png?alt=media&amp;token=3c359925-5b21-4bb7-9d1a-b01904e8327d" alt="" width="375"><figcaption></figcaption></figure>
6. Запустите процесс обновления **версии 4.3.0**

   <figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FTSZWImNElF0NJCB9Ai3H%2Fstart-update.gif?alt=media&amp;token=cd922345-f1a3-487d-868a-036440094620" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Процесс обновления установит все предыдущие версии включая версию 4.3.0
{% endhint %}

{% hint style="warning" %}
Если у вас возникли проблемы в процессе обновления, воспользуйтесь [рекомендациями для восстановления из бекапа](/obnovleniya/avtoobnovleniya/vosstanovlenie-iz-bekapa)

Если вы испытываете серьезные проблемы с процессом обновления — [создайте тикет](https://mmoweb.biz/panel/tickets/add)
{% endhint %}


# Автообновления

Система автоматического обновления позволяет обновлять ваш сайт до последней версии без необходимости ручной загрузки и установки файлов. Все обновления происходят безопасно с автоматическим созданием резервных копий.

{% hint style="info" %}
Система работает через GitHub и автоматически применяет только те файлы, которые были изменены в новой версии.
{% endhint %}


# Как работает автообновление

#### Этапы процесса

1. **Проверка условий** - система проверяет, что обновление возможно
2. **Создание резервной копии** - автоматически создается полный бекап текущей версии
3. **Загрузка новой версии** - скачивается релиз с GitHub
4. **Применение изменений** - обновляются только измененные файлы
5. **Завершение** - версия обновляется, система готова к работе

{% hint style="success" %}
Всё обновление обычно занимает от 1 до 5 минут в зависимости от размера проекта и скорости интернета.
{% endhint %}


# Безопасность обновлений

#### Защита данных

* Все обновления проходят проверку подписи
* Создается автоматический бекап перед любыми изменениями
* Защита от ZIP Slip атак

#### Аутентификация

Все API запросы требуют HMAC-SHA256 подпись с использованием секретного ключа.


# Требования системы

#### Минимальные требования

* **PHP версия**: 7.4.33
* **PHP расширения**: `zip`, `curl`, `json`
* **Свободное место**: минимум в 2 раза больше размера проекта
* **Доступ к GitHub API**: порт 443 должен быть открыт
* **Права доступа**: запись в директорию `Files/`

#### Проверка требований

Система автоматически проверяет все требования перед началом обновления. Если что-то не соответствует, вы получите сообщение об ошибке с подробным описанием проблемы.


# Запуск обновления

#### Через панель управления

1. Откройте административную [панель mmoweb.biz](https://mmoweb.biz)
2. Перейдите в раздел [проекты](https://mmoweb.biz/panel/project)
3. Нажмите кнопку "Проверить обновления"
4. Если доступна новая версия, нажмите "Обновить"
5. Дождитесь завершения процесса


# Резервное копирование

#### Автоматический бекап

Перед каждым обновлением система автоматически создает полную резервную копию всех файлов проекта.

**Расположение бекапов**:

```
Files/update/{уникальный_код_процесса}/backup.zip
```

**Пример**:

```
Files/update/115abb9f3a36cfbb/backup.zip
```

#### Что НЕ попадает в бекап

В бекап не включаются:

* Архивы (`.zip`, `.rar`, `.7z`, `.tar`, `.gz`)
* Предыдущие процессы обновления (папка `Files/update/`)
* Символические ссылки
* Нечитаемые файлы

{% hint style="info" %}
Все важные файлы (код, конфигурация, шаблоны) сохраняются в бекапе.
{% endhint %}


# Отслеживание прогресса

#### Индикатор выполнения

Во время обновления вы можете видеть процент выполнения:

(need screenshot here)

#### Через API

{% hint style="info" %}
Требуется авторизация с помощью HMAC-256 ключа
{% endhint %}

```http
GET https://your-site.com/api/get_updater_process_progress?process_key={код}
```

**Ответ**:

```json
{
    "result_code": "PROGRESS_RETRIEVED",
    "metadata": {
        "progress": 67.5
    }
}
```


# Логи обновлений

#### Где найти логи

Все логи сохраняются в директории `/Debug/`

**Формат имени лога**:

```
update_2026-02-14_15-30_115abb9f.log
```

Где:

* `2026-02-14_15-30` - дата и время начала обновления
* `115abb9f` - первые 8 символов уникального кода процесса

#### Что записывается в логи

* Начало и завершение процесса
* Какие файлы были обновлены
* Процент выполнения на каждом этапе
* Ошибки (если они возникли)
* Информация о системе (в режиме отладки DEBUG = true)


# Проблемы и решения

#### Ошибка: "Обновление уже запущено"

**Причина**: Предыдущий процесс обновления еще не завершен или завис.

**Решение**:

```bash
# Проверьте статус процесса
cat cache/update.txt

# Если процесс завис (прошло более 30 минут), очистите кеш
rm -f cache/update*
```

***

#### Ошибка: "Недостаточно места на диске"

**Причина**: Не хватает места для создания бекапа или загрузки новой версии.

**Решение**:

```bash
# Проверьте свободное место
df -h

# Очистите старые бекапы (оставьте 2-3 последних)
rm -rf Files/update/старый_код/

# Очистите логи старше 30 дней
find Files/logs/ -name "*.log" -mtime +30 -delete
```

{% hint style="info" %}
Рекомендуется иметь свободного места минимум в 2 раза больше размера вашего проекта.
{% endhint %}

***

#### Ошибка: "Failed to create update process directory"

**Причина**: Недостаточно прав для записи в директорию `Files/`.

**Решение**:

```bash
# Установите правильного владельца
chown -R www-data:www-data /var/www/your-site

# Установите права на директорию Files
chmod 775 Files/
chmod 775 Files/update/
chmod 775 Files/logs/
chmod 775 Files/cache/
```

***

#### Ошибка: "GitHub API rate limit exceeded"

**Причина**: Превышен лимит запросов к GitHub API.

**Решение**:

1. Убедитесь, что используется токен авторизации в `Library/configs/github.json`
2. С токеном лимит: 5000 запросов/час
3. Без токена: только 60 запросов/час
4. Подождите час или используйте токен

**Как создать GitHub токен**:

1. Откройте <https://github.com/settings/tokens>
2. Нажмите "Generate new token (classic)"
3. Выберите scope: `public_repo`
4. Скопируйте токен и добавьте в конфигурацию

***

#### Ошибка: "ZIP file corrupted"

**Причина**: Файл релиза был поврежден при загрузке.

**Решение**:

```bash
# 1. Удалите поврежденный файл
rm Files/update/{код процесса}/*.zip

# 2. Очистите кеш
rm -f cache/update*

# 3. Запустите обновление заново
```

***

#### Ошибка: "PHP version error"

**Причина**: Установлена устаревшая версия PHP.

**Решение**:

```bash
# Проверьте текущую версию
php -v

# Обновите PHP до версии 7.4.33 или выше
# Для Ubuntu/Debian:
sudo apt update
sudo apt install php7.4

# Для CentOS/RHEL:
sudo yum install php74
```

***

#### Ошибка: "PHP version error"

**Причина**: Установлена некорректная версия PHP.

**Решение**: Установите PHP версии 7.4.33


# Восстановление из бекапа

#### Когда может понадобиться

* Обновление завершилось с ошибкой
* После обновления сайт работает некорректно
* Вы хотите вернуться к предыдущей версии

{% hint style="danger" %}
Восстановление полностью заменит все файлы на версию из бекапа. Все изменения, сделанные после обновления, будут потеряны.
{% endhint %}

#### Шаг 1: Найдите бекап

```bash
# Показать все доступные бекапы
ls -lth Files/update/*/backup.zip
```

#### Шаг 2: Выберите нужный бекап

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

```bash
# Пример вывода:
-rw-r--r-- 1 www-data www-data 15M Feb 14 15:30 Files/update/115abb9f/backup.zip
-rw-r--r-- 1 www-data www-data 14M Feb 10 12:15 Files/update/a7c3d2e1/backup.zip
```

#### Шаг 3: Распакуйте бекап

{% hint style="info" %}
**Рекомендация:** Создайте тестовую копию на локальном сервере перед восстановлением на production!
{% endhint %}

```bash
# 1. Перейдите в корневую директорию проекта
cd /var/www/your-site

# 2. Создайте временную копию текущей версии (опционально)
tar -czf /tmp/current_backup_$(date +%Y%m%d_%H%M%S).tar.gz .

# 3. Распакуйте бекап (замените путь на ваш)
unzip -o Files/update/115abb9f/backup.zip

# 4. Восстановите права доступа
chown -R www-data:www-data .
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
chmod 775 Files/
```

#### Проверьте работу сайта

1. Откройте сайт в браузере
2. Проверьте основные функции
3. Проверьте соединение и версию в админ-панели


# Конфигурационные файлы

#### version.json

Хранит информацию о текущей установленной версии.

**Расположение**: `Library/configs/version.json`

```json
{
    "tag": "v1.2.3",
    "timestamp": "2026-01-15T12:34:56Z",
    "release_id": 123456
}
```

**Поля**:

* `tag` - версия (соответствует тегу в GitHub)
* `timestamp` - дата публикации релиза
* `release_id` - ID релиза в GitHub

***

#### github.json

Настройки подключения к GitHub API.

**Расположение**: `Library/configs/github.json`

```json
{
    "api_base_uri": "https://api.github.com",
    "repository_path": "owner/repository-name",
    "token": "ghp_xxxxxxxxxxxxxxxxxxxx",
    "timeout": 15
}
```

**Поля**:

* `api_base_uri` - базовый URL GitHub API (обычно не требует изменений)
* `repository_path` - путь к репозиторию в формате `владелец/репозиторий`
* `token` - Personal Access Token для доступа к API (необязательно)
* `timeout` - таймаут запросов в секундах

{% hint style="info" %}
Токен увеличивает лимит запросов к GitHub API с 60 до 5000 в час.
{% endhint %}


# Часто задаваемые вопросы

#### Перестанут ли работать кастомизации?

Да, кастомизации могут перестать работать, если вы вносили изменения в:

* Системные классы и файлы (Class, Controllers, helpers и пр.)
* Основные файлы шаблонов (или вы не вносили изменения через папку /custom)
* Языковые файлы в папке Language

{% hint style="info" %}
Если вы пользуетесь модифицированной версией Mmoweb, обратитесь в поддержку для помощи с обновлением.
{% endhint %}

***

#### Как часто выходят обновления?

Обновления выпускаются по мере готовности новых функций и исправлений. В среднем 1-2 раза в месяц.

***

#### Можно ли пропустить версию?

Нет, система требует строгой очередности установки обновлений. "Перепрыгивание" через версии не рекомендуется.&#x20;

***

#### Что делать, если обновление прервалось?

1. Проверьте логи в `Files/logs/update_*.log`
2. Если ошибка критическая - восстановитесь из бекапа
3. Если ошибка временная (сеть, таймаут) - запустите обновление заново

***

#### Нужно ли делать бекап базы данных?

Система обновлений работает только с файлами и не затрагивает базу данных. Однако рекомендуется регулярно создавать бекапы БД независимо от обновлений.

***

#### Сколько времени занимает обновление?

Обычно от 1 до 5 минут в зависимости от:

* Размера проекта
* Количества измененных файлов
* Скорости интернет-соединения
* Производительности сервера

***

#### Можно ли откатиться на предыдущую версию?

Да, используйте процедуру [восстановления из бекапа](/obnovleniya/avtoobnovleniya/vosstanovlenie-iz-bekapa).

***

#### Работает ли система на shared hosting?

Да, если выполняются минимальные требования:

* PHP 7.4.33+
* Расширение ZIP
* Доступ к GitHub API
* Права на запись в Files/

***

#### Как обновиться вручную?

Для ручного обновления:

1. Скачайте релиз вручную
2. Распакуйте файлы локально
3. Замените файлы через FTP/SFTP

{% hint style="warning" %}
При ручном обновлении бекап не создается автоматически!
{% endhint %}

***


# Техническая документация

### Описание

Система автоматического обновления MmoWeb Client реализует механизм безопасного развёртывания новых версий приложения через GitHub Releases API. Система поддерживает автоматическое резервное копирование, поэтапное применение изменений и отслеживание прогресса обновления в реальном времени.

***

### Архитектура системы

#### Основные компоненты

1. **UpdateService** (`Class/Services/UpdateService.php`)
   * Центральный сервис управления обновлениями
   * Отвечает за скачивание, распаковку и применение релизов
2. **Repository** (`Class/GitHub/Repository.php`)
   * Абстракция работы с GitHub API
   * Обработка запросов к репозиторию и релизам
3. **ApiController** (`Controllers/ApiController.php`)
   * HTTP endpoints для удалённого управления обновлениями
   * Методы: `updater_check_connection`, `install_update`, `get_version`, `get_updater_process_progress`
4. **Cache система**
   * Хранилище состояния процесса обновления
   * Кеширование прогресса выполнения

***

### Процесс обновления

#### 1. Инициализация

**Вызов API endpoint**

```http
POST /api/install_update
Content-Type: application/x-www-form-urlencoded

hash={HMAC_SHA256_SIGNATURE}&tag=v1.2.3
```

**Валидация**

* Проверка версии PHP (только 7.4.33)
* Проверка соединения с GitHub API
* Проверка конфигурации версии
* Проверка отсутствия активного процесса обновления

**Генерация процесса**

* Создаётся уникальный `process_key` (SHA256 хеш)
* Устанавливается статус `CREATED`
* Возвращается `process_key` клиенту

**Файл**: `UpdateService.php:82-104`

***

#### 2. Создание директории процесса

**Расположение**: `Files/update/{process_key}/`

Структура директории:

```
Files/update/{process_key}/
├── backup.zip          # Полный бекап текущей версии
└── {tag}.zip          # Скачанный релиз с GitHub
```

**Файл**: `UpdateService.php:106-127`

***

#### 3. Создание резервной копии

**Параметры бекапа**

* **Путь**: `Files/update/{process_key}/backup.zip`
* **Метод**: Рекурсивная архивация через `ZipArchive`
* **Исключения**:
  * Директория `Files/update/` (любые процессы обновления)
  * Архивы: `.zip`, `.rar`, `.7z`, `.tar`, `.gz`, `.bz2`, `.xz`, `.tgz`
  * Символические ссылки
  * Нечитаемые файлы

**Алгоритм**

1. Сканирование всех файлов от `ROOT_DIR`
2. Фильтрация по критериям исключения
3. Добавление файлов и директорий в ZIP с сохранением структуры
4. Проверка целостности (размер > 0 байт)

**Время выполнения**: зависит от размера проекта (обычно 5-30 секунд)

**Файл**: `UpdateService.php:233-312`

***

#### 4. Загрузка релиза

**Источник**

* **URL**: `{release.zipball_url}` из GitHub API
* **Таймаут**: 2100 секунд (35 минут)

**Механизм загрузки**

```php
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 2100);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
```

**Путь сохранения**

`Files/update/{process_key}/{tag}.zip`

**Файл**: `UpdateService.php:129-179`

***

#### 5. Анализ изменений коммита

**Получение списка файлов**

Система запрашивает все файлы из коммита релиза через GitHub API:

```
GET /repos/{owner}/{repo}/commits/{sha}?page={N}
```

**Пагинация**

* Обрабатываются все страницы (max 50)
* Паузы между запросами: 250ms (`usleep(250000)`)

**Типы изменений файлов**

* **added** - новый файл
* **modified** - изменённый файл
* **renamed** - переименованный файл (обрабатывается как копирование)
* **removed** - удалённый файл (логируется, но НЕ удаляется локально)

**Файл**: `UpdateService.php:345-390`

***

#### 6. Применение изменений

**Процесс обработки файлов**

```
Для каждого файла из коммита:
1. Определить путь в архиве: {releaseFolder}/{filename}
2. Проверка ZIP Slip атак (путь не должен содержать `..` или абсолютные пути)
3. Применить операцию согласно статусу
4. Обновить progress
5. Отправить прогресс в Global API (каждые 3 секунды)
```

**Метод извлечения файла**

**Атомарная операция**:

1. Создание временного файла `{targetPath}.tmp`
2. Копирование потока из ZIP в временный файл
3. Установка прав `0644`
4. Атомарная замена через `rename()`

**Безопасность**:

* Автоматическое создание директорий с правами `0755`
* Откат при ошибке (удаление `.tmp`)

**Файл**: `UpdateService.php:604-631`

***

#### 7. Завершение процесса

**При успешном обновлении**

1. Статус устанавливается в `COMPLETED`
2. Обновляется конфигурация `version.json`:

   ```json
   {
       "tag": "v1.2.3",
       "timestamp": "2026-01-15T12:34:56Z",
       "release_id": 123456
   }
   ```
3. Очистка кеша (если `DEBUG = false`):
   * `update_progress_{process_key}`
   * `update`

**Файл**: `UpdateService.php:548-563`

**При ошибке**

1. Статус устанавливается в `FAILED`
2. Запись в лог с полным трейсом ошибки
3. Отправка ошибки в Global API
4. Бекап остаётся нетронутым в `Files/update/{process_key}/backup.zip`

**Файл**: `UpdateService.php:565-574`

***

### Логирование

#### Расположение логов

**Директория**: `Files/logs/`

**Формат имени**:

```
update_{Y-m-d_H-i}_{first_8_chars_of_process_key}.log
```

**Пример**:

```
update_2026-02-14_15-30_115abb9f.log
```

#### Содержимое логов

**Стандартная информация**

* Начало установки релиза
* Создание директории процесса
* Загрузка ZIP файла
* SHA коммита релиза
* Создание бекапа
* Обработка каждого файла (статус и путь)
* Прогресс обновления (% выполнения)
* Окончание процесса

**Debug информация (если `DEBUG = true`)**

**Системная информация**:

```
=== System information ===
[PHP]
Version: 8.1.2
SAPI: fpm-fcgi

[Environment]
OS: Linux
Architecture: 64-bit

[Limits]
Memory limit: 256M
Max execution time: 1800
Upload max filesize: 2M
Post max size: 8M

[Extensions]
- Core: unknown
- date: 8.1.2
- zip: 1.20.0
...
==========================
```

**Файл**: `UpdateService.php:633-639, 314-343`

#### Критические ошибки

**Обработчик Shutdown**

Регистрируется на старте обновления и отлавливает фатальные ошибки:

* `E_ERROR`
* `E_PARSE`
* `E_CORE_ERROR`
* `E_COMPILE_ERROR`
* `E_USER_ERROR`

При фатальной ошибке:

1. Пишется в лог с префиксом `FATAL ERROR:`
2. Кеш устанавливается в `FAILED`
3. Уведомление отправляется в Global API

**Файл**: `UpdateService.php:182-231`

***

### Управление состоянием

#### Кеширование статуса

**Ключ кеша: `update`**

**Структура**:

```php
[
    'status' => 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'CREATED',
    'process_key' => '{SHA256_HASH}'
]
```

**TTL**: 1800 секунд (30 минут)

**Файл**: `UpdateService.php:92-104`

***

#### Кеширование прогресса

**Ключ кеша: `update_progress_{process_key}`**

**Значение**: Float (0.00 - 100.00)

**TTL**: 600 секунд (10 минут)

**Обновление**: При обработке каждого файла

**Пример файла**: `cache/update_progress_{hash}.txt`

```php
a:3:{
    s:4:"time";i:1770805760;
    s:3:"ttl";i:600;
    s:4:"data";d:100;  // progress = 100.0
}
```

**Файл**: `UpdateService.php:532-533`

***

### API Endpoints

#### 1. Проверка соединения

**Endpoint**: `POST /api/updater_check_connection`

**Проверки**:

* Валидность конфигурации версии
* PHP = 7.4.33
* Соединение с GitHub API

**Ответы**:

```json
// Успех
{
    "result_code": "CHECK_SUCCESS",
    "metadata": {}
}

// Ошибка версии PHP
{
    "result_code": "PHP_VERSION_ERROR",
    "metadata": {
        "current_version": "7.3.0",
        "minimum_version": "7.4.33"
    }
}
```

**Файл**: `ApiController.php:432-475`

***

#### 2. Установка обновления

**Endpoint**: `POST /api/install_update`

**Параметры**:

* `tag` (required) - тег релиза (например, `v1.2.3`)
* `process_key` (optional) - ключ процесса при продолжении

**Двухэтапный процесс**:

**Этап 1: Создание процесса**

```http
POST /api/install_update
tag=v1.2.3
```

Ответ:

```json
{
    "result_code": "PROCESS_CREATED",
    "metadata": {
        "process_key": "115abb9f3a36cfbb5d8988ed6ac7bb74d930af6572e26bbdb23c964f8f5b453e"
    }
}
```

**Этап 2: Выполнение обновления**

```http
POST /api/install_update
tag=v1.2.3&process_key=115abb9f...
```

Ответ при успехе:

```json
{
    "result_code": "INSTALL_SUCCESS",
    "metadata": {}
}
```

Ответ при ошибке:

```json
{
    "result_code": "INSTALL_FAILED",
    "metadata": {
        "error": "Failed to open ZIP file..."
    }
}
```

**Файл**: `ApiController.php:477-572`

***

#### 3. Получить текущую версию

**Endpoint**: `POST /api/get_version`

**Ответ**:

```json
{
    "result_code": "CURRENT_VERSION",
    "metadata": {
        "version": "v1.2.3"
    }
}
```

**Файл**: `ApiController.php:574-590`

***

#### 4. Получить прогресс обновления

**Endpoint**: `GET /api/get_updater_process_progress?process_key={key}`

**Ответ**:

```json
{
    "result_code": "PROGRESS_RETRIEVED",
    "metadata": {
        "progress": 45.67
    }
}
```

**Файл**: `ApiController.php:592-630`

***

### Обработка ошибок и recovery

#### Типовые ошибки

**1. Обновление уже запущено**

**Статус**: `423 Locked`

```json
{
    "result_code": "UPDATE_IN_PROGRESS",
    "metadata": {}
}
```

**Решение**: Дождаться завершения текущего процесса или проверить статус в кеше

***

**2. Тег уже установлен**

**Exception**: `The specified tag is already installed.`

**Решение**: Проверить текущую версию через `/api/get_version`

***

**3. Проблемы с GitHub API**

**Возможные причины**:

* Неверный токен авторизации
* Rate limiting
* Таймаут соединения
* Несуществующий релиз/тег

**Диагностика**:

* Проверить логи `Debug/github.log`
* Проверить конфигурацию `Library/configs/github.json`
* Тест соединения: `/api/updater_check_connection`

**Файл**: `Repository.php:53-115`

***

**4. Ошибка создания бекапа**

**Возможные причины**:

* Недостаточно места на диске
* Нет прав на запись в `Files/update/`
* Исчерпана память PHP (`memory_limit`)

**Решение**:

1. Проверить свободное место: `df -h`
2. Проверить права: `ls -la Files/`
3. Увеличить `memory_limit` в php.ini (по умолчанию устанавливается 256M)

**Файл**: `UpdateService.php:233-312`

***

**5. Битый ZIP файл**

**Exception**: `Failed to open ZIP file... The file may be corrupted.`

**Решение**:

1. Проверить файл вручную: `unzip -t Files/update/{process_key}/{tag}.zip`
2. Удалить процесс и повторить обновление
3. Проверить стабильность сетевого соединения

**Файл**: `UpdateService.php:449-451`

***

**6. ZIP Slip атака**

**Exception**: `ZIP Slip detected: invalid path: ...`

**Причина**: Попытка записи файла за пределы `ROOT_DIR`

**Защита**: Проверка на наличие `..` или абсолютных путей в именах файлов

**Файл**: `UpdateService.php:492-497`

***

#### Восстановление из бекапа

**Автоматическое восстановление**

При ошибке процесс останавливается, но **откат не производится автоматически.**

**Ручное восстановление**

1. Найти директорию последнего обновления:

   ```bash
   ls -lt Files/update/ | head -n 2
   ```
2. Проверить наличие бекапа:

   ```bash
   ls -lh Files/update/{process_key}/backup.zip
   ```
3. Распаковать бекап:

   ```bash
   # НЕ ИСПОЛЬЗУЙТЕ unzip напрямую в продакшене!
   # Создайте скрипт восстановления:

   cd /path/to/project
   unzip -o Files/update/{process_key}/backup.zip
   ```
4. Проверить права доступа:

   ```bash
   find . -type f -exec chmod 644 {} \;
   find . -type d -exec chmod 755 {} \;
   ```
5. Очистить кеш обновления:

   ```bash
   rm -f Files/cache/update*
   ```

***

### Безопасность

#### Аутентификация API (клиентская часть)

Все API endpoints используют HMAC-SHA256 подпись:

```php
// Генерация подписи
ksort($_POST);
$signature = hash_hmac('sha256', json_encode($_POST), API_KEY);
$_POST['hash'] = $signature;
```

**Константа**: `API_KEY` из Config.php

**Файл**: `ApiController.php:14-44`

***

#### Защита от атак

**1. ZIP Slip Protection**

Проверка всех путей файлов на наличие:

* `..` (выход за пределы директории)
* Абсолютных путей (`/`, `\`, `C:`)

**2. Игнорирование пользовательского прерывания**

```php
ignore_user_abort(true);
```

**3. Ограничения выполнения**

* **Таймаут**: 1800 секунд (30 минут)
* **Память**: 256MB
* **Umask**: 0022 (права по умолчанию)

**Файл**: `UpdateService.php:395-400`

***

#### Конфигурация GitHub

**Файл**: `Library/configs/github.json`

```json
{
    "api_base_uri": "https://api.github.com",
    "repository_path": "PlaygridDev/playgrid-client",
    "token": "",
    "timeout": 15
}
```

**Файл**: `Repository.php:21-36`

***

### Производительность

#### Таймауты

| Операция                       | Таймаут           | Конфигурация              |
| ------------------------------ | ----------------- | ------------------------- |
| Процесс обновления             | 1800 сек (30 мин) | `PROCESS_EXECUTE_TIMEOUT` |
| Загрузка ZIP с GitHub          | 2100 сек (35 мин) | `CURLOPT_TIMEOUT`         |
| GitHub API запрос              | 15 сек            | `Repository->timeout`     |
| Пауза между запросами коммитов | 250 мс            | `usleep(250000)`          |

***

#### Оптимизация

**1. Прогресс-репортинг с дебаунсом**

Отправка прогресса в Global API происходит не чаще 1 раза в 3 секунды:

```php
if ($sendedProgressTime === 0 || (time() - $sendedProgressTime) >= 3) {
    $this->globalApi->sendUpdaterProcessProgress($this->processKey, $progress);
    $sendedProgressTime = time();
}
```

**Файл**: `UpdateService.php:536-539`

***

**2. Потоковая обработка файлов**

Использование `stream_copy_to_stream()` вместо загрузки в память:

```php
$stream = $zip->getStream($archivePath);
stream_copy_to_stream($stream, $out);
```

**Файл**: `UpdateService.php:607-617`

***

### Мониторинг

#### Проверка статуса обновления

```php
// Проверить активность процесса
$status = Cache::get('update');
if ($status['status'] === 'IN_PROGRESS') {
    $processKey = $status['process_key'];
    $progress = Cache::get('update_progress_' . $processKey);
    echo "Прогресс: {$progress}%";
}
```

***

#### Проверка логов

```bash
# Найти последние логи обновлений
ls -lt Files/logs/update_* | head -n 5

# Просмотр активного процесса
tail -f Files/logs/update_2026-02-14_15-30_115abb9f.log

# Поиск ошибок
grep -i "error\|exception\|fatal" Files/logs/update_*.log
```

***

### Конфигурационные файлы

#### version.json

```json
{
    "tag": "v1.2.3",
    "timestamp": "2026-01-15T12:34:56Z",
    "release_id": 123456
}
```

**Расположение**: `Library/configs/version.json`

***

#### github.json

```json
{
    "api_base_uri": "https://api.github.com",
    "repository_path": "PlaygridDev/playgrid-client",
    "token": "ghp_xxxxxxxxxxxxxx",
    "timeout": 15
}
```

**Расположение**: `Library/configs/github.json`

***

### Troubleshooting

#### Проблема: Обновление зависло

**Диагностика**:

1. Проверить статус процесса:

   ```bash
   php -r "var_dump(Cache::get('update'));"
   ```
2. Проверить PHP процессы:

   ```bash
   ps aux | grep php
   ```
3. Проверить последний лог:

   ```bash
   tail -50 Files/logs/update_*.log | tail -n 50
   ```

**Решение**:

* Если процесс завис > 30 минут - очистить кеш вручную
* Проверить доступность GitHub API
* Повторить обновление

***

#### Проблема: Недостаточно прав доступа

**Симптомы**:

```
Failed to create update process directory
Failed to add file to backup
Failed to replace file
```

**Решение**:

```bash
# Установить правильного владельца
chown -R www-data:www-data /path/to/project

# Установить права
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
chmod 775 Files/
chmod 775 Files/update/
chmod 775 Debug/
chmod 775 cache/
```

***

#### Проблема: GitHub API rate limit

**Симптомы**:

```
GitHub API returned error code 403: API rate limit exceeded
```

**Решение**:

* Используйте [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)

* Authenticated requests: 5000 req/hour

* Unauthenticated: 60 req/hour

***

### Рекомендации для специалистов

#### Pre-deployment checklist

* [ ] Убедиться в наличии свободного места (минимум 2x размер проекта)
* [ ] Проверить версию PHP = 7.4.33
* [ ] Убедиться, что extension `zip` установлен
* [ ] Проверить права на запись в `Files/`
* [ ] Убедиться, что нет активных процессов обновления
* [ ] Создать ручной бекап критичных данных (БД, конфиги)

***

#### Post-deployment checklist

* [ ] Проверить успешность обновления: `/api/get_version`
* [ ] Проверить логи на наличие ошибок
* [ ] Протестировать основной функционал приложения
* [ ] Убедиться в корректности прав доступа к файлам
* [ ] При необходимости удалить старые бекапы из `Files/update/`


# Плагины


# Покупка

Магазин плагинов в mmoweb

В MMOWEB расширения функционала происходит с помощью плагинов.

Все доступные плагины находятся  Плагины > Магазин плагинов&#x20;

![](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MMHyrtdgWytYark2YPi%2F-MMHz0G6cXCe-aarIl1p%2Fimage.png?alt=media\&token=d774f47d-d50a-4c9a-b61e-199a2290fa24)

Выбрав необходимый плагин, нажмите купить.&#x20;

Вы будете перенаправлены на страницу покупки.

![Форма покупки плагина](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCghraQgS3HaNEZjiLP%2F-MCgjEe9dJTuz4nAU3eh%2Fimage.png?alt=media\&token=ff948403-98f2-425f-8727-0ad482e7acbf)

Выберите период использования плагина и нажмите "Купить".&#x20;

Если у вас недостаточно средств на счету, Вам будет предложено пополнить баланс.&#x20;

После покупки/подключения плагина он появится в меню, в разделе Плагины.

&#x20;


# Продление

Окончание срока действия плагина

Информацию о том когда продлить плагин вы можете увидеть на главной странице персонального кабинета.

![Информация о состоянии плагинов](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCghraQgS3HaNEZjiLP%2F-MCgkQC4Kl0UWgV-oHoG%2Fimage.png?alt=media\&token=a51fd252-31cc-4ba3-97cb-01119b2f1c9d)

Чтобы продлить срок действия плагина, нажмите "продлить" и Вы будете перенаправлены на форму выбора периода продления.&#x20;

![Форма продления плагина](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCghraQgS3HaNEZjiLP%2F-MCgkkGaGzk4OcrejK0j%2Fimage.png?alt=media\&token=48c69da8-ed54-4f10-8b90-6399895c52d8)

После выбора срока действия нажмите,`Продлить` и вы увидите сообщение об успешном продлении и следующем сроке окончания.


# Доступные плагины

Список доступных плагинов


# Бонус код

Система бонус кодов

Плагин "бонус-код" позволит вам **создавать коды, при активации которых игрок получит деньги на счет или предмет в игру** (зависит от типа кода).

&#x20;**Цена плагина:** 15$ в месяц.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FZEQkvxRwlT7KNzwYZEbp%2Fimage.png?alt=media&amp;token=58654060-a6c2-4dab-9f8f-67a2b8a13a10" alt=""><figcaption></figcaption></figure>

&#x20;**Описание полей формы:**

&#x20;**Тип активации кода:**

* **Одноразовый** (активация только один раз). После первой активации, этот код больше нельзя будет активировать ни на Мастер Аккаунте, который первый раз его активировал, ни на любом другом.
* **Множественный** (невозможно активировать повторно на одном Мастер Аккаунте) Данный код можно активировать на конкретный МА всего 1 раз, повторно активация на этот же МА не будет работать НО можно активировать на любой другой МА единажды.

**Выберите вариант кода:**\
Тут вам на выбор представлены варианты случайного кода, или вы можете выбрать опцию "указать свой" и ввести желаемый код произвольно.

&#x20;**Тип бонуса:**

* Выдать деньги (игровую валюту) на счет Мастер Аккаунта;
* Выдать предметы в игру.

**Кол-во кодов:**\
Вы можете указать количество сгенерированных кодов с этими параметрами, но **не можете указывать количество, когда код генерируется не случайно, а написан вами в ручную.**

![Рис. 1.2. Поле ввода количества кодов и переключатель объединения кодов в группу​](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCglRiX_60QphfKHlU5%2F-MCgmluId-BiXvtDgt8M%2Fimage.png?alt=media\&token=e968b5ad-b66c-4d92-9d1b-48ded89bc3ee)

Если кодов будет более 2х, система предложит объединить их в группу. Эта **опция группирует коды** так, что **если пользователь уже использовал хоть 1 код** из данной группы на своем МА, то **он больше не сможет активировать другие коды из этой группы**.\
Допустим, есть группа из 10 кодов, если пользователь активировал хотя бы 1, то он уже не сможет активировать остальные 9 на этом МА.<br>

Тем самым можно контролировать активацию кодов и не дать Мастер Аккаунту активировать их все.

### &#x20;**Описание других форм и окон:**

&#x20;**Форма добавления предметов в Бонус-Код:**

![Рис. 2.1. Форма добавления предметов в Бонус-Код​](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCglRiX_60QphfKHlU5%2F-MCgmxmTghBjoo75UnBt%2Fimage.png?alt=media\&token=5bf188ce-bcdd-4ecb-a479-ae9bf3bf2f55)

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

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FCzOFortYIx6NPL2HAUID%2Fimage.png?alt=media&amp;token=efea935b-efe2-48d5-a04f-72947aad2427" alt=""><figcaption></figcaption></figure>

В детальном просмотре можно получить всю необходимую информацию об активации:

Удобно работать с группами кодов, которые сразу отображаются, а также с множественными активациями, которые отображают сколько раз был активирован конкретный код и на каких аккаунтах.\
\
Бонус-Код **невозможно изменять** доступно только удаление и копирование!

**Копирование Кода**

Перейдите в режим просмотра Бонус-Кода и нажмите на спец. символ копирования

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FS5FeBeEUZcSDqfrcUTbZ%2Fimage.png?alt=media&amp;token=3c25315d-c738-4b34-a25e-8851ed8f2813" alt=""><figcaption></figcaption></figure>

Создайте новый код и вставьте содержимое в поле под предметами. Кликните на пустое место для применения изменений.


# Магазин

Магазин игровых ценностей

Плагин позволит вам **продавать игровые ценности, как авторизированному пользователю, так и не авторизированному** перенаправляя его сразу на оплату.

**Цена плагина:** 25$ в месяц

## **Описание возможностей магазина**

**Скидки**\
Есть возможность создавать скидки на продаваемые товары.

![Рис. 1.1. Окно настройки/создания скидки​](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCgnKFzmPWeA9_IAa9m%2F-MCgnhx7iyp4MLkdd0NI%2Fimage.png?alt=media\&token=931db586-e29a-4989-96f9-98a81ce1cf5e)

&#x20;**Описание полей:**

* **Название** – будет отображаться в магазине для пользователя;
* **% скидки** – указывается как целое число и не может превышать 100%;
* **Начало / конец** – дата начал и окончания скидки;
* \[Опционально] **Таймер на скидку** – отображается таймер на товаре с обратным отсчетом до конца скидки;
* **Шаг отображения** – если дата окончания скидки указана на длительный период, вы можете указать максимальный часовой диапазон для таймера, который каждый раз будет обновляться по истечению времени. Допустим скидка закончится через 30 дней, но вы можете указать, чтобы на товаре отображалось, допустим, 6 часов, и каждый раз по истечению 6 часов, таймер будет обновляться.

**Разделы:**\
Можно создавать разделы с различными именами и указывать, на каком языке они будут отображаться пользователю.&#x20;

Если у раздела не выбран ни один из языков, раздел будет скрыт.

![Рис. 1.2. Окно создания/редактирования разделов магазина​](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCgnKFzmPWeA9_IAa9m%2F-MCgoP2D6JTBwaL836jA%2Fimage.png?alt=media\&token=bc28ee9c-be7e-4e69-be57-4cb197731e6d)

**Управление магазином:**\
\
В окне создания и редактирования товара, вы можете добавлять и удалять товары, перемещать их между разделами и добавлять скидку.

![Рис. 1.3. Главное окно редактирования списка товаров магазина​](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCgnKFzmPWeA9_IAa9m%2F-MCgoU1B6Wr6I6U1fB6N%2Fimage.png?alt=media\&token=ce0bacef-0939-4e49-a628-e26fa324bcc3)

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

&#x20;**Список доступных настроек:**

* **Название** – название товара;
* **Обложка** – изображение товара, отображаемое на странице магазина;
* **Описание** – описание товара, на странице товара в магазине (с поддержкой HTML);
* **Раздел** – выбор раздела, в котором будет отображаться товар;
* **Статус** – выключен или отключен данный товар;
* **Варианты продажи:**
  * **Продажа в розницу** – продажа товаров с возможностью выбрать предмет из списка предметов;
  * **Продажа оптом** – продажа оптовых наборов товара, без возможности покупать выборочно предмет из списка, только целый пакет предметов.
* **Цена \[Продажа оптом]** – цена в этом поле указывается только если стоит "Продажа оптом", это цена за весь пакет предметов;
* **Ассортимент товара** – перечень предметов, которые продаются в товаре оптом или в розницу. Доступно указать ID предмета, количество, заточку (для затачиваемых предметов), цену (если продажа в розницу) и поставить галочку "продажа поштучно" для того, чтобы игрок мог сам выбирать количество для покупки.

![Рис. 1.4. Окно создания/редактирования товара](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCgnKFzmPWeA9_IAa9m%2F-MCgodT1xHPtUcya-kYy%2Fimage.png?alt=media\&token=eda58cda-d447-41fd-97b1-14425739ce61)

&#x20;**В окне дополнительных настроек, можно:**

* ограничить возможность покупки товара только на МА или на МА и персонажа;​
* добавить или изменить скидку на товар;​
* обозначить дату начала продаж текущего товара;​
* обозначить дату окончания продаж.​
* ограничить продажи по игровому или мастер аккаунтам
* установить максимальное количество предметов для покупки
* запретить покупку товара при необходимости

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FVdmk2VB5uPHTVd1C8vPz%2Fimage.png?alt=media&amp;token=f60d31df-b188-452c-a4a8-51376ff3648e" alt=""><figcaption></figcaption></figure>


# Служба поддержки

Плагин тех. поддержки для игроков

ех.Поддержка

&#x20;**Цена плагина:** 15$ в месяц.

Плагин `тех.поддержки` для игроков позволяет принимать от игроков обращения  по следующим категориям&#x20;

1. Общие вопросы
2. Сайт, Форум, ЛК
3. Ошибки клиента
4. Ошибки игры
5. Блокировка аккаунта/персонажа
6. Пропажа предметов
7. Жалоба на бота
8. Проблемы с пополнением баланса
9. Прочее

Интерфейс для игрока максимально упрощен&#x20;

![Интерфейс для пользователя](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYeW2wPQqlM_0vYtzui%2F-MYe_nyFEErHzaMWMM19%2Fimage.png?alt=media\&token=bd964f33-9260-43bb-891a-1c4b6c781641)

Представлены 3 раздела:&#x20;

1. Ожидает ответа - `список тикетов на который должен ответить пользователь`
2. Обрабатываются - `список тикетов которые ожидают ответа администрации`
3. Закрытые

Кнопки для быстрого создания тикета `Проблемы с донатом` и `Пропали предметы`

`Создать тикет` открывает форму ввода обращения `(см. скриншот ниже)`

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

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FjAhsR4RuMOa5K9786Yz2%2Fimage.png?alt=media&amp;token=24de8d45-2568-4801-b8aa-23c6f0f8c8fb" alt=""><figcaption></figcaption></figure>

> допустимые форматы и размер прикрепляемых файлов находится в Config.php

После создания обращения тикет появится в суппорт центре mmoweb.biz

![Центр обращений ](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYeW2wPQqlM_0vYtzui%2F-MYebgWjHoY0ffLlFrnn%2Fimage.png?alt=media\&token=35d6da2d-480e-4acf-aac7-8daafa1d1699)

Открыв обращения мы увидим&#x20;

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FSdMRq4jpIWqBLJZ7xxaB%2Fimage.png?alt=media&amp;token=0200a32a-4c2f-4b29-9804-0fd626b64c21" alt=""><figcaption></figcaption></figure>

1. Информация по обращению
2. В состоянии обращения и возможность его изменять без ответа на него
3. Заметка видна только администратору
4. Ответ пользователя с прикрепленным изображением `Attachments`

Во вкладке `Ответить`&#x20;

![Ответ на тикет](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYeW2wPQqlM_0vYtzui%2F-MYeg9LZK7VGvtf-OY5Z%2Fimage.png?alt=media\&token=c2f010a3-154c-480f-9944-a6e66adf5db8)

1. Быстрый ответ на тикет из-за ранее подготовленных шаблонов (Макросы)
2. Содержимое ответа
3. Состояния тикета и кнопка `ответить`

### Макросы

В плагине предусмотрена возможно заготовить ответы для быстрой вставки их в обращения находится данная функция в разделе макросы&#x20;

![Вид интерфейса управление макросами](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYeW2wPQqlM_0vYtzui%2F-MYegxft2XtLyOqbbqfE%2Fimage.png?alt=media\&token=1a0c1f6e-9993-4e16-9e7c-f7268fab7e2b)

Вы можете создавать разделы для быстрого поиска макроса.

Также если принять тикет и подключить телеграм - бота Вы будете получать уведомления об ответе в телеграм - боте моментально.


# Мульти аккаунт

Переключения между мастер аккаунтами

&#x20;**Цена плагина:** 8$ в месяц.

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

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FgCi35uenohugYXixpk4t%2Fimage.png?alt=media&amp;token=875f96b3-86e2-4990-befb-d6b10929ffb7" alt=""><figcaption></figcaption></figure>

Нажав `Добавить учетную запись` откроется окно с вводом информации

![Настройка мульти аккаунта](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYehvY7XnungAU7k6_b%2F-MYej-y_XgxBgQO5sAu7%2Fimage.png?alt=media\&token=9b95a12a-0a37-4e31-b32e-fbfe9d45b5af)

**Управление мастер аккаунтами** - тут отображаются ранее подключённые мастер аккаунты с возможностью удалить их из списка

**Подключить учетную запись мастер аккаунта** - для подключения мастер аккаунта необходимо заполнить данные и указать пин-код мастер аккаунта, после чего ожидать подтверждения по почте или смс кодом.

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

{% hint style="info" %}
обратите внимание, что эту процедуру нужно делать на каждом мастер аккаунте отдельно!
{% endhint %}


# Внутриигровой рынок

Игровая биржа (RMT)

Плагин позволяет организовать продажу игровых вещей и персонажей в интерфейсе MMOWeb.

&#x20;**Цена плагина:** 30$ в месяц.

Работает не со всеми сборками. Просьба проверять перед покупкой

Первичные настройки сервиса находятся в разделе Настройки -> Рынок: Главные настройки

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

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FTvVlHs1cevsAU9lyVJDX%2Fimage.png?alt=media&amp;token=6d484f59-9570-4781-aefc-24ab99beefdc" alt=""><figcaption></figcaption></figure>

Обязательно установите доступные для продажи типы предметов в строке Разделы. Функция BL Статуса позволяет регулировать комиссии и развивать систему лояльности.

**Раздел Фильтра**

Данный раздел позволяет установить запрет на продажу предметов. Назначить премодерацию и настроить необходимую конфигурацию маркета по опциям предметов.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fk3eGPBXjX1YKrDKsLCsC%2Fimage.png?alt=media&amp;token=8f51a71e-53d1-4221-980f-7003180af001" alt=""><figcaption></figcaption></figure>

**Раздел Ценовая политика для предметов**

Данный раздел позволяет оградить ваш маркет от демпинга или завышения цен.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F7gTyd6ONQfcNihIb5fxs%2Fimage.png?alt=media&amp;token=e985cd92-731f-445d-950f-711154e1be9f" alt=""><figcaption></figcaption></figure>

## Рынок: настройки пополнений баланса

Настройки пополнения баланса вынесены во вторую вкладку общих настроек плагина. Содержит настройку типа пополнения баланса и список Агрегаторов для пополнения при использовании отдельного баланса маркета.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FZsZuZCLayocXz3saO1Mv%2Fimage.png?alt=media&amp;token=b94f52fc-80fa-4a3b-862c-2c349fd9b378" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fl74ujuaTwmbDh1CBDfwS%2Fimage.png?alt=media&amp;token=4e431fef-a429-4cf7-89c6-7d1582059fb3" alt=""><figcaption></figcaption></figure>


# Игра Lucky Wheel

Колесо фортуны

&#x20;**Цена плагина:** 10$ в месяц.

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

![Интерфейс игры](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYenkIySv3VUU1EFHBx%2F-MYepP59u1_R1Vatg221%2Fimage.png?alt=media\&token=5fd5f63c-b49a-4a6c-8979-bdc82395b66f)

1. История выигрышей
2. Баланс и информация цены за прокрутку
3. Список призов
4. Запуск рулетки
5. Информация - меняется в языковых файлах&#x20;

После запуска рулетки появляется окно с информацией о предмете

![Приз рулетки](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYenkIySv3VUU1EFHBx%2F-MYepqWvWnKIPiI4GtZu%2Fimage.png?alt=media\&token=0ff3181a-f48e-4ae3-b435-d8c608de13ba)

Колесо фортуны настраивается в админ панели mmoweb.biz`раздел колесо фортуны`

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FC2QLBLRASxH1Gr3pp4Tm%2Fimage.png?alt=media&amp;token=3164ad26-85c1-448f-8ef5-d734a1c552ff" alt=""><figcaption></figcaption></figure>

1. Имя проекта
2. Загрузка `настроек колеса` фортуны на проект
3. Сервера подключенные к этому проекту
4. Настройка `колеса фортуны`
5. Тестирования игры с 1000 прокруткой

Преходим к настройке колеса фортуны `(см. кнопка 4 выше)`

![Интерфейс настройки](https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MYertn_tAB7rN33WPZW%2F-MYesyX9M_qRZsURfj_j%2Fimage.png?alt=media\&token=20c1384c-c03d-4b49-aace-c80acb0af114)

1. Настройки состояния и цены и возможности передачи предмета
2. Шанс группы предметов он не должен превышать или быть меньше 100%
3. Список предметов которые участвуют в розыгрыше


# Игра Кейсы

Игра кейсы по аналогии CSS

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

&#x20;**Цена плагина:** 20$ в месяц.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FfSZSEfSuURT72stApSV1%2Fimage.png?alt=media&amp;token=4eed7aa9-7029-46df-be1c-cbacbe1a30a2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fg3MPgYbPCbWyBd9u3zyP%2Fimage.png?alt=media&amp;token=a79d60af-a7f9-4fc6-96f7-84271e940235" alt=""><figcaption></figcaption></figure>

Интерфейс настроек прост. Если вы уже работали с плагином Магазин, то настройка не вызовет проблем.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F4pkNwqm1QiaLEbaKVK07%2Fimage.png?alt=media&amp;token=3f6d2584-9147-4f36-8794-00b1520679c7" alt=""><figcaption></figcaption></figure>

Каждый кейс имеет обложку и строки для установки ваших изображений.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FQGbRDv3EYGOi2esbvysp%2Fimage.png?alt=media&amp;token=2463fc51-ba16-44ce-acc5-6be6283039d2" alt=""><figcaption></figcaption></figure>

В разделе дополнительных настроек можно задать скидки и даты доступности кейса.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F5f1fV5ChmYQlo0n6iBj4%2Fimage.png?alt=media&amp;token=c93927cb-f3cd-4027-8bcd-f5ffb6405f83" alt=""><figcaption></figcaption></figure>

Не забудьте загрузить настройки на сайт!

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FfeybN72ZlpEAnAKWeYPS%2Fimage.png?alt=media&amp;token=008a867b-722e-42c7-93d8-f388080b57e9" alt=""><figcaption></figcaption></figure>


# Подарочные коды

Позволяет вашим пользователям дарить баланс в виде Бонус Кода. Работает только в связке с плагином Бонус Код.

{% content-ref url="/spaces/-MBKZbS5Cb7cxz5sHYKf-1508421016/pages/-MBKiIsEJAnCEukl4bVi" %}
[Бонус код](/plaginy/dostupnye-plaginy/bonus-kod)
{% endcontent-ref %}

&#x20;**Цена плагина:** 10$ в месяц.

Интерфейс Игрока содержит информацию о всех приобретенных кодах

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fjc0Uug0eBdljCDkW8sYG%2Fimage.png?alt=media&amp;token=0ab50629-01c8-417e-b2a9-bf3ef4d72734" alt=""><figcaption></figcaption></figure>

Плагин имеет стандартный интерфейс настройки

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FP9Ut8IQdSSXgnkFbSzue%2Fimage.png?alt=media&amp;token=c6dafee9-89cb-4af1-b22c-2ff85b8ca45d" alt=""><figcaption></figcaption></figure>

Не забывайте загружать настройки после своих изменений.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FtqEv9LSvwxj6Z72FfCaM%2Fimage.png?alt=media&amp;token=aa98537f-3709-4f6b-ab28-b46ec387d9ef" alt=""><figcaption></figcaption></figure>

Настройка Свободной покупки позволяет пользователям самостоятельно обозначить сумму подарочного кода. Имеется настройка процента комиссии при включенной опции Свободной Покупки.


# Массовая выдача на склад

Плагин массовой выдачи предметов на склад

Можно как выдавать, так и удалять предметы группой. Список выданных предметов можно увидеть в разделе Склада Личного Кабинета Пользователя.

&#x20;**Цена плагина:** 10$ в месяц

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FCguXGCgslGwZ6z8PN79N%2Fimage.png?alt=media&amp;token=dfd57e40-96b5-47b5-b6a8-78a162998172" alt=""><figcaption></figcaption></figure>

Плагин имеет настройку возможности передачи предмета

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FhULLOVpgSb2QHYNBPVHF%2Fimage.png?alt=media&amp;token=50341d47-a0e1-44f1-8446-220f34e38e90" alt=""><figcaption></figcaption></figure>


# Промо игры

Плагин позволяет настраивать конфигурации для ваших промо страниц

**Цена плагина:** 5$ в месяц

Плагин позволяет настраивать конфигурации для ваших промо страниц и интегрировать в них логику игры с призами.

**Плагин сделан в виде API. Требует работы и интеграции на уровне fron-end. Перед покупкой проконсультируйтесь со своим разработчиком.**

Функции интеграции находятся в файле In.php, папка Controllers

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FmArirIkOGEaEUUOesFxM%2Fimage.png?alt=media&amp;token=308283b7-34ea-46a5-813a-e9750d755060" alt=""><figcaption></figcaption></figure>


# Реферальная система

Реферальная система приглашения для игроков

**Цена плагина:** 10$ в месяц

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

Имеет встроенную систему защиты от накрутки и недобросовестных игроков.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F9V9FTyy72dYLJ7mltzaq%2Fimage.png?alt=media&amp;token=3112df31-3536-48fc-ae45-ad9d98f98d24" alt=""><figcaption></figcaption></figure>

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

## Глобальные настройки на проект

Содержит настройки для приглашающей стороны. Имеет настройку для ограничения доступности для определённого списка МА. Скидки и бонусы можно настроить от количества приглашенных или от суммы доната приглашенных. Глобальные настройки находятся возле названия проекта.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FLj7TOFbFSwi3McePTg9B%2Fimage.png?alt=media&amp;token=567f85bd-9099-4b1c-8367-e7e0de3a93a1" alt=""><figcaption></figcaption></figure>

## Настройка на сервер

Содержит настройку бонусов для приглашенной стороны. Кнопка настройки находится возле название сервера. Можно настроить индивидуальные бонусы под определенного приглашающего игрока с повышенным приоритетом получения.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F0838JiUcQohXahWeEbNb%2Fimage.png?alt=media&amp;token=630020d0-227e-41ef-82a7-de8e95670bf1" alt=""><figcaption></figcaption></figure>


# FAQ

Часто задаваемые вопросы

## Сколько стоит ваш продукт?

25$ ежемесячно.

## Что в него входит?

Это полноценная вэб обвязка сайта, кабинет и админ панель по управлению проектом и его мониторингу.​

## На каких условиях происходит продажа?

Перманентной продажи нет, вэб сдается в аренду на ежемесячной основе.​

## Получу ли я файлы на руки?

&#x20;Да, мы выдаем клиентскую веб часть и вы устанавливаете ее у себя на хостинге. Она взаимодействует с нашим **REST API**, который обрабатывает всю логику.​

## &#x20;Получается, что ваш **REST API** подключается к игровым серверам напрямую?

Да, наш **REST API** подключается напрямую к вашим игровым серверам. Ему необходим доступ к базам данных.

## Вы адаптируете наш дизайн под вашу обвязку?

&#x20;Да, мы занимались адаптацией графики. Цена - от 2000р (в зависимости от сложности)​​

## Какой хостинг посоветуете?

У нас есть партнер который ни разу нас не подвел, умеет делать все от настройки SMTP до защиты вашего гейм сервера, его телеграм [Route179](https://t.me/Route179)

## Какие требования у обвязки?

* &#x20;**Apache 2.4**
* **PHP 7.4.33**
* **MySQL 8**

## Вы помогаете установить обвязку на хостинг?

Для этого существует пошаговая документация, которая описывает подробно каждый шаг установки.

В случае технических проблем я всегда отвечу на вопросы по контактам.

## Если я хочу, чтобы мне разработали необходимый функционал, - это возможно?

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

&#x20;Если у Вас остались вопросы - вы можете задать их на форуме или по контактам.


# Добавление способов оплаты

### Введение

Этот гайд описывает как интегрировать новый способ оплаты в личный кабинет. Процесс включает настройку [Application Token](/rest-api/autentifikaciya), создание обработчика вебхуков, регистрацию в конфигурации и настройку платежной системы.

### Архитектура платежей

```
Платежная система (вебхук)
    ↓
PaymentController::webhook($paymentSystem)
    ↓
PaymentHandler (ваш класс обработчика)
    ├─ Проверка IP адреса
    ├─ Проверка статуса платежной системы
    └─ Обработка вебхука (webhook())
    ↓
API: POST /v2/payment/order/complete
    ├─ payment_system: "cstm:your_system"
    ├─ order_id: "Order:XXXXXXXX"
    └─ payment_id: "внешний_id"
    ↓
Пополнение баланса пользователя
```

***

### Требования

**Обязательно:**

* Понимание REST API и PHP (версия 7.4+)
* Учетные данные платежной системы (merchant ID, API ключи и т.д.)
* Документация платежной системы (формат вебхуков, способ подписи)

**Рекомендуется:**

* Знакомство с примером FreeKassa в `Modules/Globals/Donations/Integrations/Handlers/FreeKassa.php`

***

### Шаг 1: Выпуск Application Token

**Это критичный шаг — без токена платежи не будут обрабатываться!**

Application Token требуется для аутентификации при вызове API endpoint'а `/v2/payment/order/complete`.

#### Создание токена

1. Перейдите в панель администратора: `https://mmoweb.biz/panel/settings/Globals.ApiKeyApp/add`
2. Укажите название
3. В разделе **"Доступы ключа"** включите разрешение: **Финализация платежного ордера**
4. **Скопируйте токен** — он больше не будет отображён
5. Нажмите "Создать"

#### Установка токена

Откройте файл `Modules/Globals/Donations/Integrations/PaymentHandler.php` и найдите строку:

```php
const APPLICATION_TOKEN = '';
```

Вставьте ваш токен:

```php
const APPLICATION_TOKEN = 'ваш_64_символьный_токен';
```

> **ВАЖНО:** Храните токен в безопасности. Не коммитьте в публичные репозитории. Если токен скомпрометирован — создайте новый и отключите старый.

***

### Шаг 2: Создание класса обработчика

Создайте файл

&#x20;`Modules/Globals/Donations/Integrations/Handlers/YourPaymentSystem.php`:

```php
<?php

namespace Modules\Globals\Donations\Integrations\Handlers;

use Modules\Globals\Donations\Integrations\PaymentHandler;
use Modules\Globals\Donations\Integrations\HandlerInterface;
use Modules\Globals\Donations\Integrations\DTO\CheckoutResponse;
use Modules\Globals\Donations\Integrations\Exceptions\PaymentWebhookException;

class YourPaymentSystem extends PaymentHandler implements HandlerInterface
{
    // Содержимое класса (см. ниже)
}
```

**Требования:**

* Класс должен наследоваться от `PaymentHandler`
* Класс должен реализовывать `HandlerInterface`
* Имя класса должно совпадать с именем файла

***

### Шаг 3: Определение конфигурации

Внутри класса определите статические свойства:

```php
private static bool $status = false;  // Включить после настройки
private static string $identifier = 'your_payment_system';  // идентификатор платежной системы
private static array $orderDescription = [
    'ru' => 'Пополнение баланса',
    'en' => 'Balance topup',
];
private static string $currency = 'RUB';  // RUB, USD, EUR и т.д.
private static int $sortOrder = 1;

private static array $config = [
    'merchant_id'   => '',  // ID магазина
    'api_key'       => '',  // API ключ
    'secret_key'    => '',  // Секретный ключ для подписи
];

private static array $allowedIps = [
    // '1.2.3.4',  // разрешенные IP адреса для обработки вебхука (опционально)
];
```

#### Конструктор

```php
public function __construct()
{
    $this->setStatus(self::$status);
    $this->setIdentifier(self::$identifier);
    $this->setSortOrder(self::$sortOrder);
    $this->setDescription(self::$orderDescription);
    $this->setCurrency(self::$currency);
    $this->setConfig(self::$config);
    $this->setAllowedIps(self::$allowedIps);
}
```

***

### Шаг 4: Реализация метода checkout()

Этот метод подготавливает платеж и возвращает URL для перенаправления пользователя.

{% hint style="info" %}
Реализуйте метод checkout() для получения URL перенаправления пользователя, в соответствии с документацией платежной системы.
{% endhint %}

```php
public function checkout(array $orderData): CheckoutResponse
{
    // 1. Проверяем статус
    if (!$this->getStatus()) {
        throw new \Exception('Payment method is unavailable');
    }

    // 2. Валидируем параметры
    if (empty($orderData['order_id']) || empty($orderData['sum']) || $orderData['sum'] <= 0) {
        throw new \Exception('Invalid order data');
    }

    // 3. Формируем параметры для платежной системы
    $params = [
        'merchant_id'  => $this->getConfig('merchant_id'),
        'amount'       => $orderData['sum'],
        'order_id'     => $orderData['order_id'],
        'currency'     => $this->getCurrency(),
        'description'  => $this->getDescription()['ru'] ?? 'Payment',
    ];

    // 4. Вычисляем подпись (если требуется)
    $signature = md5(
        $this->getConfig('merchant_id') . ':' .
        $orderData['sum'] . ':' .
        $this->getConfig('secret_key') . ':' .
        $orderData['order_id']
    );
    $params['signature'] = $signature;

    // 5. Формируем URL
    $redirectUrl = 'https://payment-system.example.com/pay?' . http_build_query($params);

    // 6. Возвращаем ответ
    return new CheckoutResponse($redirectUrl);
}
```

***

### Шаг 5: Реализация метода webhook()

Этот метод обрабатывает входящий вебхук от платежной системы.

{% hint style="info" %}
Реализуйте метод webhook() в соответствии с документацией обработки успешных платежей вашей платежной системы.
{% endhint %}

```php
public function webhook(): bool
{
    try {
        // 1. Получаем данные вебхука
        // Формат зависит от системы: $_POST, $_GET или JSON
        $payload = $_POST;  // или json_decode(file_get_contents('php://input'), true)

        if (empty($payload)) {
            throw new PaymentWebhookException('No data in webhook');
        }

        // 2. Проверяем обязательные поля
        if (empty($payload['order_id']) || empty($payload['signature'])) {
            throw new PaymentWebhookException('Missing required fields');
        }

        // 3. Валидируем подпись (КРИТИЧНО!)
        $expectedSignature = $this->getWebhookSignature($payload);
        if (!hash_equals($expectedSignature, $payload['signature'])) {
            throw new PaymentWebhookException('Invalid signature');
        }

        // 4. Проверяем статус платежа
        if ($payload['status'] !== 'completed' && $payload['status'] !== 'success') {
            throw new PaymentWebhookException('Payment not completed');
        }

        // 5. Извлекаем данные
        // order_id должен быть в формате "Order:XXXXXXXX"
        $this->setOrderId($payload['order_id']);
        $this->setPaymentId($payload['payment_id'] ?? '');

        return true;

    } catch (PaymentWebhookException $e) {
        error_log("Webhook error: " . $e->getMessage());
        log_write('payment_errors', $e->getMessage());
        return false;
    }
}
```

***

### Шаг 6: Реализация метода getWebhookSignature()

Вычисляет ожидаемую подпись вебхука для верификации.

```php
public function getWebhookSignature(array $data): string
{
    // Формула зависит от платежной системы!
    // Пример для MD5:
    return md5(
        $this->getConfig('merchant_id') . ':' .
        $data['order_id'] . ':' .
        $data['amount'] . ':' .
        $this->getConfig('secret_key')
    );
    
}
```

> **ВАЖНО:** Формула подписи должна **точно совпадать** с документацией платежной системы!

***

### Шаг 7: Регистрация в Config.php

Откройте файл `Config.php` и добавьте вашу систему:

```php
define('PAYMENT_INTEGRATIONS', [
    'freekassa'      => \Modules\Globals\Donations\Integrations\Handlers\FreeKassa::class,
    'your_payment_system' => \Modules\Globals\Donations\Integrations\Handlers\YourPaymentSystem::class,
]);
```

**Важно:** Ключ в массиве должен совпадать с `$identifier` в созданном ранее классе.

***

### Шаг 8: Добавление изображения платежной системы

Добавьте логотип платежной системы:

**Путь:**

```
template/panel/assets/media/payment/your_identifier.png
```

**Требования:**

* **Формат:** PNG или SVG
* **Фон:** прозрачный или белый
* **Имя файла:** должно совпадать с `$identifier`

***

### Шаг 9: Настройка URL вебхука в платежной системе

URL вебхука формируется автоматически:

```
https://ваш-сайт.ru/payment/webhook/{identifier}
```

**Примеры:**

* `$identifier = 'stripe'` → `https://ваш-сайт.ru/payment/webhook/stripe`
* `$identifier = 'paypal'` → `https://ваш-сайт.ru/payment/webhook/paypal`

#### Что делать:

1. Войдите в панель управления платежной системой
2. Найдите раздел "Webhooks" / "Notifications" / "Integration"
3. Добавьте новый вебхук
4. Вставьте URL: `https://ваш-сайт.ru/payment/webhook/your_identifier`
5. Выберите события: обычно "Payment completed" или "Payment success"
6. Сохраните

***

### Шаг 10: Включение платежной системы

Откройте ваш класс обработчика и измените:

```php
private static bool $status = true;  // Включаем платежную систему
```

После этого способ оплаты **автоматически появится** на странице:

```
https://ваш-сайт.ru/panel/donations
```

***

### Чек-лист перед тестированием

Проверьте что выполнены все шаги:

* Application Token выпущен и установлен в `PaymentHandler::APPLICATION_TOKEN`
* Класс обработчика создан в `Modules/Globals/Donations/Integrations/Handlers/`
* Класс зарегистрирован в `PAYMENT_INTEGRATIONS` в `Config.php`
* Изображение добавлено в `template/panel/assets/media/payment/your_identifier.png`
* URL вебхука настроен в платежной системе
* `$status = true` установлен в классе
* `checkout()` возвращает объект `checkoutResponse($redirectUrl)`
* `webhook()` возвращает `boolean`

***

### Тестирование

#### Проверка отображения

1. Перейдите на `https://ваш-сайт.ru/panel/donations`
2. Убедитесь что ваша платежная система отображается в списке

#### Тестовый платеж

1. Выберите вашу платежную систему
2. Укажите сумму пополнения
3. Нажмите "Пополнить"
4. Убедитесь что произошел редирект на платежный шлюз
5. Выполните тестовый платеж
6. Проверьте что баланс пополнился

***

### Частые ошибки

| Ошибка                              | Причина              | Решение                                           |
| ----------------------------------- | -------------------- | ------------------------------------------------- |
| `ORDER_NOT_FOUND`                   | Ордер не найден      | Проверьте формат order\_id: `Order:XXXXXXXX`      |
| `Invalid webhook signature`         | Подпись не совпадает | Проверьте формулу подписи в документации          |
| `Payment system not supported`      | Не зарегистрирована  | Проверьте PAYMENT\_INTEGRATIONS в Config.php      |
| `Forbidden: IP address not allowed` | IP не разрешен       | Добавьте IP в $allowedIps или используйте подпись |
| `ORDER_ALREADY_COMPLETED`           | Ордер уже обработан  | Нормально при повторной отправке вебхука          |

***

### Рекомендации по безопасности

1. **Всегда проверяйте статус платежа** в методе `webhook()`

   ```php
   if ($payload['status'] !== 'completed') {
       throw new PaymentWebhookException('Payment not completed');
   }
   ```
2. **Всегда проверяйте подпись вебхука** используя `hash_equals()`

   ```php
   if (!hash_equals($expectedSignature, $payload['signature'])) {
       throw new PaymentWebhookException('Invalid signature');
   }
   ```
3. **Альтернативно: проверяйте IP адрес** если платежная система не использует подписи

   ```php
   private static array $allowedIps = [
       '1.2.3.4',  // IP платежной системы
   ];
   ```

**Дополнительно:**

* Проверяйте сумму платежа если она приходит в вебхуке
* Используйте HTTPS для всех запросов
* Логируйте все платежи для аудита
* Не доверяйте клиентским редиректам — только вебхукам

***

### Полный пример класса

```php
<?php

namespace Modules\Globals\Donations\Integrations\Handlers;

use Modules\Globals\Donations\Integrations\PaymentHandler;
use Modules\Globals\Donations\Integrations\HandlerInterface;
use Modules\Globals\Donations\Integrations\DTO\CheckoutResponse;
use Modules\Globals\Donations\Integrations\Exceptions\PaymentWebhookException;

class MyPaymentSystem extends PaymentHandler implements HandlerInterface
{
    private static bool $status = true;
    private static string $identifier = 'mypayment';
    private static array $orderDescription = [
        'ru' => 'Оплата через MyPayment',
        'en' => 'Payment via MyPayment',
    ];
    private static string $currency = 'USD';
    private static int $sortOrder = 2;
    private static array $config = [
        'merchant_id' => 'your_merchant_id',
        'secret_key'  => 'your_secret_key',
    ];
    private static array $allowedIps = [];

    public function __construct()
    {
        $this->setStatus(self::$status);
        $this->setIdentifier(self::$identifier);
        $this->setSortOrder(self::$sortOrder);
        $this->setDescription(self::$orderDescription);
        $this->setCurrency(self::$currency);
        $this->setConfig(self::$config);
        $this->setAllowedIps(self::$allowedIps);
    }

    public function checkout(array $orderData): CheckoutResponse
    {
        if (!$this->getStatus()) {
            throw new \Exception('Payment unavailable');
        }
        if (empty($orderData['order_id']) || empty($orderData['sum'])) {
            throw new \Exception('Invalid data');
        }

        $params = [
            'merchant' => $this->getConfig('merchant_id'),
            'amount'   => $orderData['sum'],
            'order'    => $orderData['order_id'],
            'sign'     => md5($this->getConfig('merchant_id') . $orderData['sum'] . $this->getConfig('secret_key'))
        ];

        $url = 'https://pay.example.com?' . http_build_query($params);
        return new CheckoutResponse($url);
    }

    public function webhook(): bool
    {
        try {
            $payload = $_POST;

            if (empty($payload['order_id']) || empty($payload['signature'])) {
                throw new PaymentWebhookException('Missing fields');
            }

            if (!hash_equals($this->getWebhookSignature($payload), $payload['signature'])) {
                throw new PaymentWebhookException('Invalid signature');
            }

            if ($payload['status'] !== 'success') {
                throw new PaymentWebhookException('Payment not completed');
            }

            $this->setOrderId($payload['order_id']);
            $this->setPaymentId($payload['payment_id'] ?? '');

            return true;

        } catch (PaymentWebhookException $e) {
            error_log("Webhook error: " . $e->getMessage());
            return false;
        }
    }

    public function getWebhookSignature(array $data): string
    {
        return md5($data['order_id'] . $data['amount'] . $this->getConfig('secret_key'));
    }
}
```


# Адаптация шаблона

Адаптация html-шаблона

## Адаптация html-шаблона

Рассмотрим, как самостоятельно можно внедрить html-вёрстку на сайт под управлением CMS MMOWEB. Вам подойдёт любой чистый html-шаблон, который вы можете найти! (разумеется, в том случае, если вы используете шаблон, уже адаптированный для других CMS, вам придётся сначала очистить его от специальных функций, переменных и т. д.)

Таким образом всё, что вам нужно сделать - заказать у дизайнера макет, у верстальщика - шаблон и далее заняться внедрением шаблона на сайт. Также вы можете воспользоваться уже готовым html-шаблоном. В этом случае, при поиске, именно такой запрос вам нужно писать в поисковой системе ("html-шаблоны", "html-templates" и т.д.).

Данный шаблон легко может быть использован для небольшого проекта.

У нас есть html шаблон теперь нужно создать директорию  для нашего шаблона, заходим на FTP где расположена CMS MMOWEB и переходим в директорию `template/site`

В этой директории создаем папку с названием который хотим пример: `multiworld`

В итоге получаем, `template/site/multiworld`&#x20;

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FfQ7SNRedEJGsQhZvnBFg%2Fimage.png?alt=media&amp;token=881b664d-fb9b-4e55-b984-517ae34bec4d" alt=""><figcaption></figcaption></figure>

Заходим вновь созданную папку `multiworld` и загружаем туда наш скаченный html-шаблон.

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2FURcArmIxtH95RqNjS7Sx%2Fimage.png?alt=media&amp;token=23a96878-f0b1-4e0e-bc67-cd7aab3124b0" alt=""><figcaption></figcaption></figure>

Далее нам необходимо создать файлы, чтоб CMS MMOWEB увидела наш шаблон.

{% hint style="info" %}
Этот пункт упрошен, вам необходимо просто скопировать файлы уже из имеющего дефолтного шаблона в папке `/template/site/default`

Копируем файлы и папки: <img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MChcNJs9MdBo8v4uYq5%2F-MChfTLKyCVMM_BCGRkH%2Fimage.png?alt=media&amp;token=5afce252-42af-4cf9-950d-90d965362668" alt="" data-size="original"> в наш новый шаблон.

Вот что должно получится по итогу: <img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MChcNJs9MdBo8v4uYq5%2F-MChg1SUkPBK_VeZMbku%2Fimage.png?alt=media&amp;token=f3026afd-5785-43be-9b50-c4cbea55b654" alt="" data-size="original">&#x20;
{% endhint %}

Далее отрываем файл `Info.php` и заполняем его.

```php
<?php
return array(
    'name' => 'Default',
    'author' => 'Mex-Vision',
    'html' => 'Get-Web',
    'platform' => 'CMS',
    'poster' => '/images/poster.jpg',
);
```

Примечание, в поле poster нужно указать путь к скриншоту шаблона, чтоб он корректно отображался в админ панели. Пример можно посмотреть в дефолтном шаблоне.

После заходим в папку с нашим шаблоном `template/site/multiworld` и переименовываем `index.html` в `index.tpl` и открываем его в редакторе.

Первое, что необходимо сделать, это поправить путь к картинкам, css и js файлам.

Находим первый попавшийся html-teg где идет подключение какого то файла в нашем случаи иконка сайта

```markup
<link rel="shortcut icon" href="images/ico.png">
```

и добавляем к пути файла `{$.site.dir_site}/`  таким образом чтоб получилось&#x20;

```markup
<link rel="shortcut icon" href="{$.site.dir_site}/images/ico.png">
```

Исправляем пути у остальных файлов в шаблоне.

```markup
<!--... Фрагмент кода с измененым источник ....-->
<!-- swiper -->
<script src="{$.site.dir_site}/libs/swiper/js/swiper.min.js"></script>
<link rel="stylesheet" href="{$.site.dir_site}/libs/swiper/css/swiper.min.css">

<!-- insertmedia -->
<script src="{$.site.dir_site}/libs/insertmedia/src/insertmedia.js?ver=0.0.1"></script>

<!-- Main style -->
<link rel="stylesheet" href="{$.site.dir_site}/css/style.css?ver=0.0.1">

<!-- Adaptation style -->
<link rel="stylesheet" href="{$.site.dir_site}/css/adaptation.css?ver=0.0.1">

<!-- Main app -->
<script src="{$.site.dir_site}/js/app.js?ver=0.0.1"></script>
<!--... Фрагмент кода с измененым источник ....-->
```

После чего сохраняем наш index.tpl и загружаем в `template/site/multiworld`&#x20;

Остался последний пункт необходимо перейти в корень CMS MMOWEB и открыть файл `Config.php` и ищем настройку шаблона&#x20;

```php
/**
* Готовые шаблоны можно купить в админ панели ммовеб
* Шаблон сайта. Находится: /template/site
* Ready-made templates can be bought in the admin panel of mmoweb
* Site template. Location: /template/site
*/
define('TEMPLATE',       'default'); //По умолчанию: default
```

И устанавливаем наш шаблон `multiworld`

```php
define('TEMPLATE',       'multiworld'); //По умолчанию: default
```

Сохраняем конфиг, теперь можно зайти на сайт и увидеть шаблон.

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


# Основа шаблонизатора

Вводная часть

В CMS MMOWEB упрощена шаблонизация сайта на сколько это было возможно, добавлены теги отвечающие за рендеринг виджетов и основных элементов движка.

## &#x20;**Список основных тегов.**

```markup
<html lang="{$_LANG}">
  <head>
    {$_SEO_HEAD}
  </head>
  <body class="body">
    {$_SEO_BODY}
      .....
    {$_SEO_FOOTER}
  </body>
</html>
```

## SEO теги и подключение js и css файлов.

| ТЕГ              | Описание                                                                                        |
| ---------------- | ----------------------------------------------------------------------------------------------- |
| {$\_LANG}        | Тег языка распростряняется на все шаблоны содержить ru,en итд в зависимости от выбранного языка |
| {$\_SEO\_HEAD}   | Этот тег парсится из файлов Headers.php и IncludeJsCss.php                                      |
| {$\_SEO\_BODY}   | Этот тег парсится из файла IncludeJsCss.php                                                     |
| {$\_SEO\_FOOTER} | Этот тег парсится из файла IncludeJsCss.php                                                     |

Рекомендовано для сайтов использующие переключения языков все заголовки содержанию информацию на нескольких языках к примеру такие как title description и тому подобные выносить в файл Headers.php формат:

```php
return array(
    'ru' => array(
        //Общий конфиг для лк
        'init' => array(
            'head' => array(
                ['idx' => 'title',      'typex' => 'title',                                         'content' => '%site_name% Сайт сервера %server_name%.'],
                ['idx' => 'og_title',   'typex' => 'meta', 'property' => 'og:title',                'content' => '%site_name% Сайт сервера %server_name%.'],
                ['idx' => 'og_s_name',  'typex' => 'meta', 'property' => 'og:site_name',            'content' => '%site_name%'],
                ['idx' => 'og_type',    'typex' => 'meta', 'property' => 'og:type',                 'content' => 'website'],
                ['idx' => 'og_url',     'typex' => 'meta', 'property' => 'og:url',                  'content' => '%url%'],
                ['idx' => 'desc',       'typex' => 'meta', 'name' => 'description',                 'content' => '%site_name% Сайт сервера %server_name%!'],
                ['idx' => 'og_desc',    'typex' => 'meta', 'property' => 'og:description',          'content' => '%site_name% Сайт сервера %server_name%!'],
                ['idx' => 'tw_desc',    'typex' => 'meta', 'property' => 'twitter:description',     'content' => '%site_name% Сайт сервера %server_name%!'],
                ['idx' => 'keywords',   'typex' => 'meta', 'name' => 'keywords',                    'content' => 'mmoweb, mmoweb4'],

            ),
        ),
    ),
    'en' => array(),
);
```

Для создания источника тега необходимо создать по примеру запись в массиве `head` обязательные поля `idx` - ключ тега для замены из файла IncludeJsCss.php в случаях когда сайт содержит больше 1 страницы и необходимо заменить тег на другой `typex` - ключ указывающий, что за тип тега может иметь следующие значения title, meta, link, script, html

**Значения поля `typex`**

| Ключ   | Описание                                                                     |
| ------ | ---------------------------------------------------------------------------- |
| title  | Принемаемый параметр **content**                                             |
| meta   | Может принемать любые ключи                                                  |
| link   | Может принемать любые ключи                                                  |
| script | Может принемать любые ключ. Доп.ключ на выполнения javascript кода ключ `js` |
| html   | Принемает параметр `html`                                                    |

### Пример создания тега:

```php
['idx' => 'favicons', 'typex' => 'link', 'rel' => 'shortcut icon', 'href' => TEMPLATE_DIR.'/images/favicon.ico'],
```

### Результат:&#x20;

```markup
<link rel="shortcut icon" href="/template/site/multiworld/images/favicon.ico">
```

Тут наглядно видно, что объявленный параметр rel передался в html со значением из ключа, и так можно передать любой ключ со значением.

### Параметры автозамены в тегах

В CMS MMOWEB есть дополнительная возможность передавать определенные вложения которые будут на выходе замениться в зависимости от настроек и выбранных параметров пользователя, к примеру %site\_name% заменится на название проекта которое вы указали в админ панели mmoweb.biz.

### Доступные значения.

| Значение                 | Описание                                     |
| ------------------------ | -------------------------------------------- |
| %site\_name%             | Имя проекта                                  |
| %server\_name%           | Имя текушего сервера                         |
| %platform\_server\_name% | Платформа и имя сервера                      |
| %url%                    | Ссылка на сайт пример: <https://mmoweb.biz/> |

Для более продвинутых можно самостоятельно добавить значения Class/SeoX.php method initReplaceTeg()

## Редактирование IncludeJsCss.php &#x20;

IncludeJsCss.php по сравнению с Headers.php имеет массив с body и footer вставляя теги в эти поля они будут отрисовываться в одноименных шаблонных тегах {$\_SEO\_HEAD} и {$\_SEO\_FOOTER}  принцип добавления такой же, как и Headers.php.

## &#x20;**Добавление тега из шаблона**

Бывают задачи добавить JS или CSS только в определенном шаблоне, для этого есть конструкция

```markup
{$.site._SEO->addTegHTML('head', 'telInput_css', 'link', ['rel'=>'stylesheet', 'href'=> $.const.VIEWPATH~'/panel/assets/css/intl-telInput/intlTelInput.css?ver=0.1'])}
{$.site._SEO->addTegHTML('footer', 'telInput', 'script', ['src'=> $.const.VIEWPATH~'/panel/assets/js/plugins/intl-telInput/intlTelInput.js?ver=0.1'])}
```

И при вызове шаблона, где объявлены эти методы будет произведена вставка перед отрисовкой.

## Теги виджетов на сайте

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

### Список доступных тегов для сайта

| Тег                                       | Описание                                                                                                                                                                                                                                                                           |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| {language tpl='language.tpl'}             | <p>Тег выбора языка шаблон language.tpl</p><p>аргумент tpl необязательный, сделан для подмены дефолтного шаблона на кастомный </p>                                                                                                                                                 |
| {include 'site:is\_login.tpl'}            | Это не совсем тег это конструкция сразу подключает нужный фрагмент в шаблон в нашем случаи is\_login.tpl                                                                                                                                                                           |
| {server count=3 tpl='server\_status.tpl'} | <p>Виджет серверов онлайн шаблон server\_status.tpl доп поля настраиваются из админки. Можно передать сколько вывести элементов count=3. </p><p>2 аргумент необязательный, сделан для подмены дефолтного шаблона на кастомный </p>                                                 |
| {forum count=5 tpl='forum.tpl'}           | <p>Последние темы с форума настройка источник из админки шаблон forum.tpl. Можно передать сколько вывести элементов count=5</p><p>2 аргумент необязательный, сделан для подмены дефолтного шаблона на кастомный </p>                                                               |
| {rating count=10 tpl='rating.tpl'}        | <p>Сложный виджет, у него есть иерархия платформа тип статистики главный шаблон rating.tpl под категории /rating/lineage2/top\_clan.tpl. Можно передать сколько вывести элементов count=5</p><p>2 аргумент необязательный, сделан для подмены дефолтного шаблона на кастомный </p> |
| {news count=3 page=1}                     | Новостной блок, принимает параметры кол-во новостей и страницу, передача их не обязательна есть дефолтные параметры 10,1 шаблон news.tpl                                                                                                                                           |
| {iblock ikey='event' count=3}             | Виджет инфо блока - блоки создаются в админ панели и наполняются контентом                                                                                                                                                                                                         |
| {streams count=3 tpl='streams.tpl'}       | <p>Виджет стимов - блоки создаются в админ панели и наполняются контентом</p><p>2 аргумент необязательный, сделан для подмены дефолтного шаблона на кастомный </p>                                                                                                                 |
| {$.site.dir\_site}                        | Путь к выбронному шаблону пример: src="/template/site/default"                                                                                                                                                                                                                     |
| *{$L\_MENU\_BTN\_HOME}*                   | *Тег языковой, настраивается либо из /Lang/ru.php в шаблоне либо через админку*                                                                                                                                                                                                    |


# Смена языка

Языковые настройки сайта

## Смена языка на сайте

Первым делом нам нужно в директории нашего шаблона создать шаблон переключения языка, language.tpl&#x20;


# Статус серверов

Информация о состоянии сервера

Скоро...


# Темы с форума

Подключение вывод тес с форума

Скоро...


# Stream трансляции

Онлайн трансляции YouTube и Twitch

Скоро...


# Новости

Новостная лента на сайте

Скоро...


# Топ игроков

Рейтинг игроков на сайте

Скоро...


# Инфо блок

Акции ивенты слайдеры прочие элементы для вывода информации

Скоро...


# Шаблонизатор TPL

MMOWEB использует шаблонизатор Fenom

В CMS MMOWEB используется шаблонизатор [Fenom](https://github.com/fenom-template/fenom) он легок быстр и имеет хорошую [документацию](https://github.com/fenom-template/fenom/blob/master/docs/ru/readme.md).

## Документация Fenom

**Внимание! Документация в режиме беты, тексты могут содержать опечатки**

#### Fenom

* [Быстрый старт](https://github.com/fenom-template/fenom/blob/master/docs/ru/start.md)
* [Разработка Fenom](https://github.com/fenom-template/fenom/blob/master/docs/ru/dev/readme.md)
* [Настройки](https://github.com/fenom-template/fenom/blob/master/docs/ru/configuration.md)
* [Синтаксис](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md)
  * [Переменные](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5)
  * [Значения](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%A1%D0%BA%D0%B0%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F)
  * [Массивы](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%9C%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D1%8B)
  * [Операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md)
  * [Модификаторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%9C%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D1%8B)
  * [Теги](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%A2%D0%B5%D0%B3%D0%B8)
  * [Параметры тегов](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B-%D1%82%D0%B5%D0%B3%D0%BE%D0%B2)

#### Теги

[Использование](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%A2%D0%B5%D0%B3%D0%B8) тегов.

* [set](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/set.md), [add](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/set.md#add) и [var](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/set.md#var) — определение значения переменной
* [if](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/if.md), [elseif](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/if.md#elseif) и [else](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/if.md#else) — условный оператор
* [foreach](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/foreach.md), [foreachelse](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/foreach.md#foreachelse), [break](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/foreach.md#break) и [continue](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/foreach.md#continue) — перебор элементов массива или объекта
* [switch](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/switch.md) и [case](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/switch.md#case) — групповой условный оператор
* [cycle](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/cycle.md) — циклический перебор массива значений
* [include](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/include.md), [insert](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/include.md#insert) — вставляет и исполняет указанный шаблон
* [extends](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/extends.md), [use](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/extends.md#use), [block](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/extends.md#block), [parent](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/extends.md#parent) и [paste](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/extends.md#paste) — [наследование](https://github.com/fenom-template/fenom/blob/master/docs/ru/inheritance.md) шаблонов
* [filter](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/filter.md) — применение модификаторов к фрагменту шаблона
* [ignore](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/ignore.md) — игнорирование тегов Fenom
* [macro](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/macro.md) и [import](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/macro.md#macro) — пользовательские функции шаблонов
* [autoescape](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/autoescape.md) — экранирует фрагмент шаблона
* [raw](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/raw.md) — отключает экранирование фрагмента шаблона
* [unset](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/unset.md) — удаляет переменные
* или [добавьте](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%82%D0%B5%D0%B3%D0%BE%D0%B2) свои

Устаревшие теги

* [for](https://github.com/fenom-template/fenom/blob/master/docs/ru/tags/for.md), `forelse`, `break` and `continue` — цикл

#### Модификаторы

[Использование](https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#modifiers) модификаторов.

* [upper](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/upper.md) aka `up` — конвертирование строки в верхний регистр
* [lower](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/lower.md) aka `low` — конвертирование строки в нижний регистр
* [date\_format](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/date_format.md) - форматирует дату, штамп времени через strftime() функцию
* [date](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/date.md) - форматирует дату, штамп времени через date() функцию
* [truncate](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/truncate.md) — обрезает текст до указанной длины
* [escape](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/escape.md) aka `e` — экранирует строку
* [unescape](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/unescape.md) — убирает экранирование строки
* [strip](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/strip.md) — удаляет лишние пробелы
* [length](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/length.md) — подсчитывает длину строки, массива, объекта
* [in](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/in.md) — проверяет наличие значения в массиве
* [match](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/match.md) — проверяет соответствие паттерну
* [ematch](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/ematch.md) — проверяет соответствие регулярному выражению
* [replace](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/replace.md) — заменяет все вхождения подстроки на строку замену
* [ereplace](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/ereplace.md) — заменяет все соответствия регулярному выражению на строку замену.
* [split](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/split.md) — разбивает строку по подстроке
* [esplit](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/esplit.md) — разбивает строку по регулярному выражению
* [join](https://github.com/fenom-template/fenom/blob/master/docs/ru/mods/join.md) — объединяет массив в строку
* так же разрешены функции: `json_encode`, `json_decode`, `count`, `is_string`, `is_array`, `is_numeric`, `is_int`, `is_object`, `strtotime`, `gettype`, `is_double`, `ip2long`, `long2ip`, `strip_tags`, `nl2br`
* или [добавьте](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BC%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2) свои

#### Операторы

* [Арифметические операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%90%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `+`, `-`, `*`, `/`, `%`
* [Логические операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9B%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `||`, `&&`, `!$var`, `and`, `or`, `xor`
* [Операторы сравнения](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B-%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F) — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
* [Битовые операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `|`, `&`, `^`, `~$var`, `>>`, `<<`
* [Операторы присвоения](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B-%D0%BF%D1%80%D0%B8%D1%81%D0%B2%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F) — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
* [Строковые операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `$str1 ~ $str2`, `$str1 ~~ $str2`, `$str1 ~= $str2`
* [Тернарные операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%A2%D0%B5%D1%80%D0%BD%D0%B0%D1%80%D0%BD%D1%8B%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
* [Проверяющие операторы](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9F%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B5-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B) — `$var?`, `$var!`
* [Оператор тестирования](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80-%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F) — `is`, `is not`
* [Оператор содержания](https://github.com/fenom-template/fenom/blob/master/docs/ru/operators.md#%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D0%BD%D0%B8%D1%8F) — `in`, `not in`

#### Расширение

* [Источники шаблонов](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%98%D1%81%D1%82%D0%BE%D1%87%D0%BD%D0%B8%D0%BA%D0%B8-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2)
* [Добавление модификаторов](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BC%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2)
* [Добавление тегов](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%82%D0%B5%D0%B3%D0%BE%D0%B2)
* [Расширение тестового оператора](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5-%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B0)
* [Расширение глобальной переменной](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md#%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9)
* [Расширение Fenom](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extend.md)
* [Add-ons](https://github.com/fenom-template/fenom/blob/master/docs/ru/ext/extensions.md)


# Введение в API v2

### Что такое API?

API (прикладной программный интерфейс) — набор правил и форматов для обмена данными и вызова операций между приложениями. Через API одно приложение может безопасно запрашивать данные у другого или отдавать ему команды для выполнения задач.

API MMOWeb v2 предоставляет программный доступ к возможностям платформы: управлению мастер-аккаунтами, балансами, платежами и другим сущностям, необходимым для интеграции и автоматизации.

***

### Основные параметры

* **Base URL:** `https://api.mmoweb.biz/`
* **Версионирование:** версия указывается в пути (например, `/v2`)
* **Формат данных:** JSON
* **Методы:** большинство endpoint'ов использует POST; некоторые — GET с query-параметрами
* **Аутентификация:** Application Token

***

### Принципы запросов и ответов

* Формат ответа — JSON. В каждом ответе присутствует поле:
  * `success` (boolean) — `true`, если операция выполнена успешно.
* Структура успешного ответа зависит от конкретного endpoint'а и описывается в его документации.
* Ошибки возвращаются в виде JSON с полями `success: false`, `code` и `message`.

***

### HTTP-статусы

Ниже приведены наиболее часто встречаемые коды ответов. Для полного списка статусов и специфичных для конкретного endpoint'а кодов обратитесь к его документации.

<table data-search="false"><thead><tr><th>Код</th><th>Значение</th><th>Описание</th></tr></thead><tbody><tr><td><code>200</code></td><td>OK</td><td>Запрос успешно обработан</td></tr><tr><td><code>400</code></td><td>Bad Request</td><td>Ошибка в параметрах или валидация не пройдена</td></tr><tr><td><code>401</code></td><td>Unauthorized</td><td>Отсутствует или неверен токен аутентификации</td></tr><tr><td><code>403</code></td><td>Forbidden</td><td>Недостаточно прав или доступ запрещён</td></tr><tr><td><code>404</code></td><td>Not Found</td><td>Ресурс или endpoint не найден</td></tr><tr><td><code>409</code></td><td>Conflict</td><td>Конфликт состояния (например, ресурс уже существует)</td></tr><tr><td><code>422</code></td><td>Unprocessable Entity</td><td>Ошибки при пакетной обработке или валидации данных</td></tr><tr><td><code>500</code></td><td>Internal Server Error</td><td>Ошибка на сервере</td></tr></tbody></table>

{% hint style="info" %}
При обработке ошибок всегда опирайтесь на документацию конкретного endpoint'а, так как там могут быть описаны дополнительные коды и особенности их обработки.
{% endhint %}


# Аутентификация

### Обзор

API v2 использует Application Token (токены приложений) для аутентификации. Каждый токен предоставляет доступ к определённым endpoint'ам API с детальным контролем прав доступа.

**Ключевые характеристики:**

* Единовременная генерация: токены отображаются только один раз при создании
* Bearer токен: передаётся в заголовке `Authorization`
* Контроль доступа: каждый токен имеет специфические разрешения
* Привязка к проекту: каждый токен принадлежит одному проекту
* Отзываемость: токены можно отключить или удалить в любой момент
* Невосстанавливаемость: потерянный токен не может быть восстановлен; необходимо создать новый

***

### Создание Application Token

#### Где создать токен

Токены создаются и управляются в панели администратора.

{% hint style="info" %}
Создайте ваш первый [Application Token](https://mmoweb.biz/panel/settings/Globals.ApiKeyApp/add)
{% endhint %}

#### Процесс создания

1. Перейдите по ссылке выше
2. Укажите описательное имя для токена (для справки)
3. Настройте **"Доступы ключа"**, выбрав необходимые endpoint'ы API v2
4. Нажмите "Создать" или "Сохранить"
5. **Важно:** Скопируйте Application Token сразу — он больше не будет отображён

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2Fu5BnsHaafL4OCH4Jcl9U%2Fimage.png?alt=media&amp;token=8d0f1262-33cc-4927-b32d-0264baf1b4e9" alt="" width="563"><figcaption></figcaption></figure>

#### Свойства токена

| Свойство       | Описание                                                     |
| -------------- | ------------------------------------------------------------ |
| Формат         | 64-символьная буквенно-цифровая строка                       |
| Отображение    | Показывается один раз при создании; больше не доступен       |
| Восстановление | Восстановление невозможно; требуется создание нового токена  |
| Управление     | Отключение, удаление, перевыпуск через панель администратора |

***

### Настройка прав доступа токена

#### Типы разрешений

Разрешения определяют, какие endpoint'ы API v2 может использовать токен.

В разделе **"Доступы ключа"**:

* Отметьте каждый endpoint, который разрешён для использования
* Неотмеченные endpoint'ы вернут ошибку `ACCESS_DENIED`
* Изменения вступают в силу немедленно

<figure><img src="https://1569636441-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1508421016%2Fuploads%2F8LmHi2PPbs0X3oBF3L78%2Fimage.png?alt=media&amp;token=cbbef1aa-4ad5-4926-ba2d-6b559244c539" alt="" width="512"><figcaption></figcaption></figure>

#### Область действия разрешений

**Application Token используется только для API v2.**

Не используйте Application Token для других версий API или сервисов.

***

### Использование токена

#### Заголовок Authorization

Все запросы к API v2 должны содержать токен в заголовке `Authorization`:

```http
Authorization: Bearer <токен>
```

#### Правила валидации токена

Токен должен:

* Содержать ровно 64 символа
* Существовать в системе
* Иметь статус "активен" (не отключён)
* Иметь хотя бы одно разрешение
* Быть привязанным к активному проекту

***

### Примеры аутентификации

#### cURL

```bash
curl -X GET "https://api.mmoweb.biz/v2/endpoint" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json"
```

#### JavaScript (fetch)

```javascript
const token = 'APPLICATION_TOKEN_HERE';

fetch('https://api.mmoweb.biz/v2/endpoint', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

#### PHP

```php
<?php

$token = 'APPLICATION_TOKEN_HERE';

$ch = curl_init('https://api.mmoweb.biz/v2/endpoint');

curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json'
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET'
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT);
?>
```

***

### Ошибки аутентификации и авторизации

#### Отсутствует заголовок Authorization

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "EMPTY_TOKEN"
}
```

**Причина:** Заголовок `Authorization` отсутствует в запросе.

**Решение:** Добавьте заголовок `Authorization: Bearer APPLICATION_TOKEN_HERE` в запрос.

***

#### Неверный формат токена

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "INVALID_TOKEN"
}
```

**Причина:** Токен должен содержать ровно 64 символа. Проверяется длина токена после удаления префикса `Bearer` .

**Решение:**

* Убедитесь, что вы скопировали полный токен
* Проверьте, что нет лишних пробелов в начале или конце
* При необходимости создайте новый токен в панели

***

#### Токен не существует в системе

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "TOKEN_NOT_FOUND"
}
```

**Причина:** Указанный токен не найден в системе.

**Решение:**

* Проверьте, что используете правильный токен
* Убедитесь, что токен не был удалён в панели
* Если токен потерян, создайте новый (восстановление невозможно)

***

#### Токен отключён

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "TOKEN_DISABLED"
}
```

**Причина:** Токен существует, но отключён (статус неактивен).

**Решение:**

* Включите токен в панели настроек
* Или создайте новый активный токен

***

#### Разрешения не настроены для токена

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "EMPTY_ACCESS"
}
```

**Причина:** Для токена не установлено ни одного разрешения на endpoint'ы.

**Решение:** Настройте хотя бы одно разрешение в разделе "Доступы ключа" при редактировании токена.

***

#### Проект не найден или неактивен

**HTTP Status:** `404 Not Found`

```json
{
  "success": false,
  "code": "PROJECT_NOT_FOUND"
}
```

**Причина:** Проект, к которому привязан токен, не существует или отключён в системе.

**Решение:**

* Проверьте статус проекта в панели администратора
* Свяжитесь с поддержкой, если проект должен быть активным

***

#### Endpoint не найден

**HTTP Status:** `404 Not Found`

```json
{
  "success": false,
  "code": "NOT_FOUND"
}
```

**Причина:** Запрошенный endpoint не существует в API v2, или неверно указан метод запроса (GET/POST).

**Решение:**

* Проверьте URL endpoint'а в документации
* Убедитесь, что используете правильный HTTP-метод (GET или POST)
* Проверьте, что версия API правильна (`/v2/`)

***

#### Доступ запрещён (недостаточно разрешений)

**HTTP Status:** `403 Forbidden`

```json
{
  "success": false,
  "code": "ACCESS_DENIED"
}
```

**Причина:** Токен не имеет разрешения на доступ к этому endpoint'у.

**Решение:**

* Добавьте этот endpoint в разрешения токена в панели ("Доступы ключа")
* Используйте другой токен, у которого есть это разрешение
* Проверьте корректность URL и метода запроса

***

### Лучшие практики безопасности

**Храните токены безопасно:**

* Используйте переменные окружения или защищённые системы управления конфигурацией
* Никогда не коммитьте токены в систему контроля версий (Git)
* Не передавайте токены в URL параметрах или логах

**Ограничивайте права токена:**

* Включайте только те endpoint'ы, которые действительно нужны
* Принцип наименьших привилегий снижает риск при компрометации токена

**Регулярно ротируйте токены:**

* Установите график замены токенов
* Создавайте новый токен перед удалением старого (без прерывания сервиса)

**Мониторьте использование:**

* Проверяйте логи на признаки подозрительной активности
* Отключайте токены, которые больше не используются

**Потеря токена:**

* Потерянный токен не может быть восстановлен
* Немедленно создайте новый и отключите скомпрометированный
* Обновите конфигурацию в вашем приложении

***

### Решение проблем

| Проблема          | Возможная причина                   | Решение                                         |
| ----------------- | ----------------------------------- | ----------------------------------------------- |
| `INVALID_TOKEN`   | Неправильная длина токена           | Проверьте, что токен содержит ровно 64 символа  |
| `TOKEN_NOT_FOUND` | Токен не существует                 | Проверьте значение; создайте новый если потерян |
| `TOKEN_DISABLED`  | Токен отключён                      | Включите токен в настройках или создайте новый  |
| `ACCESS_DENIED`   | Недостаточно разрешений             | Добавьте endpoint в разрешения токена           |
| `EMPTY_ACCESS`    | Разрешения не настроены             | Настройте "Доступы ключа" для токена            |
| `EMPTY_TOKEN`     | Отсутствует заголовок Authorization | Добавьте `Authorization: Bearer <токен>`        |


# Мастер-аккаунт


# Список мастер-аккаунтов

#### Описание

Endpoint возвращает список мастер-аккаунтов проекта, к которому привязан ваш Application Token.

Список отдаётся постранично и отсортирован по `id` по возрастанию, поэтому при последовательном обходе страниц вы получите каждый аккаунт ровно один раз. Набор полей каждого аккаунта совпадает с ответом endpoint'а [Получение мастер-аккаунта](/rest-api/master-akkaunt/poluchenie-master-akkaunta).

Endpoint работает в двух режимах:

* **Без параметров `filters` и `search`** — возвращает общий список всех мастер-аккаунтов проекта постранично.
* **С параметрами** — `filters` сужает список по дате регистрации и статусу, `search` находит аккаунты по пачке идентификаторов (`user_ids`, `emails`, `phones`) за один запрос.

Вы можете использовать данный endpoint для:

* Синхронизации базы пользователей с внешними системами (CRM, аналитика, рассылки)
* Периодической выгрузки новых регистраций по дате создания
* Массовой проверки, какие из ваших пользователей зарегистрированы в проекте, и получения их `user_id`
* Получения списка заблокированных или неподтверждённых аккаунтов

> Endpoint возвращает персональные данные пользователей (email, телефон, IP). Выдавайте право `Список мастер аккаунтов (v2)` только тем ключам, которым оно действительно необходимо.

***

#### Endpoint

```
GET https://api.mmoweb.biz/v2/master-account/list
```

**Требуемое разрешение ключа:** `Список мастер аккаунтов (v2)`

***

#### Параметры

Все параметры передаются в строке запроса (query string) и являются необязательными. Без `filters` и `search` возвращается общий список аккаунтов проекта. Параметры делятся на три группы: пагинация, фильтры и поиск.

**Пагинация**

| Параметр   | Тип     | Обязателен | Формат                        | Описание                               |
| ---------- | ------- | ---------- | ----------------------------- | -------------------------------------- |
| `page`     | integer | Нет        | `≥ 1`, по умолчанию `1`       | Номер страницы                         |
| `per_page` | integer | Нет        | `1..1000`, по умолчанию `100` | Количество аккаунтов на одной странице |

**Фильтры `filters[...]`**

Сужают список. Если передано несколько фильтров, аккаунт должен подходить под **все** из них.

| Параметр                | Тип    | Обязателен | Формат                                 | Описание                                                             |
| ----------------------- | ------ | ---------- | -------------------------------------- | -------------------------------------------------------------------- |
| `filters[created_from]` | string | Нет        | `YYYY-MM-DD` или `YYYY-MM-DD HH:MM:SS` | Показать аккаунты, созданные начиная с указанной даты (включительно) |
| `filters[created_to]`   | string | Нет        | `YYYY-MM-DD` или `YYYY-MM-DD HH:MM:SS` | Показать аккаунты, созданные до указанной даты (включительно)        |
| `filters[statuses]`     | string | Нет        | Значения `0`, `1`, `2` через запятую   | Показать аккаунты с любым из перечисленных статусов                  |

> **Статусы аккаунта:** `0` — активный, `1` — email не подтверждён, `2` — заблокирован.

> **Даты без времени.** Значение `YYYY-MM-DD` трактуется как `00:00:00` этого дня. Чтобы включить в диапазон весь день, укажите время явно: `filters[created_to]=2026-01-31 23:59:59`.

**Поиск `search[...]`**

Находит аккаунты по идентификаторам. Аккаунт попадает в ответ, если совпал **хотя бы с одним** значением из любого списка. Если одновременно переданы `filters`, они применяются к найденным аккаунтам.

| Параметр           | Тип    | Обязателен | Формат значений                                           | Описание                        |
| ------------------ | ------ | ---------- | --------------------------------------------------------- | ------------------------------- |
| `search[user_ids]` | string | Нет        | Целые числа `≥ 1` через запятую                           | Идентификаторы мастер-аккаунтов |
| `search[emails]`   | string | Нет        | Валидные email через запятую                              | Email мастер-аккаунтов          |
| `search[phones]`   | string | Нет        | Только цифры, 7–18 символов, первая не `0`, через запятую | Телефоны мастер-аккаунтов       |

> **Формат телефона.** Код страны и номер одной строкой из цифр, без `+`, пробелов, скобок и дефисов: `+7 (900) 123-45-67` передаётся как `79001234567`.

**Правила для `filters` и `search`**

* **Списки — через запятую.** Значения перечисляются в одной строке: `search[user_ids]=15,42,108`. Пробелы вокруг запятых допустимы, повторы учитываются один раз.
* **Массивный синтаксис не поддерживается.** Запрос вида `search[user_ids][]=15` возвращает `VALIDATION_ERROR`.
* **Переданный ключ не может быть пустым.** Запросы вида `search[emails]=` или `filters[statuses]=,` возвращают `VALIDATION_ERROR`. Если условие не нужно, не передавайте ключ вовсе.
* **Только известные ключи.** Внутри `filters` и `search` допускаются только перечисленные выше ключи. Опечатка вроде `search[email]` возвращает `VALIDATION_ERROR`, а не общий список.
* **Лимиты поиска.** Не более **100** значений в каждом списке `search` и не более **300** значений суммарно. Превышение возвращает `VALIDATION_ERROR`.

***

#### Пагинация в ответе

| Поле        | Тип             | Описание                                                                  |
| ----------- | --------------- | ------------------------------------------------------------------------- |
| `page`      | integer         | Текущая страница                                                          |
| `per_page`  | integer         | Размер страницы                                                           |
| `pages`     | integer         | Общее количество страниц с учётом `filters` и `search`                    |
| `next_page` | integer \| null | Номер следующей страницы. `null` означает, что текущая страница последняя |
| `total`     | integer         | Общее количество аккаунтов с учётом `filters` и `search`                  |

Рекомендуемый алгоритм обхода: запросите `page=1`, затем повторяйте запрос с `page=next_page` и теми же `filters`/`search`, пока `next_page` не станет `null`.

***

#### Кодировка

**Запрос**

* Значения параметров передаются в кодировке UTF-8 и должны быть URL-кодированы (percent-encoding).
* Квадратные скобки в именах параметров можно передавать как есть (`filters[statuses]`) или в кодированном виде (`filters%5Bstatuses%5D`).
* Запятая-разделитель допускается как есть или как `%2C`.
* Символ `+` в email обязательно кодируйте как `%2B`. Незакодированный `+` читается как пробел, и такой email не пройдёт проверку.
* Символ `@` допускается как в исходном виде, так и в виде `%40`.

| Исходные данные                              | Значение в query string                      |
| -------------------------------------------- | -------------------------------------------- |
| статусы `0` и `2`                            | `filters[statuses]=0,2`                      |
| email `a@x.com` и `b+promo@x.com`            | `search[emails]=a%40x.com,b%2Bpromo%40x.com` |
| телефоны `+7 (900) 123-45-67`, `79001234568` | `search[phones]=79001234567,79001234568`     |

Стандартные средства формирования query string кодируют значения автоматически: `URLSearchParams` в JavaScript, `http_build_query()` в PHP, `--data-urlencode` в cURL. Список значений при этом соберите в одну строку через запятую заранее.

**Ответ**

Ответ возвращается в формате JSON в кодировке UTF-8 с заголовком `Content-Type: application/json`.

***

#### Примеры

**Общий список без параметров**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET "https://api.mmoweb.biz/v2/master-account/list" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

fetch('https://api.mmoweb.biz/v2/master-account/list', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/master-account/list';

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

**Фильтр: заблокированные и неподтверждённые аккаунты за январь 2026**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET -G "https://api.mmoweb.biz/v2/master-account/list" \
  --data-urlencode "filters[statuses]=1,2" \
  --data-urlencode "filters[created_from]=2026-01-01" \
  --data-urlencode "filters[created_to]=2026-01-31 23:59:59" \
  --data-urlencode "per_page=500" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const params = new URLSearchParams({
  'filters[statuses]': [1, 2].join(','),
  'filters[created_from]': '2026-01-01',
  'filters[created_to]': '2026-01-31 23:59:59',
  per_page: 500
});

fetch(`https://api.mmoweb.biz/v2/master-account/list?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$url = 'https://api.mmoweb.biz/v2/master-account/list?' . http_build_query([
  'filters' => [
    'statuses' => implode(',', [1, 2]),
    'created_from' => '2026-01-01',
    'created_to' => '2026-01-31 23:59:59'
  ],
  'per_page' => 500
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

**Поиск: пачка аккаунтов по email и телефонам**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET -G "https://api.mmoweb.biz/v2/master-account/list" \
  --data-urlencode "search[emails]=first@example.com,second+promo@example.com" \
  --data-urlencode "search[phones]=79001234567,79001234568" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const emails = ['first@example.com', 'second+promo@example.com'];
const phones = ['+7 (900) 123-45-67', '79001234568'].map(p => p.replace(/\D/g, ''));

const params = new URLSearchParams({
  'search[emails]': emails.join(','),
  'search[phones]': phones.join(',')
});

fetch(`https://api.mmoweb.biz/v2/master-account/list?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => {
  if (!data.success) {
    console.error(data.code, data.not_found);
    return;
  }
  console.log('Найдено:', data.accounts.map(a => a.id));
  if (data.not_found) {
    console.log('Не найдены email:', data.not_found.emails);
    console.log('Не найдены телефоны:', data.not_found.phones);
  }
})
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$emails = ['first@example.com', 'second+promo@example.com'];
$phones = array_map(fn($p) => preg_replace('/\D/', '', $p), ['+7 (900) 123-45-67', '79001234568']);

$url = 'https://api.mmoweb.biz/v2/master-account/list?' . http_build_query([
  'search' => [
    'emails' => implode(',', $emails),
    'phones' => implode(',', $phones)
  ]
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

if (!$data['success']) {
  echo "Ошибка: {$data['code']}\n";
  exit;
}

echo "Найдено: " . implode(', ', array_column($data['accounts'], 'id')) . "\n";

if (isset($data['not_found'])) {
  echo "Не найдены email: " . implode(', ', $data['not_found']['emails']) . "\n";
  echo "Не найдены телефоны: " . implode(', ', $data['not_found']['phones']) . "\n";
}
?>
```

{% endtab %}
{% endtabs %}

**Полный обход списка по страницам**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

async function fetchAllAccounts(filters = {}) {
  const accounts = [];
  let page = 1;

  while (page !== null) {
    const params = new URLSearchParams({ page, per_page: 1000 });
    for (const [key, value] of Object.entries(filters)) {
      params.set(`filters[${key}]`, value);
    }

    const response = await fetch(
      `https://api.mmoweb.biz/v2/master-account/list?${params}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );
    const data = await response.json();

    if (!data.success) {
      if (data.code === 'ACCOUNTS_NOT_FOUND') break;
      throw new Error(data.code);
    }

    accounts.push(...data.accounts);
    page = data.next_page;
  }

  return accounts;
}

fetchAllAccounts({ statuses: '0', created_from: '2026-01-01' })
  .then(accounts => console.log(`Получено аккаунтов: ${accounts.length}`))
  .catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

function fetchPage(string $token, int $page, array $filters): array
{
  $url = 'https://api.mmoweb.biz/v2/master-account/list?' . http_build_query([
    'page' => $page,
    'per_page' => 1000,
    'filters' => $filters
  ]);

  $ch = curl_init($url);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token]
  ]);
  $response = curl_exec($ch);
  curl_close($ch);

  return json_decode($response, true);
}

$filters = ['statuses' => '0', 'created_from' => '2026-01-01'];
$accounts = [];
$page = 1;

while ($page !== null) {
  $data = fetchPage($token, $page, $filters);

  if (!$data['success']) {
    if ($data['code'] === 'ACCOUNTS_NOT_FOUND') {
      break;
    }
    throw new RuntimeException($data['code']);
  }

  $accounts = array_merge($accounts, $data['accounts']);
  $page = $data['next_page'];
}

echo "Получено аккаунтов: " . count($accounts) . "\n";
?>
```

{% endtab %}
{% endtabs %}

***

#### Ответы

**Успешный ответ (200 OK)**

```json
{
  "success": true,
  "page": 1,
  "per_page": 100,
  "pages": 1,
  "next_page": null,
  "total": 1,
  "accounts": [
    {
      "id": 1,
      "email": "first@example.com",
      "phone": "79001234567",
      "shield": 0,
      "affiliate": 0,
      "select_lid": 1,
      "select_sid": 3,
      "project_id": 5,
      "status": 0,
      "desc_status": "",
      "created_at": "2026-01-01 10:00:00",
      "last_login": "2026-02-01 12:30:00",
      "last_ip": "203.0.113.10",
      "email_valid": 1,
      "lang": "ru",
      "iso": "RU",
      "telegram": ""
    }
  ],
  "not_found": {
    "user_ids": [],
    "emails": ["second+promo@example.com"],
    "phones": ["79001234568"]
  }
}
```

> В примере выше запрос искал два email и два телефона. Найден один аккаунт, поэтому `total: 1`, а второй email и второй телефон перечислены в `not_found`. Если бы все значения нашлись, блока `not_found` в ответе не было бы. Подробнее — в разделе «Важные особенности».

**Поля аккаунта:**

| Поле          | Тип            | Описание                                                                         |
| ------------- | -------------- | -------------------------------------------------------------------------------- |
| `id`          | integer        | Идентификатор мастер-аккаунта                                                    |
| `email`       | string \| null | Email                                                                            |
| `phone`       | string \| null | Телефон. `"0"` означает, что телефон не указан                                   |
| `shield`      | integer        | Включена ли дополнительная защита аккаунта (`1` — да, `0` — нет)                 |
| `affiliate`   | integer        | Идентификатор пригласившего аккаунта, `0` — реферал не установлен                |
| `select_lid`  | integer        | Идентификатор выбранного логин-сервера                                           |
| `select_sid`  | integer        | Идентификатор выбранного игрового сервера                                        |
| `project_id`  | integer        | Идентификатор проекта                                                            |
| `status`      | integer        | Статус аккаунта (`0` — активный, `1` — email не подтверждён, `2` — заблокирован) |
| `desc_status` | string \| null | Сообщение, которое видит пользователь при блокировке                             |
| `created_at`  | string         | Дата регистрации в формате `YYYY-MM-DD HH:MM:SS`                                 |
| `last_login`  | string \| null | Дата последнего входа в формате `YYYY-MM-DD HH:MM:SS`                            |
| `last_ip`     | string \| null | IP-адрес последнего входа                                                        |
| `email_valid` | integer        | Подтверждён ли email (`1` — да, `0` — нет)                                       |
| `lang`        | string \| null | Язык интерфейса пользователя                                                     |
| `iso`         | string \| null | ISO-код страны                                                                   |
| `telegram`    | string \| null | Telegram пользователя                                                            |

**Ошибка структуры параметров (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "search.email": "Unknown key. Allowed keys: user_ids, emails, phones."
  }
}
```

> **Когда встречается:** неизвестный ключ внутри `filters` или `search`, массивный синтаксис `[]` вместо строки через запятую, ключ передан с пустым значением (`search[emails]=`), либо `filters`/`search` переданы без ключа (`filters=abc`)

**Превышен лимит поиска (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "search.emails": "Maximum 100 values allowed.",
    "search": "Maximum 300 values allowed in total."
  }
}
```

**Неверный формат значения (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "search.emails.1": "The search.emails field must contain a valid email address.",
    "filters.statuses.0": "The filters.statuses field must be one of: 0,1,2."
  }
}
```

> **Когда встречается:** `page` или `per_page` вне допустимого диапазона, дата не распознана, статус не из списка `0,1,2`, среди `user_ids` есть не целое число, среди `emails` — невалидный адрес, среди `phones` — значение с символами кроме цифр, ведущим `0` или неверной длиной. Для списков ключ ошибки содержит позицию проблемного значения, начиная с `0`: в примере выше это второй email и первый статус

**Некорректный диапазон дат (400 Bad Request)**

```json
{
  "success": false,
  "code": "INVALID_DATE_RANGE"
}
```

> **Когда встречается:** `filters[created_from]` позже `filters[created_to]`

**Страница за пределами списка (400 Bad Request)**

```json
{
  "success": false,
  "code": "PAGE_OUT_OF_RANGE",
  "pages": 7,
  "total": 67
}
```

> **Когда встречается:** запрошенный `page` больше количества страниц. В ответе возвращаются актуальные `pages` и `total`, чтобы вы могли скорректировать запрос

**Аккаунты не найдены (404 Not Found)**

```json
{
  "success": false,
  "code": "ACCOUNTS_NOT_FOUND",
  "not_found": {
    "user_ids": [15],
    "emails": [],
    "phones": []
  }
}
```

> **Когда встречается:** ни один аккаунт проекта не подходит под `filters` и `search`. Успешный ответ никогда не содержит пустой список. Если передан `search`, в ответе есть блок `not_found` со всеми переданными идентификаторами

**Недостаточно прав (403 Forbidden)**

```json
{
  "success": false,
  "code": "ACCESS_DENIED"
}
```

> **Когда встречается:** у Application Token не включено разрешение `Список мастер аккаунтов (v2)`

***

#### Коды ошибок

| Код                  | HTTP Status | Описание                                                        | Что делать                                                                                                           |
| -------------------- | ----------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`   | 400         | Неверная структура, превышен лимит или неверный формат значения | Сверьте имена ключей, лимиты 100/300 и форматы значений с разделом «Параметры»                                       |
| `INVALID_DATE_RANGE` | 400         | Начало диапазона дат позже его конца                            | Поменяйте `filters[created_from]` и `filters[created_to]` местами или исправьте значения                             |
| `PAGE_OUT_OF_RANGE`  | 400         | Запрошенная страница больше `pages`                             | Используйте `pages` из ответа; при обходе списка ориентируйтесь на `next_page`                                       |
| `ACCOUNTS_NOT_FOUND` | 404         | Под указанные условия не подходит ни один аккаунт               | Это нормальный результат для пустой выборки; при поиске используйте `not_found`, чтобы узнать, что именно не найдено |
| `ACCESS_DENIED`      | 403         | У токена нет разрешения на этот endpoint                        | Включите разрешение `Список мастер аккаунтов (v2)` для ключа в панели администратора                                 |

Ошибки аутентификации (`EMPTY_TOKEN`, `INVALID_TOKEN`, `TOKEN_NOT_FOUND`, `TOKEN_DISABLED`) общие для всех endpoint'ов API v2 и описаны во введении.

***

#### Важные особенности

**Без параметров — общий список**

Если не переданы ни `filters`, ни `search`, endpoint возвращает всех мастер-аккаунтов проекта постранично. Это основной режим для полной выгрузки.

**Фильтры сужают, поиск объединяет**

Условия внутри `filters` объединяются через И: аккаунт должен подходить под каждое. Значения внутри `search` объединяются через ИЛИ: достаточно совпадения по любому `user_id`, email или телефону. Если переданы обе группы, в ответ попадают аккаунты, которые совпали с `search` и одновременно подходят под `filters`. Например, `search[emails]=a@x.com&filters[statuses]=2` вернёт аккаунт `a@x.com`, только если он заблокирован; иначе ответ будет `ACCOUNTS_NOT_FOUND`, а email окажется в `not_found`.

**Пустой результат — это ошибка, а не успех**

Если под условия не попал ни один аккаунт, endpoint возвращает `ACCOUNTS_NOT_FOUND` (404), а не `success: true` с пустым массивом. При обходе списка обрабатывайте этот код как штатное завершение.

**`not_found` появляется только при пропусках**

Блок `not_found` есть в ответе, только если передан `search` и хотя бы одно его значение не нашлось. Если найдены все идентификаторы, блока нет, поэтому проверяйте его наличие перед чтением. Внутри блока всегда три списка: `user_ids`, `emails`, `phones`; списки без пропусков пустые.

Значение попадает в `not_found`, если по нему не найден ни один аккаунт, подходящий под `filters`. Блок рассчитывается по всей выборке, не зависит от `page` и `per_page` и одинаков на каждой странице.

**Стабильный порядок**

Аккаунты всегда отсортированы по `id` по возрастанию. Новые регистрации получают больший `id`, поэтому они появляются на последних страницах и не сдвигают уже прочитанные.

**Сравнение email и телефонов**

Регистр букв в email не учитывается. Алиасы вида `user+promo@example.com` и `user@example.com` считаются разными адресами. Телефон должен совпадать полностью, включая код страны.

***

#### Рекомендации

**Безопасность:**

* Храните Application Token на сервере и никогда не передавайте его в браузер или мобильное приложение
* Выдавайте разрешение `Список мастер аккаунтов (v2)` отдельному ключу, который используется только для выгрузки
* Используйте HTTPS для всех запросов

**Производительность:**

* Для полной выгрузки используйте `per_page=1000`, чтобы сократить количество запросов
* Для регулярной синхронизации запрашивайте только новые аккаунты через `filters[created_from]` с даты последней выгрузки
* Для проверки пачки пользователей используйте `search` вместо отдельных запросов к Получению мастер-аккаунта: до 300 идентификаторов за один запрос

**Надёжность:**

* Реализуйте retry logic с экспоненциальной задержкой при ошибках 5xx и сетевых сбоях
* Обрабатывайте `ACCOUNTS_NOT_FOUND` как пустую выборку, а не как сбой
* Ориентируйтесь на `next_page` вместо самостоятельного расчёта номера следующей страницы
* Передавайте одни и те же `filters` и `search` на каждой странице обхода

**Интеграция:**

* Собирайте списки для `search` в строку через запятую средствами языка (`join`, `implode`) и формируйте query string стандартными функциями кодирования
* Убедитесь, что токен приложения имеет разрешение `Список мастер аккаунтов (v2)`


# Получение мастер-аккаунта

#### Описание

Endpoint возвращает данные одного мастер-аккаунта проекта, к которому привязан ваш Application Token.

Аккаунт можно найти по одному из трёх идентификаторов: `user_id`, `email` или `phone`. Набор полей в ответе совпадает с полями элемента списка из endpoint'а [Список мастер-аккаунтов](/rest-api/master-akkaunt/spisok-master-akkauntov), поэтому оба endpoint'а можно обрабатывать одной моделью данных.

Вы можете использовать данный endpoint для:

* Проверки существования аккаунта перед начислением баланса или выдачей предметов
* Получения `user_id` по email или телефону из внешней системы
* Отображения профиля игрока в CRM, службе поддержки или боте

> Endpoint возвращает персональные данные пользователя (email, телефон, IP). Выдавайте право `Получение мастер аккаунта (v2)` только тем ключам, которым оно действительно необходимо.

***

#### Endpoint

```
GET https://api.mmoweb.biz/v2/master-account
```

**Требуемое разрешение ключа:** `Получение мастер аккаунта (v2)`

***

#### Параметры

Все параметры передаются в строке запроса (query string). Необходимо передать **хотя бы один** идентификатор.

| Параметр  | Тип     | Обязателен                               | Формат                                                 | Описание                      |
| --------- | ------- | ---------------------------------------- | ------------------------------------------------------ | ----------------------------- |
| `user_id` | integer | Да, если не переданы `email` и `phone`   | Целое число `≥ 1`                                      | Идентификатор мастер-аккаунта |
| `email`   | string  | Да, если не переданы `user_id` и `phone` | Валидный email без пробелов                            | Email мастер-аккаунта         |
| `phone`   | string  | Да, если не переданы `user_id` и `email` | Только цифры, от 7 до 18 символов, первая цифра не `0` | Телефон мастер-аккаунта       |

> **Приоритет идентификаторов.** Если передано несколько параметров, используется первый непустой в порядке `user_id` → `email` → `phone`, остальные игнорируются. Например, при запросе `?user_id=123&email=user@example.com` поиск выполняется только по `user_id`.

> **Формат телефона.** Передавайте телефон одной строкой цифр: код страны и номер, без `+`, пробелов, скобок и дефисов. Например, `+7 (900) 123-45-67` передаётся как `79001234567`. Код страны обязателен и должен совпадать с тем, что указан у пользователя.

***

#### Кодировка

**Запрос**

* Значения параметров передаются в кодировке UTF-8 и должны быть URL-кодированы (percent-encoding), как и любые данные в query string.
* Символ `+` в email обязательно кодируйте как `%2B`. Незакодированный `+` в query string читается как пробел, и такой email не пройдёт проверку.
* Символ `@` допускается как в исходном виде, так и в виде `%40`.
* Пробелы в значениях не допускаются, в том числе по краям.

| Исходное значение        | Значение в query string                                    |
| ------------------------ | ---------------------------------------------------------- |
| `user@example.com`       | `email=user%40example.com` или `email=user@example.com`    |
| `user+promo@example.com` | `email=user%2Bpromo%40example.com`                         |
| `+7 (900) 123-45-67`     | `phone=79001234567` (после очистки от нецифровых символов) |

Стандартные средства формирования query string кодируют значения автоматически: `URLSearchParams` в JavaScript, `http_build_query()` в PHP, `--data-urlencode` в cURL.

**Ответ**

Ответ возвращается в формате JSON в кодировке UTF-8 с заголовком `Content-Type: application/json`.

***

#### Примеры

**Поиск по user\_id**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET "https://api.mmoweb.biz/v2/master-account?user_id=123" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const params = new URLSearchParams({ user_id: 123 });

fetch(`https://api.mmoweb.biz/v2/master-account?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$url = 'https://api.mmoweb.biz/v2/master-account?' . http_build_query([
  'user_id' => 123
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

**Поиск по email**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET -G "https://api.mmoweb.biz/v2/master-account" \
  --data-urlencode "email=user+promo@example.com" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const params = new URLSearchParams({ email: 'user+promo@example.com' });

fetch(`https://api.mmoweb.biz/v2/master-account?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$url = 'https://api.mmoweb.biz/v2/master-account?' . http_build_query([
  'email' => 'user+promo@example.com'
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

**Поиск по телефону**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET "https://api.mmoweb.biz/v2/master-account?phone=79001234567" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const rawPhone = '+7 (900) 123-45-67';
const phone = rawPhone.replace(/\D/g, '');

const params = new URLSearchParams({ phone });

fetch(`https://api.mmoweb.biz/v2/master-account?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$rawPhone = '+7 (900) 123-45-67';
$phone = preg_replace('/\D/', '', $rawPhone);

$url = 'https://api.mmoweb.biz/v2/master-account?' . http_build_query([
  'phone' => $phone
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

#### Ответы

**Успешный ответ (200 OK)**

```json
{
  "success": true,
  "account": {
    "id": 123,
    "email": "user@example.com",
    "phone": "79001234567",
    "shield": 0,
    "affiliate": 0,
    "select_lid": 1,
    "select_sid": 3,
    "project_id": 5,
    "status": 0,
    "desc_status": "",
    "created_at": "2026-01-01 10:00:00",
    "last_login": "2026-02-01 12:30:00",
    "last_ip": "203.0.113.10",
    "email_valid": 1,
    "lang": "ru",
    "iso": "RU",
    "telegram": ""
  }
}
```

**Поля аккаунта:**

| Поле          | Тип            | Описание                                                                         |
| ------------- | -------------- | -------------------------------------------------------------------------------- |
| `id`          | integer        | Идентификатор мастер-аккаунта                                                    |
| `email`       | string \| null | Email                                                                            |
| `phone`       | string \| null | Телефон. `"0"` означает, что телефон не указан                                   |
| `shield`      | integer        | Включена ли дополнительная защита аккаунта (`1` — да, `0` — нет)                 |
| `affiliate`   | integer        | Идентификатор пригласившего аккаунта, `0` — реферал не установлен                |
| `select_lid`  | integer        | Идентификатор выбранного логин-сервера                                           |
| `select_sid`  | integer        | Идентификатор выбранного игрового сервера                                        |
| `project_id`  | integer        | Идентификатор проекта                                                            |
| `status`      | integer        | Статус аккаунта (`0` — активный, `1` — email не подтверждён, `2` — заблокирован) |
| `desc_status` | string \| null | Сообщение, которое видит пользователь при блокировке                             |
| `created_at`  | string         | Дата регистрации в формате `YYYY-MM-DD HH:MM:SS`                                 |
| `last_login`  | string \| null | Дата последнего входа в формате `YYYY-MM-DD HH:MM:SS`                            |
| `last_ip`     | string \| null | IP-адрес последнего входа                                                        |
| `email_valid` | integer        | Подтверждён ли email (`1` — да, `0` — нет)                                       |
| `lang`        | string \| null | Язык интерфейса пользователя                                                     |
| `iso`         | string \| null | ISO-код страны                                                                   |
| `telegram`    | string \| null | Telegram пользователя                                                            |

**Не передан идентификатор (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": "user_id, email or phone is required"
}
```

> **Когда встречается:** в запросе нет ни одного из параметров `user_id`, `email`, `phone`, либо все они пустые

**Неверный формат параметра (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "phone": "The phone field is not in the correct format."
  }
}
```

> **Когда встречается:** `user_id` не является целым числом `≥ 1`, `email` не является валидным адресом либо `phone` содержит символы кроме цифр, начинается с `0` или не подходит по длине. В `message` возвращается объект, где ключ — имя параметра, а значение — описание ошибки

**Аккаунт не найден (404 Not Found)**

```json
{
  "success": false,
  "code": "USER_NOT_FOUND"
}
```

> **Когда встречается:** в проекте нет мастер-аккаунта с указанным идентификатором

**Недостаточно прав (403 Forbidden)**

```json
{
  "success": false,
  "code": "ACCESS_DENIED"
}
```

> **Когда встречается:** у Application Token не включено разрешение `Получение мастер аккаунта (v2)`

***

#### Коды ошибок

| Код                | HTTP Status | Описание                                                 | Что делать                                                                                        |
| ------------------ | ----------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR` | 400         | Не передан идентификатор или он не соответствует формату | Передайте один из `user_id`, `email`, `phone` в формате из раздела «Параметры»                    |
| `USER_NOT_FOUND`   | 404         | Аккаунт с таким идентификатором не найден в проекте      | Проверьте идентификатор; для телефона убедитесь, что код страны указан так же, как у пользователя |
| `ACCESS_DENIED`    | 403         | У токена нет разрешения на этот endpoint                 | Включите разрешение `Получение мастер аккаунта (v2)` для ключа в панели администратора            |

Ошибки аутентификации (`EMPTY_TOKEN`, `INVALID_TOKEN`, `TOKEN_NOT_FOUND`, `TOKEN_DISABLED`) общие для всех endpoint'ов API v2 и описаны во введении.

***

#### Важные особенности

**Только текущий проект**

Токен привязан к одному проекту. Endpoint ищет аккаунт только среди мастер-аккаунтов этого проекта, параметра для выбора проекта нет. Для аккаунта другого проекта вернётся `USER_NOT_FOUND`.

**Один запрос — один аккаунт**

Endpoint всегда возвращает ровно один аккаунт или ошибку `USER_NOT_FOUND`. Для получения нескольких аккаунтов используйте [Список мастер-аккаунтов](/rest-api/master-akkaunt/spisok-master-akkauntov).

**Телефон — только цифры**

Запрос с `+`, пробелами, скобками или дефисами в `phone` отклоняется с `VALIDATION_ERROR`. Очищайте номер от нецифровых символов на своей стороне перед вызовом, как показано в примерах. Значение `0` не принимается: по нему нельзя найти аккаунт без телефона.

**Сравнение email**

Регистр букв в email не учитывается: `User@Example.com` и `user@example.com` находят один и тот же аккаунт. Алиасы вида `user+promo@example.com` и `user@example.com` считаются разными адресами.

***

#### Рекомендации

**Безопасность:**

* Храните Application Token на сервере и никогда не передавайте его в браузер или мобильное приложение
* Не логируйте ответ endpoint'а целиком: он содержит персональные данные пользователя
* Используйте HTTPS для всех запросов

**Надёжность:**

* Предпочитайте поиск по `user_id`: он однозначен и не зависит от формата email или телефона
* Обрабатывайте `USER_NOT_FOUND` как штатный результат, а не как сбой
* Реализуйте retry logic с экспоненциальной задержкой при ошибках 5xx и сетевых сбоях

**Интеграция:**

* Формируйте query string стандартными средствами языка, чтобы не ошибиться с кодированием `+` и `@`
* Сохраняйте `user_id` на своей стороне после первого успешного поиска по email или телефону
* Убедитесь, что токен приложения имеет разрешение `Получение мастер аккаунта (v2)`


# Баланс


# Получение баланса

### Описание

Endpoint возвращает балансы мастер-аккаунта на выбранном сервере: основной баланс вместе с суммой пополнений и суммой списаний, а также бонусный баланс.

Вы можете использовать данный endpoint для:

* Отображения баланса игрока в CRM, службе поддержки или боте
* Проверки баланса перед начислением или списанием через создание транзакций
* Получения текущих значений перед установкой балансов
* Сверки балансов с внешним биллингом

***

### Endpoint

```
GET https://api.mmoweb.biz/v2/master-account/balance
```

**Требуемое разрешение ключа:** `Получение балансов пользователя (v2)`

***

### Параметры

Все параметры передаются в строке запроса (query string).

| Параметр       | Тип     | Обязателен                    | Формат             | Описание                                                                                                                  |
| -------------- | ------- | ----------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `user_id`      | integer | Да, если не передан `email`   | Целое число `≥ 1`  | Идентификатор мастер-аккаунта                                                                                             |
| `email`        | string  | Да, если не передан `user_id` | Валидный email     | Email мастер-аккаунта                                                                                                     |
| `server_id`    | integer | Да                            | Целое число `≥ 0`  | Игровой сервер, баланс которого нужен. `0` — общий баланс                                                                 |
| `balance_type` | string  | Нет                           | `main` или `bonus` | `main` — основной баланс, сумма пополнений и сумма списаний; `bonus` — бонусный баланс. Если не передан, возвращается всё |

> **Приоритет идентификаторов.** Если переданы и `user_id`, и `email`, поиск выполняется по `user_id`.

> **Как выбирается баланс по server\_id**
>
> Основной баланс, сумма пополнений и сумма списаний:
>
> * `server_id=0` — общий баланс мастер-аккаунта
> * `server_id > 0` — баланс на этом сервере. Если на сервере включён общий баланс, возвращается общий баланс — то же, что при `server_id=0`
>
> Бонусный баланс читается строго по переданному `server_id`: `0` — общий бонусный баланс, `5` — бонусный баланс сервера 5. Если бонусный баланс на проекте общий для всех серверов, передавайте `server_id=0`.

***

#### Кодировка

* Значения параметров передаются в кодировке UTF-8 и должны быть URL-кодированы, как и любые данные в query string.
* Символ `+` в email обязательно кодируйте как `%2B`: незакодированный `+` читается как пробел, и такой email не пройдёт проверку.
* Стандартные средства формирования query string кодируют значения автоматически: `URLSearchParams` в JavaScript, `http_build_query()` в PHP, `--data-urlencode` в cURL.

Ответ возвращается в формате JSON в кодировке UTF-8 с заголовком `Content-Type: application/json`.

***

### Примеры

**Все балансы по user\_id**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -G "https://api.mmoweb.biz/v2/master-account/balance" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  --data-urlencode "user_id=123" \
  --data-urlencode "server_id=5"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const params = new URLSearchParams({
  user_id: '123',
  server_id: '5'
});

fetch(`https://api.mmoweb.biz/v2/master-account/balance?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$url = 'https://api.mmoweb.biz/v2/master-account/balance?' . http_build_query([
  'user_id' => 123,
  'server_id' => 5
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

**Основной баланс по email**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -G "https://api.mmoweb.biz/v2/master-account/balance" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  --data-urlencode "email=user+promo@example.com" \
  --data-urlencode "balance_type=main" \
  --data-urlencode "server_id=0"
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const params = new URLSearchParams({
  email: 'user+promo@example.com',
  balance_type: 'main',
  server_id: '0'
});

fetch(`https://api.mmoweb.biz/v2/master-account/balance?${params}`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$url = 'https://api.mmoweb.biz/v2/master-account/balance?' . http_build_query([
  'email' => 'user+promo@example.com',
  'balance_type' => 'main',
  'server_id' => 0
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

### Ответы

**Успешный ответ (200 OK)**

Без `balance_type`:

```json
{
  "main_balance": 1500.5,
  "total_balance": 12000,
  "spent_balance": 10499.5,
  "bonus_balance": 250,
  "success": true
}
```

С `balance_type=main`:

```json
{
  "main_balance": 1500.5,
  "total_balance": 12000,
  "spent_balance": 10499.5,
  "success": true
}
```

С `balance_type=bonus`:

```json
{
  "bonus_balance": 250,
  "success": true
}
```

**Поля ответа:**

| Поле            | Тип    | Описание                                                                     |
| --------------- | ------ | ---------------------------------------------------------------------------- |
| `main_balance`  | number | Основной баланс — сумма, которую игрок может потратить                       |
| `total_balance` | number | Сумма пополнений за всё время. От неё зависит уровень скидки мастер-аккаунта |
| `spent_balance` | number | Сумма списаний за всё время                                                  |
| `bonus_balance` | number | Бонусный баланс. `0`, если бонусный баланс отключён в проекте                |
| `success`       | bool   | `true`                                                                       |

> Суммы возвращаются числами JSON без округления — с точностью хранения, до 3 знаков после точки: `1500.5`, `12000`, `0.125`. Если у аккаунта ещё нет баланса на сервере, возвращается `0`.

**Ошибка валидации (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "email": "The email field is required when user_id is not present.",
    "user_id": "The user_id field is required when email is not present."
  }
}
```

> **Когда встречается:**
>
> * не передан ни `user_id`, ни `email`;
> * `user_id` не является целым числом, `email` не является валидным адресом;
> * не передан `server_id` или он не является целым числом `≥ 0`;
> * `balance_type` не равен `main` или `bonus`.
>
> В `message` возвращается объект, где ключ — имя параметра, а значение — описание ошибки.

**Аккаунт не найден (404 Not Found)**

```json
{
  "success": false,
  "code": "USER_NOT_FOUND"
}
```

> **Когда встречается:** в проекте нет мастер-аккаунта с указанным `user_id` или `email`

**Сервер не найден (404 Not Found)**

```json
{
  "success": false,
  "code": "SERVER_NOT_FOUND"
}
```

> **Когда встречается:** сервер с указанным `server_id` не подключён к проекту или выключен

**Недостаточно прав (403 Forbidden)**

```json
{
  "success": false,
  "code": "ACCESS_DENIED"
}
```

> **Когда встречается:** у Application Token не включено разрешение `Получение балансов пользователя (v2)`

***

### Коды ошибок

| Код                | HTTP Status | Описание                                           | Что делать                                                                                   |
| ------------------ | ----------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR` | 400         | Параметры не переданы или не соответствуют формату | Исправьте параметры по разделу «Параметры»; описание ошибки — в `message`                    |
| `USER_NOT_FOUND`   | 404         | Аккаунт не найден в проекте                        | Проверьте `user_id` или `email`                                                              |
| `SERVER_NOT_FOUND` | 404         | Сервер не подключён к проекту или выключен         | Проверьте `server_id`                                                                        |
| `ACCESS_DENIED`    | 403         | У токена нет разрешения на этот endpoint           | Включите разрешение `Получение балансов пользователя (v2)` для ключа в панели администратора |

Ошибки аутентификации (`EMPTY_TOKEN`, `INVALID_TOKEN`, `TOKEN_NOT_FOUND`, `TOKEN_DISABLED`) общие для всех endpoint'ов API v2 и описаны в разделе [Аутентификация](https://docs.mmoweb.biz/rest-api/autentifikaciya).

***

### Важные особенности

**Что входит в основной баланс**

* `main_balance` — деньги на счету игрока. Растёт при пополнении, уменьшается при покупках.
* `total_balance` — сколько игрок пополнил за всё время. Растёт при пополнении и при зачислении на основной баланс через создание транзакций; при покупках не уменьшается.
* `spent_balance` — сколько игрок потратил с основного баланса за всё время.

Все три значения можно установить напрямую через установку балансов.

**Только текущий проект**

Токен привязан к одному проекту. Endpoint возвращает балансы только мастер-аккаунтов и серверов этого проекта, параметра для выбора проекта нет.

***

### Рекомендации

**Безопасность:**

* Храните Application Token на сервере и никогда не передавайте его в браузер или мобильное приложение
* Используйте HTTPS для всех запросов

**Надёжность:**

* Обрабатывайте `USER_NOT_FOUND` как штатный результат, а не как сбой
* Реализуйте retry logic с экспоненциальной задержкой при ошибках 5xx и сетевых сбоях

**Интеграция:**

* Разбирайте суммы как десятичные числа и округляйте до 3 знаков после точки при выводе
* Передавайте `balance_type`, если нужен только один тип баланса
* Предпочитайте поиск по `user_id`: он однозначен и не зависит от формата email
* Убедитесь, что токен приложения имеет разрешение `Получение балансов пользователя (v2)`


# Управление балансом

### О транзакциях

Управление балансом мастер-аккаунта происходит через **транзакции**. Каждая транзакция — это одна операция по изменению баланса пользователя. Все транзакции логируются и сохраняются в системе для аудита.

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

* Если транзакция валидна и успешна — она выполняется и баланс изменяется
* Если транзакция имеет ошибку (пользователь не найден, недостаточно средств и т.д.) — она не выполняется
* Остальные транзакции в запросе продолжают обрабатываться независимо от ошибок в других

Это означает, что в одном запросе некоторые транзакции могут пройти успешно, а некоторые — не пройти. В этом случае возвращается код `PARTIAL_FAILURE`

**Типы операций:**

* `credit` — пополнение баланса
* `debit` — снятие с баланса

**Типы баланса:**

* `main` — основной баланс
* `bonus` — бонусный баланс (требуется плагин: бонусный баланс)

***

### Описание

Endpoint позволяет создавать транзакции для изменения баланса мастер-аккаунта. Можно обрабатывать до 50 транзакций в одном запросе.

Все операции логируются. Если хотя бы одна из них не прошла, возвращается статус `422` с кодом `PARTIAL_FAILURE`, но успешные транзакции остаются в системе.

***

### Endpoint

```
POST https://api.mmoweb.biz/v2/master-account/balance/transaction/create
```

**Content-Type:** `application/json`

***

### Структура запроса

Запрос содержит массив `transactions`, каждый элемент которого описывает одну операцию:

```json
{
  "transactions": [
    {
      "transaction_type": "credit",
      "balance_type": "main",
      "amount": "100.50",
      "user_id": 123,
      "server_id": 1
    }
  ]
}
```

***

### Параметры

#### Общие параметры

| Параметр       | Тип   | Описание                                 |
| -------------- | ----- | ---------------------------------------- |
| `transactions` | array | Массив транзакций. Максимум 50 элементов |

#### Параметры каждой транзакции

<table data-search="false"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязателен</th><th>Описание</th></tr></thead><tbody><tr><td><code>transaction_type</code></td><td>string</td><td>Да</td><td><code>credit</code> (пополнение) или <code>debit</code> (снятие)</td></tr><tr><td><code>balance_type</code></td><td>string</td><td>Да</td><td><code>main</code> (основной) или <code>bonus</code> (бонусный)</td></tr><tr><td><code>amount</code></td><td>number</td><td>Да</td><td>Сумма операции. Должна быть > 0</td></tr><tr><td><code>user_id</code></td><td>integer</td><td>Да*</td><td>Идентификатор пользователя</td></tr><tr><td><code>email</code></td><td>string</td><td>Да*</td><td>Email пользователя</td></tr><tr><td><code>server_id</code></td><td>integer</td><td>Да</td><td>Идентификатор сервера или <code>0</code> для общего баланса</td></tr><tr><td><code>lifetime</code></td><td>integer</td><td>Нет</td><td>Время жизни бонусов в часах. Только для <code>balance_type=bonus</code></td></tr></tbody></table>

\*Необходимо передать либо `user_id`, либо `email`

> **На что влияет server\_id:**
>
> * `server_id=0` — операция с **общим балансом** мастер-аккаунта
> * `server_id > 0` — операция с **балансом на конкретном сервере**

***

### Примеры

#### Пополнить основной баланс

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/master-account/balance/transaction/create" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      {
        "transaction_type": "credit",
        "balance_type": "main",
        "amount": "500.00",
        "user_id": 123,
        "server_id": 0
      }
    ]
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const transactions = [
  {
    transaction_type: 'credit',
    balance_type: 'main',
    amount: '500.00',
    user_id: 123,
    server_id: 0
  }
];

fetch('https://api.mmoweb.biz/v2/master-account/balance/transaction/create', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ transactions })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/master-account/balance/transaction/create';

$transactions = [
  [
    'transaction_type' => 'credit',
    'balance_type' => 'main',
    'amount' => '500.00',
    'user_id' => 123,
    'server_id' => 0
  ]
];

$payload = json_encode(['transactions' => $transactions]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

#### Пополнить бонусный сервера (со сроком действия бонусов)

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/master-account/balance/transaction/create" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      {
        "transaction_type": "credit",
        "balance_type": "bonus",
        "amount": "100.00",
        "email": "user@example.com",
        "server_id": 2,
        "lifetime": 24
      }
    ]
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const transactions = [
  {
    transaction_type: 'credit',
    balance_type: 'bonus',
    amount: '100.00',
    email: 'user@example.com',
    server_id: 2,
    lifetime: 24
  }
];

fetch('https://api.mmoweb.biz/v2/master-account/balance/transaction/create', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ transactions })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/master-account/balance/transaction/create';

$transactions = [
  [
    'transaction_type' => 'credit',
    'balance_type' => 'bonus',
    'amount' => '100.00',
    'email' => 'user@example.com',
    'server_id' => 2,
    'lifetime' => 24
  ]
];

$payload = json_encode(['transactions' => $transactions]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

#### Пакетная операция с несколькими пользователями

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/master-account/balance/transaction/create" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      {
        "transaction_type": "credit",
        "balance_type": "main",
        "amount": "100.00",
        "user_id": 123,
        "server_id": 1
      },
      {
        "transaction_type": "debit",
        "balance_type": "main",
        "amount": "50.00",
        "email": "player@example.com",
        "server_id": 1
      },
      {
        "transaction_type": "credit",
        "balance_type": "bonus",
        "amount": "250.00",
        "user_id": 456,
        "server_id": 0,
        "lifetime": 48
      }
    ]
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const transactions = [
  {
    transaction_type: 'credit',
    balance_type: 'main',
    amount: '100.00',
    user_id: 123,
    server_id: 1
  },
  {
    transaction_type: 'debit',
    balance_type: 'main',
    amount: '50.00',
    email: 'player@example.com',
    server_id: 1
  },
  {
    transaction_type: 'credit',
    balance_type: 'bonus',
    amount: '250.00',
    user_id: 456,
    server_id: 0,
    lifetime: 48
  }
];

fetch('https://api.mmoweb.biz/v2/master-account/balance/transaction/create', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ transactions })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/master-account/balance/transaction/create';

$transactions = [
  [
    'transaction_type' => 'credit',
    'balance_type' => 'main',
    'amount' => '100.00',
    'user_id' => 123,
    'server_id' => 1
  ],
  [
    'transaction_type' => 'debit',
    'balance_type' => 'main',
    'amount' => '50.00',
    'email' => 'player@example.com',
    'server_id' => 1
  ],
  [
    'transaction_type' => 'credit',
    'balance_type' => 'bonus',
    'amount' => '250.00',
    'user_id' => 456,
    'server_id' => 0,
    'lifetime' => 48
  ]
];

$payload = json_encode(['transactions' => $transactions]);

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

### Ответы

#### Все транзакции успешны (200 OK)

```json
{
  "success": true,
  "transactions": [
    {
      "index": 0,
      "success": true,
      "balance_type": "main",
      "transaction_type": "credit",
      "amount": "100.50",
      "balance_before": "500.00",
      "balance_after": "600.50",
      "lifetime": null
    },
    {
      "index": 1,
      "success": true,
      "balance_type": "bonus",
      "transaction_type": "credit",
      "amount": "250.00",
      "balance_before": "1000.00",
      "balance_after": "1250.00",
      "lifetime": 24
    }
  ]
}
```

#### Часть транзакций не прошла (422 Unprocessable Entity)

```json
{
  "success": false,
  "code": "PARTIAL_FAILURE",
  "transactions": [
    {
      "index": 0,
      "success": true,
      "balance_type": "main",
      "transaction_type": "credit",
      "amount": "100.00",
      "balance_before": "500.00",
      "balance_after": "600.00",
      "lifetime": null
    },
    {
      "index": 1,
      "success": false,
      "code": "INSUFFICIENT_FUNDS",
      "balance_type": "main",
      "transaction_type": "debit",
      "balance_before": "250.00"
    },
    {
      "index": 2,
      "success": false,
      "code": "USER_NOT_FOUND",
      "balance_type": "bonus"
    }
  ]
}
```

#### Ошибка валидации (400 Bad Request)

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "transactions.0.amount": "Amount field must contain a number."
  }
}
```

#### Слишком много транзакций (400 Bad Request)

```json
{
  "success": false,
  "code": "BATCH_TOO_LARGE",
  "message": "Maximum 50 transactions per request"
}
```

***

### Коды ошибок

#### На уровне запроса (HTTP 400)

| Код                | Описание                                  | Решение                                                  |
| ------------------ | ----------------------------------------- | -------------------------------------------------------- |
| `VALIDATION_ERROR` | Ошибка в структуре или параметрах запроса | Проверьте формат JSON и обязательные поля                |
| `BATCH_TOO_LARGE`  | Передано более 50 транзакций              | Разделите запрос на несколько с максимум 50 транзакциями |

#### На уровне отдельной транзакции

| Код                      | HTTP Status | Описание                          | Когда встречается                                                                |
| ------------------------ | ----------- | --------------------------------- | -------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`       | 422         | Проблемы с параметрами транзакции | `amount <= 0`, отсутствуют `user_id` и `email`                                   |
| `SERVER_NOT_FOUND`       | 422         | Сервер не найден                  | Передан `server_id > 0`, но такого сервера нет в системе                         |
| `USER_NOT_FOUND`         | 422         | Пользователь не найден            | Пользователь с указанным `user_id` или `email` не существует                     |
| `BONUS_BALANCE_DISABLED` | 422         | Бонусный баланс отключен          | Попытка операции с `balance_type=bonus`, но бонусный баланс отключен для проекта |
| `INSUFFICIENT_FUNDS`     | 422         | Недостаточно средств              | Попытка снять (`debit`) больше, чем есть на балансе                              |

#### Общий результат

| Код               | HTTP Status | Описание                                                            |
| ----------------- | ----------- | ------------------------------------------------------------------- |
| `success: true`   | 200         | Все транзакции выполнены успешно                                    |
| `PARTIAL_FAILURE` | 422         | Некоторые транзакции не прошли, результаты в массиве `transactions` |

***

### Особенности и рекомендации

#### Бонусный баланс (`bonus`)

* Может быть отключен/не приобретен модуль на уровне проекта — в этом случае любая операция вернет `BONUS_BALANCE_DISABLED`
* При `credit` (пополнении) можно указать `lifetime` в часах (автоматически истекут через указанное время)
* Если `lifetime` не указан, бонусы остаются неограниченными по времени

#### Обработка результатов

* **Каждая транзакция имеет свой `index`** — используйте его для маппинга результатов на исходные данные
* **Если `success: false` на уровне запроса**, проверьте код ошибки и структуру
* **Если `PARTIAL_FAILURE`**, обработайте каждый результат отдельно
* **Балансы в ответе — это строки** для сохранения точности при работе с дробными числами

#### Пакетная обработка

* Максимум 50 транзакций за раз
* Проверка серверов кэшируется в рамках одного запроса (если несколько транзакций на один `server_id`, проверка происходит один раз)
* Если в одном запросе разные `server_id`, каждый проверяется отдельно

***

### Примечания

* Все операции логируются на платформе с полной информацией (пользователь, сумма, тип операции, источник)
* `lifetime` применяется только к бонусному балансу и отсчитывается от момента получения
* Используйте `server_id=0` для работы с общим балансом, независимо от конкретного сервера


# Редактирование баланса

### Описание

Endpoint устанавливает балансы мастер-аккаунта на конкретные значения: основной баланс, сумму пополнений и сумму списаний. Вы передаёте итоговое значение, а не сумму изменения.

Этим он отличается от создания [транзакций](/rest-api/master-akkaunt/balans/upravlenie-balansom). Транзакция прибавляет или списывает сумму, а зачисление на основной баланс ещё и увеличивает сумму пополнений. Редактирование баланса ничего не прибавляет и не списывает: в каждом переданном поле оказывается ровно то значение, которое вы указали.

Вы можете использовать данный endpoint для:

* Переноса балансов игроков из другой системы
* Исправления ошибочно начисленных или списанных сумм
* Корректировки суммы пополнений, от которой зависит уровень скидки игрока
* Синхронизации балансов с внешним биллингом

{% hint style="info" %}
Endpoint меняет деньги игроков без проверок и ограничений по сумме. Выдавайте право `Установка балансов пользователя (v2)` только ключам, которым оно действительно необходимо, и храните такой ключ отдельно от остальных.
{% endhint %}

***

### Endpoint

```
POST https://api.mmoweb.biz/v2/master-account/balance
```

**Content-Type:** `application/json`

**Требуемое разрешение ключа:** `Установка балансов пользователя (v2)`

***

### Параметры

Все параметры передаются в JSON теле запроса. Нужно передать идентификатор аккаунта, `server_id` и **хотя бы одно** из полей баланса.

| Параметр        | Тип              | Обязателен                    | Формат                                                  | Описание                                               |
| --------------- | ---------------- | ----------------------------- | ------------------------------------------------------- | ------------------------------------------------------ |
| `user_id`       | integer          | Да, если не передан `email`   | Целое число `≥ 1`                                       | Идентификатор мастер-аккаунта                          |
| `email`         | string           | Да, если не передан `user_id` | Валидный email                                          | Email мастер-аккаунта                                  |
| `server_id`     | integer          | Да                            | Целое число `≥ 0`                                       | Игровой сервер, баланс которого устанавливается        |
| `main_balance`  | string \| number | Нет\*                         | От `0` до `9999999.999`, не больше 3 знаков после точки | Основной баланс — сумма, которую игрок может потратить |
| `total_balance` | string \| number | Нет\*                         | От `0` до `9999999.999`, не больше 3 знаков после точки | Сумма пополнений за всё время                          |
| `spent_balance` | string \| number | Нет\*                         | От `0` до `9999999.999`, не больше 3 знаков после точки | Сумма списаний за всё время                            |

\* Хотя бы одно из полей `main_balance`, `total_balance`, `spent_balance` обязательно. Меняются только переданные поля, остальные остаются как были.

> **Приоритет идентификаторов.** Если переданы и `user_id`, и `email`, поиск выполняется по `user_id`.

> **Формат сумм.** Передавайте суммы строкой: `"850.125"`. Числа JSON (`850.125`) тоже принимаются, но строка исключает искажения при сериализации float на вашей стороне. Суммы не округляются: значение с четырьмя и более знаками после точки отклоняется с `VALIDATION_ERROR`. Не принимаются отрицательные значения, `null`, экспоненциальная запись (`1e3`), запятая вместо точки и пробелы.

> **Сервер и общий баланс.** Если на сервере включён общий баланс проекта, значение записывается в общий баланс — тот же, что возвращает [получение баланса](https://docs.mmoweb.biz/rest-api/master-akkaunt/balans/poluchenie-balansa) с этим `server_id`. `server_id = 0` — общий баланс проекта напрямую. Передавайте `server_id` только в теле запроса. Если он есть и в строке запроса, значения должны совпадать, иначе запрос отклоняется с `VALIDATION_ERROR`.

***

### Примеры

#### Установка суммы списаний

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/master-account/balance" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 123,
    "server_id": 5,
    "spent_balance": "850.125"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  user_id: 123,
  server_id: 5,
  spent_balance: '850.125'
};

fetch('https://api.mmoweb.biz/v2/master-account/balance', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$payload = [
  'user_id' => 123,
  'server_id' => 5,
  'spent_balance' => '850.125'
];

$ch = curl_init('https://api.mmoweb.biz/v2/master-account/balance');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

#### Установка нескольких балансов по email

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/master-account/balance" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "server_id": 0,
    "main_balance": "150.5",
    "total_balance": "1000"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  email: 'user@example.com',
  server_id: 0,
  main_balance: '150.5',
  total_balance: '1000'
};

fetch('https://api.mmoweb.biz/v2/master-account/balance', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';

$payload = [
  'email' => 'user@example.com',
  'server_id' => 0,
  'main_balance' => '150.5',
  'total_balance' => '1000'
];

$ch = curl_init('https://api.mmoweb.biz/v2/master-account/balance');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

### Ответы

#### Успешный ответ (200 OK)

```json
{
  "success": true,
  "balances": {
    "main_balance": {
      "before": "100.000",
      "after": "150.500"
    },
    "total_balance": {
      "before": "1200.000",
      "after": "1000.000"
    }
  }
}
```

В `balances` возвращаются только поля, переданные в запросе, в порядке `main_balance` → `total_balance` → `spent_balance`.

**Поля каждого баланса:**

| Поле     | Тип    | Описание                                                                              |
| -------- | ------ | ------------------------------------------------------------------------------------- |
| `before` | string | Значение до установки. `"0.000"`, если у аккаунта ещё не было баланса на этом сервере |
| `after`  | string | Значение после установки — ровно то, что сохранено                                    |

> Суммы возвращаются строками с тремя знаками после точки, например `"150.500"`, чтобы исключить погрешности float при разборе ответа.

**Не передано ни одного баланса (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": "main_balance, total_balance or spent_balance is required"
}
```

> **Когда встречается:** в запросе нет ни одного из полей `main_balance`, `total_balance`, `spent_balance`

**Неверный формат параметра (400 Bad Request)**

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "spent_balance": "The spent_balance field must be a number from 0 to 9999999.999 with no more than 3 decimal places."
  }
}
```

> **Когда встречается:**
>
> * сумма вне диапазона, отрицательная, `null` или содержит больше 3 знаков после точки;
> * не передан ни `user_id`, ни `email`, либо они в неверном формате;
> * не передан `server_id`, он не является целым числом `≥ 0` или не совпадает с `server_id` в строке запроса;
> * тело запроса не является JSON-объектом.
>
> В `message` возвращается объект, где ключ — имя параметра, а значение — описание ошибки. Ошибки по всем параметрам возвращаются одним ответом.

**Аккаунт не найден (404 Not Found)**

```json
{
  "success": false,
  "code": "USER_NOT_FOUND"
}
```

> **Когда встречается:** в проекте нет мастер-аккаунта с указанным `user_id` или `email`

**Сервер не найден (404 Not Found)**

```json
{
  "success": false,
  "code": "SERVER_NOT_FOUND"
}
```

> **Когда встречается:** сервер с указанным `server_id` не подключён к проекту или выключен

**Недостаточно прав (403 Forbidden)**

```json
{
  "success": false,
  "code": "ACCESS_DENIED"
}
```

> **Когда встречается:** у Application Token не включено разрешение `Установка балансов пользователя (v2)`

**Ошибка записи (500 Internal Server Error)**

```json
{
  "success": false,
  "code": "UPDATE_FAILED"
}
```

> **Когда встречается:** балансы не удалось сохранить. Изменения при этом не применяются: ни одно поле не меняется, запись в историю не появляется. Запрос можно безопасно повторить

***

### Коды ошибок

| Код                | HTTP Status | Описание                                           | Что делать                                                                                   |
| ------------------ | ----------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR` | 400         | Параметры не переданы или не соответствуют формату | Исправьте параметры по разделу «Параметры»; описание ошибки — в `message`                    |
| `USER_NOT_FOUND`   | 404         | Аккаунт не найден в проекте                        | Проверьте `user_id` или `email`                                                              |
| `SERVER_NOT_FOUND` | 404         | Сервер не подключён к проекту или выключен         | Проверьте `server_id`                                                                        |
| `ACCESS_DENIED`    | 403         | У токена нет разрешения на этот endpoint           | Включите разрешение `Установка балансов пользователя (v2)` для ключа в панели администратора |
| `UPDATE_FAILED`    | 500         | Балансы не сохранены, изменения не применены       | Повторите запрос                                                                             |

Ошибки аутентификации (`EMPTY_TOKEN`, `INVALID_TOKEN`, `TOKEN_NOT_FOUND`, `TOKEN_DISABLED`) общие для всех endpoint'ов API v2 и описаны в разделе [Аутентификация](https://docs.mmoweb.biz/rest-api/autentifikaciya).

***

### Важные особенности

**Значение, а не изменение**

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

**Меняются только переданные поля**

Поле, которого нет в запросе, остаётся без изменений. Например, установка `spent_balance` не трогает основной баланс и сумму пополнений.

**Новый баланс создаётся автоматически**

Если у аккаунта ещё нет баланса на этом сервере, он создаётся. Поля, не переданные в запросе, получают значение `0`.

**История изменений**

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

**Что зависит от суммы пополнений**

`total_balance` — накопленная сумма пополнений игрока. Новое значение сразу учитывается там, где проект смотрит на эту сумму:

* уровень скидки мастер-аккаунта при покупках;
* условия доступности платёжных систем по сумме пополнений.

Прогресс Premium Club хранится отдельно и этим endpoint'ом не меняется. Чтобы учесть новую сумму пополнений, запустите «Синхронизацию накопления» в разделе Premium Club панели администратора. Синхронизация только повышает прогресс, понизить его через сумму пополнений нельзя.

**Одновременные операции игрока**

Покупка или пополнение, которые игрок совершает в тот же момент, могут перезаписать установленное значение: итог рассчитается от баланса до установки. Если точное значение важно, устанавливайте балансы, когда игрок не совершает операций, и сверяйте результат через [получение баланса](https://docs.mmoweb.biz/rest-api/master-akkaunt/balans/poluchenie-balansa).

**Только текущий проект**

Токен привязан к одному проекту. Endpoint работает только с мастер-аккаунтами и серверами этого проекта, параметра для выбора проекта нет.

***

### Рекомендации

**Безопасность:**

* Храните Application Token на сервере и никогда не передавайте его в браузер или мобильное приложение
* Заведите для установки балансов отдельный ключ и выдайте ему только это разрешение
* Используйте HTTPS для всех запросов

**Надёжность:**

* Передавайте суммы строками, чтобы значение не исказилось при сериализации
* При ошибках 5xx и сетевых сбоях повторяйте тот же запрос: результат не зависит от числа повторов
* Сохраняйте `before` и `after` из ответа в журнале своей системы

**Интеграция:**

* Перед установкой получите текущие значения через [получение баланса](https://docs.mmoweb.biz/rest-api/master-akkaunt/balans/poluchenie-balansa): так вы сможете показать оператору, что изменится
* Предпочитайте поиск по `user_id`: он однозначен и не зависит от формата email
* Убедитесь, что токен приложения имеет разрешение `Установка балансов пользователя (v2)`


# Платежи


# Завершение платежного ордера

### Описание

Endpoint используется для финализации платежного ордера и обработки платежа.&#x20;

При успешном завершении:

* Статус ордера изменяется на **завершённый**
* Баланс пользователя пополняется согласно сумме платежа
* Операция логируется в систему

Вы можете использовать данный endpoint для обработки вебхуков и колбеков от платежных шлюзов.

***

### Endpoint

```
POST https://api.mmoweb.biz/v2/payment/order/complete
```

**Content-Type:** `application/json`

***

### Параметры

Все параметры передаются в JSON теле запроса.

| Параметр         | Тип    | Обязателен | Формат                    | Описание                                                                 |
| ---------------- | ------ | ---------- | ------------------------- | ------------------------------------------------------------------------ |
| `payment_system` | string | Да         | `cstm:[a-z]{4,20}`        | Идентификатор платежной системы (например: `cstm:yandex`, `cstm:paypal`) |
| `order_id`       | string | Да         | `Order:[A-Za-z0-9]{8,11}` | Уникальный идентификатор ордера, выданный при создании                   |
| `payment_id`     | string | Нет        | Строчное значение         | ID платежа в платежной системе (используется для отслеживания)           |

> **Форматы параметров:**
>
> * `payment_system`: начинается с `cstm:`, за которым следуют 4-20 строчных букв (пример: `cstm:stripe`, `cstm:cryptobox`)
> * `order_id`: начинается с `Order:`, за которым следуют 8-11 буквенно-цифровых символов (пример: `Order:abc12345`)

***

### Примеры

#### Базовое завершение платежа

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/payment/order/complete" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_system": "cstm:yandex",
    "order_id": "Order:abc12345",
    "payment_id": "yandex_payment_123456"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  payment_system: 'cstm:yandex',
  order_id: 'Order:abc12345',
  payment_id: 'yandex_payment_123456'
};

fetch('https://api.mmoweb.biz/v2/payment/order/complete', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/payment/order/complete';

$payload = [
  'payment_system' => 'cstm:yandex',
  'order_id' => 'Order:abc12345',
  'payment_id' => 'yandex_payment_123456'
];

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

#### Завершение платежа без payment\_id

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.mmoweb.biz/v2/payment/order/complete" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_system": "cstm:paypal",
    "order_id": "Order:xyz98765"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  payment_system: 'cstm:paypal',
  order_id: 'Order:xyz98765'
};

fetch('https://api.mmoweb.biz/v2/payment/order/complete', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/payment/order/complete';

$payload = [
  'payment_system' => 'cstm:paypal',
  'order_id' => 'Order:xyz98765'
];

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

### Ответы

#### Успешное завершение (200 OK)

```json
{
  "success": true,
  "code": "PAYMENT_PROCESSED",
  "message": "Payment processed successfully",
  "order": {
    "id": 12345,
    "mid": 789,
    "sid": 2,
    "pid": 1,
    "team": 1,
    "order_id": "Order:abc12345",
    "payment_system": "cstm:yandex",
    "amount": "500.00",
    "currency": "RUB",
    "status": 1,
    "date_create": "2026-08-05 10:30:00",
    "date_complete": "2026-08-05 10:32:15",
    "payment_id": "yandex_payment_123456",
    "custom_data": null
  }
}
```

#### Ошибка валидации параметров (400 Bad Request)

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "payment_system": "payment_system field must match the regex pattern cstm:[a-z]{4,20}",
    "order_id": "order_id field must match the regex pattern Order:[A-Za-z0-9]{8,11}"
  }
}
```

#### Ордер не найден (404 Not Found)

```json
{
  "success": false,
  "code": "ORDER_NOT_FOUND",
  "message": "Order not found"
}
```

> **Когда встречается:** ордер не существует, не принадлежит текущему проекту/команде или платежная система не совпадает

#### Ордер уже завершен (409 Conflict)

```json
{
  "success": false,
  "code": "ORDER_ALREADY_COMPLETED",
  "message": "Order has already been completed"
}
```

#### Ошибка обновления статуса (500 Internal Server Error)

```json
{
  "success": false,
  "code": "ORDER_UPDATE_FAILED",
  "message": "Failed to update order status"
}
```

#### Ошибка при обработке платежа (зависит от конкретной ошибки)

```json
{
  "success": false,
  "code": "PAYMENT_PROCESSING_ERROR",
  "message": "An error occurred while processing the payment"
}
```

***

### Коды ошибок

| Код                        | HTTP Status | Описание                                                                       | Что делать                                                                        |
| -------------------------- | ----------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`         | 400         | Один или несколько параметров не соответствуют формату                         | Проверьте формат `payment_system` и `order_id` согласно спецификации              |
| `ORDER_NOT_FOUND`          | 404         | Ордер не существует, не принадлежит проекту или платежная система не совпадает | Убедитесь что используете правильный `order_id` и `payment_system`                |
| `ORDER_ALREADY_COMPLETED`  | 409         | Этот ордер уже был завершен                                                    | Дублированная обработка вебхука; это нормально — повторно завершение не требуется |
| `ORDER_UPDATE_FAILED`      | 500         | Ошибка при обновлении статуса в БД                                             | Повторите попытку позже; если ошибка повторяется, свяжитесь с поддержкой          |
| `PAYMENT_PROCESSING_ERROR` | Переменный  | Ошибка при обработке платежа в системе                                         | Проверьте логи; платеж может быть обработан, но сообщение не отправлено           |

***

### Поток обработки платежа

1. **Получение вебхука** — платежная система отправляет колбек на ваш сервер
2. **Вызов API** — ваш сервер вызывает этот endpoint с данными платежа
3. **Валидация** — проверяется формат параметров и существование ордера
4. **Обновление статуса** — статус ордера изменяется на завершённый
5. **Обработка платежа** — платеж обрабатывается (зачисление на баланс и т.д.)
6. **Логирование** — операция записывается в логи для аудита
7. **Ответ** — возвращается результат обработки

***

### Важные особенности

#### Идемпотентность

Если ордер уже завершен, endpoint вернет ошибку `ORDER_ALREADY_COMPLETED` (409). **Это нормальное поведение** и означает, что платеж уже был обработан. Не пересылайте запрос повторно.

#### Совпадение платежной системы

Параметр `payment_system` в запросе **должен совпадать** с платежной системой, которая была указана при создании ордера. Если системы не совпадают, ордер не будет найден.

#### Payment ID (опционально)

Параметр `payment_id` не обязателен, но рекомендуется передавать ID платежа из платежной системы для отслеживания и согласования.

#### Время обработки

После завершения ордера баланс пользователя пополняется немедленно. Убедитесь, что платеж действительно прошел в платежной системе перед вызовом этого endpoint'а.

***

### Рекомендации

**Безопасность:**&#x20;

* Проверяйте подпись вебхука от платежной системы перед вызовом API
* Убедитесь что `payment_system` соответствует вашей конфигурации
* Используйте HTTPS для всех запросов

**Надёжность:**

* Реализуйте retry logic с экспоненциальной задержкой при ошибках 5xx
* Сохраняйте полные логи всех вебхуков для отладки
* Обрабатывайте ответ `ORDER_ALREADY_COMPLETED` как успех (платеж уже обработан)

**Интеграция:**

* Тестируйте с тестовыми платежами перед запуском в production
* Проверяйте что все параметры имеют правильный формат
* Убедитесь что токен приложения имеет необходимые разрешения


# Api v1

Controllers/Api.php


# Globals


# User


# Settings


# Payment


# Warehouse


# Statistic


# Vote


# Plugins


# Shop


# Service


# Bonus cod


# Support


# Manager


# Main

### What MmoWeb can offer to you:

* This is a completely thought out personal account for the user, which has a 8-year history of development.&#x20;
* We took into account all possible desires of users, simplified the interface as much as possible. However, this does not mean that the personal account interface is simple and there are no features that distinguish it from other available CMS.&#x20;
* This means that the interface has become more intuitive, with an increased number of functions and capabilities.

### CMS MmoWeb consists of two parts:&#x20;

* Site management;&#x20;
* Personal account management.

### Section \[Site Management]

#### The CMS of the Site includes modules necessary for any project, such as:&#x20;

* Multilingual;&#x20;
* Server status (information about the state of the server on the site);&#x20;
* Recent topics from the forum;&#x20;
* News on the site;&#x20;
* Player statistics;&#x20;
* Live broadcasts;&#x20;
* IBlock - for displaying any information in the form of sliders, etc.&#x20;

Static pages for the site and for the office. All modules are controlled through the built-in admin panel in the CMS MmoWeb, have easy extensibility if necessary (by contacting technical support).

The site template system deserves special attention: **Now ANYONE CAN ADAPT THEIR DESIGN BY ITSELF** by reading the documentation and looking at the examples in the default template supplied in the kit.

### Section \[Manage Personal Account]&#x20;

For the convenience of users, the administrative panel of MmoWeb has been redesigned! Now it has a nice design and a well-thought-out structure + search (you won't get lost among the settings).

**You can put MmoWeb in 4 quickly and easily:**&#x20;

* each step of the installation is described in the user manual with examples and pictures;&#x20;
* the installation begins with registration and proceeds to creating a connection to the login server, then to the game server and the project, with the further connection of the newly created servers to the project.&#x20;

For those who have never used the MmoWeb system, migrating your own CMS to MmoWeb will be painless, all game accounts will successfully connect to the newly created master user accounts after confirming the mail.

For those who already use MmoWeb v.3 or other CMS, where there are balances and other monetary systems, **we can organize migration (through contacting technical support), without losing data**. More details can be found by contacts:

### How much does it cost?&#x20;

MmoWeb 4 has a very flexible pricing policy.&#x20;

**The minimum monthly payment is $ 25.**&#x20;

We consider this amount to be extremely low for a stable CMS + round-the-clock tech. support.

Also in MmoWeb there are plugins, buying which you will expand the functionality of both the admin panel and the personal account for users.

### Plugin List:&#x20;

* Bonus codes plugin;&#x20;
* Shop + Services plugin;&#x20;
* Technical support for users plugin;&#x20;
* Multi-account plugin;&#x20;
* Registration analytics plugin.&#x20;
* (The list of plugins will continue to grow!)

**Personal account for players:**&#x20;

* Master account registration \[optional]&#x20;
* Registration by email&#x20;
* Registration by phone&#x20;

(With or without creating a game account, with or without a prefix - it's up to you).

* **Authorization \[optional]**&#x20;
  * By email&#x20;
  * By phone&#x20;
  * Through social media&#x20;
  * Password recovery \[optional]&#x20;
    * By email&#x20;
    * By phone
* **Unauthorized user pages. \[optional]**&#x20;
  * Shop - with the ability to buy for a game character or for a personal warehouse in the master account;
  * Donations - with the ability to buy per character;
  * Player stats.
* Authorized User Pages&#x20;
  * MAIN&#x20;
  * Displaying all game accounts with characters on them&#x20;
  * Displaying information on the master account with quick links to settings
  * Balance display&#x20;
  * Warehouse display&#x20;
  * Displaying the Discount System
  * Add. widget from the store with promotions for the product
* **Rating (statistics)**
  * Top PVP
  * Top PC
  * Top EXP
  * Top Clan
  * Top Clan PVP
  * Top Alliance
  * Castle
  * Clan halls
  * total stats
  * Online history
* **Store \[plugin]**
  * Product display
  * Service Display
* **Technical support**
  * List of appeals
  * Interface for creating a new case
* **Balance**
  * Donation form with the calculation of all bonuses to the payment.
  * Available systems:&#x20;

    * g2a&#x20;
    * unitpay&#x20;
    * payu&#x20;
    * paypal&#x20;
    * payop&#x20;
    * paymentwall&#x20;
    * pagseguro&#x20;
    * nextpay&#x20;
    * paygol&#x20;
    * alikassa&#x20;
    * enot

    (The list will expand)&#x20;
* **Settings:**

  * Master account management&#x20;
  * Multi-account management \[plugin]&#x20;
  * Hidden game accounts&#x20;
  * User logs

## MMOWEB service consists of 3 related subsystems:

1. Admin panel - for managing your projects and game servers.&#x20;
2. REST API - interacts with your game database&#x20;
3. The web part (client part) is the CMS that you install on your website:

   1. (Public side of your webside) - there is a default template&#x20;
   2. Personal account - for the player to manage the master account&#x20;
   3. Admin panel - site management

   <figure><img src="https://926669381-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1972196547%2Fuploads%2FZaG8aaUJeWUOLeTb5JE1%2Fimage.png?alt=media&amp;token=6082f8f7-4258-4abf-8fc7-11c76fe23770" alt=""><figcaption></figcaption></figure>


# Quick start guide

От А до Я


# Registration

Registration your own personal account in MMOWEB panel

First of all you should register your personal account.

To do this, follow steps:

* specify all required fields:

<figure><img src="https://926669381-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1972196547%2Fuploads%2FkF7OwK9MQV5slPV48LFd%2Fimage.png?alt=media&amp;token=c9a46fba-1db8-4593-a4bb-c5bea22101f1" alt=""><figcaption></figcaption></figure>

| Field         | Comments                                                  |
| ------------- | --------------------------------------------------------- |
| Team name     | The name of your game team                                |
| Game platform | Game project platform name                                |
| Nickname      | Your game nickname                                        |
| Login         | Your account login - your EMAIL                           |
| Password      | at leat 6 chars with latin letters and digits             |
| Accept terms  | Switching on this checkbox you will agree with our rules. |

**After registration you need to pay $50.**&#x20;

To do this, after registration, an url will be sent to your email to make a deposit of $50:

![Finally click the "Pay 30$..." button to make a deposit of $ 30](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCIBhWJGKW1FpxNcXb9%2F-MCINpkxucU0Sgath2UN%2Fpay.png?alt=media\&token=e4f45989-428c-46f8-b349-6d4eda1a76a7)

**Troubleshooting:**

* **Incorrect email specified during registration**

*In this case, simply re-register.*

* **Successful registration email has not been received**

*Either you entered an incorrect email address, or the letter ended up in the spam folder.*

* **The link to pay the deposit in the letter does not work.**&#x20;

*In this case, contact technical support, according to the contact details*&#x20;

*Don't forget to specify  your account email*&#x20;

* **The invoice has been paid, but the balance has not been replenished**

*In this case, contact technical support, according to the contact details*

*Don't forget to specify  your account email*&#x20;


# First payment

Making a deposit

After successful registration in the MMO system, you will receive a notification containing a link to pay your first deposit:

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCIBhWJGKW1FpxNcXb9%2F-MCINpkxucU0Sgath2UN%2Fpay.png?alt=media\&token=e4f45989-428c-46f8-b349-6d4eda1a76a7)

When you click on the payment link, you will be prompted to pay in one of several ways:

<figure><img src="https://926669381-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBKZbS5Cb7cxz5sHYKf-1972196547%2Fuploads%2F6QMhtAjjuGrQNHhjtsh1%2Fimage.png?alt=media&amp;token=82eac921-7cdd-43ee-9d47-638565b68f07" alt=""><figcaption></figcaption></figure>

Possible payment options:&#x20;

* bank cards;&#x20;
* electronic money;&#x20;
* payment from the balance of a cell phone.&#x20;

After successful payment, you will be able to log in to the MMO system using the login and password specified during registration.

**Troubleshooting:**&#x20;

in case of a problem in the process of making a deposit, send to the contact details of technical support:&#x20;

* login;&#x20;
* your transaction number;&#x20;
* error text or description of the problem.


# Balance replenishment

Replenish you balance

To replenish your balance, follow these steps: ‌&#x20;

1. Log in to the control panel
2. Go to the balance replenishment page
3. In the field "Replenish balance by" specify the required amount:

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCw0hJjwY4M4tA1bQ9l%2F-MCw1psHx8X0wkPqzHd1%2Freplenish_eng.png?alt=media\&token=5093596d-9a38-4790-986e-23fafeb5fd4b)

4\. Click the Next button ‌

Then follow the payment instructions, similar to the First payment guide.

After successful replenishment of the balance on your account, in the "Balance" field, the completed payment will be reflected - your balance will increase by the amount of payment you made.

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCw0hJjwY4M4tA1bQ9l%2F-MCw31585BaKl5SLnfKb%2Fbalance_eng.png?alt=media\&token=fdedd48e-b318-40d5-88b9-2e3333ff386c)


# Tariff purchase

Choose and purchase your tariff

After successful registration and replenishment of the balance, your account will have $ 3&#x30;**.**

In order to start using your personal account, you need to select a tariff.&#x20;

Further, when you have chosen which tariff suits you, make sure that there are enough funds on the balance to pay for the monthly tariff.&#x20;

{% hint style="warning" %}
ATTENTION!&#x20;

If there is not enough money on the balance to pay for the selected tariff (for the period), then the balance must be replenished.
{% endhint %}

Now you can choose your tariff:

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MCw3SqY68Srq4PfINpp%2F-MCw50gsv43Mml4SZBy3%2Ftariff%20select.png?alt=media\&token=f8d4bf65-70ac-49c0-834d-c13dcfdb3ebe)

For this:

1. Сlick on the "GetStarted" button
2. In the window that opens, select the period of using the tariff
3. Click the "BUY" button

![Tariff purchase form](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBORF3iL1Rdb_Fnxwxp%2F-MBORhCGciQGkWxNYrvl%2Fimage.png?alt=media\&token=c3dc0552-e0a1-4291-bdfd-4d11b11fdd15)

{% hint style="warning" %}
ATTENTION!&#x20;

When paying for a tariff for more than 3 months, you get a discount:
{% endhint %}

| Period of tariff activity | Discount |
| ------------------------- | -------- |
| From 3 to 5 months        | 5%       |
| 5 months                  | 6%       |
| From 6 to 10 months       | 7%       |
| 10 months                 | 8%       |
| 11 months                 | 9%       |
| 12 months                 | 10%      |

After purchasing the tariff, you will be able to connect to the server login setting.


# Settings

Первичная настройка проекта


# 1. Login servers

Login-server connection setup

You can create a connection to the login server in the Projects -> Login Server

1\. Click on the "Add server login" button

2\. Choose a gaming platform from the available ones

{% hint style="warning" %}
ATTENTION! If the gaming platform you need is not among the available platforms, please report it to the technical support contact information:
{% endhint %}

3\. After choosing a gaming platform, fill in the login server settings:

There will be 3 tabs available for filling: `Basic`, `Database` and `Ports`

**DATABASE**

To connect to the login server database, fill in the following fields:

|  №  | Field title    | Description                                                       |
| :-: | -------------- | ----------------------------------------------------------------- |
|  1  | Database type  | Login Server Database Type (depends on the server build provider) |
|  2  | Database host  | database address IP                                               |
|  3  | Database name  | Name of the database on the login-server                          |
|  4  | Enter login    | login for authorization in the database                           |
|  5  | Enter password | Password for authorization in the database                        |

**PORTS**

Specify the IP and port to access the login server. Using user root in mysql or sa in mssql is not safe!

**4.** Click "SUBMIT"

After filling in all the data and creating a new login, the server will appear in the section "Login servers"

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MDDsZ0_kV8JGW5WwHIN%2F-MDDvGKcP6Nu-ZiBSuO3%2Fp4.png?alt=media\&token=b76b2e80-fcea-4c8a-8256-4fc4d02a851f)

After your login server appears in the server list, you can check the server availability from the MMO system.&#x20;

To do this, click on the "Check connection" button

!["Check connection" button](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MBKwsGVUL71c4u9Jj9Y%2F-MBL-C8mhRQXbxbhhhOo%2Fimage.png?alt=media\&token=c9f34635-6b80-406f-80fd-1c52d9186cf1)

A window with status information will open:

![](https://926669381-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MBKZbS5Cb7cxz5sHYKf%2F-MDDsZ0_kV8JGW5WwHIN%2F-MDDwUX0bVOeZ3rvOBgc%2Fp5.png?alt=media\&token=f5f0697d-a89e-49c8-9ea7-19e722647b49)

If there are no connection errors, the status will be OK for all rows.

If there are some errors, the error text will be shown.&#x20;

If there are some error messages in the above window and you do not know what to do with them, contact technical support, indicating your MMO account and the name of the login server




---

[Next Page](https://docs.mmoweb.biz/llms-full.txt/1)

