Типичный заказ выполненный на WordPress

Действующий сайт:

Код темы wp
(без плагина интеграции банка):

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

Задачу поставил один из моих старых заказчиков, которому в прошлые годы я уже делал ряд сайтов с использованием WordPress, поэтому варианты реализации помимо WP я рассматривал очень недолго. Окончательно убедил меня встреченный где-то на Medium комментарий от человека, в течение ряда лет работавшего над реализацией и развитием обычного сайта со скромными запросами, используя современный стек на основе SPA. Свою работу он характеризовал как поточное производство велосипедов. Это подтвердило мои подозрения и заставило отбросить желание испробовать современный стек на малом проекте.

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

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

В результате я пришёл к следующему гибридному решению, оптимальному, на мой взгляд, для решаемой задачи. Сайт существует как обычный сайт WordPress с сокращённым количеством роутов, то есть основные разделы обладают собственными адресами, но содержат на странице одно или несколько мини приложений (виджетов) реакт, предоставляющих основной функционал без перезагрузки страницы, выполняя свои api-запросы.

Для того, чтобы с сервера приходила полноценная страница, данные, извлекаемые из базы, не отдаются сразу в html, а сохраняются в переменные, после чего посылаются дважды: в виде html и в виде json.

Браузер отображает нормальную веб-страницу, а react-приложение (виджет) рендерится, замещая собой часть DOM-элементов, но без необходимости делать api запрос на сервер, так как все необходимые данные уже присутствуют на странице в виде json.

Выгоды этого подхода перевешивают недостаток в виде двойного рендера (виджетов не может быть много в силу природы предметной области и рендер происходит быстро):

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

Отображение данных в реальном времени

В процессе работы с сайтом данные должны обновляться без перезагрузи страницы, то есть нужно получить отображение на странице количества собранных средств для каждой благотворительной программы в реальном времени, даже если в этот момент деньги перечисляет не данный пользователь, а какие-то другие. Для работы виджетов в таком режиме, без перезагрузки страницы, я использую базу firebase real time database. Google рекомендует переходить на использование firestore в качестве активной базы данных, однако, реализация управления этой бд для php требует наличия php-плагина, то есть накладывает ограничения на хостинг. Я же хотел, чтобы любой стандартный хостинг подходил для функционирования системы, так что пришлось остановиться на real time database, чего для скромных нужд проекта более чем достаточно. Виджеты отображения подписываются на соответствующую запись firebase rtdb напрямую, виджет оплаты взаимодействует с firebase обращаясь к функциям api WordPress сервера, который, в свою очередь, записывает данные в firebase при помощи функций пакета rtdb php admin.

Админка WordPress синхронизируется с firebase через специальный wp-плагин. Например, при создании новой благотворительной программы заводится соответствующая запись в базе firebase, и затем - в базе WordPress. В специальном разделе админки отображается информация о программах и платежах из firebase.

Интеграция приёма платежей по qr-коду

Сайт подключен к СБП (системе быстрых платежей) через сервис Плати QR Сбербанка. Виджет платежа можно вызвать, кликнув на него в блоке определённой благотворительной программы. Виджет запрашивает сумму пожертвования, и подтверждение, после чего обращается к api сайта, а сервер - в свою очередь к серверу сбера за одноразовым токеном для проведения платежа. Как только токен получен, также при посредстве api высылается запрос на получение платёжной ссылки. При получении ссылки и идентификатора платежа, специальным api - запросом заводится новая запись о платеже в firebase и осуществляется прямая подписка веб-страницы (виджета) на эту запись. Если браузер пользователя определяется как десктоп, виджет генерирует QR-код по платёжной ссылке и демонстрирует его пользователю. На мобильных платформах ссылка открывается стандартным выбором системы, то есть чаще всего приложением банка. По результату платежа сервис сбера высылает api запрос на заранее настроенный в админке Sberpay адрес. Запрос обрабатывается сайтом и меняет запись firebase в зависимости от успеха операции. Платёжный виджет в браузере пользователя, подписанный на эту запись через web-сокет, отображает результат операции пользователю.

Огромный плюс использования СБП - отсутствие необходимости ввода на сайте хоть каких-то платёжных или персональных данных.

Безопасность запросов обеспечивается сертификатом сбера, доступным через переменные окружения. В разработке используется платформа bedrock, интегрирующая WordPress в стандартный composer workflow, и позволяющая устанавливать wp-плагины как обычные composer-модули.

Взаимодействие сервера с firebase и Sberpay реализовано методами двух классов, объединённых в один кастомный wp-плагин.

Для реализации кастомных типов "программа" и "платёж" используется плагин Advanced Custom Fields.