Как работает корзина Opencart 2.3 и почему ее не так просто изменить (но у нас все получится). Цель: сделать одностраничное оформление заказа без регистраций и смс.

Ввиду последнего обновления opencart и грядущих, которые переписывают контроллеры – примеры кода беcполезны, главное общий ход размышлений.

Загрузка начинается с контроллера checkout/checkout. В нем происходит подготовка страницы и вывод “болванки” под работу корзины. Далее работает все на js, обработчиках которые по шагам ведут пользователя к победному заказу.
0 Шаг. Его пользователи не видят – он происходит в tpl части контроллера checkout/checkout. Определяется зарегистрирован ли покупатель, если не зарегистрирован вызывается контроллер checkout/login (Чтобы увидеть шаг 1.) – либо контроллер для зарегистрированных пользователей (здесь не рассматривается).
1 Шаг. На этом этапе заказчик делает первый выбор – зарегистрироваться, войти или оформить заказ без регистрации.

Для оформления без регистрации (обязательно разрешить в админке) исследуем форму:

Сначала идет проверка зарегистрирован ли пользователь. Очень похоже на наследие прошлой версии, так как мы еще в шаге 0 проверили это. В браузере смотрим id кнопки, которая поможет оформить без регистрации: button-account. И находим обработчик для таковой кнопки. Обработчик получает значение радио-кнопки, оно важно – так как является названием следующего контроллера.

Получая значение этой кнопки “guest” – переходим к шагу 2. Так же, просмотрев контроллер на предмет изменений каких либо данных в сессии или других местах понимаем, что контроллер только ПОЛУЧАЕТ данные, но не сохраняет их куда либо. Этот факт разрешает нам безболезненно пропустить шаг 1 и сразу перейти к 2.

2 Шаг. Запрос к контроллеру checkout/guest.

Этот контроллер важен, так как устанавливает в сессию (хранилище данных для каждого, кто вошел на сайт) дефолтные значения важных для opencart переменных. Его вызывать будем по любому. Далее, установив стандартные значения и получив нужные для шаблона переменные – он его вызывает.

Открываем tpl файл, написанный в контроллере, видим много-много html с формами, но интересует нас js. В js наблюдаются по порядку: сортировки полей, ajax запросы при изменении некоторых полей, можно прикрепить какой то файл.. И все, обработчика для кнопки отправить нет. Значит файл нам по сути не нужен, отправляемся искать его к контроллеру шага 0.

На данном этапе обработчик кнопки отправки платежной информации собирает данные со всей формы, пакует их в json и отправляет контроллеру checkout/guest/ и функции в нем save.

Для того, чтобы не заниматься долгим разбором формы можно “перехватить” данные.

Разберемся с функцией save контроллера checkout/guest:

$json = $this->request->post;

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

Возвращаем все на место, Смотрим что происходит далее. Далее мы видим снова развилку в логике:

Выберем для себя что доставка нужна всегда (добавим “самовывоз” в методы доставки), так же что адрес плательщика совпадает. Почему так? Потому, что 2 адреса – оплаты и доставки – в СНГ не нужны, да и за границей, не так часто люди используют функционал налогов.

Шаг 4. (3 шаг пропущен галочкой совпадения адреса). Запрос к контроллеру checkout/shipping_method. Никаких данных ему не отправляется, все уже записано в сессию (важное замечание).

Этот контроллер так же ничего не меняет, только получает данные формы, НО при успешном его вызове – сразу посылается второй ajax запрос на контроллер checkout/guest_shipping, который заполняет в тихую Шаг 3. Это тоже важный контроллер, который пишет в сессию дефолтные значения.

На этом этапе у нас висит форма добавления комментария и выбор доставки. Так же в сессию уже записаны все данные пользователя, следующие действия выполнятся по нажатию кнопки “Продолжить” на Шаге 4. и мы перейдем к следующему:

Шаг 5. По нажатию кнопки продолжить js отправляет ajax запрос контроллеру checkout/shipping_method, его методу save. В этом месте на всякий случай проверяется минимальное количество продукции в корзине, но мы предварительно выключили контроль в админке, радиокнопка доставки гарантированно установлена и все проверки пройдут успешно. И главное – будет сохранен комментарий и способ доставки.

В случае удачного прохождения этого этапа – идет запрос к checkout/payment_method. Опять таки важный контроллер, который заполняет некоторые дефолтные значения.

Он получает методы оплаты и выводит их в форму (и комментарий).

Нажатие кнопки “продолжить” – делает все по накатанной. Вызываем функцию save, валидируем, пишем что не так, вдруг что – и стучимся к следующему контроллеру.

Шаг 6. checkout/confirm.

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

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

Подытожим что нам нужно сделать:

  1. Поменять в контроллере checkout/checkout вызов шаблона на, к примеру, checkout2.tpl.
  2. В нем написать кучу ajax вызовов для получения данных (скопировать с существующих скриптов, вырезав функции save)
  3. По кнопке проверить данные – вызвать по очереди все функции save()
  4. Если все хорошо – получить ответ от последнего этапа с табличкой заказа и кнопкой “продолжить”, которая сгенерирована каким либо платежным модулем.

Порядок запросов:

  1. checkout/guest
  2. checkout/guest/save
  3. checkout/shipping_method
  4. checkout/guest_shipping/save
  5. checkout/shipping_method/save
  6. checkout/payment_method
  7. checkout/payment_method/save

Так же придется в checkout/shipping_method/save и checkout/payment_method/save скопировать получение методом доставки и оплаты (они в начале контроллера) в начало функции.

Такой порядок Позволит не нарушить логику заказа и все будет работать как надо.

Файлы с osStore 2.3, которые использовались при написании статьи (внимание, заменяют системные!):
1pagecart2.3.zip

Тоже самое, но модулем: web-porosya-page-cart1.0.ocmod (2.3)

UPD: опенкарт как обычно что-то поменял втихую и куча модулей сломалась. На этот раз валидация почты. Если ошибка в корзине на эту тему – пот патч: guest2. (пока только на новейшей сборке опенкарта 2.3.0.2 чистого, русские сборки не поменялись)