---
title: "JoomShopping 5.9.0: полный жизненный цикл оформления заказа от корзины до страницы \"спасибо за заказ\" - WebTolk"
description: "Справочная статья для разработчиков Joomla и JoomShopping: полный поток данных оформления заказа, порядок исполнения    кода, триггеры плагинов в хронологическом порядке, их входные параметры и типы, а также способы передавать данные из    плагина в шаблон через _tmp_var-позиции."
url: "https://web-tolk.ru/blog/joomshopping-5-9-0-polnyj-zhiznennyj-tsikl-oformleniya-zakaza-ot-korziny-do-stranitsy-spasibo-za-zakaz"
date: "2026-03-06T17:22:41+00:00"
language: "ru-RU"
---

# JoomShopping 5.9.0: полный жизненный цикл оформления заказа от корзины до страницы "спасибо за заказ"

 Автор: Сергей Толкачев Создано: 06 марта 2026 Обновлено: 07 марта 2026 Просмотров: 946

Joomla разработчикам и в частности разработчикам, работающим с JoomShopping часто не хватает актуальной документации для работы. Эта справочная статья призвана восполнить этот пробел и дать представление о всём потоке данных в процессе оформления заказа в компоненте интернет-магазина JoomShopping. Описывается порядок исполнения кода, все триггеры плагинов в хронологическом порядке, а так же какие данные они получают на вход и типы этих данных, описывается как прокидывать свои данные из плагина в шаблон JoomShopping в позиции вида `_tmp_var...`.

## Оглавление

## Как читать этот документ

Этот документ построен строго по времени выполнения кода. Для каждого этапа показано:

1. Где мы находимся (**Controller -> Model -> View preparation -> View template**).
2. Какие события плагинов срабатывают и в каком порядке.
3. Какие аргументы получает каждое событие (с типами аргументов).
4. Что именно в этот момент можно прокинуть в шаблон: существующие `_tmp_*` позиции и собственные поля.

Собрано по файлам JoomShopping 5.9.0.

## Принятый порядок слоев

В процессе оформления заказа (checkout) у JoomShopping фактический порядок чаще всего такой:

1. Controller стартует этап.
2. Controller вызывает model-методы, где формируются данные/фрагменты и срабатывают события плагинов в Model / Table.
3. Controller собирает `View` и вызывает `onBeforeDisplay...View`.
4. Только после этого выполняется template (`display()` или `loadTemplate()`).

Важно: в `site/View/Checkout/HtmlView.php` нет собственных `triggerEvent(...)`.

---

## Этап 0. Корзина (кнопка «Оформить заказ»)

### Где мы

- Controller: `CartController::view()` — `site/Controller/CartController.php`.
- Model: `CartModel` — `site/Model/CartModel.php`, `CartpreviewModel` — `site/Model/CartpreviewModel.php`, `CheckoutModel` (навигация) — `site/Model/CheckoutModel.php`.
- View: `site/templates/default/cart/cart.php`.

### Поток данных этапа

1. Загружается cart и пересчитываются суммы/налоги.
2. Генерируется `href_checkout` через `CartpreviewModel::getUrlCheckout()`.
3. В template выводится кнопка `JSHOP_CHECKOUT` с ссылкой на `checkout&task=step2` (иногда `check_login=1`).

### Хронология trigger-ов

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть в шаблон |
| --- | --- | --- | --- | --- |
| 1 | `CartController::init()` | `onConstructJshoppingControllerCart` | `(&$obj)` (`CartController`) | Можно изменить поведение контроллера до `view()` |
| 2 | `CartModel::__construct()` | `onConstructJshopCart` | `(&$obj)` (`CartModel`) | Глобальная инициализация cart model |
| 3 | `CartModel::load()` | `onBeforeCartLoad` | `(&$obj)` (`CartModel`) | Подготовка cart данных до загрузки |
| 4 | `CartModel::load()` | `onAfterCartLoad` | `(&$obj)` | Можно дописать поля продуктов cart |
| 5 | `CartModel::load()` | `onAfterLoadPriceAndCountProducts` | `(&$obj)` | После расчета цен/количества |
| 6 | `CartpreviewModel::prepareView()` | `onBeforeDisplayCart` | `(&$cart, &$obj)` (`CartModel`, `CartpreviewModel`) | Удобная точка для подготовки cart-вставок до view |
| 7 | `CheckoutModel::showCheckoutNavigation()` | `onBeforeDisplayCheckoutNavigator` | `(&$output, &$array_navigation_steps, &$step)` (`array`, `array`, `string|int`) | Можно менять HTML шагов в навигаторе |
| 8 | `CheckoutModel::showCheckoutNavigation()` | `onAfterDisplayCheckoutNavigator` | `(&$view)` (`checkout view`) | Можно добавить поля в view меню |
| 9 | `CartController::view()` | `onBeforeDisplayCartView` | `(&$view)` (`cart view`) | Прямое назначение `_tmp_*` полей cart template |

### Template-позиции cart, доступные на этом этапе

В `CartController::view()` инициализируются: `_tmp_ext_html_cart_start`, `_tmp_html_after_subtotal`, `_tmp_html_after_total`, `_tmp_ext_subtotal`, `_tmp_html_before_buttons`, `_tmp_html_after_buttons`, `_tmp_ext_html_before_discount`, `_tmp_ext_html_after_discount`, `_tmp_ext_total`, `_tmp_ext_discount_text`, `_tmp_ext_discount`, массив `_tmp_ext_tax`.

### Пример (этап корзины)

```
public function onBeforeDisplayCartView(&$view): void
{
    $view->_tmp_ext_html_cart_start = '<div class="alert alert-info">Проверка корзины перед checkout</div>';
    $view->_tmp_ext_total = '<span class="text-muted"> (с учетом ваших условий)</span>';
}
```

---

## Этап 1. Заполнение данных пользователя (`checkout step2`)

### Где мы

- Controller: `CheckoutController::step2()` и `step2save()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutModel` (`showCheckoutNavigation`, `loadSmallCart`, `setEmptyCheckoutPrices`, `setMaxStep`) — `site/Model/CheckoutModel.php`; `CartModel` — `site/Model/CartModel.php`; `CartpreviewModel` — `site/Model/CartpreviewModel.php`.
- View: `site/templates/default/checkout/adress.php` + `site/templates/default/cart/checkout.php` (малая корзина).

### Поток данных этапа

1. Открытие шага `step2`: загрузка профиля пользователя, полей формы, навигатора и малой корзины.
2. Сохранение `step2save`: валидация/сохранение пользователя, сброс shipping/payment в корзине.
3. Переход на следующий шаг через `CheckoutStepModel::getNextStep(2)`.

### Хронология trigger-ов (`step2`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::init()` | `onConstructJshoppingControllerCheckout` | `(&$obj)` (`CheckoutController`) | Глобальная инициализация checkout controller |
| 2 | `CheckoutController::step2()` | `onLoadCheckoutStep2` | `()` | Старт шага, до подготовки view |
| 3 | `CheckoutModel::showCheckoutNavigation()` | `onBeforeDisplayCheckoutNavigator` | `(&$output, &$array_navigation_steps, &$step)` | Модификация навигатора |
| 4 | `CheckoutModel::showCheckoutNavigation()` | `onAfterDisplayCheckoutNavigator` | `(&$view)` | Доп. данные menu template |
| 5 | `CartModel::__construct()` (в `showSmallCart`) | `onConstructJshopCart` | `(&$obj)` | Инициализация cart model для small cart |
| 6 | `CartModel::load()` | `onBeforeCartLoad` | `(&$obj)` | Перед загрузкой cart |
| 7 | `CartModel::load()` | `onAfterCartLoad` | `(&$obj)` | После загрузки cart |
| 8 | `CartModel::load()` | `onAfterLoadPriceAndCountProducts` | `(&$obj)` | После пересчетов |
| 9 | `CartpreviewModel::prepareView()` (`step=2`) | `onBeforeDisplaySmallCart` | `(&$cart, &$obj)` | Подготовка данных малой корзины |
| 10 | `CartModel::getTaxExt()` | `onAfterCartGetTaxExt` | `(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` | Можно корректировать tax-list |
| 11 | `CartModel::getSum()` | `onAfterCartGetSum` | `(&$obj, &$incShiping, &$incRabatt, &$incPayment)` | Можно влиять на итог fullsum |
| 12 | `CheckoutModel::showSmallCart()` | `onBeforeDisplayCheckoutCartView` | `(&$view)` | Прямые `_tmp_*` вставки в `cart/checkout.php` |
| 13 | `CheckoutController::step2()` | `onBeforeDisplayCheckoutStep2View` | `(&$view)` (`checkout view`) | Прямые вставки в `checkout/adress.php` |

### Хронология trigger-ов (`step2save`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step2save()` | `onLoadCheckoutStep2save` | `(&$post)` (`array<string,mixed>`) | Нормализация входных данных формы |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Правки cart перед сохранением. |
| 3 | `CheckoutController::step2save()` | `onBeforeSaveCheckoutStep2` | `(&$adv_user, &$user, &$cart, &$model)` | Записать свои поля в user/cart до save |
| 4 | `CheckoutController::step2save()` | `onAfterSaveCheckoutStep2` | `(&$adv_user, &$user, &$cart)` | Пост-обработка после save |
| 5 | `CheckoutModel::setMaxStep()` | `onAfterSetMaxStepJshopCheckout` | `(&$step)` | Контроль перехода на следующий шаг |

### Template-позиции этапа

В `step2` доступны: `_tmp_ext_html_address_start`, `_tmp_ext_html_address_end`, `_tmpl_address_html_2..._tmpl_address_html_9`.

### Пример (этап step2)

```
public function onBeforeDisplayCheckoutStep2View(&$view): void
{
    $view->_tmp_ext_html_address_start = '<div class="checkout-tip">Заполните обязательные поля</div>';
    $view->_tmpl_address_html_7 .= '<div class="custom-block">Доп. блок перед submit</div>';
    $view->myAddressMeta = ['source' => 'plugin', 'ts' => time()];
}
```

---

## Этап 2. Выбор оплаты (`checkout step3`)

### Где мы

- Controller: `CheckoutController::step3()` и `step3save()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutPaymentModel` — `site/Model/CheckoutpaymentModel.php`, `CheckoutModel` (навигация/малая корзина) — `site/Model/CheckoutModel.php`, `CartModel` — `site/Model/CartModel.php`, `CartpreviewModel` — `site/Model/CartpreviewModel.php`.
- View: `site/templates/default/checkout/payments.php`.

### Поток данных этапа

1. Загружается список способов оплаты.
2. Для каждого метода может быть построена HTML-форма платежного плагина.
3. На `step3save` проверяется и сохраняется выбранный метод оплаты и её **params**.

### Хронология trigger-ов (`step3`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step3()` | `onLoadCheckoutStep3` | `()` | Старт шага оплаты |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Коррекция cart перед рендером оплаты |
| 3 | `CheckoutModel::showCheckoutNavigation()` | `onBeforeDisplayCheckoutNavigator` | `(&$output, &$array_navigation_steps, &$step)` | Меню checkout |
| 4 | `CheckoutModel::showCheckoutNavigation()` | `onAfterDisplayCheckoutNavigator` | `(&$view)` | Данные в menu view |
| 5 | `CartpreviewModel::prepareView()` (`step=3`) | `onBeforeDisplaySmallCart` | `(&$cart, &$obj)` | Данные small cart для шага оплаты |
| 6 | `CartModel::getTaxExt()` | `onAfterCartGetTaxExt` | `(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` | Влияние на налоги |
| 7 | `CartModel::getSum()` | `onAfterCartGetSum` | `(&$obj, &$incShiping, &$incRabatt, &$incPayment)` | Влияние на итог |
| 8 | `CheckoutModel::showSmallCart()` | `onBeforeDisplayCheckoutCartView` | `(&$view)` | `_tmp_*` для малой корзины |
| 9 | `CheckoutController::step3()` | `onBeforeDisplayCheckoutStep3View` | `(&$view)` | `_tmp_ext_html_payment_start/end`, свои поля view |

### Хронология trigger-ов (`step3save`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step3save()` | `onBeforeSaveCheckoutStep3save` | `(&$post)` | Валидировать/переписать post-параметры |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Подготовка cart к savePaymentData |
| 3 | `CheckoutController::step3save()` | `onAfterSaveCheckoutStep3save` | `(&$adv_user, &$paym_method, &$cart)` | До перехода на следующий step |
| 4 | `CheckoutModel::setMaxStep()` | `onAfterSetMaxStepJshopCheckout` | `(&$step)` | Контроль маршрута |

### Template-позиции этапа

В `step3` доступны `_tmp_ext_html_payment_start` и `_tmp_ext_html_payment_end`.

### Пример (этап step3)

```
public function onBeforeDisplayCheckoutStep3View(&$view): void
{
    $view->_tmp_ext_html_payment_start = '<div class="pay-note">Оплата защищена</div>';
    $view->myPaymentFlags = ['supportsInstallments' => true];
}
```

---

## Этап 3. Выбор доставки (`checkout step4`)

### Где мы

- Controller: `CheckoutController::step4()` и `step4save()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutShippingModel` — `site/Model/CheckoutshippingModel.php`, `CheckoutModel` — `site/Model/CheckoutModel.php`, `CartModel` — `site/Model/CartModel.php`, `CartpreviewModel` — `site/Model/CartpreviewModel.php`.
- View: `site/templates/default/checkout/shippings.php`.

