Историю нашумевшей технической ошибки «Додо Пиццы», партнера Яндекс.Кассы, нам рассказал системный архитектор компании Андрей Моревский — сразу передаю микрофон автору.


Еду я в «Сапсане» на открытие первой в Санкт-Петербурге пиццерии «Додо», как вдруг получаю оповещение о множественных отменах оплаченных заказов. И не просто множественных — наша система за час умудрилась откатить якобы оплаченные заказы на 8 миллионов рублей!


Сейчас эта история вызывает только улыбку, но в то утро было совсем не смешно. Поэтому хочу поделиться некоторыми техническими подробностями инцидента и сделанными выводами, а заодно немного рассказать про систему обработки заказов «Додо Пиццы».


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


Немного ретроспективы и информации о потерях.

Наш сервер отменил платежей на 7,84 миллиона рублей. Для сети с ежегодным оборотом почти в 3 миллиарда это серьезные деньги. К тому же, это более 10% от привлеченных за последний раунд инвестиций. Согласитесь, слишком серьезная цена для одной ошибки.


В тот же день основатель сети Федор Овчинников сообщил об инциденте в социальных сетях, и история быстро разошлась по новостным сайтам.


И сразу спойлер — все закончилось хорошо


Пока мы делали все возможное для возврата средств, читатели недоумевали, как такое вообще произошло и азартно перебирали варианты возможной расправы над «программистами». Да что там, я лично получил с десяток тревожных сообщений от знакомых: ребята интересовались, все ли у меня хорошо и предлагали вакансии «на всякий случай».


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


Деньги нам в итоге вернули, хотя мы и потеряли на банковских комиссиях 150 тысяч рублей за переводы, еще 40 тысяч ушло на SMS-уведомления клиентов..


В поисках причин и следствий


С первого дня «Додо Пицца» разрабатывает собственную информационную систему (Dodo IS).

Сегодня эта система круглосуточно обслуживает 183 пиццерии в девяти странах. За пять лет разработки мы прошли путь от примитивного блока приема заказов до полноценной облачной ERP-системы, которая управляет заказами, работой на кухне, планированием графиков, запасами, финансами — практически всеми аспектами нашего бизнеса.


Мы тестируем Dodo IS на нескольких окружениях: есть «песочницы» для демонстрации продуктовым менеджерам, есть интеграционные контуры. Перед выкладкой в продакшн финальная версия тестируется аналитиками и QA в окружении stable. Для проверки мы используем реальные данные, которые регулярно копируем с «боевой» базы. Разумеется, все данные при пересечении границы продакшн-**среды** обезличиваются.


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


За день до инцидента произошло сразу два неудачных совпадения, в лучших традициях законов Мерфи:


  • из-за ошибки в конфигурации оказалось, что фоновая задача смотрит не на имитацию платежного сервиса, а на реальное подключение к Яндекс.Кассе;


  • при этом фоновая задача смотрела на версию тестовой базы, в которой были обезличенные платежные транзакции, но не было соответствующих им заказов.

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


Про виновных, ответственность и доверие


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


«Безусловно, мы сделаем серьезнейшие выводы из этой критической ошибки. Мы не будем наказывать людей — мы просто сделаем все, чтобы такого больше не повторилось.»
Сообщение на странице Федора Овчинникова в Facebook и ВКонтакте сразу после инцидента.

Страх наказания рано или поздно парализует работу любой компании. Уверен, многим из вас встречались компании, где пишут много документов и писем, чтобы оказаться как можно дальше от «области поражения». Где ни один менеджер не готов принять ни то что смелое, но даже пустяковое решение без 20-ти согласований. Я считаю, что такие компании не способны к созиданию и развитию, им остается лишь годами «доедать» ресурсы, созданные их более смелыми предшественниками-первопроходцами.


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


«Если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдёт.»
Закон Мерфи.

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


Теперь самое интересное — что делать


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


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


Последние полгода мы занимаемся реинжинирингом системы и переводим наш монолит на рельсы SOA (Service-Oriented Architecture). Сегодня каждый в компании — от программистов до управленцев — понимает, что технический долг необходимо возвращать.


В рамках перевода системы на SOA мы выделяем отдельный сервис обработки платежей — платежный шлюз. Этот сервис инкапсулирует всю платежную логику, включая взаимодействия с эквайерами. Фактически, мы разрабатываем собственный платежный агрегатор для собственных нужд. Платежный шлюз станет единой точкой проведения онлайн-платежей для клиентского сайта (dodopizza.ru) и других наших интернет-каналов продаж.


