company_banner

Новый API Яндекс.Кассы: платежное лего для e-commerce всех мастей


    Буквально сегодня свет увидел новый API Яндекс.Кассы, разработанный программистами для программистов. Набор протоколов стал единообразным, логичным и простым в освоении. Но статья не об этом – я хочу рассказать, как и почему в один прекрасный момент API решено было переписать с нуля.


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


    Исторически в Яндекс.Деньгах протоколы в API появлялись по мере необходимости и разрабатывались разными подразделениями – не стали исключением и сервисы Яндекс.Кассы.


    Как получилось так, что нужен новый API


    Яндекс.Касса – универсальное решение для онлайн-платежей – родилась в 2013 году в стенах Яндекс.Денег. С её помощью компании могут принимать оплату всеми популярными способами: из кошельков в Яндекс.Деньгах, с банковских карт, со счетов мобильных номеров или наличными через специальные терминалы.


    Тогда Касса преимущественно состояла из протокола приема платежей через платежную форму. Этот протокол позволял через платежную форму на сайте контрагента перенаправить плательщика на сайт Яндекс.Денег и провести платеж.


    Когда контрагентам потребовалось осуществлять возвраты, получать списки возвратов и платежей, для всего этого появился еще один новый протокол. Он работал на базе PKCS#7 криптопакетов и XML, а порог технического вхождения для него оказался достаточно высок. В общем, с реализацией справлялись только те, кто по-настоящему в этом нуждался.


    Кроме того, в 2014 году появились протокол выплат и протокол эквайринга банковских карт для крупных контрагентов, которые прошли PCI DSS аудит и могут хранить данные банковских карт на своей стороне.


    Все эти протоколы выполняли свои узконаправленные задачи, но, к сожалению, были разными с точки зрения интеграции. Если мерчант хотел принимать оплату всеми возможными способами, ему нужно было реализовать целых четыре протокола, которые сильно отличались друг от друга.


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


    Так появился новый API Яндекс.Кассы, который строился на трех основных принципах: единая модель данных для всего взаимодействия, однозначность признаков и статусов платежей, асинхронность при взаимодействии магазина с Яндекс.Кассой. Сейчас новый API покрывает все протоколы прошлой версии, кроме выплат – они появятся чуть позже.


    Единая модель данных


    При проектировании API мы использовали объектно-ориентированный подход на основные ценности REST-like протоколов. При этом старались использовать знакомые контрагентам и разработчикам сущности, которые уже существуют в их системах и процессах: платежи, возвраты, сохраненные способы оплаты (они же – привязки) и другие. Эту концепцию принято называть проблемно-ориентированным проектированием.


    Структура объекта платежа неизменна от запроса к запросу и позволяет получать необходимую информацию в любой момент без необходимости хранить все это на своих серверах. Что особенно важно, это позволяет одинаково интерпретировать данные объекта в любое время. Создаете ли вы объект платежа (Payment) через POST, получаете его состояние через GET, подтверждаете или отменяете его – во всех ситуациях вы работаете с одним и тем же объектом Payment.


    {
      "id": "2171eeff-000f-50be-b000-02e31251204a",
      "status": "pending",
      "paid": false,
      "amount": {
        "value": "2.00",
        "currency": "RUB"
      },
      "confirmation": {
        "type": "redirect",
        "confirmation_url": "https://money.yandex.ru/payments/kassa/confirmation?orderId=2171eeff-000f-50be-b000-02e31251204a"
      },
      "created_at": "2017-10-12T21:14:39.577Z",
      "payment_method": {
        "type": "bank_card",
        "id": "2171eeff-000f-50be-b000-02e31251204a",
        "saved": false,
        "card": {
            "last4": "7918",
            "expiry_year": "2017",
            "expiry_month": "07",
            "card_type": "MasterCard"
        }
      }
    }

    Пример объекта платежа (Payment).


    Из соображений единообразия все объекты платежа, возврата, а также платежные методы живут по одним законам и обладают похожими признаками и структурой.


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


    Однозначность признаков и статусов платежей


    У платежных систем есть одна особенность, которая серьезно затрудняет реализацию протоколов по REST-like принципу: все сущности в рамках API обладают своим жизненным циклом. Он отличается от метода к методу и влияет на значения и структуру полей.


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



    Состояния платежа по новому жизненному циклу: waiting_for_capture присутствует не всегда – есть режим проведения платежа с автоматическим capture.


    На стадии pending и waiting_for_capture платеж может быть отменен магазином или нами и тогда перейдет в статус canceled.


    {
      "id": "2171f067-000f-50be-b000-01cc0f0843c3",
      "status": "waiting_for_capture",
      "paid": true,
      "amount": {
        "value": "1000.00",
        "currency": "RUB"
      },
      "created_at": "2017-10-12T21:21:08.594Z",
      "payment_method": {
            "type": "bank_card",
        "id": "2171eeff-000f-50be-b000-02e31251204a",
        "saved": false,
        "card": {
            "last4": "7918",
            "expiry_year": "2017",
            "expiry_month": "07",
            "card_type": "MasterCard"
        }  },
      "receipt_registration": "succeeded"
    }

    Ответ сервера при прохождении стадии waiting_for_capture.


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


    Также мы даем контрагентам набор признаков, по которым можно получить дополнительную информацию: например, о необходимости подтверждения платежа пользователем, о внесении им денег или регистрации чека в облачной кассе для выполнения требований 54-ФЗ.


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


    1. Создание платежа.
    2. Получение подтверждения пользователя.
    3. Регистрация чека в онлайн-кассе.
    4. Подтверждение готовности принять платеж.
    5. Получение денег на расчетный счет уже на следующий рабочий день.

    Шаги 2-4 опциональны, но последовательность этих действий всегда неизменна.


    Чтобы ознакомиться с реальными примерами, посмотрите в инструкциях раздел по проведению платежа «Быстрый старт».


    Асинхронность при взаимодействии с Кассой


    Начну издалека. API Яндекс.Кассы связывает магазин, покупателя, партнеров и эмитентов банковских карт (банк, который выпустил вашу карту), то есть в каждом платеже задействовано множество участников. Иногда ответ всех участников процесса занимает достаточно продолжительное время.


    Если бы взаимодействие было синхронным, компаниям приходилось бы все это время держать соединение открытым, что требует больше ресурсов. И именно поэтому мы сделали API асинхронным.


    Чтобы поддерживать асинхронность и защититься от задвоения платежей, мы предлагаем использовать ключ идемпотентности. Если Касса по какой-то причине не успеет провести платеж за отведенное время, клиент API получит в ответе HTTP-код 202 (Request Accepted) с просьбой повторить запрос с тем же ключом чуть позже. Даже при множественных запросах с одним и тем же ключом и одинаковым телом запроса операция всегда будет совершена только один раз.


    curl https://payment.yandex.net/api/v3/payments \
      -X POST \
      -u <Идентификатор магазина>:<Секретный ключ> \
      -H 'Idempotence-Key: <Ключ идемпотентности>' \
      -H 'Content-Type: application/json' \
      -d '{
            "amount": {
              "value": "2.00",
              "currency": "RUB"
            },
            "payment_method_data": {
              "type": "bank_card"
            },
            "confirmation": {
              "type": "redirect",
              "return_url": "https://www.merchant-website.com/return_url"
            }
          }'

    Пример запроса с ключом идемпотентности.


    При этом достаточно выбрать генератор случайных чисел с минимально возможной коллизией (рекомендуем использовать v4 UUID). Мы запоминаем каждый из идентификаторов на 24 часа, после чего можно воспользоваться им повторно. При этом вам не нужно хранить ключ идемпотентности вечно – достаточно получить постоянный идентификатор объекта Платежа или Возврата, сгенерированного Кассой. Впоследствии вся работа с объектом осуществляется через этот идентификатор.


    Некоторые процессы оплаты в Яндекс.Кассе асинхронны по своей природе. Например, при подтверждении оплаты через SMS в Сбербанке Онлайн контрагент должен передать нам номер телефона своего покупателя, а затем ожидать подтверждения платежа пользователем, на которое может уйти от нескольких минут до часа.


    Поэтому Касса передает контрагенту информацию о факте отправки SMS-сообщения и ожидает подтверждения пользователем. В это время клиент Кассы может периодически повторять запросы о статусе платежа либо подписаться на уведомления от сервера, которые направляются на указанный в личном кабинете Кассы URL при смене статуса платежа. В обоих случаях контрагент получает полный объект Платежа.


    Все эти решения позволяют компаниям не подстраивать свои бизнес-процессы под Яндекс.Кассу, а гибко встраивать наш API в любые платежные сценарии.


    Как мы расширяем API, или Сначала попробуем сами


    При создании предыдущих протоколов мы столкнулись с проблемой расхождения документации и реализации, потому что исходники документации существовали отдельно. В новом API с этим тоже нужно было покончить, поэтому для сборки документов решили использовать Swagger. Сейчас на рынке есть множество решений all-in-one, которые позволяют импортировать Swagger-спецификации, но идеальных с точки зрения кастомизации и информационного дизайна не нашлось.


    Поэтому документы конвертировали с использованием формата Markdown, а в качестве инструмента для отображения выбрали Slate. Для прототипа каждой новой функции теперь используется спецификация в формате Swagger и сценарии, которые описывают последовательности действий и возможные исходы.


    Классический сценарий добавления новых функций в API выглядит следующим образом: менеджер продукта создает Pull Request в репозиторий с документацией, сопровождая его ссылкой на измененный пользовательский сценарий. Pull Request проходит ревью как аналитиков, так и команды разработчиков API.


    Пример изменений, которые вносит заказчик в документацию (API reference), добавляя запрос на создание платежа с объектом, хранящим данные банковской карты.
      PaymentMethodDataBankCard:
        description: Данные для оплаты банковской картой
        allOf:
        - $ref: '#/definitions/PaymentMethodData'
        - type: object
          properties:
            type:
              description: Тип объекта.
              type: string
              enum:
                - bank_card
            card:
              description: Данные банковской карты (необходимы, если вы собираете данные карты пользователей на своей стороне).
              type: object
              properties:
                number:
                  description: Номер банковской карты
                  type: string
                  pattern: "[0-9]{13,19}"
                  example: '4444444444444448'
                expiry_year:
                  description: Срок действия, год, YY
                  type: string
                  pattern: "[0-9]{4}"
                  example: '2017'
                expiry_month:
                  description: Срок действия, месяц, MM
                  type: string
                  pattern: "[0-9]{2}"
                  example: '10'
                csc:
                  description: Код CVC2 или CVV2, 3 или 4 символа, печатается на обратной стороне карты
                  type: string
                  pattern: "[0-9]{3,4}"
                  example: '012'
                cardholder:
                  description: Имя владельца карты
                  type: string
                  pattern: "[a-zA-Z]{0,26}"
                  example: 'John Smith'
              required:
                - number
                - expiry_year
                - expiry_month
                - csc
        required:
          - type

    После того как все договорились о финальной версии спецификации и Pull Request получил все необходимые согласования, начинается реализация. Параллельно от ветки спецификации отводится еще одна, в которой копирайтеры исправляют тексты и объединяют их отдельным Pull Request.


    Как только новая функция реализована разработчиком, она тестируется по этой спецификации и далее отправляется на продакшен.


    Dogfooding и мониторинг в перерывах


    Перед тем как отдавать новую функцию пользователям, мы обязательно устраиваем «dogfooding», то есть сами пробуем наш продукт. Для этого используется специально разработанный демо-магазин, где можно купить виртуальную Капибару и реализовать другие сценарии клиентов Кассы. Вспомогательная цель его использования – снизить порог вхождения для сотрудников-новичков и показать платежные сценарии любому желающему внутри компании.


    Как только мы вычитаем документацию, протестируем новые функции и убедимся в их простоте и понятности – выполняется Merge Pull Request Swagger-спецификации в master-ветку, чтобы она автоматически собралась в публичную документацию и попала на сайт.


    После выпуска новой функции в мир наступает бесконечно увлекательный момент поддержки и мониторинга. Как и другие подразделения Яндекс.Денег, мы используем Grafana. Наблюдения проводятся с помощью множества метрик, поэтому приведу тут только основные: запросы к API, отправленные уведомления, успешность прохождения платежей и их подтверждение (capture), частота возникновения определенных ошибок.


    Вместе с запуском нового API появился обновленный портал документации и SDK на PHP. Начался и постепенный переход наших CMS-модулей на новый протокол – сейчас регистрация на новый протокол доступна для OpenCart 1.5 и WooComerce. К ноябрю 2017 к ним присоединятся Y.CMS для Opencart 2, Prestashop, Webasyst Shop-Script, Drupal (модуль для Commerce и Ubercart), JoomShopping и SimplaCMS.


    Мы также запускаем библиотеку YandexCheckout.js, которая позволяет создавать формы для приема карточных платежей любых форм и размеров. Первыми такую библиотеку 6 лет назад предложил Stripe. С тех пор нечто похожее сделали другие платежные агрегаторы для решения проблемы оплаты картами прямо на сайте интенет-магазина. Мы учли лучшие наработки наших западных коллег и выпустили YandexCheckout.js. Теперь компаниям не придется проходить полный и дорогой аудит PCI DSS, чтобы принимать платеж на своей стороне — достаточно заполнить опросник SAQ D и пройти ASV сканирование (с чем мы тоже можем помочь). Сейчас эта опция доступна в индивидуальном порядке, но открытие ее для всех как раз в планах на будущее.


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


    Нет, мы не предлагаем все сломать и сделать заново


    Многих беспокоит, что будет со старым протоколом и как скоро мы предложим всем перейти на новый. Могу вас успокоить – работу со старым протоколом принудительно ограничивать не планируем. То есть для всех, у кого процесс налажен и кого он полностью устраивает, ничего не изменится. Но если вы все равно хотите попробовать новые возможности – наши менеджеры могут создать для вас новый магазин с обновленным API.


    Если же вы сами разрабатываете новую площадку или давно ждали возможностей нового API – при регистрации будет использован уже обновленный API Яндекс.Кассы. В начале 2018 года также планируется публичный запуск возможности перевода старых магазинов на новый протокол.


    Напоследок две самые важные ссылки:



    Если у вас остались вопросы или опасения относительно нового API – приглашаю в комментарии к статье.

    Яндекс.Деньги 98,16
    Об электронных платежах и устройстве Я.Денег
    Поделиться публикацией
    Комментарии 22
    • +2
      Я бы хотел ознакомится на практике с API яндекс.кассы в тестовом режиме до того как появится реальная необходимость в его использовании (чтобы быть готовым быстро написать собственное решение для проекта достаточно быстро, когда это понадобится), но на данный момент за плечами нет организации, и соответственно возможности зарегистрироваться в системе. Я недавно спрашивал об этом тех поддержку, может с введением нового функционала появится возможность воспользоваться тестовым режимом без регистрации с ИНН?
      • 0
        К сожалению, сейчас выдача тестового магазина возможна только после одобрения анкеты (а значит нужен реальный ИНН и расчетный счет), но если вы хотите потрогать протокол — напишите мне в личку и мы создадим для вас логин/пароль для аутентификации в API. Если же вы планируете писать модули под CMS — напишите, пожалуйста, на cms@yamoney.ru
        • 0
          И это супер косяк. Я в свое время тоже хотел потыкать и разобраться, а нельзя. В чем сложность выдать тестовый магазин без всяких там расчетных счетов — загадка.
          • 0

            И это не единственный косяк. Не далее как в августе помогал интегрировать кассу знакомому. Так после успешной тестовой обкатки решения, было отказано во включении боевого режима без объяснения причин. Слишком всё усложнили. В итоге ушли к Paymaster, где без проблем тебе выдают и тестовый доступ и подключают к магазину. Хотя нужно признать, в кассе протокол надёжнее будет.

            • 0
              Отказ может быть связан с тем, что продаваемые товары и услуги не входят в перечень разрешенных правилами МПС или если и покупатель, и продавец — юридические лица, тогда как Касса проводит платежи от физиков. Могут быть и другие причины, и обычно коллеги стараются ответить подробно. В любом случае если снова будет актуально — приходите, постараемся помочь.
      • +3
        А есть ли вариант организовать приём платежей на сайте через Я.Кассу (с приёмом денег с карт) без аренды кассы у партнёров?
        • 0
          Да, но по закону ФЗ-54 для онлайн-торговли нужна онлайн-касса — либо купленная, либо арендованная. Если арендовать у партнеров Кассы, то онлайн-чеки, передача в ОФД и т.п. — вопрос решенный. Если у другой компании, с кассами которых Яндекс.Касса не интегрирована, то придется настраивать обмен данными между онлайн-кассой и Я.Кассой самостоятельно.
          • 0
            Если ИП на патенте, оказывает услуги, вроде онлайн касса не нужна пока?
            • 0
              ИП на патенте ККТ сейчас правда не нужна. Но этот режим налогооблажения недоступен для дистанционной торговли.
              Что касается услуг, можно пока не применять ККТ при условии выдачи клиенту в момент оплаты БСО. А бланк строгой отчётности — это бумажка, а значит обеспечить её выдачу в момент оплаты в онлайне невозможно. Следовательно нужно применять ККТ
        • 0
          Новое API это хорошо, но буквально неделю назад столкнулся с банальной проблемой, ssl сертификат от cloudflare не подходит для вызова вебхуков в моем магазине. Именно по этой причине мы пока решили остаться на робокассе.
          Выдержка из документации
          Если вы используете HTTPS от cloudflare

          Доступ по HTTPS от Cloudflare работает по технологии SNI. В настоящий момент наша платежная система не поддерживает этот режим (поддержка ожидается примерно в четвертом квартале 2017 года). Если ваш сайт работает через Cloudflare, вам надо обратиться в техподдержку Cloudflare с просьбой перевода на HTTPS без режима SNI.

          В статье об этом ни слова, но я надеюсь вы двигаетесь в этом направлении.
          • +1
            Да, к сожалению, это известная боль старых протоколов и именно поэтому в новом API такой проблемы больше нет
          • –1
            Не прошло и четырёх лет, как чекаут в строю.
            С идемпотентностью подсуетились, реализовали всего на полгода позже ;)
            • 0
              Не прошло и 6 лет, если вы про Stripe ;) Наши API всегда были идемпотентными, начиная с эквайрингового пртокола в 2013. Все-таки это маст-хэв для платежного протокола
            • 0
              У меня только один вопрос
              возможно ли выставить чек потенциальному покупателю с признаком «ПЛАТЁЖ» независимо от того совершил он платёж или нет? То есть ДО совершения расчетов?
              • 0
                Расскажите, а какой сценарий вы реализуете и почему появилась такая потребность? Сейчас выставить чек до взаиморасчетов нельзя, так как чек является подтверждением проведения взаиморасчетов между покупателем и продавцом.
                • 0
                  то что в фз-54 прописано
                  5. Пользователи при осуществлении расчетов с использованием электронных средств платежа, исключающих возможность непосредственного взаимодействия покупателя (клиента) с пользователем или уполномоченным им лицом, и применением устройств, подключенных к сети «Интернет» и обеспечивающих возможность дистанционного взаимодействия покупателя (клиента) с пользователем или уполномоченным им лицом при осуществлении этих расчетов (далее — расчеты с использованием электронных средств платежа в сети «Интернет»), обязаны обеспечить передачу покупателю (клиенту) кассового чека или бланка строгой отчетности в электронной форме на абонентский номер либо адрес электронной почты, указанные покупателем (клиентом) до совершения расчетов.

                  1) клиент присылает мне адрес электронной почты
                  2) я отправляю клиенту договор оказания услуг в электронном виде и фискализированный чек с признаком «ПЛАТЁЖ» и хэш функцией файла с договором в описании платежа(могу без проблем, это не описание услуги, а сведения о платеже)
                  3) клиент получает чек проверяет соответствие договора хэш функции с файлом договора (собственно мне все равно проверит или нет в сведениях о платеже хэш указан)
                  4) клиент оплачивает платёж (акцептует договор).
                  5) я оказываю услуг
                  6) клиент производит оплату услуги
                  7) деньги поступают на мой счет
                  8) я распечатываю чек и отправляю клиенту электронный экземпляр чека на электронную почту с описанием оказанной услуги и сведениями о поступившей оплате по договору выше. Печатный экземпляр храню у себя. Могу клиенту передать.
                  9) все довольны

                  при такой схеме интернет не нужен вообще. отмечать какие то галочки не нужно. Условия договора известны еще до осуществления платежа и фискализированы в налоговой. У суда есть достоверный источник информации о сделке.
                  • 0
                    то что в фз-54 прописано
                    5. Пользователи при осуществлении расчетов с использованием электронных средств платежа, исключающих возможность непосредственного взаимодействия покупателя (клиента) с пользователем или уполномоченным им лицом, и применением устройств, подключенных к сети «Интернет» и обеспечивающих возможность дистанционного взаимодействия покупателя (клиента) с пользователем или уполномоченным им лицом при осуществлении этих расчетов (далее — расчеты с использованием электронных средств платежа в сети «Интернет»), обязаны обеспечить передачу покупателю (клиенту) кассового чека или бланка строгой отчетности в электронной форме на абонентский номер либо адрес электронной почты, указанные покупателем (клиентом) до совершения расчетов.

                    1) клиент присылает мне адрес электронной почты
                    2) я отправляю клиенту договор оказания услуг в электронном виде и фискализированный чек с признаком «ПЛАТЁЖ» и хэш функцией файла с договором в описании платежа(могу без проблем, это не описание услуги, а сведения о платеже, информация о том по какому договору БУДЕТ осуществлен платёж)
                    3) клиент получает чек проверяет соответствие договора хэш функции с файлом договора (собственно мне все равно проверит или нет в сведениях о платеже хэш указан)
                    4) клиент оплачивает платёж (акцептует договор).
                    5) я оказываю услугу
                    6) клиент производит оплату услуги
                    7) деньги поступают на мой счет
                    8) я распечатываю чек и отправляю клиенту электронный экземпляр чека на электронную почту с описанием оказанной услуги и сведениями о поступившей оплате по договору выше. Печатный экземпляр храню у себя. Могу клиенту передать.
                    9) все довольныи суд рад, что теперь в случае спора он может истребовать из налоговой основание платежа и разрешить спор (например, какого качества должна была быть оказана услуга)

                    при такой схеме интернет сайт не нужен вообще. отмечать какие то галочки не нужно. Интернет магазин превращается в простую витрину. Условия договора известны еще до осуществления платежа и фискализированы в налоговой. У суда есть достоверный источник информации о сделке.
                • 0
                  Как насчет такого же АРІ для массовых выплат? Сейчас приходится ну уж очень изворачиваться с SOAP протоколом и всеми этими сертификатами.
                  • 0
                    Полностью вас понимаю! Сейчас мы движемся по пути постепенных улучшений — начали с протокола платежей, как наиболее востребованного и популярного. Протокол массовых выплат следующий на очереди. Как только будет готово — обязательно расскажем об этом публично :)
                    • 0
                      Есть какие-то таймлайны? Месяц-три-полгода-год?
                      • 0
                        Соориентировать по времени, к сожалению, пока что не могу, но если вы планируете начать новый проект на протоколе выплат, то лучше не откладывать его в ожидании нового API. Как только выйдет новый протокол — мы обязательно выпустим инструкцию по миграции для существующих пользователей.
                        • 0
                          Ок, спасибо! Будем ждать с нетерпением.

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

                  Самое читаемое