### Поток данных этапа

1. Вычисляются доступные способы доставки по стране/оплате.
2. Для каждого метода может отрисовываться форма способа доставки (shipping form).
3. На `step4save` сохраняются параметры, пересчитываются суммы, при необходимости обновляется стоимость заказа (payment price).

### Хронология trigger-ов (`step4`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step4()` | `onLoadCheckoutStep4` | `()` | Старт шага доставки |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Коррекция cart |
| 3 | `CheckoutModel::showCheckoutNavigation()` | `onBeforeDisplayCheckoutNavigator` | `(&$output, &$array_navigation_steps, &$step)` | Навигатор |
| 4 | `CheckoutModel::showCheckoutNavigation()` | `onAfterDisplayCheckoutNavigator` | `(&$view)` | Навигатор view |
| 5 | `CartpreviewModel::prepareView()` (`step=4`) | `onBeforeDisplaySmallCart` | `(&$cart, &$obj)` | Small cart |
| 6 | `CartModel::getTaxExt()` | `onAfterCartGetTaxExt` | `(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` | Налоги |
| 7 | `CartModel::getSum()` | `onAfterCartGetSum` | `(&$obj, &$incShiping, &$incRabatt, &$incPayment)` | Итог |
| 8 | `CheckoutModel::showSmallCart()` | `onBeforeDisplayCheckoutCartView` | `(&$view)` | `_tmp_*` малого cart |
| 9 | `CheckoutController::step4()` | `onBeforeDisplayCheckoutStep4View` | `(&$view)` | `_tmp_ext_html_shipping_start/end`, custom поля |

### Хронология trigger-ов (`step4save`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step4save()` | `onBeforeSaveCheckoutStep4save` | `()` | Превалидация перед saveShippingData |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Коррекция cart |
| 3 | `CheckoutController::step4save()` | `onAfterSaveCheckoutStep4` | `(&$adv_user, &$sh_method, &$shipping_method_price, &$cart)` | Фиксация выбора доставки |
| 4 | `CheckoutModel::setMaxStep()` | `onAfterSetMaxStepJshopCheckout` | `(&$step)` | Переход |

### Template-позиции этапа

В `step4` доступны `_tmp_ext_html_shipping_start` и `_tmp_ext_html_shipping_end`.

---

## Этап 4. Подтверждение заказа (`checkout step5`)

### Где мы

- Controller: `CheckoutController::step5()` и `step5save()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutModel` — `site/Model/CheckoutModel.php`, `CheckoutOrderModel` — `site/Model/CheckoutorderModel.php`, `CartModel` — `site/Model/CartModel.php`, `OrderTable` — `site/Table/OrderTable.php`, `CartpreviewModel` — `site/Model/CartpreviewModel.php`.
- View: `site/templates/default/checkout/previewfinish.php` + малая корзина `site/templates/default/cart/checkout.php`.

### Поток данных этапа

1. Отображается финальный предпросмотр заказа: адрес, доставка, оплата, суммы.
2. При отправке формы (`step5save`) выполняются проверки AGB (согласия на обработку перс.данных и право возврата) / stock (списание, наличие) / coupon (работа с купонами).
3. Создается **order** и **order items**.
4. Если оплата не нужна или сумма ноль — сразу `finish`, иначе `step6/step6iframe`.

### Хронология trigger-ов (`step5`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step5()` | `onLoadCheckoutStep5` | `()` | Старт preview |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Подготовка cart |
| 3 | `CheckoutModel::showCheckoutNavigation()` | `onBeforeDisplayCheckoutNavigator` | `(&$output, &$array_navigation_steps, &$step)` | Навигатор |
| 4 | `CheckoutModel::showCheckoutNavigation()` | `onAfterDisplayCheckoutNavigator` | `(&$view)` | Навигатор view |
| 5 | `CartpreviewModel::prepareView()` (`step=5`) | `onBeforeDisplaySmallCart` | `(&$cart, &$obj)` | Small cart |
| 6 | `CartModel::getTaxExt()` | `onAfterCartGetTaxExt` | `(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` | Налоги |
| 7 | `CartModel::getSum()` | `onAfterCartGetSum` | `(&$obj, &$incShiping, &$incRabatt, &$incPayment)` | Итог |
| 8 | `CheckoutModel::showSmallCart()` | `onBeforeDisplayCheckoutCartView` | `(&$view)` | `_tmp_*` малого cart |
| 9 | `CheckoutController::step5()` | `onBeforeDisplayCheckoutStep5` | `(&$sh_method, &$pm_method, &$delivery_info, &$cart, &$view)` | Можно дописать данные в `delivery_info` и view |
| 10 | `CheckoutController::step5()` | `onBeforeDisplayCheckoutStep5View` | `(&$view)` | `_tmp_ext_html_previewfinish_*`, custom поля |

