Кейс интеграции сайта на Tilda с Бизнес.Ру: отображение наличия товаров в разных городах

Кейс интеграции сайта на Tilda с Бизнес.Ру: отображение наличия товаров в разных городах

В одном из прошлых постов в своем блоге в Telegram я упоминал о том, что сейчас я чаще работаю с конструктором сайтов Tilda.
Сегодня я хочу рассказать об очередной интеграции, которую я делал для интернет-магазина на этом конструкторе — на этот раз с платформой складского учета Бизнес.Ру.

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

Алексей Иванов
Фулстек веб-разработчик

Содержание

1. Постановка задачи

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

Дано

У клиента есть система складского учета Бизнес.Ру, в которой производится учет товарных позиций и заказов. У каждой позиции есть информация о наличии по каждому складу отдельно.

Проблема

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

Решение

При открытии карточки товара на сайте Tilda можно дополнительно загружать информацию о наличии этого товара на нужных складах через API Бизнес.Ру.

2. Архитектура интеграции

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

Для корректного подключения API необходимо создать приложение-прослойку между Tilda и Бизнес.Ру в виде программы на языке PHP:

Общая схема взаимодействия сайта на Tilda с API Бизнес.Ру через приложение
Общая схема взаимодействия сайта на Tilda с API Бизнес.Ру через приложение

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

3. Реализация программы

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

Выбор языка программирования был сделан просто: библиотека Бизнес.Ру для взаимодействия c API написана для PHP. И хотя сейчас я чаще работаю с TypeScript, чтобы не тратить время на реализацию взаимодействия с их API с нуля, а решил использовать готовую библиотеку.

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

Технические аспекты реализации

К сожалению, библиотека от Бизнес.Ру достаточно старая — последнее обновление было в 2022 году, и написана она была для PHP 7-й версии. Поэтому при попытке использовать ее в современном проекте возникли ошибки из-за остутствия аннотации типов (type hinting) в некоторых местах.

Чтобы это исправить, я вынес зависимость Composer в локальный каталог и исправил код там. Для использования исправленного варианта в коде, я модифицировал раздел autoload в composer.json:

{ "require": { ... }, "autoload": { "psr-4": { "App\\": "src/", "bru\\api\\": "lib/business-ru/business-online-sdk-php/src/" } } }

После этого стало возможным использовать данную библиотеку в соответсвии с документацией API.

Структура программы

Микрофреймворк Slim имеет следующие основные структурные элементы:

  • Точка входа в программу — app.php, в котором производится инициализация и запуск приложения, подгрузка всех зависимостей и конфигурации;
  • Промежуточная логика для каждого запроса — middleware.php. Здесь находится логика, отвечающая за ограничение доступа по ключу API (к нашему приложению, а не к API Бизнес.Ру) и настройка CORS-политики для ограничения обращения только нужного нам домена сайта на Tilda;
  • В файле routes.php определены машруты нашего приложения и их обработчики (контроллеры). В данном случае у нас только один маршрут: /remains.

Вот так выглядит точная файловая структура приложения (опуская файлы для разворачивания в Docker контейнер):

. ├── composer.json ├── public │ └── index.php <== Точка входа в приложение для реверс-прокси └── src ├── app.php <== Точка входа для запуска приложения ├── middleware.php <== Авторизация доступа и настройка CORS ├── routes.php <== Машрутизация ├── services.php ├── Services <== Сервисы для инъекций зависимостей │ ├── BusinessRuApi.php │ └── Env.php └── Controllers <== Контроллеры с логикой для обработки запросов └── RemainsController.php

Каждый запрос от клиента обрабатывается файлом index.php, который в свою очередь вызывает app.php. Именно там происходит инициализация приложения на фреймворке Slim:

<?php namespace App; use DI\Container; use Slim\Factory\AppFactory; use Slim\Factory\ServerRequestCreatorFactory; AppFactory::setSlimHttpDecoratorsAutomaticDetection(false); ServerRequestCreatorFactory::setSlimHttpDecoratorsAutomaticDetection(false); $container = new Container(); // Load service definitions (require __DIR__ . '/services.php')($container); $app = AppFactory::createFromContainer($container); // Load middleware (require __DIR__ . '/middleware.php')($app); // Load routes (require __DIR__ . '/routes.php')($app); $app->run();

