Puppy City — диагностика и починка checkout (WooCommerce)
Интернет-магазин щенков (зоо-ритейл, США) · E-commerce / зоотовары (продажа щенков от заводчиков)
Интернет-магазин не мог принять оплату: на оформлении заказа крутилась бесконечная загрузка. Причину искали до меня и не нашли.
- PHP
- WordPress
- WooCommerce
- JavaScript
- jQuery
- ACF
- Elementor
- MySQL
- HTML
- CSS/SCSS
- Select2
- Slick
- платежи (NMI Gateway / Collect.js)
В цифрах
- 5
- выявленных причин сбоя оформления заказа (4 ранних + корневая — LoftLoader)
- 31
- активных плагинов на сайте (источник нагрузки и конфликтов)
- 1.6 ГБ
- размер debug.log из-за повторяющихся PHP Fatal Error
- WooCommerce 10.6.1
- версия на проде на момент аудита
- 128M
- PHP memory_limit на проде (рекомендовано поднять до 256M)
Ключевое
- Нашёл корневую: поверх страницы висел заставочный экран, ждавший полной загрузки, а платёжная форма во вложенном окне это событие задерживала — заставка не снималась никогда.
- Восстановил вторую цепочку отказа: расширение исчерпывало отведённую память, сервер аварийно обрывал запрос, ответ не приходил, и корзина оставалась заблокированной.
- Журнал ошибок раздулся до 1,6 ГБ от одной повторяющейся аварии — по нему и удалось восстановить порядок событий.
- Нашёл ещё три причины: код сайта удалял поля плательщика, которых требует платёжная система; два расширения доставки роняли сайт одинаковыми именами функций; штатная доставка была отключена.
- Собрал отчёт с проверяемым решением по каждой из пяти причин: что чинить, в каком порядке и как убедиться, что помогло.
Задача
Интернет-магазин щенков от заводчиков не мог принять оплату. На странице оформления заказа крутилась бесконечная загрузка: покупатель заполнял форму, нажимал оплатить и упирался в вечное ожидание. Заплатить картой было невозможно.
Проблему искали до меня: несколько причин нашли и устранили, но симптом остался. Магазин при этом живой, и трогать в нём можно было только то, что действительно ломает оформление, — любая лишняя правка рисковала обрушить работающее.
Что сделано
- Разбирал по цепочке событий, а не по симптому. Прочитал журнал ошибок сервера, раздувшийся до 1,6 ГБ от одной повторяющейся аварии, и восстановил по нему последовательность: что происходит, в каком порядке и где обрывается.
- Нашёл корневую причину, до которой не дошли раньше: поверх страницы висел заставочный экран, который ждал полной загрузки. Платёжная форма грузится во вложенном окне и это событие задерживает — заставка не снималась никогда, хотя страница под ней была готова.
- Восстановил вторую цепочку отказа: одно из расширений исчерпывало отведённую память, сервер аварийно обрывал запрос, ответ не приходил, и корзина оставалась заблокированной ожиданием, которое уже не наступит.
- Обнаружил конфликт в самом коде сайта: он удалял все поля плательщика, которых платёжная система требует обязательно.
- Нашёл два расширения доставки с одинаково названными функциями — вместе они роняли сайт — и отключённую штатную доставку.
- Собрал всё в отчёт: по каждой причине цепочка «что происходит и почему» и проверяемое решение, а не совет «попробуйте отключить плагины».
Итог
Найдены пять причин, из-за которых не проходило оформление заказа, включая корневую — ту, до которой не дошли предыдущие попытки. Каждая описана цепочкой событий и подтверждена журналом сервера, а не догадкой.
Заказчик получил проверяемый план: что именно чинить, в каком порядке и как убедиться, что помогло. Пока причина не названа точно, магазин чинят наугад, а каждый день без приёма карт — это потерянные заказы.
Технические детали
Решение и подход
Ключевой инсайт — симптом «вечного спиннера» имел не одну, а несколько наложенных причин, и «очевидные» (память, поля, доставка) маскировали настоящую:
- Корневая причина — LoftLoader. Плагин показывал полноэкранный полупрозрачный overlay (opacity ~0.55,
position: fixed,z-index: 999999) на всех страницах, включая checkout. Overlay снимается по событиюwindow.load, ноCollect.js(NMI) создаёт iframes с внешнегоsandbox.nmi.com, которые задерживаютwindow.load; приdata-max-load-time=0у плагина не было fallback-таймаута → overlay висел бесконечно и блокировал все взаимодействия (поля видны «сквозь», но кликабельность заблокирована). Предложены три варианта (dequeue + скрытие разметки на checkout/cart; «Homepage only»; полное отключение). - Память и AJAX. JetEngine при
update_order_reviewупирался в 128M → Fatal Error → AJAX без ответа → WooCommerceblockUIне снимался. Рекомендация — поднятьmemory_limitи очистить раздувшийсяdebug.log. - Поля заказа. Фильтры в
functions.php(строки 140–151) удаляли все секцииbilling/shipping, конфликтуя с Checkout Field Editor Pro и лишая NMI обязательных billing-данных (AVS). Рекомендация — отдать управление полями плагину. - Доставка. Зафиксирован конфликт двух кастомных плагинов доставки (дублирующие функции → Fatal Error при одновременной активации) и отключение нативной доставки фильтром
woocommerce_cart_needs_shipping → __return_false(строка 1201). - Чистка. Указан мёртвый код
puppycity_fix_paypal_blockui(строки 1217–1253) при деактивированном PayPal.
Косвенное свидетельство хирургического подхода к шаблонам — переопределения checkout-темы были выведены из работы переименованием каталогов (woocommerce/checkout.bak, woocommerce/checkout.copy), чтобы checkout рендерился штатным шаблоном WooCommerce при диагностике.
Стек и обоснование
WordPress + WooCommerce (классический checkout принудительно включён фильтром woocommerce_checkout_is_block_checkout → __return_false) как платформа магазина; дочерняя тема twentytwentyone-child со «своей» логикой на PHP/jQuery (кастомная AJAX-авторизация покупателей и заводчиков, OTP-сброс пароля через transients, AJAX-фильтры товаров-щенков, кастомная корзина). ACF — кастомные поля товаров/таксономий; Elementor, Select2, Slick, Fancybox, SweetAlert2 — UI. Платёжный слой — NMI Gateway с токенизацией через Collect.js (PCI DSS), что и стало источником задержки window.load. Оптимизация загрузки — ручной dequeue/deregister ассетов по page ID в deque-enque.php.
Инженерные вызовы
- Многослойный симптом. Один и тот же «вечный спиннер» порождался несколькими независимыми причинами; «очевидные» правки не снимали проблему и маскировали корневую (LoftLoader). Потребовалась диагностика именно на уровне событий браузера (
window.load) и взаимодействия со сторонними iframes платёжного провайдера. - Хрупкая legacy-среда. 31 плагин (WooCommerce, Elementor, JetEngine, ACF Pro, Wordfence и др.), захардкоженные ID страниц, дублирующие кастомные плагины доставки, конфликтующие фильтры полей — изменения нужно было предлагать точечно и обратимо.
- Внешняя зависимость в платеже. Поведение Collect.js (sandbox.nmi.com, сеть/VPN/блокировщики) напрямую влияло на снятие overlay — диагностика учитывала клиент-серверную и сетевую составляющие.
Услуги в проекте
- аудит
- диагностика checkout
- доработка существующего
- поддержка
- удалённая диагностика прод-сервера