Мы решили сертифицировать платежный шлюз по PCI DSS Self-Assessment. Идея может выглядеть спорной (ведь карточные номера PAN мы не храним), но стандарт PCI DSS — это не бюрократическая формальность, а чек-лист, состоящий из правильных практик и советов по работе с sensitive-данными и написанный «кровью».


Платежный шлюз изнутри


У каждого платежного шлюза должна быть архитектура, описанная UML-диаграммой. Так выглядит компонентная модель нашего шлюза:


image alt text


А вот что находится внутри IBackService, IPlugin и прочих интерфейсов:


image alt text


Но сколько диаграмм не рисуй, а словами объяснять все равно придется :) Из чего же состоит шлюз, и какую роль выполняют его компоненты?


Клиентский сайт


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


Платежный шлюз


Шлюз представляет собой RESTful-сервис, который принимает запросы на возвраты и оплату заказов, для чего предоставляет два API:


  1. Back API предназначен только для вызовов со стороны Dodo IS и доступен только в DMZ.


  2. Public API открыт всему интернету — он обрабатывает запросы эквайеров и перенаправления пользователей с клиентского сайта.

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


Плагины


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


Сервисы данных и база данных


Платежный шлюз хранит информацию о платежах в собственной базе данных, закрытой от внешнего мира и от других частей Dodo IS. Доступ к ним невозможен даже для самого шлюза. У базы есть собственный API для управления сущностями, открытый только внутри платежного контура.


Чтобы нагляднее увидеть роль каждого компонента и представить, куда и как текут данные, предлагаю посмотреть на диаграмму потоков данных:


image alt text


Если после просмотра диаграммы вы все еще не понимаете, как проходит платеж в новой архитектуре, посмотрите подробный пример под спойлером.


Типовой сценарий проведения платежа в новой архитектуре на примере Яндекс.Кассы.

Сценарий начала оплаты


N Шаг Пример (Яндекс.Касса)
1 Клиент находится на Клиентском сайте и переходит к оплате заказа. -
2 Клиентский сайт запрашивает у Платежного шлюза доступные для конкретной пиццерии безналичные способы оплаты, вызывая метод GetPaymentTypes. -
3 Клиентский сайт отображает клиенту способы оплаты. Клиент выбирает способ оплаты. Клиент выбирает оплату через Яндекс.Кассу
4 Клиентский сайт отправляет запрос на создание платежа в Платежный шлюз, вызывая метод CreatePayment. Передаются выбранный способ оплаты, идентификатор пиццерии, идентификатор заказа, сумма к оплате, URL'ы оповещения о статусе платежа, успешного возврата и неуспешного возврата. -
5 Платежный шлюз создает платеж в статусе Draft. -
6 Платежный шлюз валидирует платеж и присваивает ему статус Accepted или Rejected. -
7 Платежный шлюз возвращает платеж Клиентскому сайту. -
8 Если платеж отклонен (Rejected), то Клиентский сайт показывает клиенту ошибки и сценарий заканчивается. -
9 Клиентский сайт определяет тип встраивания Платежного шлюза. Тип встраивания указан для каждого способа оплаты.
если тип встраивания «через редирект», Клиентский сайт перенаправляет клиента на страницу оплаты Платежного шлюза PaymentPage, передавая идентификатор платежа.
если тип встраивания «через фрейм», Клиентский сайт отображает клиенту фрейм, в котором открывает страницу оплаты Платежного шлюза PaymentPage, передавая идентификатор платежа.
Тип встраивания для Яндекс.Кассы — «через редирект». Поэтому Клиентский сайт перенаправляет клиента на страницу оплаты Платежного шлюза PaymentPage, передавая идентификатор платежа.
10 Платежный шлюз присваивает платежу статус Started, если платеж находится в статусе Accepted. В противном случае, переходим к сценарию неуспешного завершения оплаты. -
11 Платежный шлюз отображает страницу оплаты с анимацией ожидания. -
12 Платежный шлюз валидирует платеж по идентификатору. Если валидация не пройдена, переходим к сценарию неуспешного завершения оплаты. -
13 Платежный шлюз по способу оплаты определяет плагин, который будет проводить платеж через эквайера. Если плагин не найден, переходим к сценарию неуспешного завершения оплаты. Выбирается плагин для Яндекс.Кассы.
14 Платежный шлюз вызывает у плагина метод StartPayment, передавая платеж. -
15 Плагин выполняет свои специфичные действия, вызывает системы эквайера и возвращает шлюзу результат. Плагин возвращает Платежному шлюзу результат «редирект» и URL страницы оплаты в Яндекс.Кассе
16 Платежный шлюз обрабатывает результат плагина:
если результат — «ошибка», Платежный шлюз переходит к сценарию неуспешного завершения оплаты.
если результат — «платеж проведен», Платежный шлюз возвращает ответ, полученный из плагина, и переходит к сценарию успешного завершения оплаты.
если результат — «ожидание», Платежный шлюз возвращает ответ, полученный из плагина.
если результат — «редирект», Платежный шлюз осуществляет перенаправление на URL, полученный из плагина, и переходит к сценарию ожидания оплаты.
Платежный шлюз перенаправляет клиента на URL страницы оплаты в Яндекс.Кассе и переходит к сценарию ожидания оплаты.

Сценария ожидания оплаты


N Шаг Пример (Яндекс.Касса)
1 Платежный шлюз прослушивает запросы эквайера через универсальный endpoint Acquiring. Этот же endpoint обрабатывает и редиректы клиента, инициированные эквайером. Яндекс.Касса отправляет HTTPS POST на адрес pay.dodopizza.com/acquiring/yamoney/checkOrder
или
Яндекс.Касса отправляет HTTPS POST на адрес pay.dodopizza.com/acquiring/yamoney/checkAviso
или
Яндекс.Касса перенаправляет клиента на адрес pay.dodopizza.com/acquiring/yamoney/success
2 Получив запрос, Платежный шлюз извлекает из параметров запроса имя плагина и создает соответствующий плагин Платежный шлюз по имени yamoney находит плагин для Яндекс.Кассы
3 Платежный шлюз авторизует запрос, вызвав метод плагина AuthorizeAcquiringRequest Плагин проверяет подлинность запроса.
4 Платежный шлюз отправляет запрос на обработку плагина, вызвав метод ProcessAcquiringRequest. Плагин выполняет свои специфичные действия и возвращает шлюзу результат. По параметрам запроса плагин выбирает соответствующий обработчик.
CheckOrder:
Плагин возвращает шлюзу результат «ожидание» и ответ для отправки Яндекс.Кассе
CheckAviso:
Плагин возвращает шлюзу результат «платеж проведен» и ответ для отправки Яндекс.Кассе
success:
Плагин возвращает шлюзу результат «редирект» и URL успешного возврата.
5 Платежный шлюз обрабатывает результат плагина:
если результат «ошибка», Платежный шлюз переходит к сценарию неуспешного завершения оплаты.
если результат «платеж проведен», Платежный шлюз возвращает ответ, полученный из плагина, и переходит к сценарию успешного завершения оплаты.
если результат «ожидание», Платежный шлюз возвращает ответ, полученный из плагина.
если результат «редирект», Платежный шлюз осуществляет перенаправление на URL, полученный из плагина, и переходит к сценарию ожидания оплаты.

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

Поделиться с друзьями
-->