Полный исходный код приложения доступен в репозитории на GitHub:

Возвращение наличия товара по запросу клиента

Интернет-магазин клиента продает одежду. У одного и того же товара есть разные варианты размера и цвета. Следовательно одного артикула для поиска товара недостаточно, надо также учитывать все модификации товара (например, размер: 42, цвет: черный).

Это было учтено при разработке, и поэтому конечный запрос со стороны сайта к серверу имеет следующий вид:

/remains? store[]=казань&store[]=москва&sku=NNN& variant[Размер]=42&variant[Цвет]=черный

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

За обработку данного запроса и возврат данных отвечает метод index контроллера RemainsController:

public function index(Request $request, Response $response) { try { $remains = $this->getRemains($request, new RemainsOptions( actualAmount: false, manyThresholdAmount: 5, )); $response->getBody()->write(json_encode([ 'result' => [ 'remains' => $remains, ], ])); } catch (\Exception $e) { return $response->withStatus(500); } return $response->withHeader('Content-Type', 'application/json'); }

Форматирование данных

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

class RemainsOptions { public function __construct( public bool $actualAmount = true, public int $manyThresholdAmount = 5, ) {} } ... protected function getRemains( Request $request, RemainsOptions $options = null, ) { ... foreach ($stores as $store) { ... /* * Форматирование результата зависит от указанных настроек и может * быть как количеством, так и названием "много", "мало" и т.п. */ if ($options?->actualAmount) { $entry['amount'] = $this->getAmount($store, $modification); } else { $entry['quantity'] = $this->getQuantity( $store, $modification, $options ); } $remains[] = $entry; } return $remains; }

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

4. Разработка модификации для Tilda

После разработки программы на PHP и установки ее на VPS-сервер, также была разработана модификация для сайта на Tilda, которая выводила отображение наличия при выборе определенного варианта товара (цвет, размер).

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

document.addEventListener('DOMContentLoaded', async () => { // Инициализация наличия товаров при открытии попапа $(document).on('click', async e => { const productLink = e.target.closest('a[href*="/tproduct/"]') if (productLink != null) { await showRemains() }; }); // Инициализация наличия товаров при загрузке страницы (async () => { const snippet = await waitForElement('.t-store__product-snippet', 100) if (!snippet) return; await showRemains(); })() })

Здесь waitForElement — моя utility-функция для асинхронного ожидания элементов на странице, которую я использую практически в каждом своем проекте, связанным с Tilda.

showRemains — процедура, которая модифицирует верстку страницы, добавляя блок для отображения текста с наличием:

Промежуточный вариант без группировки складова по городам
Промежуточный вариант без группировки складова по городам

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

5. Конечный результат

В итоге для клиента была создана интеграция, состоящая из нескольких элементов:

  • Собственного сервера, на котором размещена программа для взаимодействия с API Бизнес.Ру. Этот сервер выступает связующим звеном между сайтом на Tilda и системой складского учета;
  • Программы на языке PHP, которая запакована в Docker-контейнер и установлена на вышеупомянутый сервер;
  • Модификации сайта на Tilda для отображения информации в интерфейсе. Информация о наличии товара отображается на сайте в простом и понятном виде (например: «много», «мало», «нет в наличии») и помещена в раскрывающийся список рядом с другими параметрами товара.

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

Если вам понравилась статья — поставьте лайк 🔥 или напишите комментарий. Так я пойму, что подобные посты с кейсами интересны и буду писать больше таких статьей.

Если вам нужна разработка уникальной модификации или интеграции Tilda с CRM или сторонним сервисом по API: Telegram-ботом, искуственным интеллектом / ChatGPT или даже маркетплейсом — примеры моих работ и контакты доступны по ссылке: codly.cc

А в своем блоге «Код без тайн» я периодически пишу о веб-разработке, информатике и других сферах, которые меня вдохновляют (искусственный интеллект, дизайн и многое другое).
11
11
Начать дискуссию