### Хронология trigger-ов (`step5save`)

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step5save()` | `onLoadStep5save` | `(&$checkagb)` (`string|null`) | Переопределить AGB check |
| 2 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Подготовка cart |
| 3 | `CartModel::checkListProductsQtyInStore()` | `onBeforeCheckListProductsQtyInStore` | `(&$obj)` | Влиять на pre-check stock |
| 4 | `CartModel::checkListProductsQtyInStore()` | `onCheckListProductsQtyInStoreForeach` | `(&$obj, &$key, &$product, &$attr, &$qtyInStock, &$checkqty, &$check)` | Проверка каждого товара |
| 5 | `CartModel::checkListProductsQtyInStore()` | `onAfterCheckListProductsQtyInStore` | `(&$obj)` | Финал stock-check |
| 6 | `CartModel::checkCoupon()` | `onBeforeCheckCouponStep5save` | `(&$obj, &$coupon)` | Проверка купона перед **orderDataSave** |
| 7 | `OrderTable::getListFieldCopyUserToOrder()` | `onBeforeGetListFieldCopyUserToOrder` | `(&$list)` | Добавить/убрать поля копирования user->order |
| 8 | `OrderTable::formatOrderNumber()` | `onAfterFormatOrderNumber` | `(&$number, &$num)` | Формат номера заказа |
| 9 | `OrderTable::copyDeliveryData()` (если надо) | `onAfterCopyDeliveryData` | `(&$obj)` | Правка delivery полей в order |
| 10 | `CheckoutOrderModel::createOrder()` | `onBeforeCreateOrder` | `(&$order, &$cart, &$obj)` | Ключевая точка перед `order->store()` |
| 11 | `OrderTable::store()` | `onBeforeStoreTableOrder` | `(&$obj)` | Последний guard перед сохранением заказа |
| 12 | `CheckoutOrderModel::orderDataSave()` | `onAfterCreateOrder` | `(&$order, &$cart)` | После создания order |
| 13 | `CheckoutOrderModel::couponFinished()` | `onBeforeCouponFinished` | `(&$coupon, &$cart, &$user_id, &$order)` | Коррекция coupon finalize |
| 14 | `OrderTable::saveOrderItem()` | `onBeforeSaveOrderItem` | `(&$order_item, &$value)` | Изменение order item перед store |
| 15 | `CheckoutOrderModel::orderDataSave()` | `onAfterCreateOrderFull` | `(&$order, &$cart)` | После полного набора order данных |
| 16 | `OrderTable::saveOrderHistory()` | `onBeforeJshopOrderSaveOrderHistory` | `(&$history, &$notify, &$comments, &$obj)` | Комментарий/флаги history |
| 17 | `OrderTable::changeProductQTYinStock()` | `onBeforechangeProductQTYinStock` | `(&$items, &$obj, &$change)` | До списания/возврата склада |
| 18 | `OrderTable::changeProductQTYinStock()` | `onAfterchangeProductQTYinStock` | `(&$item, &$change, &$obj)` | После каждой позиции |
| 19 | `OrderTable::changeProductQTYinStock()` | `onAfterchangeProductQTYinStockPSR` | `(&$items, &$obj, &$change, &$product_stock_removed)` | После всего batch |
| 20 | `CheckoutController::step5save()` | `onEndCheckoutStep5` | `(&$order, &$cart)` | Финал шага и выбор следующего этапа |
| 21 | `CheckoutModel::setMaxStep()` | `onAfterSetMaxStepJshopCheckout` | `(&$step)` | Переход к `step6`/`finish` |

### Template-позиции этапа

В preview (`step5`) доступны:
- `_tmp_ext_html_previewfinish_start`
- `_tmp_ext_html_previewfinish_agb`
- `_tmp_ext_html_previewfinish_before_button`
- `_tmp_ext_html_previewfinish_end`

В малой корзине (`showSmallCart`) доступны:
- `_tmp_ext_subtotal`, `_tmp_ext_discount_text`, `_tmp_ext_discount`, `_tmp_ext_shipping`, `_tmp_ext_shipping_package`, `_tmp_ext_payment`, `_tmp_ext_tax[]`, `_tmp_ext_total`
- `_tmp_html_after_subtotal`, `_tmp_html_after_total`, `_tmp_html_after_checkout_cart`
- `checkoutcartdescr`

### Пример (этап step5)

```
public function onBeforeDisplayCheckoutStep5View(&$view): void
{
    $view->_tmp_ext_html_previewfinish_before_button = '<div class="legal">Нажимая кнопку, вы принимаете условия.</div>';
}

public function onBeforeDisplayCheckoutCartView(&$view): void
{
    $view->checkoutcartdescr = '<p>Итоговые суммы могут зависеть от статуса оплаты.</p>';
}
```

---

## Этап 5. Переход к платежной системе (`step6` / `step6iframe`)

### Где мы

- Controller: `CheckoutController::step6iframe()` / `step6()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutOrderModel` — `site/Model/CheckoutorderModel.php`, `CheckoutModel` — `site/Model/CheckoutModel.php`, `OrderChangeStatusModel` (если отмена) — `site/Model/OrderchangestatusModel.php`.
- View: `site/templates/default/checkout/step6iframe.php` (iframe-режим).

### Поток данных этапа

1. `step6iframe` строит URL в платежный этап и может менять размеры/URL через trigger.
2. `step6` вызывает `showEndFormPaymentSystem($order_id)`.
3. Если пользователь вернулся назад в ПС (`getSendEndForm()==1`), вызывается `cancelPayOrder()` с полноценным статусным lifecycle.

### Хронология trigger-ов

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step6iframe()` | `onBeforeStep6Iframe` | `(&$width, &$height, &$url)` | Можно изменить URL iframe, размеры |
| 2 | `CheckoutOrderModel::showEndFormPaymentSystem()` | `onBeforeShowEndFormStep6` | `(&$order, &$cart, $pm_method)` | Дополнить order/cart перед `showEndForm()` |
| 3 | `CheckoutModel::cancelPayOrder()` (ветка отмены) | `onAfterCancelPayOrderJshopCheckout` | `(&$order_id, $status, $sendmessage)` | Пост-обработка cancel |

### Если на `step6` произошла отмена: status-lifecycle triggers

При вызове `cancelPayOrder()->changeStatusOrder()->OrderChangeStatusModel::store()`:

- `onBeforeChangeOrderStatus(...)` или `onBeforeChangeOrderStatusAdmin(...)`
- `onBeforeJshopOrderSaveOrderHistory(...)`
- `onBeforeCreateMailOrderStatusView(&$view)`
- `onBeforeSendClientMailOrderStatus(...)` / `...Admin...` / `...Vendor...`
- `onBeforeSendMailChangeOrderStatusClient(...)` / `...Admin...` / `...Vendor...`
- `onAfterChangeOrderStatus(...)` или `...Admin...`

---

## Этап 6. Обработка уведомлений о статусе заказа Callback/Return/Notify (`step7`)

### Где мы

- Controller: `CheckoutController::step7()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutBuyModel` — `site/Model/CheckoutbuyModel.php`, `CheckoutOrderModel` — `site/Model/CheckoutorderModel.php`, `OrderTable` — `site/Table/OrderTable.php`, `OrderChangeStatusModel` — `site/Model/OrderchangestatusModel.php`.
- View: отсутствует (в этом шаге нет обычного `display` checkout view).

### Поток данных этапа

1. Загружаются URL params платежного метода (`loadUrlParams`).
2. `buy()` проверяет транзакцию, вычисляет статус, сохраняет trx-данные.
3. Если нужно, впервые «создает» order в смысле `order_created=1` и меняет статус.
4. Для `notify` завершает через `nofityFinish` и `die()`.
5. Для return/прочих завершает `finish(...)` и редиректит на `checkout finish`.

