Как сделать платежную систему своими руками


    Привет, Хабр! Мы в RBKmoney новый платежный процессинг написали. С нуля. Ну не мечта ли?


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


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


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


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


    Disclaimer

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


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


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


    Корзина, в которую можно положить покупки даже во время торнадо



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


    Подход звучит знакомо, не так ли?


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


    Конечно, мы не нарушаем законы физики и не придумали как опровергнуть CAP-теорему. Не факт, что платеж тут же и проведется — ведь могут быть неполадки и на стороне банков, но запрос сервис создаст, и пользователь увидит, что все сработало. Да и нам до идеала еще десяток листингов беклога с техническим долгом, чего греха таить, можем и 504 ответить изредка.


    Заглянем в бункер, раз торнадо за окном



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


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


    Сами приложения у нас крутятся в Docker-контейнерах, логи из которых мы надежно сливаем в центральное Elasticsearch-хранилище; друг друга они находят через Service Discovery, а данные передают по IPv6 внутри Макросервиса.


    Все собранные и работающие совместно микросервисы вместе с сопутствующими службами являются Макросервисом, который предоставляет вам в итоге платежный шлюз, каким вы его видите снаружи в виде нашего публичного API.


    За порядком приглядывает SaltStack, в котором описано все состояние Макросервиса.


    Мы еще вернемся с подробным описанием всего этого хозяйства.


    С приложениями легче.


    А вот если хранить где-то состояние, то обязательно в такой базе, в которой минимальна цена выхода из строя части нод. Еще чтобы в ней не было мастер-нод с данными. Чтобы могла с предсказуемым временем ожидания на запросы отвечать. Это тут мечтают? Тогда еще чтобы ее обслуживать особо не надо было, и чтобы разработчикам-эрлангистам нравилась.


    Да, разве мы еще не сказали, что вся онлайн-часть нашего процессинга на Эрланге написана?


    Как многие уже, наверное, догадались выбора у нас как такового и не было.


    Все состояние онлайн-части нашей системы хранится в Basho Riak. О том, как готовить Riak и не сломать себе пальцы (потому что мозг вы сломаете обязательно), мы еще расскажем, а пока продолжим дальше.


    Где деньги, Лебовски?



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


    К счастью, это привело к положительным эффектам. Когда понимаешь, что тебе как разработчику, будет несколько затруднительно получить 40 физических ядер, адресующих 512GB оперативки, приходится выкручиваться и писать маленькие приложения. Зато их можно развернуть сколько угодно много — сервера все-таки недорогие.


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


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


    Но с серверами легче.


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


    Но с дисковыми массивами так не поступить! Выход из строя даже небольшого дискового хранилища — это отказ части платежного сервиса, чего мы себе позволить не можем. Дублировать СХД? Слишком нецелесообразно.


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


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


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


    Таким образом у нас получилась удобная, отказоустойчивая и универсальная система — стойка, набитая простыми дешевыми серверами, несколько свитчей. Следующая стойка. И так далее.


    Просто, удобно и в целом — очень надежно.


    Прослушайте правила поведения на борту



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


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


    Мы решили ничего не запрещать, а наоборот, поощрять все новое. Так у нас в продакшене построился Макросервис из огромной кучи приложений в докер-контейнерах, управляемый через SaltStack, кластеры Riak'а, Consul в качестве Service Discovery, оригинальная реализация трассировки запросов в распределенной системе и множество других замечательных технологий.


    И все это безопасно настолько, что можно без стыда публиковать программу Bugbounty на hackerone.com.


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


    Спасибо, что выбрали нашу авиакомпанию!


    P.S.: Original content! Все фотографии в посте — сцены из жизни нашего офиса.

    RBK.money 83,74
    RBK.money – современная платежная платформа
    Поделиться публикацией
    Комментарии 18
      –1

      Оооо… на Erlang? Да вы решили открыть собственную велосипедостроительную фабрику…

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

          Есть такая возможность. Вам достаточно передать popupMode=true в API чекаута он откроется в новой вкладке вот так: https://rbk.mn/3anEhu1a0ra

            +2
            Недоглядел, спасибо.
          +2

          Статья ни о чем, деталей нет. Вроде как "блаблабла, да еще блаблабла".


          • Как реализована обработка транзакций, откатов и факапов с ними?
          • Сколько нагрузка в среднем или, уж, сколько ресурсов (запросов, вызовов внутри софта и памяти) жрет обработка?
          • Рилтайм или нерилтайм, и как быть с блокировками?

          Где все это?

            +4

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


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


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


            Этот блог не будет маркетинговой водой, честно!

              0

              Жду с нетерпением!

            0
            Есть ли возможность для одного магазина создавать инвойсы в разной валюте? В заявке на открытие магазина можно указать только одну.
              +2

              В одном магазине может быть только одна валюта одновременно. Но вы можете себе создать сколько угодно магазинов в нужной вам валюте, просто укажите ее символьный код в https://dashboard.rbk.money/shop/create/.


              Единственный нюанс — платформа технически поддерживает любые валюты, но на бою будут доступны RUB, EUR и USD на данный момент. В тестовом магазине можете указывать какую угодно.

              0
              Интересно, что все эти штуки дают с точки зрения конечного продукта — для пользователя и для мерчанта?
                +2

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


                Я не маркетолог и этот блог не бизнесовый.


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

                +1
                Наконец-то динамический опердень на erlang
                  +1
                  Когда увидел отсылку к Amazon Dynamo — сразу почему-то подумал, что речь пойдет о Riak, Erlang, Consistent hashing, Riak Pipes и т.д. Мы еще в далеком 14-м году это пробовали, но потом забросили, к сожалению. Очень интересны технические подробности. Кстати, работники в команду не нужны?:)
                    +1

                    Технические подробности будут обязательно, следите за блогом.


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

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

                    Интересный подход, обычно пишут чтоб комфортно было потребителям.

                    В описании bug bunty написано:
                    Политика вознаграждения
                    В настоящий момент мы не осуществляем выплату вознаграждения за найденные уязвимости в соответствии с правилами HackerOne Vulnerability disclosure program (VDP).


                    Насколько бесплатная программа будет эффективной?
                      +1
                      Насколько бесплатная программа будет эффективной?

                      Ну чтобы прямо было сильное отличие от платной программы я не заметил. Мы благодарим за репорты кармой в ха1, это тоже имеет ценность для исследователей. Разве что сильно меньше трешака от "хакеров с кволисом" и репортов типа "у вас тут http без TLS в мир открыт, уязвимость!".

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

                      Очень интересует общая схема маших сервисов+бд и как у вас реализованы транзакции и их откаты.
                        0

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


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


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

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

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