Введение и базовые концепции
Модуль Интернет-магазин sale отвечает за процесс покупки: от корзины до оформленного заказа. В заказе он связывает товары с покупателем, оплатой, доставкой, скидками и документами.
Типовой сценарий заказа состоит из нескольких шагов:
-
Покупатель выбирает товар или торговое предложение из каталога.
-
Товар попадает в корзину.
-
На основе корзины создается заказ.
-
К заказу добавляют свойства, оплату и отгрузку.
-
Интернет-магазин применяет правила работы с корзиной и купоны.
-
После оформления заказа интернет-магазин меняет статусы заказа и формирует документы.
Связь с торговым каталогом
Модуль Торговый каталог хранит данные для продажи товара: тип товара, цены, остатки, доступность, НДС, единицы измерения и торговые предложения. Модуль Интернет-магазин берет эти данные при добавлении позиции в корзину и при расчете заказа.
Товар или торговое предложение -> Корзина -> Заказ
Если у товара есть торговые предложения, в корзину добавляют конкретное предложение. Родительская карточка хранит общее описание товара, а предложение хранит выбранный вариант: размер, цвет, комплектацию, цену и остаток.
Подробнее о товарах в разделе Торговый каталог.
Основные термины
Корзина — набор товаров и услуг, которые покупатель выбрал до оформления заказа. С корзиной работает класс Bitrix\Sale\Basket.
Позиция корзины — один товар, торговое предложение или услуга в корзине. Позиция хранит количество, цену, валюту, название, поставщика товара и служебные данные для расчета.
Покупатель — пользователь, к которому привязана корзина и для которого создается заказ. Класс Bitrix\Sale\Fuser связывает корзину с идентификатором покупателя.
Заказ — оформленная продажа. Заказ объединяет корзину, покупателя, сайт, тип плательщика, свойства, оплаты, отгрузки, скидки, статусы и историю изменений. С заказом работает класс Bitrix\Sale\Order.
Тип плательщика — настройка, которая определяет доступные свойства заказа, платежные системы и службы доставки. Например, можно настроить разные способы оформления заказа для физического и юридического лица.
Свойства заказа — данные, которые покупатель или интеграция передают при оформлении заказа: имя, телефон, адрес, ИНН, комментарий и другие поля.
Оплата — часть заказа, которая фиксирует сумму к оплате, платежную систему и состояние оплаты. С оплатой работает класс Bitrix\Sale\Payment.
Платежная система — обработчик оплаты. Платежная система создает платежную ссылку, перенаправляет покупателя на страницу оплаты или принимает ответ от платежного сервиса.
Отгрузка — часть заказа, которая фиксирует доставляемые позиции, службу доставки, стоимость доставки и состояние отгрузки. С отгрузкой работает класс Bitrix\Sale\Shipment.
Служба доставки — обработчик доставки. Служба доставки рассчитывает стоимость и срок, хранит настройки обработчика и участвует в создании отгрузки.
Статус — состояние заказа или отгрузки. Например, заказ может быть новым, выполненным или отмененным. Состояние оплаты хранится в полях оплаты, например в поле PAID.
Правило работы с корзиной — правило скидки или другого изменения условий покупки. Расчетом скидок и правил занимается Bitrix\Sale\Discount.
Купон — код, который покупатель вводит для применения правила работы с корзиной.
Касса — обработчик онлайн-кассы. Касса получает данные заказа, оплаты или отгрузки и формирует фискальные документы в зависимости от типа операции.
Чек — фискальный документ, который отражает оплату, возврат или другой кассовый сценарий.
Местоположение — справочник стран, регионов, городов и других адресных объектов. Свойства заказа, службы доставки и ограничения используют местоположения для адресов и условий оформления заказа.
Настройки в интерфейсе продукта
Настройки модуля находятся в разделе Настройки > Настройки продукта > Настройки модулей > Интернет-магазин. На странице доступны группы настроек:
-
служебные параметры магазина: e-mail отдела продаж, хранение корзины, блокировка и отображение заказов, валюта, округление и сайты-магазины,
-
параметры корзины, cookies и идентификатора пользователя магазина,
-
настройки скидок, налога для доставки, просмотренных и сопутствующих товаров,
-
пути к пользовательским обработчикам платежных систем и служб доставки,
-
параметры веса, адрес магазина и виджет местоположений,
-
права на заказы и уровень доступа к модулю,
-
автоматизация статусов заказа и отгрузки, архивирование и шаблон нумерации заказов,
-
настройки чеков, страниц результата оплаты, подписок на товары, напоминаний и истории изменения заказов.
Основные справочники магазина настраивают на отдельных страницах административного интерфейса:
-
типы плательщиков, свойства заказа, статусы, платежные системы, службы доставки, кассы и местоположения — в разделе Магазин,
-
товары, торговые предложения, цены и остатки — в разделе Контент и настройках модуля Торговый каталог.
Если заказ создается из кода, заранее подготовьте настройки, которые понадобятся в сценарии: тип плательщика, свойства заказа, платежную систему, службу доставки, валюту и товары каталога. Код использует эти настройки по идентификаторам и символьным кодам, поэтому они должны существовать до запуска сценария.
Компоненты магазина
Для вывода корзины и формы оформления заказа на сайте используйте компоненты. Компоненты подходят для типовых публичных сценариев: корзины, формы оформления заказа, списка заказов покупателя, страницы оплаты и персональных разделов.
Компонент получает данные корзины и заказа, учитывает параметры показа и передает результат в шаблон. Если нужно изменить бизнес-логику оформления, используйте объектную модель модуля sale, а компонент оставьте для вывода формы и работы с интерфейсом.
Подробнее о работе компонентов читайте в статье Компоненты.
Базовый порядок работы
Работа с объектной моделью модуля sale в большинстве сценариев начинается с корзины.
-
Создайте или загрузите корзину для сайта и покупателя.
-
Добавьте в корзину товары, торговые предложения или услуги.
-
Создайте заказ и передайте в него корзину.
-
Укажите сайт, валюту, покупателя и тип плательщика.
-
Заполните свойства заказа.
-
Создайте отгрузку через коллекцию заказа, выберите службу доставки и рассчитайте ее стоимость.
-
Создайте оплату с текущей суммой заказа и выберите доступную платежную систему.
-
Выполните финальный расчет, обновите сумму оплаты и повторно проверьте доступность выбранных сервисов.
-
Сохраните заказ и обработайте результат.
Оплата и отгрузка относятся к заказу. Не создавайте их отдельно от заказа, если вы оформляете покупку через объектную модель. Если при первом сохранении оплата или пользовательская отгрузка не нужны, пропустите соответствующий шаг и добавьте объект позже через коллекцию загруженного заказа.
API модуля
Перед использованием API подключите модуль sale. Если сценарий работает с товарами каталога, подключите модуль catalog.
if (!\Bitrix\Main\Loader::includeModule('sale'))
{
throw new \RuntimeException('Не удалось подключить модуль sale');
}
if (!\Bitrix\Main\Loader::includeModule('catalog'))
{
throw new \RuntimeException('Не удалось подключить модуль catalog');
}
В модуле Интернет-магазин для разных задач используют разные группы API. Выбор зависит от сценария.
-
Объектная модель подходит для оформления заказа и изменения его частей. Используйте классы
Basket,Order,PaymentиShipment, чтобы создать корзину, заказ, оплату и отгрузку с проверками и событиями модуля. -
ORM-классы
*Tableиспользуйте для чтения справочников: типов плательщиков, свойств заказа, статусов, платежных систем, служб доставки, местоположений и других записей. -
Сервисы и менеджеры используйте, когда нужно получить настроенную платежную систему, службу доставки, кассу или ограничение.
-
Классический API используйте там, где для сценария нет полной замены на D7 или код уже написан на классическом API.
Основные объекты для первого сценария:
|
Объект |
Роль в сценарии |
|
|
Хранит позиции до создания заказа и передает их в заказ |
|
|
Определяет покупателя, к которому привязана корзина |
|
|
Объединяет корзину, свойства, оплаты, отгрузки, скидки, статусы и историю продажи |
|
|
Хранит сумму, платежную систему и состояние оплаты внутри заказа |
|
|
Хранит доставляемые позиции, службу доставки, стоимость и состояние отгрузки внутри заказа |
|
|
Рассчитывает правила работы с корзиной, скидки и купоны для корзины или заказа |
Пример. Создадим заказ с одним товаром из каталога, заполним свойство заказа, добавим отгрузку и оплату, затем сохраним заказ.
// Перед запуском примера подготовьте:
// $productId — идентификатор товара или торгового предложения
// $userId — идентификатор покупателя
// $personTypeId — идентификатор типа плательщика
// $propertyCode — символьный код свойства заказа
// $propertyValue — значение свойства заказа
// $paySystemId — идентификатор платежной системы
// $deliveryId — идентификатор службы доставки
if (!\Bitrix\Main\Loader::includeModule('sale'))
{
throw new \RuntimeException('Не удалось подключить модуль sale');
}
if (!\Bitrix\Main\Loader::includeModule('catalog'))
{
throw new \RuntimeException('Не удалось подключить модуль catalog');
}
$siteId = SITE_ID;
$currency = 'RUB';
// Создать корзину для сайта
$basket = \Bitrix\Sale\Basket::create($siteId);
// Добавить товар каталога в корзину
$basketResult = \Bitrix\Catalog\Product\Basket::addProductToBasket($basket, [
'PRODUCT_ID' => $productId,
'QUANTITY' => 1,
], [
'SITE_ID' => $siteId,
'USER_ID' => $userId,
]);
if (!$basketResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $basketResult->getErrorMessages()));
}
// Создать заказ покупателя
$order = \Bitrix\Sale\Order::create($siteId, $userId, $currency);
$personTypeResult = $order->setPersonTypeId($personTypeId);
if (!$personTypeResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $personTypeResult->getErrorMessages()));
}
$basketSetResult = $order->setBasket($basket);
if (!$basketSetResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $basketSetResult->getErrorMessages()));
}
// Заполнить свойство заказа по символьному коду
$propertyCollection = $order->getPropertyCollection();
$property = $propertyCollection->getItemByOrderPropertyCode($propertyCode);
if (!$property)
{
throw new \RuntimeException('Свойство заказа не найдено');
}
$propertyResult = $property->setValue($propertyValue);
if (!$propertyResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $propertyResult->getErrorMessages()));
}
// Добавить отгрузку и ее позиции
$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem();
$shipmentItemCollection = $shipment->getShipmentItemCollection();
foreach ($basket as $item)
{
$shipmentItem = $shipmentItemCollection->createItem($item);
if (!$shipmentItem)
{
throw new \RuntimeException('Не удалось создать позицию отгрузки');
}
$shipmentItemResult = $shipmentItem->setQuantity($item->getQuantity());
if (!$shipmentItemResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $shipmentItemResult->getErrorMessages()));
}
}
// Выбрать доступную службу доставки
$availableDeliveries = \Bitrix\Sale\Delivery\Services\Manager::getRestrictedObjectsList(
$shipment
);
$delivery = $availableDeliveries[$deliveryId] ?? null;
if (!$delivery)
{
throw new \RuntimeException('Служба доставки недоступна для заказа');
}
$shipment->setDeliveryService($delivery);
$deliveryResult = $shipmentCollection->calculateDelivery();
if (!$deliveryResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $deliveryResult->getErrorMessages()));
}
// Добавить оплату и выбрать доступную платежную систему
$paymentCollection = $order->getPaymentCollection();
$payment = $paymentCollection->createItem();
$paymentResult = $payment->setFields([
'SUM' => $order->getPrice(),
'CURRENCY' => $currency,
]);
if (!$paymentResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $paymentResult->getErrorMessages()));
}
$availablePaySystems = \Bitrix\Sale\PaySystem\Manager::getListWithRestrictions(
$payment,
\Bitrix\Sale\Services\Base\RestrictionManager::MODE_CLIENT
);
if (!isset($availablePaySystems[$paySystemId]))
{
throw new \RuntimeException('Платежная система недоступна для заказа');
}
$paySystem = \Bitrix\Sale\PaySystem\Manager::getObjectById($paySystemId);
if (!$paySystem)
{
throw new \RuntimeException('Платежная система не найдена');
}
$payment->setPaySystemService($paySystem);
// Рассчитать заказ после выбора доставки и платежной системы
$calculateResult = $order->doFinalAction(true);
if (!$calculateResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $calculateResult->getErrorMessages()));
}
$paymentResult = $payment->setField('SUM', $order->getPrice());
if (!$paymentResult->isSuccess())
{
throw new \RuntimeException(implode('; ', $paymentResult->getErrorMessages()));
}
// Повторно проверить сервисы после финального расчета
$availableDeliveries = \Bitrix\Sale\Delivery\Services\Manager::getRestrictedObjectsList(
$shipment
);
if (!isset($availableDeliveries[$deliveryId]))
{
throw new \RuntimeException('Служба доставки недоступна после расчета заказа');
}
$availablePaySystems = \Bitrix\Sale\PaySystem\Manager::getListWithRestrictions(
$payment,
\Bitrix\Sale\Services\Base\RestrictionManager::MODE_CLIENT
);
if (!isset($availablePaySystems[$paySystemId]))
{
throw new \RuntimeException('Платежная система недоступна после расчета заказа');
}
// Сохранить заказ и проверить результат
$result = $order->save();
if (!$result->isSuccess())
{
throw new \RuntimeException(implode('; ', $result->getErrorMessages()));
}
После успешного выполнения примера метод save() сохранит заказ. Корзина станет частью заказа. Отгрузка будет содержать доставляемые позиции, а оплата — платежную систему и рассчитанную сумму заказа.
В примере показан базовый порядок работы с объектной моделью. В рабочем сценарии учитывайте:
-
что товар или торговое предложение должны быть активны и доступны для покупки,
-
обязательные свойства заказа нужно заполнить до сохранения,
-
платежная система и служба доставки должны быть доступны для выбранного сайта, типа плательщика и условий заказа,
-
нужно проверить права пользователя, от имени которого выполняется код.
Связанные материалы
Основной сценарий работы с заказом в материалах:
-
Схема работы интернет-магазина и основные объекты — разберитесь, как связаны корзина, заказ, свойства, оплаты и отгрузки.
-
Как выбрать API интернет-магазина — выберите объектную модель, ORM, менеджер сервиса или классический API для своей задачи.
-
Базовые настройки интернет-магазина — подготовьте сайт, валюту, тип плательщика и настройки, которые нужны вашему сценарию.
-
Работа с корзиной — создайте или загрузите корзину и подготовьте позиции.
-
Оформление заказа и публичные сценарии — используйте стандартную публичную форму оформления.
-
Создание заказа — соберите заказ в серверном, фоновом или интеграционном сценарии.
Если товары, цены и остатки еще не настроены, прочитайте Введение и базовые концепции торгового каталога.
После создания заказа переходите к профильной задаче: