Comepay-Кошелек. API для оплат - Описание протокола. V1.1.2

Страница создана Дарья Сорокина
 
ПРОДОЛЖИТЬ ЧТЕНИЕ
Comepay-Кошелек. API для оплат - Описание протокола. V1.1.2
Comepay-Кошелек. API для оплат.
     Описание протокола. V1.1.2

                                  1
Содержание
1. Введение

      1.1 Назначение API
      1.2 Технические моменты при работе с API
      1.3 Способы передачи параметров
             1.3.1 Query String
             1.3.2 POST параметры
             1.3.3 JSON
             1.3.4 XML

2. Интерфейс выставления счетов

      2.1 Создание запроса
      2.2 Запрос на получение статуса выставленного счета
      2.3 Перенаправление при оплате счета
      2.4 Отмена неоплаченного счета
      2.5 Возвраты
      2.6 Получение статуса запроса на возврат
      2.7 Ответ сервера

3. Интерфейс клиента

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

      4.1 Авторизация запроса к ComePay
      4.2 Авторизация запроса к интерфейсу клиента

5. Логика реализации

6. Приложения

      6.1 Статус запроса
      6.2 Статус платежа
      6.3 Коды ошибок
      6.4 Коды уведомлений

                                                            2
1. Введение
1.1 Назначение API
Данное API предназначено для интернет-магазинов, или провайдеров, для которых есть
необходимость в реализации интерфейса оплаты счетов на собственных сайтах. В
дальнейшем, в документе, реализующая сторона именуется «Агент».

1.2 Технические моменты при работе с API
Для работы с API Агенту необходимо зарегистрировать в системе ComePay Кошелек аккаунт
интернет-магазина. Регистрация доступна по адресу https://shop.comepay.ru/Account/Register.
После регистрации в системе у Агента появится возможность войти в личный кабинет
интернет-магазина с помощью данных, которые будут высланы SMS сообщением на номер
мобильного телефона, указанный в анкете. После проверки регистрационных данных
администратором системы ComePay Кошелек, ваш аккаунт будет активирован, и вы сможете
выставлять счета.

Для тестирования API развернут тестовый сервер по адресу https://moneytest.comepay.ru:439.
Для работы с тестовым сервером требуется отдельная регистрация. Заказы и данные на
рабочем и тестовом серверах независимы друг от друга, и не будут перенесены с одного
сервера на другой.

Кошелек ComePay использует номер мобильного телефона, как уникальный идентификатор
пользователя кошелька. Если по заданному номеру клиента кошелек в системе ComePay
найден не будет, регистрация нового кошелька будет произведена автоматически. При
необходимости платежные пароли и данные для входа пользователей отсылаются по СМС.

Пользователи могут осуществлять платежи со своего баланса при помощи терминалов
ComePay, кредитных карт, привязанных кредитных карт, [мобильных счетов]. Оплата счетов
клиентом возможна через основной сайт https://money.comepay.ru, через мобильные
приложения: https://play.google.com/store/apps/details?id=ru.comepay и
https://itunes.apple.com/us/app/comepay-wallet/id866025468?ls=1&mt=8; и через сеть
терминалов Comepay.
API предоставляет возможность перенаправлять клиента с платформы Агента на страницу
оплаты счета в системе Comepay сразу после успешного выставления счета.

Взаимодействие платформы ComePay и платформы Агента осуществляется посредством
HTTP протокола.

Платформа Агента осуществляет запрос к платформе ComePay посредством передачи
параметров через HTTP-запрос. Возвращаемые данные могут быть двух видов, в

                                                                                             3
зависимости от значения заголовка «Accept» HTTP – запроса:

   •   JSON (значение заголовка «Accept»: «application/json», «text/json»)
   •   XML (значение заголовка «Accept»: «application/xml», «text/xml»)

По умолчанию возвращается ответ в json-формате.

Все запросы осуществляются с использованием «application/x-www-form-urlencoded» для
«content type».