### Хронология trigger-ов

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::step7()` | `onLoadStep7` | `()` | Старт callback этапа |
| 2 | `OrderTable::orderCreateAndSetStatus()` | `onOrderCreateAndSetStatus` | `(&$order_id, &$status, &$prev_order_status_data)` | Реакция на атомарную смену order_status/order_created |
| 3 | `CheckoutBuyModel::buy()` (если order создан впервые на step7) | `onStep7OrderCreated` | `(&$order, &$res, &$obj, &$pmconfigs)` | Пост-логика после «досоздания» заказа |
| 4 | `OrderChangeStatusModel::store()` (если смена статуса) | `onBeforeChangeOrderStatus...` -> mail triggers -> `onAfterChangeOrderStatus...` | См. этап 5 | Управление бизнес-логикой смены статуса |
| 5 | `CheckoutBuyModel::buy()` | `onStep7BefereNotify` | `(&$order, &$obj, &$pmconfigs)` | Последняя точка перед `notify/finish` ПС |
| 6 | `CheckoutModel::setMaxStep()` (успешный путь) | `onAfterSetMaxStepJshopCheckout` | `(&$step)` | Переход на `finish` |

### Где хранить свои данные на этом этапе

Здесь нет checkout-view. Данные обычно прокидывают через:

- поля заказа (`$order->order_add_info`, пользовательские поля заказа вида `$order->my_custom_data`),
- transaction data,
- комментарий истории заказа,
- сессию/логическую метку в вашем сервисе.

---

## Этап 7. Финальный экран (`checkout finish`)

### Где мы

- Controller: `CheckoutController::finish()` — `site/Controller/CheckoutController.php`.
- Model: `CheckoutFinishModel` — `site/Model/CheckoutfinishModel.php`, `CartModel` — `site/Model/CartModel.php`, `CheckoutModel` — `site/Model/CheckoutModel.php`.
- View: `site/templates/default/checkout/finish.php`.

### Поток данных этапа

1. Загружается текст `order_finish_descr`.
2. Триггер плагина перед отображением может изменить `text`, `text_end`, `order_id`.
3. После рендера вызывается `paymentComplete()`.
4. Очищаются cart и checkout session.

### Хронология trigger-ов

| # | Где | Trigger | Аргументы (тип) | Что можно прокинуть |
| --- | --- | --- | --- | --- |
| 1 | `CheckoutController::finish()` | `onBeforeDisplayCheckoutFinish` | `(&$text, &$order_id, &$text_end)` | Основная точка финального контента на finish template |
| 2 | `CheckoutFinishModel::paymentComplete()` | `onAfterDisplayCheckoutFinish` | `(&$text, &$order, &$pm_method)` | Пост-обработка после `payment_system->complete()` |
| 3 | `CheckoutFinishModel::clearAllDataCheckout()` | динамические `Helper::Js_add_trigger(..., "before")` | `(&$callerObject, &$varsArray)` | Хуки до очистки cart/session |
| 4 | `CartModel::load()` | `onBeforeCartLoad` / `onAfterCartLoad` / `onAfterLoadPriceAndCountProducts` | `(&$obj)` | Подготовка cart перед clear |
| 5 | `CartModel::getSum()` | `onAfterCartGetSum` | `(&$obj, &$incShiping, &$incRabatt, &$incPayment)` | Если нужно вмешательство в пересчет перед clear |
| 6 | `CartModel::clear()` | `onBeforeClearCart` | `(&$obj)` | До полной очистки cart |
| 7 | `CartModel::saveToSession()` | `onAfterSaveToSessionCart` | `(&$obj)` | После фиксации пустой cart в session |
| 8 | `CheckoutModel::deleteSession()` | `onAfterDeleteDataOrder` | `(&$obj)` | После очистки checkout session |
| 9 | `CheckoutFinishModel::clearAllDataCheckout()` | динамические `Helper::Js_add_trigger(..., "after")` | `(&$callerObject, &$varsArray)` | Хуки после очистки |

### Что можно прокинуть на finish

На этапе `onBeforeDisplayCheckoutFinish` задавайте:

- `$text` (основной HTML/текст),
- `$text_end` (дополнительный блок в конце),
- свои данные через `$text`/`$text_end` или через собственные поля view (если доработан шаблон).

---

## `_tmp_var...`, `_tmp_ext...`, `_tmpl_...`: практическая карта

### Где реально доступны позиции в checkout потоке

1. `step2` (`checkout/adress.php`): `_tmp_ext_html_address_start/end`, `_tmpl_address_html_2...9`.
2. `step3` (`checkout/payments.php`): `_tmp_ext_html_payment_start/end`.
3. `step4` (`checkout/shippings.php`): `_tmp_ext_html_shipping_start/end`.
4. `step5` (`checkout/previewfinish.php`): `_tmp_ext_html_previewfinish_start`, `_tmp_ext_html_previewfinish_agb`, `_tmp_ext_html_previewfinish_before_button`, `_tmp_ext_html_previewfinish_end`.
5. Малая корзина checkout (`cart/checkout.php`): `_tmp_ext_subtotal`, `_tmp_ext_discount_text`, `_tmp_ext_discount`, `_tmp_ext_shipping`, `_tmp_ext_shipping_package`, `_tmp_ext_payment`, `_tmp_ext_tax[]`, `_tmp_ext_total`, `_tmp_html_after_subtotal`, `_tmp_html_after_total`, `_tmp_html_after_checkout_cart`, `checkoutcartdescr`.
6. Product/List (вне checkout, но часто используют вместе): `_tmp_var_start`, `_tmp_var_buttons`, `_tmp_var_end` и др.

### Универсальный паттерн для каждого trigger

Если trigger дает `&$view`:

1. Назначайте существующие `_tmp_*` позиции напрямую.
2. Добавляйте свои поля (`$view->myCustomData`) и читайте их в override template.

Если trigger дает `&$order`, `&$cart`, `&$product`:

1. Пишите данные в поля объекта (`order_add_info`, custom props).
2. Либо в следующем `...BeforeDisplay...View` переносите эти данные в `view` и `_tmp_*` позиции.

### Пример: «существующая позиция + свои данные»

```
public function onBeforeDisplayCheckoutStep4View(&$view): void
{
    // 1) В существующую позицию
    $view->_tmp_ext_html_shipping_start = '<div class="shipping-banner">Курьер приедет в выбранный слот</div>';

    // 2) Свой payload
    $view->myShippingMeta = [
        'feature' => 'slot-selector',
        'enabled' => true,
    ];
}
```

Шаблон (`checkout/shippings.php` override):

```
<?php if (!empty($this->myShippingMeta['enabled'])): ?>
    <div class="slot-info">Feature: <?php echo htmlspecialchars($this->myShippingMeta['feature'], ENT_QUOTES, 'UTF-8'); ?></div>
