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



Привет, Хабр! Мы в 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! Все фотографии в посте — сцены из жизни нашего офиса.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (16):

  1. tumikosha
    /#18874373 / -2

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

  2. tyraelqp
    /#18874427

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

    • chainick
      /#18874509

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

  3. nikitasius
    /#18874849 / -2

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


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

    Где все это?

    • chainick
      /#18874959

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


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


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


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

  4. tyraelqp
    /#18874951

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

    • chainick
      /#18874989

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


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

  5. AntonyLazer
    /#18876043

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

    • chainick
      /#18876205 / +2

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


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


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

  6. anonymouz
    /#18876549 / +1

    Наконец-то динамический опердень на erlang

  7. ElMaxo
    /#18878253 / +1

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

    • chainick
      /#18879587 / +1

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


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

  8. imbasoft
    /#18878741

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

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

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


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

    • chainick
      /#18879637 / +1

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

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