Для обеспечения приватности все передаваемые данные шифруются согласно SSL протокола.
SSL также должен быть использован для передачи данных на строну платформы Агента.

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

                                                                                        4
1.3 Способы передачи параметров.

1.3.1 Query String

Параметры передаются строкой вида query string, одним безымянным параметром в url-
encoded. То есть изначально сформированная строка параметров кодируется url-encode
преобразованием и передается безымянным параметром.

Пример:

 PUT
 https://moneytest.comepay.ru:439/api/prv/359/bills/0020
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

 =user%3Dtel%253A%252B79000000000%26amount%3D30.00%26ccy%3DRUB
 %26comment%3Dtest%26lifetime%3D2013-12-25T09%253A00%253A00%26prv_name
 %3Dsdgs

1.3.2 POST параметры
Параметры передаются как обычные пост параметры.

Пример:

 PUT
 https://moneytest.comepay.ru:439/api/prv/359/bills/0020
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

 user=tel:+79000000000
 amount=30.00
 ccy=RUB
 comment=test
 lifetime=2013-12-25T09:00:00
 prv_name=sdgs

                                                                                     5
1.3.3 JSON
Передается единственный POST параметр jsonRequest, со значением в виде JSON

Пример:

PUT
https://moneytest.comepay.ru:439/api/prv/359/bills/0020
Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
Content-Type: application/x-www-form-urlencoded; charset=utf-8

jsonRequest = {
      user:"tel:+79000000000",
      amount:10.12,
      ccy: "RUB",
      lifetime: "2015-01-01T22:54:33",
      comment: "test",
      prv_name="sdgs"
}

1.3.4 XML

Передается единственный POST параметр xmlRequest, со значением в виде XML.

Пример:

PUT
https://moneytest.comepay.ru:439/api/prv/359/bills/0020
Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
Content-Type: application/x-www-form-urlencoded; charset=utf-8

xmlRequest = 
                    tel:79000000000
                    10.12
                    RUB
                    2015-01-01T22:54:33
                    atata
                    
                                                                              6
2. Интерфейс выставления счетов.

   •   Создание запроса
   •   Получение состояния запроса
   •   Отмена неоплаченного счета
   •   Возвраты
   •   Запрос на получение статуса возврата

2.1 Создание запроса

После формирования заказа в интернет-магазине, для оплаты через Кошелек ComePay вам
следует выставить счет вашему клиенту через API. Этот счет будет выставлен от кошелька
вашего интернет-магазина на кошелек клиента, чей номер будет указан при формировании
счета. Оплата данного счета в системе ComePay будет означать успешную оплату заказа.

Для выставления счета пользователю платформа Агента должна отправить PUT запрос
следующего вида:

