PHP-библиотеки для e-commerce: работа с АТОЛ и Payture, парсинг кодов GS1 и другие задачи

    Привет, меня зовут Павел Савельев, я руководитель отдела автоматизации бизнес-процессов в Lamoda. Мы работаем с очень разными задачами, и стараемся подобрать для каждой наиболее удобный инструментарий. Соответственно, мы используем разные языки — в наших системах можно встретить и Java, и Go, и немного Kotlin под андроид. При этом значительная часть разработки ведется на PHP, на нем написаны более двух десятков сервисов, которые автоматизируют не только работу с заказами, но и операционные процессы широкой сети доставки, колл-центров в трёх странах и собственной фотостудии, а также предоставление всего этого в виде услуг нашим B2B-партнерам. Эти сервисы поддерживают и развивают 5 команд разработки нашего отдела.

    image

    По мере развития как самих сервисов, так и инфраструктуры вокруг них, в этих системах все чаще возникают похожие задачи, такие как логирование в общую CLS (Centralized Logging System), тестирование файлового хранилища, сбор метрик для Prometheus и другие. Мы стараемся стандартизировать способы решения таких задач и использовать для разных систем общие компоненты.

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

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

    Более двух десятков наших PHP-библиотек мы выложили в публичный доступ на GitHub. И планируем выкладывать и дальше. Зачем? Ну, мы вложили много ресурсов и (хочется верить) сделали хорошо. И мы хитро надеемся, что другие разработчики будут использовать наши библиотеки, помогать их допиливать и развивать дальше, вместо того, чтобы тратить время на написание своих аналогов с нуля. В этой статье я хочу кратко рассказать про семь библиотек, разработанных для решения частых для e-commerce задач — я буду рад, если они пригодятся и вам, а еще больше обрадуюсь их совместному развитию :)

    1. Онлайн-фискализация: клиент для АТОЛ Онлайн


    Как и другие компании России, мы обязаны полностью соответствовать требованиям ФЗ-54, одним из которых является онлайн-фискализация. Все заказы, предоплачиваемые на сайте lamoda.ru, обязательно фискализируются: на них формируются онлайн-чеки, которые отправляются покупателям. Наш сервис фискализации работает по API с системой АТОЛ Онлайн, и первая в нашем списке библиотека — полноценный клиент для этого сервиса. Помимо самой библиотеки мы выложили также бандл, при помощи которого можно легко подключить ее к любым проектам на базе фреймворка Symfony. Сама же библиотека может быть встроена в любой другой PHP-фреймворк: Laravel, Yii и др. — достаточно написать лишь “обертку” для библиотеки.

    2. Предоплатные платежи: взаимодействие с Payture


    Для обработки предоплатных платежей мы активно взаимодействуем с сервисом Payture. У этого сервиса есть несколько программных интерфейсов. Мы используем вариант Payture InPay и написали собственный API-клиент для него. Библиотека позволяет манипулировать несколькими терминалами, поддерживает стандартное логирование PSR-3. Также есть возможность использовать преднастроенный клиент Guzzle — это позволяет легко организовать тестирование с помощью Guzzle Mock Handler.

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

    3. Маркировка товаров: парсер кодов GS1 Datamatrix


    Один из важнейших проектов 2019 года в нашей компании — поддержка государственной маркировки товаров. В рамках этого проекта на все товары определенных категорий будут наноситься специальные уникальные коды — в формате GS1 Datamatrix. Эти коды позволят любому покупателю проверить подлинность товаров, их происхождение и историю. Для того, чтобы внутренние системы Lamoda могли работать с этими штрихкодами, мы разработали библиотеку для правильного парсинга кодов GS1.
    В ближайшее время мы также планируем выложить исходные коды разработанных нами клиентов для взаимодействия с Информационной Системой Маркировки и Прослеживаемости (ИС МП).

    4. Управление микросервисами: middleware для шины команд Tactician


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

    Однако, возникла проблема: наши фоновые команды часто взаимодействуют с внешними сервисами, которые имеют ограничение на количество операций в n секунд. А в Tactician отсутствует возможность управлять количеством исполняемых команд в определенное окно времени. Поэтому мы разработали дополнительный middleware — библиотеку Tactician rate limit. С ее помощью можно добавить новый слой обработки, который отслеживает количество выполняемых в шине команд согласно выбранной стратегии rate limiting. Стратегии подключаемы, из коробки доступны стратегии из библиотеки stiphle.

    Также в открытом доступе есть наш Symfony bundle к библиотеке.

    5. Сбор и рендеринг метрик для Prometheus


    Наши микросервисы генерируют технические и бизнес-метрики, которые потом собираются через Prometheus Operator со всего кластера k8s. Для управления всем этим мы написали библиотеку, которая обрабатывает пользовательские метрики по сценарию «собери-сохрани-покажи». При этом библиотека поддерживает режимы работы, в которых можно опустить один из пунктов сценария, чтобы увеличить эффективность. Например, для быстрых вычислимых метрик может выполняться упрощенный сценарий «собери-покажи». А работа с медленными бизнес-метриками может частично переводиться в фон, при этом разбиваясь на два этапа: «собери-сохрани» + «собери (из хранилища) — покажи».

    В библиотеке есть необходимые уровни абстракции как для написания своих генераторов метрик, так и для написания хранилищ. Из коробки есть абстрактный адаптер для Doctrine, который можно настроить на entity для сохранения данных в БД.

    В качестве форматов рендера метрик в данный момент поддерживаются prometheus и telegraf httpjson.

    В комплекте к библиотеке идет Symfony bundle, который предоставляет семантическую конфигурацию источников метрик, хранилищ и роутинга метрик. Также в нем есть команды-хелперы для отладки и сохранения метрик из источников (например, для расчета метрик по cron).

    6. Тестирование файлового хранилища: работа с разными файловыми системами


    Для автоматизации тестирования мы используем фреймворк Codeception, который позволяет нам писать тесты различных уровней и имеет достаточно обширную библиотеку стандартных модулей. Подробнее о наших подходах к разработке тестов мы писали недавно в отдельной статье и рассказывали на конференции PHP Russia. У Codeception есть готовые модули для взаимодействия с FTP и локальной файловой системой FileSystem, но в наших тестах есть потребность работы с бОльшим количеством файловых систем. Как минимум, мы используем еще AWS S3 и Webdav. Кроме того, со всеми файловыми системами хотелось бы взаимодействовать по одному API (это же всё файловые системы :)).

    К счастью, существует открытая библиотека FlySystem, которая предоставляет единый программный интерфейс для работы с разными файловыми системами. Так что нам потребовалось только объединить два инструмента — что мы и сделали, написав обертку над FlySystem в виде модуля Codeception-flysystem. Сейчас он поддерживает SFTP, S3 и Webdav. Достаточно один раз сконфигурировать настройки для подключения к нужной файловой системе в yml-конфиге тестов, и после этого можно работать со всеми файловыми системами по одинаковому набору методов: записать файл, скопировать файл, почистить директорию и т.д. Модуль уже включён в страницу дополнений и рекомендаций от Codeception: codeception.com/addons.

    7. Работа с переменными окружения в multi tenant режиме


    В отделе автоматизации бизнес-процессов существуют системы, которые работают в режиме multi tenant (многоарендности). Для обеспечения их работы необходимо уметь работать с переменными окружения — определять, какую именно переменную использовать в текущий момент времени.

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

    Продолжение следует


    Это лишь первая часть библиотек. Внутри у нас есть ещё с десяток — они ждут очереди, когда мы их немного «причешем» и выложим в общий доступ. Меня мотивирует понимание, что эти библиотеки могут быть полезны кому-то ещё. Я радуюсь комментариям и звёздочкам на гитхабе, и надеюсь дальше развивать библиотеки вместе с другими разработчиками. Ведь с АТОЛ и Payture работают многие российские e-commerce проекты. Для Datamatrix, помимо описанного в статье парсера кодов, у нас есть еще пара клиентов, которые мы уже используем внутри — эти библиотеки первые в очереди на GitHub.

    Стараемся не забывать и про остальные языки — мы уже выложили первую библиотеку на Go (про нее подробнее писали тут на Хабре) и готовим другие. Stay tuned!
    • +32
    • 3,6k
    • 8
    Lamoda
    181,13
    Russian Fashion Tech
    Поделиться публикацией

    Комментарии 8

      0
      Если возможно, расскажите поподробнее про технические и бизнес-метрики Ваших микросервисов и как и чем они потом обрабатываются для генерации отчетов?
        +1
        Технические метрики для микросервисов мы собираем глобально двух типов — инфраструктурные (la приложения, базы, состояние подов k8) и данные из работающего приложения (например длину очереди задач, внутренние счетчики ошибок\событий). Для бизнес метрик используем в основном данные из приложения — как пример мы чаще всего смотрим сколько времени занимают те или иные задачи в микросервисе (нам важны такие SLA, т.к. есть вполне конкретные юридические ограничения на время проведения некоторых финансовых операций).

        В проектах, написанных на PHP, помощью lamoda/metrics мы формируем отчеты либо в режиме on demand (т.е. пересчитываем каждый раз, когда скрейпер приходит забирать отчет), либо в фоновом режиме (тогда отдаем последний отчет скрейперу каждый раз).

        Отчеты формируем в родном формате prometheus (раньше использовали telegraf httpjson, поэтому в либе есть и этот формат).

        Дальше уже просто работаем с прометеусом как с источником данных в различных системах (grafana, icinga).

        Параллельно с этим используем (особенно для метрик связанных с фактами вида «что-то произошло») обычное логгирование
          0
          Спасибо большое!
        0
        Востребовано решение на PHP по работе с кассами АТОЛ которые не «в облаке — АТОЛ-онлайн», а которые на «столе», типа АТОЛ-55Ф и иже с ними. Многие у кого и магазин и сайт вынуждены 2 кассы держать, т.к. сайты на PHP, а работа с драйверами только на Python, С++ и на Андроиды. Костыли есть, но не многие «осиляторы»… В свое время пришлось городить транслятор вызовов из PHP в Pyhton ради того чтоб пофискализировать продажи с сайта…
          0
          Доступ к принтеру АТОЛ можно получить через COM. Тем более в стандартном комплекте дров есть примеры, в том числе, на JS.
          Зачем что-то ещё?
            0
            Многие сайты на PHP делаются до сих пор. И логично имея бекенд на PHP, писать всё на нем, чтоб не делать вермишель
              0
              Если у вас касса офф подключена к не к серверу, проще сделать через JS.
              Я делал через COM — приложение и касса были запущены на одном компе.
              Если вы каким то образом зацепитесь к кассе через СОМ от сервера — делайте на PHP.
              ewolf говорит, что есть свой веб-сервер кассы — пробуйте через него, на том же PHP.

              В общем сначала нужно читать доку.

            +1
            Мы держим АТОЛ в облаке для фискализации всех операций, которые происходят без физического участия сотрудников: онлайн платежи на сайте, возвраты и т.п. Это очень удобно именно для онлайн платежей и интернет магазинов, которые не осуществляют физические рассчеты на месте. Надеемся, что скоро станет законодательно возможно и оффлайн рассчеты тоже фискализировать через онлайн кассы.

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

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

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

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