Комментарии (69)


  1. masiandr
    06.04.2017 13:12

    я правильно понял, тестовые заказы на 7,84 миллиона рублей?


    1. BasilioCat
      06.04.2017 13:22
      +3

      судя по статье, это были реальные платежные операции из копии продакшен-базы, которые в результате «обезличивания», (а вернее чистки части данных с продакшена), потеряли связь с заказами. А поскольку транзакции и реляционная целостность в современном мире считается устаревшим подходом, для приведения базы в порядок был специальный сервис, отменяющий платежные операции, не привязанные к заказам. Интересно, почему на продакшене нельзя было делать этого вручную, или может даже исправить причину появления таких операций?


      1. masiandr
        06.04.2017 13:25

        судя по статье это были не реальные платежи

        Особенно обидно было осознавать, что мы вернули деньги, которых не получали — это были тестовые заказы.


        1. BasilioCat
          06.04.2017 13:39

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


        1. andreymore
          06.04.2017 13:45
          +3

          Под «тестовыми заказами» имеются ввиду реальные заказы на тестовой базе. Наверное, неудачная формулировка получилась.


    1. andreymore
      06.04.2017 13:40
      +2

      Это были реальные заказы, загруженные с продакшн-базы в тестовую базу.


      1. dimskiy
        06.04.2017 13:40
        +3

        Знакомьтесь — это Андрей, представитель Додо Пицца.


        1. andreymore
          06.04.2017 13:43
          +4

          Да, я тот самый Андрей Моревский, который автор статьи :)


  1. zharikovpro
    06.04.2017 13:55
    +2

    > На stable-окружении мы стараемся полностью воспроизводить боевые условия — в том числе отмену не привязанных к заказам платежей. В реальных условиях такие платежи могут иметь место из-за ошибок в процессе оплаты или из-за некорректно отработавшей процедуры отмены заказа пользователем.

    Вот этот момент вызывает много вопросов и удивляет меня. Как это может быть так, что платеж есть, а заказа нет? Это пополнение баланса в системе? Если нет — то какое основание есть для формирования счета на оплату и проведения платежа? Вряд ли вам пользователи просто так денег засылают. Поясните пожалуйста, если не сложно.

    P.S. Яндекс.Кассу подключал, как она работает в курсе.


    1. andreymore
      06.04.2017 14:39

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


      1. DenimTornado
        06.04.2017 14:57
        +2

        А что в вашем понимании тогда оформление заказа? То есть вот я выбрал пиццу, сделал заказ, оплатил, это ещё не оформление? То есть я могу заплатить за товар, который «вы» не можете продать?


        1. andreymore
          06.04.2017 15:01
          +1

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


          1. DenimTornado
            06.04.2017 15:05
            +1

            Окей, я понимаю, но как оплата может быть не привязана к заказу в ситуации НЕошибки во время платежа? То есть оплата платежа происходит ведь именно по айдишнику.


            1. andreymore
              06.04.2017 15:15

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


              1. DenimTornado
                06.04.2017 15:19

                ХитрО!


              1. zharikovpro
                06.04.2017 18:44
                +1

                Это возвращение к исходному вопросу. Как может быть оплата без заказа? Заказ это поручение исполнителю выполнить определенную работу (привезти пиццу). Вряд ли кто-то платит, ничего не заказывая. Если бы платежи и возвраты были привязаны к заказам, проблема вообще не возникла бы. Т.к. у вас пошли возвраты по уже оплаченным и даже возможно доставленным заказам.

                Что конечно же совершенно недопустимо с точки зрения архитектуры и бизнес-процессов. Или я неверно понял ситуацию? Ведь фактически вы отправляли деньги за оплаченные и/или доставленные заказы. Чего, по идее, не должно было происходить. Хоть на тестовой базе, хоть где. Сама попытка такое провернуть должна выбрасывать критическое исключение.


                1. andreymore
                  07.04.2017 00:08

                  Заказ как сущность в БД существует на момент оплаты и даже раньше. Дело не в этом. Дело в том, что после оплаты мы перепроверяем, не стала ли пиццерия в стоп за то время, пока клиент оплачивал (или не случилось ли что-то другое, что не даст исполнить заказ). И если исполнение заказа невозможно, мы говорим об этом клиенту и возвращаем деньги. За возврат денег отвечает фоновая задача, которая работает так: она ищет платежи, к которым не привязаны исполненные заказы, и отменяет эти платежи.


                  1. zharikovpro
                    07.04.2017 00:36

                    Спасибо что поясняете. Я пытаюсь понять логику возникновения проблемы. Что-то как ни тужился, не понял ее из статьи. Скрипт нашел заказы оплаченные, но не исполненные. И вернул за неисполненные но оплаченные заказы деньги. Это вроде так и должно у вас работать в обычном порядке? Или данная операция была проведена повторно?


                    1. Chupaka
                      07.04.2017 04:06

                      Заказы в продакшен-базе были оплачены и выполнены. При копировании в тестовую базу обезличивание данных сделало какие-то заказы невыполненными. Скрипт откатил оплаты по этим заказам. Но откатил не по тестовому шлюзу, а по живой Яндекс.Кассе :)


                      1. andreymore
                        07.04.2017 08:16

                        Да, именно так


                        1. zharikovpro
                          07.04.2017 11:26

                          Спасибо, теперь понятно. Экзотическое у вас однако обезличивание для стенда, которое фактически меняет статус заказов.


                    1. andreymore
                      07.04.2017 08:17

                      Посмотрите ниже ответ Chupaka, там все верно описано.


                  1. fireSparrow
                    07.04.2017 09:57
                    +1

                    Насколько я понял, тут просто была не очень хорошо продумана логика.
                    Из того, что я прочитал, мне представляется, что в норме бесхозные оплаты всё равно не должны возикать — вы же не удаляете заказы сразу после того, как их застопорили?
                    Соответственно, автоматом отменять нужно только те оплаты, которые привязаны к застопоренному заказу.
                    А возникновение вообще бесхозной оплаты должно считаться нештатной ситуацией. И если такое обнаруживается, то нужно отправлять аларм человеку, который будет руками разбираться, почему случился такой пердимонокль.


                    1. andreymore
                      07.04.2017 15:59

                      Согласен с вами


        1. shurupkirov
          06.04.2017 16:26

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


          1. DenimTornado
            06.04.2017 16:33

            Хм, ну насколько я понимаю в данном случае деньги не блокировались, а сразу уходили. Иначе бы, всем клиентам тупо вернулись их кровные. А во-вторых, даже если деньги блокируются и транзакций 2, то в первом случае уже есть привязка к некоему id, ну вот не понимаю я как можно получить деньги не привязав их сразу к какому-то родительскому id, пофиг на то, что то там дальше бужет, success_transaction_id, success_order или fail, какой-то parent_id у них обязан быть!


            1. shurupkirov
              06.04.2017 16:43

              1. да, скорее всего так.
              2. при первой транзакции создается ее id, который в дальнейшем и финишируется, если все устраивает получателя, либо финишируется с корректировкой суммы

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


  1. saintbyte
    06.04.2017 14:41
    -22

    Как бы не удивительно что такие проблемы ведь чудо написано на C#.


    1. ffs
      06.04.2017 16:27
      +4

      Видимо я что-то страшное не знаю про С#.


    1. semio
      07.04.2017 09:14
      +1

      А что не так с C#?


    1. Pakos
      07.04.2017 12:07
      +5

      На asm бы такого не случилось, ибо они бы до сих пор писали первый сервис.


  1. rznELVIS
    06.04.2017 16:20
    +2

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

    У меня приятель в Dodo работал. Рассказывал, что подобные «ускорения» приводили к тому, что js и css писали прямо в cshtml файлах в массовом порядке. Описанная в статье проблема была конечно архитектурная, а не тактическая, но симптомы на лицо. Он ушел из Dodo, потому что боялся что «ускорения» к чему-то подобному приведут. Надеюсь выводы сделаны и в дальнейшем у Dodo будет рост качества кода и безотказности системы! А пицца и так вкусная)


    1. balexa
      06.04.2017 18:56
      +1

      Там программистов тоже заставляют на кухне поработать для начала? А то у Федора в блоге (который был весьма интересным когда он писал про макдак и пападжонса) весьма в категоричной форме заявлено что все обязаны работать на кухне при поступлении.


      1. dimskiy
        06.04.2017 19:06
        +5

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


        1. balexa
          07.04.2017 00:26

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


          1. andreymore
            07.04.2017 10:58
            +1

            Если эта информационная система автоматизирует сам процесс клининга, то — да, и программистам и архитекторам и другим инженерам будет полезно помыть пол, используя свою же систему. А если система автоматизирует прием заказов на клининг, то мыть пол не нужно, а будет полезно поработать оператором.
            Это называется https://en.wikipedia.org/wiki/Eating_your_own_dog_food, и продукт в результате получается в сто раз круче.


            1. balexa
              07.04.2017 15:07

              Вы кажется путаете роль дизайнера/юзабилитиста (простите, не знаю как по русски)/аналитика и
              инженера.

              Для того чтобы писать хороший отказоустойчивый бакенд или разрабатывать архитектуру платежного гейта, или быть хорошим DBA или админом линукс-сервера не нужно знать специфику приготовления теста.
              Возможно для тех кто делает фронтенд — да, полезно. Для тех кто делает скетчи интерфейса. Для менеджеров (и то, для тимлидов именно разработки — под вопросом). Но заставлять это делать ВСЕХ разработчиков и инженеров — это просто блажь и упоротость Федора.

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

              Ну и Eating your own dog food это немного про другое. Это когда компания пользуется своим продуктом постоянно, а не когда нет разделения между программистами и уборщицей.


              1. andreymore
                07.04.2017 16:07

                Простите, но вы немного перегибаете.

                «С такой точки зрения инженерам много что полезно, побывать на всех этапах цепочки. И поработать курьером, поразвозить пиццу»
                У нас пока нет аппов для курьеров. Но где-то через год они будут и тогда — да, поработать курьером будет полезно

                «И поработать официантом, потому что они через сколько-то слоев взаимодействуют с бакендом»
                В пиццерии нет официантов.

                «И поработать уборщицей в туалете, потому что у вас вот все сотрудники взаимозаменяемы.»
                Мы не автоматизируем уборку туалетов, так что это лишнее

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


                1. balexa
                  07.04.2017 16:23
                  +1

                  У нас пока нет аппов для курьеров. Но где-то через год они будут и тогда — да, поработать курьером будет полезно

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

                  В пиццерии нет официантов.

                  Ну и что? Это ваша модель бизнеса, я же в целом говорю… Если бы официанты были, я так понимаю разработчики бы работали ими в том числе?

                  как работает пиццерия изнутри обязательно

                  Для этого совершенно необязательно работать неделю в Сывтывкаре.

                  От этого однозначно не будет хуже

                  Не будет. Но будет ли лучше — далеко не факт. Возможно это время стоило бы потратить на изучение чего-то более полезного. Например как логику тестирования платежей делать.


                  1. andreymore
                    07.04.2017 17:03
                    +3

                    «Потому что работа курьером — это мягко говоря низкоквалифицированный, тяжелый и достаточно небезопасный труд.»
                    Можно просто доставить несколько заказов, находясь рядом с настоящим курьером. Было бы желание, а решение найдется.

                    «Для этого совершенно необязательно работать неделю в Сывтывкаре.»
                    Необязательно в Сыктывкаре и неделю. Пиццерии есть в Москве.

                    «Но будет ли лучше — далеко не факт.»
                    Наш опыт показывает, что будет лучше. Опыт — штука субъективная, я понимаю. Что и хочу донести в нашей переписке.


        1. devpreview
          08.04.2017 11:14
          +1

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


      1. andreymore
        07.04.2017 00:16

        Заставляют — не совсем верное слово. Это условие работы, которое обговаривается заранее. Можно проходить стажировку не с начала, а через полгода, например.


        1. balexa
          07.04.2017 00:25
          +1

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


          1. muon
            07.04.2017 08:38
            +3

            Квалификация нарабатывается. Мосигра как-то писала, что иногда набирает в ИТ продажников с некоторыми зачаточными ИТ-навыками, а потом доучивает. С позиции рядового сотрудника это неочевидно, но учить легче, чем перевоспитывать.


            1. andreymore
              07.04.2017 10:59
              +1

              Именно так.


            1. balexa
              07.04.2017 11:24

              Она набирает эникейщиков, хелпдеск на местах. Архитектора и даже сеньор девелопера вы из пиццайоло с зачаточными навыками айти за вменяемое время не подготовите.


              1. muon
                10.04.2017 05:59
                +1

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


                1. balexa
                  10.04.2017 15:34
                  +1

                  Разработчика уровня сеньора не говоря уже про архитектора вы не подготовите из человека с зачаточными IT-навыками менее чем за 5-10 лет. Это даже не учитывая что хороший разработчик на одном таком проекте как ИС додо-пицца не вырастет.


    1. vvzvlad
      06.04.2017 21:08

      Не очень-то и вкусная. 6/10


      1. navion
        09.04.2017 23:56
        -2

        Совсем невкусная. Из массовых лучшая у Папа Джонса, не в каждой пиццерии получается хрустящая рельефная корочка, но даже без неё пицца далеко впереди конкурентов из Пиццы Хат (совсем не как в 90-е) и Доминос (у них беда с рецептами).
        А Додо может конкурировать с Империей пиццы и прочим локальным продуктом.


    1. TimsTims
      07.04.2017 11:44
      +1

      > Он ушел из Dodo, потому что боялся
      Зря боялся:
      > Мы не будем наказывать людей

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

      Итог: Вместо того, чтобы попробовать направить в нужное русло он просто свалил…


  1. StarMarine
    06.04.2017 17:00
    +1

    Я так и знал: навыки, аккуратность и опыт не заменишь UML-диаграммами.


  1. masiandr
    06.04.2017 18:34

    Советую в архитектуру добавить систему антифрода — без нее вы в будущем получите еще много неприятностей.
    И да, ни какой финансовый запрос в АПИ не должен выполняться в обход системы антифрода. Это аксиома для платежного шлюза. У разработчика не должно быть шансов создать endpoint в АПИ не унаследовав базовые проверки в антифроде. В первом приближении система антифрода может быть обычной таблицей барьерных лимитов.


    1. AK74U
      06.04.2017 19:07

      Можно для не-специалистов указать, что доброго почитать по теме?


    1. andreymore
      07.04.2017 00:18

      Спасибо! Да, планируем антифрод после запуска первой версии шлюза.


  1. customtema
    07.04.2017 00:32
    -2

    А меня за такие косяки по рукам били. И я бил.

    Неужели Senior Developer не поменяли? Просто пройтись по статье — косяков Senior Developer немеряно, начиная от «сильной связи». Жесткие такие косяки.

    Хотя, такие люди, как правило, очень амбициозны, и поэтому очень убедительны. "Я создал монстра, и потратил на это много денег" — и его начальство любит и очень ценит, ведь он так крут. «Unix Way? Игрушка. Устойчивая распределенная архитектура? Оставьте это для учебников...»

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

    Простите за прямоту.


    1. dimm_ddr
      07.04.2017 09:52
      +1

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


      1. customtema
        11.04.2017 03:22

        Схемку на коленке можно накидать за 5 минут.

        5 минут как-то задержат интеграцию? Спорим, они на тысячу порядков больше времени потеряли?


    1. ggo
      07.04.2017 10:03

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


    1. Azoh
      07.04.2017 11:38

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

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


  1. KoToSveen
    07.04.2017 09:16
    +1

    Очень радует тенденция публикования историй факапов, в которых:

    «Безусловно, мы сделаем серьезнейшие выводы из этой критической ошибки. Мы не будем наказывать людей — мы просто сделаем все, чтобы такого больше не повторилось.»

    Ни разу у вас пиццу не заказывал (в нашем городе относительно недавно), но сегодня это сделаю.


  1. envtmp
    07.04.2017 09:34
    +1

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


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

    Хотя, вероятнее, копия репозитория с некоей версией шлюза валяется на локальном диске каждого разработчика, вносившего изменения.

    Привет, Андрей, весело у тебя там.


  1. jetexe
    11.04.2017 18:19
    -1

    Как-то такие статьи очеловечивают компанию. Не было мысли попробовать заказать у вас, а сейчас сижу ем


  1. Orky
    12.04.2017 11:40
    -2

    Всем привет.
    Ситуация с Додо-пиццей привлекла и моё внимание. Именно из-за того, что
    Примерно полтора года назад мы в CloudPayments сделали возможность отменять совершенные возвраты в течение 3 часов после их совершения: в это время мы еще не отправляем окончательное подтверждение в МПС. Кроме того, даже если эти три часа будут упущены, не получится сделать возвратов больше, чем на суточный оборот.
    И в этой ситуации, чтобы не отменять вручную возвраты по всем этим 10000 заказов, можно было бы написать или позвонить в нашу поддержку, мы бы эти возвраты завернули в течение пяти минут.


  1. Filex
    12.04.2017 11:43

    недавно в развлекательных сетях проскакивала новость, что в до-до пицца сейчас вся внутренняя переписка только на английском, это правда?


  1. Mike_Lp
    12.04.2017 11:44

    Классика. Рано или поздно многие это проходят. Мы в свою очередь «привязали» продакшн условно к серверу — любое перемещение в тестовую среду просто отключает реальные клиентские сервисы…


    1. Orky
      12.04.2017 15:30

      А как у вас ПО узнает, что оно в тестовой среде?


      1. Mike_Lp
        12.04.2017 17:46

        Я думаю решений много и они очень индивидуальны в каждой системе. Если очень просто и условно, то у сервиса существует настройка — продакшн сервер. Запускаясь в тестовой среде сервис понимает, что его запустили не там где надо, и исходя из этого надо использовать альтернативную конфигурацию или что-то отключить. Параметр настройки я привел здесь достаточно условно — это может быть любым (любыми) отличиями тестовой среды.


  1. Shablonarium
    16.04.2017 03:33
    +1

    Не понимаю, как Вы еще не разорились. Никакой информации про цену доставки, про режим работы. Сидел в 3 часа ночи выбирал пиццу, регистрировался, вбивал код с телефона — и это все чтобы узнать что никто ночью не может принять мой заказ? Я удручен таким обслуживанием.