https://shop.comepay.ru/api/prv/{prv_id}/bills/{bill_id}
(https://moneytest.comepay.ru:439/api/prv/{prv_id}/bills/{bill_id} - тестовый сервер)

здесь:
   • {prv_id} – Уникальный идентификатор Кошелька в системе ComePay. (Числовое
       значение)
   • {bill_id} – Уникальный идентификатор запроса, сгенерированный на стороне Агента.
       (непустую строка до 50 символов)

Параметры запроса:

 Название           Формат            Рег. выражение         Описание                Пример
   user     Строка вида:          ^tel:\+\d{1,15}$       Идентификатор       tel:+79000000000
            «tel:{phone_number}»                         пользователя
            где {phone_number} –                         которому
            номер мобильного                             выставляется счет
            телефона в
            международном формате
  amount    Положительное число с    ^\d+(.\d{0,3})?$    Сумма счета         17.85
            двумя десятичными
            знаками (копейки)
    ccy     Три символа              ^[a-zA-Z]{3}$       Идентификатор       RUB
                                                         валюты согласно
                                                         Alpha-3 ISO 4217
                                                         (RUB или 643)

                                                                                                7
сomment       Текст до 255 символов   ^\.{0,255}$           Комментарий к     Оплата по счету
                                                             счету             №22
 lifetime      Дата, с учетом секунд   ^\d{4}-\d{2}-\d{2}T   Дата в формате    2012-12-
                                       \d{2}:\d{2}:\d{2}$    ISO 8601. По      25T14:30:00
                                                             достижении этой
                                                             даты счет будет
                                                             считаться
                                                             отвергнутым
pay_source                                                   Не используется
 prv_name Текст до 100 символов                              Имя Агента        AAA

Ответ будет содержать код результата и , если запрос был успешно осуществлен — всю
информацию о запросе (см. ответ сервера).

Пример:

 PUT
 https://moneytest.comepay.ru:439/api/prv/359/bills/0020
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

 =user%3Dtel%253A%252B79000000000%26amount%3D30.00%26ccy%3DRUB
 %26comment%3Dtest%26lifetime%3D2013-12-25T09%253A00%253A00%26prv_name
 %3Dsdgs

Ответ:

 {
     "response":
     {
         "result_code":0
         "bill":
         {
             "bill_id":"0020"
             "amount":30
             "ccy":"RUB"
             "status":"waiting"
             "error":"0"
             "user":"tel:+79000000000"
             "comment":"test"
         }
     }
 }

                                                                                                 8
P.S. Для целей отладки удобным инструментом является плагин для браузера Google Chrome -
Advanced Rest Client.

2.2 Запрос на получение статуса выставленного счета
Агент может запросить статус выставленного счета отправив GET-запрос на URL:

https://shop.comepay.ru/api/prv/{prv_id}/bills/{bill_id}

здесь:

   •     {prv_id} – Уникальный идентификатор Агента в системе ComePay. (Числовое
         значение)
   •     {bill_id} – Уникальный идентификатор запроса, сгенерированный на стороне Агента.
         (непустую строка до 200 символов)

Параметры в запросе отсутствуют.

Пример:

 GET
 https://moneytest.comepay.ru:439/api/prv/359/bills/0020
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

                                                                                            9
Ответ:

 {
     "response":
     {
             "result_code":0
             "bill":
             {
                  "bill_id":"0020"
                  "amount":30
                  "ccy":"RUB"
                  "status":"waiting"
                  "error":"0"
                  "user":"tel:+79000000000"
                  "comment":"test"
             }
     }
 }

2.3 Перенаправление при оплате счета.
Агент может предложить пользователю перейти на страницу ComePay для оплаты счета,
непосредственно после выставления счета:

         •       https://shop.comepay.ru/Order/external/main.action?shop=xxxx&transaction=yyyyyyyy
         •       https://shop.comepay.ru/Order/external/main.action?
                 shop=xxxx&transaction=yyyyyyyy&iframe=true

Оба адреса действуют аналогично, за исключение, второй адрес необходим для
использования iframe на странице Агента.

Параметры:

         Название             Тип                      Описание                             Пример
                 shop      string    Уникальный идентификатор Агента в системе,    359
                                     соответствует параметру {prv_id},
                                     использовавшемуся при создании счета
         transaction       string    Уникальный идентификатор запроса,             saas12
                                     сгенерированный на стороне Агента.
                                     Соответствует параметру {bill_id},

                                                                                                     10
использовавшемуся при создании счета
   successUrl    URL-       URL по которому пользователь будет               http://success.shop.net
                 encoded    перенаправлен после успешного платежа.
                 string     Обязательный.
     failUrl     URL-       URL по которому пользователь будет               http://fail.shop.net
                 encoded    перенаправлен после неуспешного платежа.
                 string     Обязательный.
terminalBackUrl URL-        URL по которому пользователь будет             http://delayed.shop.net
                 encoded    перенаправлен после выбора терминала в
                 string     качестве способа оплаты. В это поле следует
                            передавать ссылку на страницу состояния заказа
                            в магазине.
                            Не обязательный (по умолчанию берется из
                            настроек магазина)

Система ComePay перенаправит пользователя в зависимости от дополнительного параметра
successUrl/failUrl/terminalBackUrl. Данный URL будет содержать параметр order,
соответствующий параметру transaction – идентификатору запроса. Используя параметры
счета Агент может отобразить страницу заказа на своей платформе.
Параметр terminalBackUrl может не передаваться. Тогда в качестве значения по умолчанию
будет использовано значение из поля «URL для возврата при оплате через терминал» или,
если в настройках это поле не заполнено, адрес сайта магазина, указанный в анкете при
регистрации.

Пример:

1. Агент перенаправляет пользователя:

2. Пользователь оплачивает счет
3. Платформа ComePay перенаправляет пользователя на страницу Агента.

Внимание! Мы не рекомендуем изменять статус заказа в платформе интернет-магазина в
зависимости от того, на какой адрес был возврат со стороны системы ComePay. Для этого
следует использовать обработчик оповещений об изменении статуса заказа или запрос
статуса заказа через API.
Не стоит считать перенаправление на страницу успешной оплаты, как на свидетельство
успешно проведенного платежа, т.к. она может быть подделана на стороне пользователя. Она
служит только для удобства реализации интерфейса. Следует дождаться подтверждения
платежа со стороны платформы ComePay.

                                                                                                    11
2.4 Отмена выставленного счета

Агент может отменить выставленный ранее счет, в случае, если он еще не оплачен, используя
PATCH-запрос:

https://shop.comepay.ru/api/prv/{prv_id}/bills/{bill_id}

здесь:

         •       {prv_id} – Уникальный идентификатор Агента в системе ComePay. (Числовое
                 значение)
         •       {bill_id} – Уникальный идентификатор запроса, сгенерированный на стороне Агента.
                 (непустую строка до 200 символов)

Параметры:

Название                      Формат          Рег. выражение                 Описание
     status          "rejected"             ^rejected$         Новый статус счета - отменен

Ответ будет содержать код результата и, в случае успешного запроса, всб информацию о
счете.

Запрос:

 PATCH
 https://moneytest.comepay.ru:439/api/prv/359/bills/0020
 Accept: text/json
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

Ответ:

 {
     "response":
     {
             "result_code":0
             "bill":
             {
                  "bill_id":"0020"
                  "amount":30
                  "ccy":"RUB"
                  "status":"rejected"
                  "error":"0"
                  "user":"tel:+79000000000"
                                                                                                12
                  "comment":"test"
             }
     }
 }
2.5 Возвраты
Агент может осуществить возврат оплаченного счета используя PUT-запрос, описанный
ниже. Возврат может осуществляться только на сумму оплаченного счета.

https://shop.comepay.ru/api/prv/{prv_id}/bills/{bill_id}/refund/{refund_id}

здесь:

         •       {prv_id} – Уникальный идентификатор Агента в системе ComePay. (Числовое
                 значение)
         •       {bill_id} – Уникальный идентификатор запроса, сгенерированный на стороне Агента.
                 (непустую строка до 200 символов)
         •       {refund_id} – Уникальный идентификатор возврата для счета {bill_id},
                 сгенерированный на стороне Агента.

Параметры:

 Название                   Формат            Рег. выражение                  Описание
     amount          Положительное число с   ^\d+(.\d{0,3})?$   Сумма счета
                     двумя десятичными
                     знаками (копейки)

Ответ будет содержать код результата и, в случае успешного запроса, всб информацию о
счете.

Запрос:

 PATCH
 https://shop.comepay.ru/api/prv/359/bills/0020/refund/1
 Accept: text/json
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

Ответ:

 {
     "response":
     {
             "result_code":0
             "refund":
             {
                  "refund_id":"1"
                  "amount":30
                  "ccy":"RUB"
                  "status":"success"
                                                                                                13
                  "error":"0"
             }
     }
 }
2.6 Проверка статуса возврата
Агент может проверить статус возврата используя следующий GET-запрос:

здесь:

         •       {prv_id} – Уникальный идентификатор Агента в системе ComePay. (Числовое
                 значение)
         •       {bill_id} – Уникальный идентификатор запроса, сгенерированный на стороне Агента.
                 (непустую строка до 200 символов)
         •       {refund_id} – Уникальный идентификатор возврата для счета {bill_id},
                 сгенерированный на стороне Агента.

Параметров нет.

Запрос:

 GET
 https://shop.comepay.ru/api/prv/359/bills/0020/refund/1
 Accept: text/json
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 Content-Type: application/x-www-form-urlencoded; charset=utf-8

Ответ:

 {
     "response":
     {
             "result_code":0
             "refund":
             {
                  "refund_id":"1"
                  "amount":30
                  "ccy":"RUB"
                  "status":"success"
                  "error":"0"
             }
     }
 }

2.6 Ответ сервера
Ответ сервера представляет собой объект «response», который состоит их кода результата и

                                                                                                14
одного из объектов, следующего типа:
«invoice», «refund». Ответ сериализуется как JSON или XML.

  Название             Формат         Рег. выражение                  Описание
 result_code Целое число             ^\d{1,4}$          Код ошибки. См. «Коды ошибок»

Пример сериализации в XML:

 …
 0
 …

Пример сериализации JSON:

 …
 “result_code”: 0,
 …

Информация о запросе:

  Название             Формат         Рег. выражение                  Описание
    bill_id      Строка до 200       ^.{1,200}$         Уникальный идентификатор созданный
                 символов                               на стороне Агента
    amount       Положительное       ^\d+(.\d{0,3})?$   Сумма счета
                 число с двумя
                 десятичными
                 знаками (копейки)
      ccy        Три символа         ^[a-zA-Z]{3}$      Идентификатор валюты согласно Alpha-3
                                                        ISO 4217
                                                        (RUB или 643)
     status      Строка              ^[a-z]{1,15}$      Статус запроса См. «Статусы»

                                                                                             15
error      Целое число           ^\d{1,5}$         Код ошибки. См. «Коды ошибок»
    user       Строка вида:         ^tel:\+\d{1,15}$   Идентификатор пользователя которому
               «tel:{phone_number}»                    выставляется счет
               где {phone_number}
               – номер мобильного
               телефона в
               международном
               формате
  comment      Текст                 ^\.{0,255}$       Комментарий

Пример XML сериализации:

…

order001
50.50
RUB
paid
0
tel:+79000000000
Комментарий

…

Пример JSON сериализации:

…
“bill”: {
“bill_id”: “order001”,
“amount”: “50.50”,
“ccy”: “RUB”,
“status”: “paid”,
“error”: 0,
“user”: “tel:+79000000000”,
“comment”: “Комментарий”
}
…

                                                                                             16
Информация о возврате:

  Название          Формат           Рег. выражение                  Описание
  refund_id   Целое число           ^\d{1,4}$          Идентификатор созданный на стороне
                                                       Агента
   amount     Положительное         ^\d+(.\d{0,3})?$   Сумма счета
              число с двумя
              десятичными
              знаками (копейки)
    status    Строка                ^[a-z]{1,15}$      Статус запроса См. «Статусы»

    error     Целое число           ^\d{1,5}$          Код ошибки. См. «Коды ошибок»
    user      Строка вида:         ^tel:\+\d{1,15}$    Идентификатор пользователя которому
              «tel:{phone_number}»                     выставляется счет
              где {phone_number}
              – номер мобильного
              телефона в
              международном
              формате

Пример XML сериализации:

…

1
50.50
success
0
tel:+79000000000

…

Пример JSON сериализации:

                                                                                             17
…
“refund”: {
“refund_id”: “1”,
“amount”: “50.50”,
“status”: “success”,
“error”: 0,
“user”: “tel:+79000000000”
}
…

                             18
3. Интерфейс Агента
API позволяет Агенту получать уведомления. Для получения уведомлений сервер Агента
должен быть способен принимать и обрабатывать POST-запросы с объектом «invoice»,
содержащим все необходимые данные, сериализованные в виде параметров POST-запроса
(Application/x-www-form-urlencoded). В ответ отправляется код результата. Ответ должен
быть в виде XML-документа.

Пример запроса:

 POST
 HTTP/1.1
 http://agent.net/notification.php
 Accept: application/xml
 Content-type: application/x-www-form-urlencoded
 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=
 bill_id=order1&status=paid&error=0&amount=15.00&user=tel%3A
 %2B79000000000&prv_name=TEST&ccy=RUB&comment=result

 HTTP/1.1 200 OK
 Content-Type: text/xml
  0

Любой код результата, отличный от 0 будет рассматриваться платформой ComePay, как
временная ошибка, уведомление будет повторяться с увеличением интервала времени в
течении 24 часов. По истечении 24 часов рассылка уведомлений будет прекращена с
пометкой о возможной технической проблеме на стороне Агента.

Т.к. могут быть несколько попыток уведомления, Агент не должен осуществлять проводки
более одного раза.

Рекомендованные коды для возврата см. «Уведомления»

                                                                                         19
4. Авторизация
При регистрации Агент получает пароль, который должен использовать для авторизации
запросов к API ComePay и получения уведомлений от платформы ComePay

4.1 Авторизация запроса к платформе ComePay

Логин и пароль передаются согласно правилам «basic-authorization» HTTP-запроса.
В качестве логина используется Номер кошелька из технических настроек интернет-магазина
(https://shop.comepay.ru/Account/AboutShop).
Заголовок «Authorization» добавляется к запросу. Значение данного заголовка состоит из
ключевого слова «Basic», символа пробела и пары PurseNumber:password, закодированной
BASE64. Здесь
   •   PurseNumber – Номер кошелька Агента
   •   password — пароль Агента.

 Authorization: Basic WDA3TjlRNTFWMTpaZXJvMTk3MSE=

Передача пароля шифруется протоколом SSL

4.2 Авторизация при получении уведомлений
Рекомендуется использовать SSL протокол. При этом передаваемые данные будут
шифроваться.

Пара PurseNumber:password передается согласно правилам «basic-authorization». И должна
проверяться на стороне Агента. Если не используется SSL протокол данные передаются в
открытом виде и могут быть перехвачены.

   •   PurseNumber – Номер кошелька Агента
   •   password — пароль Агента для уведомлений.

                                                                                         20
5. Логика реализации
Пользователь отправляет заказ на платформу Агента, Агент отправляет запрос на создание
счета на платформу ComePay. В случае успеха пользователь авторизуется в системе ComePay
и производит оплату счета. Платформа Агента получает уведомление о прошедшем платеже
и осуществляет оплаченные услуги.

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

                                                                                        21
Запрос может повторяться до тех пор, пока средства не будут возвращены клиенту.

                                                                                  22
6. Приложения
6.1 Статус запроса

   Код                                    Описание                         Финальный
  waiting    Ожидает оплаты                                              Нет
   paid      Оплачен                                                     Да
  rejected   Отвергнут                                                   Да
  unpaid     Не оплачен                                                  Да
  expired    Устарел                                                     Да

6.1 Статус оплаты

   Код                                    Описание                         Финальный
 processing В ожидании                                                   Нет
  success    Успех                                                       Да
    fail     Неуспех                                                     Да

6.1 Коды ошибок

   Код                                    Описание                            Фатальная
     0       Успех                                                       Нет
     5       Неверные параметры                                          Да
    13       Сервер занят                                                Нет
    150      Ошибка авторизации                                          Да
    210      Запрос не найден                                            Да
    215      Запрос уже существует                                       Да
    241      Сумма меньше минимума                                       Да
    242      Сумма больше максимума                                      Да
    298      Пользователь не зарегистрирован                             Да
    299      Магазин не зарегистрирован                                  Да
    300      Ошибка сервера                                              Нет

Фатальная ошибка означает, что результат не измениться при повторении запроса.

                                                                                          23
6.1 Коды уведомлений

   Код                        Описание
    0    Успех
    5    Неверные параметры
   13    Ошибка БД
   150   Неверный пароль
   300   Ошибка сервера

                                         24
Вы также можете почитать