<?php endif; ?>
```

---

## Быстрый checklist для проверки своего плагина

1. В каждом этапе цепляйтесь за самый поздний `...BeforeDisplay...View`, если ваша цель — шаблон.
2. Если цель — бизнес-логика заказа, используйте `onBeforeCreateOrder`, `onAfterCreateOrderFull`, `onStep7OrderCreated`.
3. Если цель — статусная интеграция (CRM/ERP), используйте `onAfterChangeOrderStatus...` и mail-события.
4. Для изменения внешнего вида страницы "спасибо за заказ" — `onBeforeDisplayCheckoutFinish` и `onAfterDisplayCheckoutFinish`.
5. Не ожидайте триггеров внутри `Checkout HtmlView`: их нет, они происходят до `display()`.

---

## Приложение A. Полные сигнатуры trigger-ов по этапам (с путями к файлам)

События плагинов даны в хронологическом порядке срабатывания. Формат строк: `Trigger(аргументы)` — `path/to/file.php::method()`.

Обратите внимание на то, что JoomShopping до сих пор (JoomShopping 5.9.0) использует старые способы вызова событий и для получения аргументов события в своём плагине лучше, чтобы он наследовал SubscriberInterface и соответственно получал аргументы через `[$param1, $param2, $paramXXX] = $event->getArguments()`. Возможно когда-нибудь в будущем JoomShopping перейдёт на собственные классы событий.

### A1. Cart (`CartController::view`)

1. `onConstructJshoppingControllerCart(&$obj)` — `site/Controller/CartController.php::init()`.
2. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
3. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
4. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
5. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
6. `onBeforeDisplayCart(&$cart, &$obj)` — `site/Model/CartpreviewModel.php::prepareView()`.
7. `onBeforeDisplayCheckoutNavigator(&$output, &$array_navigation_steps, &$step)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
8. `onAfterDisplayCheckoutNavigator(&$view)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
9. `onBeforeDisplayCartView(&$view)` — `site/Controller/CartController.php::view()`.

### A2. Step2 (`CheckoutController::step2`, `step2save`)

1. `onConstructJshoppingControllerCheckout(&$obj)` — `site/Controller/CheckoutController.php::init()`.
2. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
3. `onLoadCheckoutStep2()` — `site/Controller/CheckoutController.php::step2()`.
4. `onBeforeDisplayCheckoutNavigator(&$output, &$array_navigation_steps, &$step)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
5. `onAfterDisplayCheckoutNavigator(&$view)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
6. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
7. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
8. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
9. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
10. `onBeforeDisplaySmallCart(&$cart, &$obj)` — `site/Model/CartpreviewModel.php::prepareView()`.
11. `onAfterCartGetTaxExt(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` — `site/Model/CartModel.php::getTaxExt()`.
12. `onAfterCartGetSum(&$obj, &$incShiping, &$incRabatt, &$incPayment)` — `site/Model/CartModel.php::getSum()`.
13. `onBeforeDisplayCheckoutCartView(&$view)` — `site/Model/CheckoutModel.php::showSmallCart()`.
14. `onBeforeDisplayCheckoutStep2View(&$view)` — `site/Controller/CheckoutController.php::step2()`.
15. `onLoadCheckoutStep2save(&$post)` — `site/Controller/CheckoutController.php::step2save()`.
16. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
17. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
18. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
19. `onBeforeSaveCheckoutStep2(&$adv_user, &$user, &$cart, &$model)` — `site/Controller/CheckoutController.php::step2save()`.
20. `onAfterSaveCheckoutStep2(&$adv_user, &$user, &$cart)` — `site/Controller/CheckoutController.php::step2save()`.
21. `onAfterSetMaxStepJshopCheckout(&$step)` — `site/Model/CheckoutModel.php::setMaxStep()`.

### A3. Step3 (`CheckoutController::step3`, `step3save`)

1. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
2. `onLoadCheckoutStep3()` — `site/Controller/CheckoutController.php::step3()`.
3. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
4. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
5. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
6. `onBeforeDisplayCheckoutNavigator(&$output, &$array_navigation_steps, &$step)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
7. `onAfterDisplayCheckoutNavigator(&$view)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
8. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
9. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
10. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
11. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
12. `onBeforeDisplaySmallCart(&$cart, &$obj)` — `site/Model/CartpreviewModel.php::prepareView()`.
13. `onAfterCartGetTaxExt(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` — `site/Model/CartModel.php::getTaxExt()`.
14. `onAfterCartGetSum(&$obj, &$incShiping, &$incRabatt, &$incPayment)` — `site/Model/CartModel.php::getSum()`.
15. `onBeforeDisplayCheckoutCartView(&$view)` — `site/Model/CheckoutModel.php::showSmallCart()`.
16. `onBeforeDisplayCheckoutStep3View(&$view)` — `site/Controller/CheckoutController.php::step3()`.
17. `onBeforeSaveCheckoutStep3save(&$post)` — `site/Controller/CheckoutController.php::step3save()`.
18. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
19. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
20. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
21. `onAfterSaveCheckoutStep3save(&$adv_user, &$paym_method, &$cart)` — `site/Controller/CheckoutController.php::step3save()`.
22. `onAfterSetMaxStepJshopCheckout(&$step)` — `site/Model/CheckoutModel.php::setMaxStep()`.

### A4. Step4 (`CheckoutController::step4`, `step4save`)

1. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
2. `onLoadCheckoutStep4()` — `site/Controller/CheckoutController.php::step4()`.
3. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
4. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
5. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
6. `onBeforeDisplayCheckoutNavigator(&$output, &$array_navigation_steps, &$step)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
7. `onAfterDisplayCheckoutNavigator(&$view)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
8. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
9. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
10. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
11. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
12. `onBeforeDisplaySmallCart(&$cart, &$obj)` — `site/Model/CartpreviewModel.php::prepareView()`.
13. `onAfterCartGetTaxExt(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` — `site/Model/CartModel.php::getTaxExt()`.
14. `onAfterCartGetSum(&$obj, &$incShiping, &$incRabatt, &$incPayment)` — `site/Model/CartModel.php::getSum()`.
15. `onBeforeDisplayCheckoutCartView(&$view)` — `site/Model/CheckoutModel.php::showSmallCart()`.
16. `onBeforeDisplayCheckoutStep4View(&$view)` — `site/Controller/CheckoutController.php::step4()`.
17. `onBeforeSaveCheckoutStep4save()` — `site/Controller/CheckoutController.php::step4save()`.
18. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
19. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
20. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
21. `onAfterSaveCheckoutStep4(&$adv_user, &$sh_method, &$shipping_method_price, &$cart)` — `site/Controller/CheckoutController.php::step4save()`.
22. `onAfterSetMaxStepJshopCheckout(&$step)` — `site/Model/CheckoutModel.php::setMaxStep()`.

### A5. Step5 (`CheckoutController::step5`, `step5save`)

1. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
2. `onLoadCheckoutStep5()` — `site/Controller/CheckoutController.php::step5()`.
3. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
4. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
5. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
6. `onBeforeDisplayCheckoutNavigator(&$output, &$array_navigation_steps, &$step)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
7. `onAfterDisplayCheckoutNavigator(&$view)` — `site/Model/CheckoutModel.php::showCheckoutNavigation()`.
8. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
9. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
10. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
11. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
12. `onBeforeDisplaySmallCart(&$cart, &$obj)` — `site/Model/CartpreviewModel.php::prepareView()`.
13. `onAfterCartGetTaxExt(&$obj, &$tax_summ, &$incShiping, &$incRabatt, $incPayment)` — `site/Model/CartModel.php::getTaxExt()`.
14. `onAfterCartGetSum(&$obj, &$incShiping, &$incRabatt, &$incPayment)` — `site/Model/CartModel.php::getSum()`.
15. `onBeforeDisplayCheckoutCartView(&$view)` — `site/Model/CheckoutModel.php::showSmallCart()`.
16. `onBeforeDisplayCheckoutStep5(&$sh_method, &$pm_method, &$delivery_info, &$cart, &$view)` — `site/Controller/CheckoutController.php::step5()`.
17. `onBeforeDisplayCheckoutStep5View(&$view)` — `site/Controller/CheckoutController.php::step5()`.
18. `onLoadStep5save(&$checkagb)` — `site/Controller/CheckoutController.php::step5save()`.
19. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
20. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
21. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
22. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
23. `onBeforeCheckListProductsQtyInStore(&$obj)` — `site/Model/CartModel.php::checkListProductsQtyInStore()`.
24. `onCheckListProductsQtyInStoreForeach(&$obj, &$key, &$product, &$attr, &$qtyInStock, &$checkqty, &$check)` — `site/Model/CartModel.php::checkListProductsQtyInStore()`.
25. `onAfterCheckListProductsQtyInStore(&$obj)` — `site/Model/CartModel.php::checkListProductsQtyInStore()`.
26. `onBeforeCheckCouponStep5save(&$obj, &$coupon)` — `site/Model/CartModel.php::checkCoupon()`.
27. `onBeforeGetListFieldCopyUserToOrder(&$list)` — `site/Table/OrderTable.php::getListFieldCopyUserToOrder()`.
28. `onAfterFormatOrderNumber(&$number, &$num)` — `site/Table/OrderTable.php::formatOrderNumber()`.
29. `onAfterCopyDeliveryData(&$obj)` — `site/Table/OrderTable.php::copyDeliveryData()`.
30. `onBeforeCreateOrder(&$order, &$cart, &$obj)` — `site/Model/CheckoutorderModel.php::createOrder()`.
31. `onBeforeStoreTableOrder(&$obj)` — `site/Table/OrderTable.php::store()`.
32. `onAfterCreateOrder(&$order, &$cart)` — `site/Model/CheckoutorderModel.php::orderDataSave()`.
33. `onBeforeCouponFinished(&$coupon, &$cart, &$user_id, &$order)` — `site/Model/CheckoutorderModel.php::couponFinished()`.
34. `onBeforeSaveOrderItem(&$order_item, &$value)` — `site/Table/OrderTable.php::saveOrderItem()`.
35. `onAfterCreateOrderFull(&$order, &$cart)` — `site/Model/CheckoutorderModel.php::orderDataSave()`.
36. `onBeforeJshopOrderSaveOrderHistory(&$history, &$notify, &$comments, &$obj)` — `site/Table/OrderTable.php::saveOrderHistory()`.
37. `onBeforechangeProductQTYinStock(&$items, &$obj, &$change)` — `site/Table/OrderTable.php::changeProductQTYinStock()`.
38. `onAfterchangeProductQTYinStock(&$item, &$change, &$obj)` — `site/Table/OrderTable.php::changeProductQTYinStock()`.
39. `onAfterchangeProductQTYinStockPSR(&$items, &$obj, &$change, &$product_stock_removed)` — `site/Table/OrderTable.php::changeProductQTYinStock()`.
40. `onEndCheckoutStep5(&$order, &$cart)` — `site/Controller/CheckoutController.php::step5save()`.
41. `onAfterSetMaxStepJshopCheckout(&$step)` — `site/Model/CheckoutModel.php::setMaxStep()`.

### A6. Step6 / Step6iframe

1. `onBeforeStep6Iframe(&$width, &$height, &$url)` — `site/Controller/CheckoutController.php::step6iframe()`.
2. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
3. `onBeforeShowEndFormStep6(&$order, &$cart, $pm_method)` — `site/Model/CheckoutorderModel.php::showEndFormPaymentSystem()`.
4. При cancel-ветке дополнительно запускается lifecycle `site/Model/OrderchangestatusModel.php::store()` (см. A7).
5. `onAfterCancelPayOrderJshopCheckout(&$order_id, $status, $sendmessage)` — `site/Model/CheckoutModel.php::cancelPayOrder()`.

### A7. Step7 (`CheckoutController::step7`, `CheckoutBuyModel::buy`)

1. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
2. `onLoadStep7()` — `site/Controller/CheckoutController.php::step7()`.
3. `onOrderCreateAndSetStatus(&$order_id, &$status, &$prev_order_status_data)` — `site/Table/OrderTable.php::orderCreateAndSetStatus()`.
4. `onStep7OrderCreated(&$order, &$res, &$obj, &$pmconfigs)` — `site/Model/CheckoutbuyModel.php::buy()`.
5. Если меняется статус, вызывается lifecycle `site/Model/OrderchangestatusModel.php::store()`:
6. `onBeforeChangeOrderStatus(&$order_id, &$status, &$sendmessage, &$comments, &$prev_status, &$return)` — `site/Model/OrderchangestatusModel.php::store()`.
7. `onBeforeChangeOrderStatusAdmin(&$order_id, &$status, &$status_id, &$notify, &$comments, &$include_comment, &$view_order, &$prev_status, &$return)` — `site/Model/OrderchangestatusModel.php::store()`.
8. `onBeforeJshopOrderSaveOrderHistory(&$history, &$notify, &$comments, &$obj)` — `site/Table/OrderTable.php::saveOrderHistory()`.
9. `onBeforeCreateMailOrderStatusView(&$view)` — `site/Model/OrderchangestatusModel.php::getMessage()`.
10. `onBeforeSendClientMailOrderStatus(&$message, &$order, &$comments, &$tbl_order_status, &$vendorinfo, &$order_details_url, &$ishtml, &$mailfrom, &$fromname, &$subject, &$datavendor)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
11. `onBeforeSendAdminMailOrderStatus(&$message, &$order, &$comments, &$tbl_order_status, &$vendorinfo, &$order_details_url, &$ishtml, &$mailfrom, &$fromname, &$subject, &$datavendor)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
12. `onBeforeSendVendorMailOrderStatus(&$message, &$order, &$comments, &$tbl_order_status, &$vendorinfo, &$order_details_url, &$ishtml, &$mailfrom, &$fromname, &$subject, &$datavendor)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
13. `onBeforeSendMailChangeOrderStatusClient(&$mailer, &$order_id, &$status, &$sendmessage, &$order)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
14. `onBeforeSendMailChangeOrderStatusAdmin(&$mailer, &$order_id, &$status, &$sendmessage, &$order)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
15. `onBeforeSendMailChangeOrderStatusVendor(&$mailer, &$order_id, &$status, &$sendmessage, &$order)` — `site/Model/OrderchangestatusModel.php::sendMail()`.
16. `onAfterChangeOrderStatus(&$order_id, &$status, &$sendmessage, &$prev_status)` — `site/Model/OrderchangestatusModel.php::store()`.
17. `onAfterChangeOrderStatusAdmin(&$order_id, &$status, &$status_id, &$notify, &$comments, &$include_comment, &$view_order, &$prev_status)` — `site/Model/OrderchangestatusModel.php::store()`.
18. `onStep7BefereNotify(&$order, &$obj, &$pmconfigs)` — `site/Model/CheckoutbuyModel.php::buy()`.
19. `onAfterSetMaxStepJshopCheckout(&$step)` — `site/Model/CheckoutModel.php::setMaxStep()`.

### A8. Finish (`CheckoutController::finish`, `CheckoutFinishModel`)

1. `onConstructJshopCheckout(&$obj)` — `site/Model/CheckoutModel.php::__construct()`.
2. `onBeforeDisplayCheckoutFinish(&$text, &$order_id, &$text_end)` — `site/Controller/CheckoutController.php::finish()`.
3. `onAfterDisplayCheckoutFinish(&$text, &$order, &$pm_method)` — `site/Model/CheckoutfinishModel.php::paymentComplete()`.
4. Динамический trigger (`Js_add_trigger before`) с параметрами `(&$callerObject, &$varsArray)` — `site/Model/CheckoutfinishModel.php::clearAllDataCheckout()`.
5. `onConstructJshopCart(&$obj)` — `site/Model/CartModel.php::__construct()`.
6. `onBeforeCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
7. `onAfterCartLoad(&$obj)` — `site/Model/CartModel.php::load()`.
8. `onAfterLoadPriceAndCountProducts(&$obj)` — `site/Model/CartModel.php::load()`.
9. `onAfterCartGetSum(&$obj, &$incShiping, &$incRabatt, &$incPayment)` — `site/Model/CartModel.php::getSum()`.
10. `onBeforeClearCart(&$obj)` — `site/Model/CartModel.php::clear()`.
11. `onAfterSaveToSessionCart(&$obj)` — `site/Model/CartModel.php::saveToSession()`.
12. `onAfterDeleteDataOrder(&$obj)` — `site/Model/CheckoutModel.php::deleteSession()`.
13. Динамический trigger (`Js_add_trigger after`) с параметрами `(&$callerObject, &$varsArray)` — `site/Model/CheckoutfinishModel.php::clearAllDataCheckout()`.

## Об авторе

![Толкачев Сергей Юрьевич](https://web-tolk.ru/images/uslugi/sergey-tolkachyov-apr-2023.webp)

### Толкачев Сергей Юрьевич

Joomla-разработчик. [Контрибьютер ядра Joomla](https://github.com/joomla/joomla-cms/pulls?q=is%3Apr+author%3Asergeytolkachyov+). Один из ведущих Telegram-канала русскоязычного Joomla-сообщества [JoomlaFeed](https://t.me/joomlafeed), один из модераторов [чата русскоязычного Joomla-сообщества](https://t.me/joomlaru). Мои расширения в официальном маркетплейсе расширений Joomla - [Joomla Extensions Directory](https://extensions.joomla.org/profile/profile/details/528051/). Имею публикации в [официальном журнале международного Joomla-сообщества - Joomla Community Magazine](https://magazine.joomla.org/authors/sergeytolkachyov) и на [официальном сайте русскоязычного Joomla-сообщества](https://joomlaportal.ru/users/sergey-tolkachyov).

Муж. Отец 3 детей.

Россия, Саратов.

## JSON-LD Schema

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","@id":"https://web-tolk.ru/#/schema/BreadcrumbList/17","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://web-tolk.ru/","name":"Главная"}},{"@type":"ListItem","position":2,"item":{"@id":"https://web-tolk.ru/blog","name":"Блог"}},{"@type":"ListItem","position":3,"item":{"name":"JoomShopping 5.9.0: полный жизненный цикл оформления заказа от корзины до страницы "спасибо за заказ""}}]}
```

```json
{
    "@context": "https://schema.org",
    "@graph": [
        {
            "@type": "Organization",
            "@id": "https://web-tolk.ru/#/schema/Organization/base",
            "name": "WebTolk",
            "url": "https://web-tolk.ru/",
            "logo": {
                "@type": "ImageObject",
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo",
                "url": "images/webtolk-1080p.jpg",
                "contentUrl": "images/webtolk-1080p.jpg",
                "width": 1920,
                "height": 1080
            },
            "image": {
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo"
            },
            "sameAs": [
                "https://github.com/WebTolk",
                "https://github.com/sergeytolkachyov",
                "https://vk.com/web_tolk",
                "https://vk.com/webtolkru",
                "https://tenchat.ru/sergeytolkachyov",
                "https://t.me/sergeytolkachyov",
                "https://t.me/webtolkru"
            ]
        },
        {
            "@type": "WebSite",
            "@id": "https://web-tolk.ru/#/schema/WebSite/base",
            "url": "https://web-tolk.ru/",
            "name": "WebTolk",
            "publisher": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            }
        },
        {
            "@type": "WebPage",
            "@id": "https://web-tolk.ru/#/schema/WebPage/base",
            "url": "https://web-tolk.ru/blog/joomshopping-5-9-0-polnyj-zhiznennyj-tsikl-oformleniya-zakaza-ot-korziny-do-stranitsy-spasibo-za-zakaz",
            "name": "JoomShopping 5.9.0: полный жизненный цикл оформления заказа от корзины до страницы \"спасибо за заказ\" - WebTolk",
            "description": "Справочная статья для разработчиков Joomla и JoomShopping: полный поток данных оформления заказа, порядок исполнения\r\n  кода, триггеры плагинов в хронологическом порядке, их входные параметры и типы, а также способы передавать данные из\r\n  плагина в шаблон через _tmp_var-позиции.",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebSite/base"
            },
            "about": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            },
            "inLanguage": "ru-RU",
            "breadcrumb": {
                "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17"
            }
        },
        {
            "@type": "Article",
            "headline": "JoomShopping 5.9.0: полный жизненный цикл оформления заказа от корзины до страницы \"спасибо за заказ\"",
            "description": "Joomla разработчикам и в частности разработчикам, работающим с JoomShopping часто не хватает актуальной документации для работы. Эта справочная статья призвана восполнить этот пробел и дать представление о всём потоке данных в процессе оформления заказа в компоненте интернет-магазина JoomShopping. Описывается порядок исполнения кода, все триггеры плагинов в хронологическом порядке, а так же какие данные они получают на вход и типы этих данных, описывается как прокидывать свои данные из плагина в шаблон JoomShopping в позиции вида _tmp_var....",
            "author": {
                "@type": "person",
                "name": "Сергей Толкачев",
                "url": "https://web-tolk.ru",
                "email": "info@web-tolk.ru"
            },
            "@id": "https://web-tolk.ru/#/schema/com_content/article/176",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebPage/base"
            }
        }
    ]
}
```
