Как выбрать API интернет-магазина
- Как выбрать между объектной моделью, ORM и менеджерами
- Корзина и заказ
- Настройки и свойства заказа
- Оплаты, доставки и кассы
- Скидки, купоны и резервирование
- Местоположения, покупатели и связанные данные
- Статусы, события и история
- Отчеты, архив и интеграции
- Сводная таблица классического API
- Типичные ошибки выбора API
В модуле sale выбор API зависит не только от данных, но и от действия над ними. Один заказ объединяет корзину, свойства, оплаты, отгрузки, скидки, статусы и историю. Если изменить только одну запись через ORM, связанные объекты могут остаться в несогласованном состоянии.
Для нового кода используйте объектную модель заказа, ORM-классы, менеджеры сервисов и обработчики D7. Классический API нужен для отдельных операций, у которых нет полной замены, и для поддержки существующего проекта.
Перед работой подключите модули:
-
sale— для работы с API интернет-магазина, -
currency— для сценариев с валютами, -
catalog— для товаров, цен, остатков, резервирования и складских операций.
Связи объектов и поля ORM-классов описаны в материале Схема работы интернет-магазина и основные объекты.
Как выбрать между объектной моделью, ORM и менеджерами
Сначала определите, нужен ли сценарию жизненный цикл объекта, выбор настроенного сервиса или только сохраненные данные. Затем выберите уровень API.
|
Задача |
Метод |
Пояснение |
|
Создать или изменить корзину, заказ, оплату либо отгрузку |
Объектная модель |
Проверяет данные, сохраняет связанные коллекции и запускает события. При сохранении заказа участвует в записи истории |
|
Получить список, отфильтровать строки или рассчитать агрегаты |
ORM-классы |
Формируют выборку без загрузки полного объекта заказа |
|
Прочитать или изменить отдельную настройку |
Профильный ORM-класс или менеджер |
Работает с настройками типов плательщиков, свойств, статусов, компаний и других объектов вне жизненного цикла заказа |
|
Выбрать платежную систему, службу доставки, кассу или компанию |
Профильный |
Возвращает настроенный сервис и учитывает его ограничения |
|
Рассчитать заказ, скидки, доставку или доступность сервиса |
Объектная модель и профильный сервис |
Расчет зависит от состава заказа, покупателя, сайта, типа плательщика и настроек |
|
Поддержать существующий код или выполнить операцию без полного D7-аналога |
Классический API |
Сохраняет совместимость или предоставляет специальную операцию, которой нет на другом уровне API |
Объектная модель
Объектная модель подходит для операций, которые меняют состояние покупки. Основные классы объектной модели:
-
Bitrix\Sale\Basket— корзина, -
Bitrix\Sale\Order— заказ, -
Bitrix\Sale\PaymentCollection— коллекция оплат, -
Bitrix\Sale\ShipmentCollection— коллекция отгрузок.
Оплату и отгрузку создавайте через коллекции заказа, а не как независимые записи.
Способ сохранения корзины зависит от ее связи с заказом. Если корзина еще не привязана к заказу, вызовите Basket::save(). Корзину сохраненного заказа отдельно не сохраняйте: вызовите Order::save().
Оба метода возвращают объект Bitrix\Sale\Result. Проверьте его после сохранения: успешное изменение отдельного поля еще не означает, что все данные записаны.
ORM-классы
ORM подходит для списков, отчетов, фильтрации, сортировки и агрегатов. Для основных данных заказа используйте классы:
-
Bitrix\Sale\Internals\OrderTable— для заказов, -
Bitrix\Sale\Internals\BasketTable— для позиций корзины, -
Bitrix\Sale\Internals\PaymentTable— для оплат, -
Bitrix\Sale\Internals\ShipmentTable— для отгрузок.
Не изменяйте через эти классы заказ и его коллекции. ORM-запись не выполняет полный жизненный цикл объектной модели и не согласует корзину, оплаты, отгрузки, свойства, скидки и историю.
Ограничение не означает, что все ORM-классы модуля доступны только для чтения. Настройки и справочники можно создавать через профильные таблицы, если такой сценарий описан для конкретного класса. Например, PersonTypeTable используют для типов плательщиков, OrderPropsTable — для настроек свойств заказа, StatusTable — для статусов. Эти классы применяют, когда магазин настраивают через код.
Менеджеры и сервисы
Менеджер выбирает настроенную реализацию и применяет правила подсистемы. Используйте:
-
Bitrix\Sale\Delivery\Services\Manager— для служб доставки, -
Bitrix\Sale\PaySystem\Manager— для платежных систем, -
Bitrix\Sale\Cashbox\ManagerиBitrix\Sale\Cashbox\CheckManager— для касс и чеков, -
Bitrix\Sale\Services\Company\Manager— для компаний, -
Bitrix\Sale\DiscountCouponsManager— для купонов в расчете корзины или заказа.
Не выбирайте сервис только по идентификатору из пользовательского запроса. Сначала получите доступные варианты с учетом сайта, типа плательщика, суммы, состава заказа и режима ограничений.
Классический API
К классическому API относятся классы CSale*. Проверяйте назначение каждого класса отдельно. Одни классы устарели целиком, другие продолжают предоставлять отдельные актуальные операции.
Для нового сценария сначала ищите объектную модель, ORM-класс или менеджер. Обращайтесь к классическому API, если для конкретной операции нет полной замены в D7.
Корзина и заказ
Корзина хранит выбранные товары, а заказ объединяет корзину, свойства, оплаты и отгрузки. Для чтения или изменения одного заказа загрузите объект Bitrix\Sale\Order. Для списка сохраненных полей используйте ORM.
|
Задача |
Метод |
Пояснение |
|
|
Для нового кода не используйте |
|
|
|
Методы загружают корзину по идентификатору покупателя без самостоятельного запроса к строкам корзины |
|
|
|
Метод заполняет рассчитанные поля товара через провайдера |
|
|
|
Не обновляйте позицию через |
|
|
|
ORM-выборка не требует загружать каждую корзину в цикле |
|
|
|
Для нового кода не используйте |
|
|
|
Не изменяйте заказ через |
|
|
Поле |
Не используйте физическое удаление для отмены покупки |
|
|
|
Не загружайте каждый заказ через |
|
|
Методы |
Уровень доступа к модулю и статус заказа не заменяют проверку права на конкретную операцию |
При изменении заказа соблюдайте последовательность действий:
-
Проверьте права.
-
Загрузите объект.
-
Измените профильную коллекцию.
-
Пересчитайте зависимые данные.
-
Сохраните заказ.
Не запускайте save() повторно без разбора ошибок и предупреждений. Повтор без условий из обработчика события может вызвать рекурсию.
Настройки и свойства заказа
Настройки существуют независимо от конкретного заказа. Для них допустима запись через профильные ORM-классы. Значения свойств внутри заказа изменяйте через коллекцию загруженного объекта.
|
Задача |
Метод |
Пояснение |
|
|
Настройка должна быть связана с нужным сайтом |
|
|
|
Классы работают с настройкой поля, не со значением в заказе |
|
|
|
Изменения сохраняются вместе с заказом |
|
|
|
Тип статуса заказа и отгрузки задавайте явно |
|
|
|
Выберите класс по типу объекта |
|
|
|
D7-сценария с сопоставлением значений нет |
|
|
|
Метод удаляет профиль вместе со связанными значениями |
Не переносите значение свойства между типами плательщика только по его идентификатору. Сначала найдите настройку по роли или символьному коду в контексте выбранного типа плательщика.
Оплаты, доставки и кассы
Оплата и отгрузка принадлежат заказу, а платежная система, служба доставки и касса являются настроенными сервисами. Поэтому для одного сценария нужны и объектная модель, и профильный менеджер.
|
Задача |
Метод |
Пояснение |
|
|
Оплата сохраняется в составе заказа |
|
|
|
Учитывает ограничения для оплаты и заказа |
|
|
|
Возвращает объект сервиса для запуска обработчика |
|
|
Наследник |
Работает в механизме платежных систем D7 |
|
|
|
Отгрузка сохраняется вместе с позициями и заказом |
|
|
|
Учитывает ограничения службы для отгрузки |
|
|
Объект службы из |
Расчет зависит от состава и адресных данных заказа |
|
|
Наследник |
Регистрируется как служба доставки нового типа |
|
|
|
Связывает заявку с отгрузками и внешней службой |
|
|
|
Учитывает ограничения кассы, оплаты, отгрузки и компании |
|
|
|
Управляет жизненным циклом чека и результатом печати |
Не создавайте оплату или отгрузку прямой записью через PaymentTable и ShipmentTable. Для отчетов эти классы подходят, но для изменения состояния нужны коллекции заказа и профильные методы.
Скидки, купоны и резервирование
Расчетные подсистемы используют состояние корзины или заказа. Запись одной итоговой суммы не заменяет расчет правил, работу провайдера товара или изменение отгрузки.
|
Задача |
Метод |
Пояснение |
|
|
Не вызывайте |
|
|
|
Выполняйте после изменений, которые влияют на стоимость |
|
|
|
Принятый код купона еще не подтверждает применение скидки |
|
|
|
У сценария настройки правила нет полной замены в D7 |
|
|
Объекты заказа, отгрузки и сервисы |
Операция связана с количеством в отгрузке и провайдером каталога |
|
|
API складских документов модуля |
Заказ и отгрузка не заменяют складской документ |
Не рассчитывайте скидку вручную и не записывайте итоговую стоимость напрямую. Ручной расчет может не учесть купоны, группы пользователя, доставку, округление и порядок применения правил.
Местоположения, покупатели и связанные данные
Для справочников и статистики выбирайте профильный класс. Если данные участвуют в оформлении заказа, передайте их в объектную модель до расчета.
|
Задача |
Метод |
Пояснение |
|
ORM-классы пространства имен |
Используйте код или идентификатор конкретного адресного объекта |
|
|
Коллекция свойств заказа и менеджер доставки |
Значение свойства должно соответствовать типу и настройке местоположения |
|
|
|
Возвращает итог для объекта заказа |
|
|
|
Полного D7-сценария для детализации нет |
|
|
|
Идентификатор покупателя корзины отличается от идентификатора пользователя |
|
|
|
Возвращает сохраненную статистику по пользователю, сайту и валюте |
|
|
|
У D7 нет класса для безопасного изменения баланса. Передавайте в |
Статусы, события и история
Статус меняйте в объектной модели после проверки разрешенной операции. Для реакции на жизненный цикл используйте события, а сохраненную историю читайте через профильный API.
|
Задача |
Метод |
Пояснение |
|
|
Матрица статусов не заменяет проверку доступа к конкретному заказу |
|
|
|
Не смешивайте статус отгрузки с признаками разрешения и списания |
|
|
|
Выберите событие по моменту: до изменения, до сохранения или после полного сохранения |
|
|
|
Класс |
|
|
Настройки почтовых событий и жизненный цикл заказа |
Не дублируйте штатное письмо собственным обработчиком |
Обработчик события не должен повторно сохранять тот же объект. Если повторное сохранение необходимо, защитите обработчик от рекурсии и повторной обработки одного заказа.
Отчеты, архив и интеграции
Эти сценарии чаще читают много заказов, поэтому полная загрузка объектной модели нужна не всегда.
|
Задача |
Метод |
Пояснение |
|
|
ORM-выборка подходит только для чтения |
|
|
Прочитать архивный заказ или восстановить архивный объект в памяти |
|
Метод |
|
|
ORM подходит для предварительного поиска, но не заменяет объект заказа с полным набором данных формы |
|
|
Компонент |
Не копируйте внутреннюю реализацию компонента в собственный модуль |
|
|
|
Загружайте объект заказа непосредственно перед чтением связанных коллекций или записью; храните внешний идентификатор и состояние обмена |
|
|
Компонент |
Не меняйте внутренние шаги компонента прямой записью в таблицы |
При пакетной обработке читайте строки частями с устойчивой сортировкой. ORM может предварительно выбрать кандидатов, но не заменяет объект заказа, если сообщение содержит корзину, свойства, оплаты или отгрузки. Перед формированием полного сообщения или записью заново загрузите заказ и проверьте его актуальное состояние. Такой порядок уменьшает риск передать устаревшие данные или перезаписать изменения параллельного процесса.
Сводная таблица классического API
К классическому API относятся классы CSale*. Для многих задач нового кода есть подход D7, но отдельные операции по-прежнему выполняют через классический API. Таблица помогает выбрать актуальный подход для конкретной задачи.
При поддержке существующего кода учитывайте события, проверки прав и побочные эффекты текущего сценария. Если операция переносится на D7, заменяйте один вызов за раз и проверяйте сохраненный заказ и связанные объекты.
|
Задача |
Классический API |
Актуальный подход |
|
Работать с корзиной |
|
|
|
Создать или изменить заказ |
|
|
|
Настроить платежную систему |
|
|
|
Настроить службу доставки |
|
|
|
Создать статус или проверить переход |
|
|
|
Создать или найти тип плательщика |
|
|
|
Настроить свойства заказа |
|
|
|
Рассчитать или настроить правило корзины |
|
|
|
Создать, изменить или удалить профиль |
|
ORM-классы профилей для чтения; |
|
Получить налог заказа |
|
|
|
Прочитать журнал изменений |
|
Полной замены для чтения журнала нет; события D7 используют для реакции на новые изменения |
|
Настроить обмен с 1С |
|
Штатный компонент обмена или собственная интеграция на |
Типичные ошибки выбора API
Ошибки выбора уровня API часто не приводят к синтаксическому сбою. Код выполняется, но пропускает часть жизненного цикла или получает неполные данные.
Выбирайте API по задаче:
-
объектная модель выполняет жизненный цикл покупки,
-
ORM читает данные массово,
-
менеджер выбирает настроенный сервис,
-
классический API выполняет операции без полной замены в D7.
После операции проверяйте результат:
-
после записи — объект
Result, -
расчета — итоговые значения и состояния,
-
пакетного чтения — полноту активных и архивных данных.
|
Ошибка |
Почему возникает проблема |
Как делать |
|
Изменять заказ через |
Не согласуются коллекции, расчеты, события и история |
Загрузить |
|
Создавать оплату или отгрузку отдельной ORM-записью |
Объект не включается корректно в коллекцию заказа |
Создать элемент через коллекцию загруженного заказа |
|
Загружать каждый заказ через |
Полная объектная модель создает лишнюю нагрузку |
Выбрать нужные поля одним ORM-запросом |
|
Менять справочник только через объект заказа |
Настройка существует независимо от заказа |
Использовать профильный ORM-класс или менеджер |
|
Выбирать сервис только методом |
Идентификатор не подтверждает доступность для текущего заказа |
Сначала получить список с ограничениями, затем загрузить выбранный сервис |
|
Считать успешное добавление купона подтверждением скидки |
Купон может быть принят, но не примениться к условиям заказа |
Пересчитать объект и проверить статус купона |
|
Проверять только статус перед изменением заказа |
Статус не подтверждает права на сайт и конкретную операцию |
Вызвать профильный метод проверки прав для заказа |
|
Смешивать активные и архивные заказы в одном источнике |
После архивирования заказ исчезает из активных ORM-таблиц |
Прочитать активные и архивные данные отдельно и объединить по явному правилу |
|
Повторять |
Причина может сохраниться, а обработчики запустятся повторно |
Разобрать результат, загрузить актуальное состояние и решить, допустим ли повтор |
|
Переписать классический вызов без проверки границы замены |
У метода может не быть полного D7-аналога |
Сверить конкретную операцию со сводной таблицей и профильной статьей |