Потребовалось на сайте реализовать упрощенный процесс покупки товара в 1 клик с указанием номера телефона и имени. Покупка осуществляется со страницы товара и в самой корзине. При покупке в корзине оформляется вся корзина, а на странице товара только этот товар.
Данные отправляются AJAX – ом и обрабатываются, чтобы не загружать страницу при загрузке, ну и чтобы при оформлении лишних перезагрузок не было.
Код максимально комментировал. Если возникнут проблемы, учите матчасть =)
В нашем случае этот обработчик кроме запросов покупки в 1 клик, обрабатывает все остальные формы сайта (если вдруг что-то лишнее нашли в коде=)).
Начнем со всплывающей формы, которая находится в подвале сайта.
<?
// ВЫВОД ИНФОРМАЦИИ О ТОВАРАХ, КОТОРЫЕ СОБИРАЕМСЯ КУПИТЬ
if($APPLICATION->GetCurPage() == '/personal/cart/') {
// Если покупка происходит в корзине
// получаем товары из корзины
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(Bitrix\Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
// выводим циклом
$basketItems = $basket->getBasketItems();
foreach ($basket as $basketItem) {
$res = CIBlockElement::GetByID($basketItem->getField('PRODUCT_ID'));
$ar_res = $res->GetNext()
?>
<div class="basket__product m-click__product flex align-center">
<a href="<?= $basketItem->getField('DETAIL_PAGE_URL') ?>" class="basket__product-img">
<img src="<?=CFile::GetPath($ar_res["PREVIEW_PICTURE"])?>" alt="<?= $basketItem->getField('NAME') ?>">
</a>
<a href="<?= $basketItem->getField('DETAIL_PAGE_URL') ?>" class="basket__product-title">
<?= $basketItem->getField('NAME') ?>
</a>
</div>
<?
}
} else {
// Если покупка происходит на странице товара
// получаем ИД товара и выводим инфу
$productID = $APPLICATION->GetPageProperty('productId');
if ($productID) :
$res = CIBlockElement::GetByID($productID);
$ar_res = $res->GetNext()
?>
<div class="basket__product m-click__product flex align-center">
<a href="<?= $ar_res['DETAIL_PAGE_URL'] ?>" class="basket__product-img">
<img src="<?=CFile::GetPath($ar_res["PREVIEW_PICTURE"])?>" alt="<?= $ar_res['NAME'] ?>">
</a>
<a href="<?= $ar_res['DETAIL_PAGE_URL'] ?>" class="basket__product-title">
<?= $ar_res['NAME'] ?>
</a>
</div>
<?
endif;
}
?>
<!-- Форма -->
<form id='m-click' class="m-contact__form" method="post" enctype="multipart/form-data" onsubmit="sendForm(event)">
<input class='modal__input' type="text" required placeholder="Ваше имя" name='userName'>
<input class='modal__input' required type="tel" maxlength="28" placeholder="Телефон" name='userTel'>
<input hidden type="text" name='pageUrl' value="<?=$APPLICATION->GetCurPage()?>">
<input hidden type="text" name='productId' value="<?=$APPLICATION->GetPageProperty('productId')?>">
<div class="m-contact__caption">
Отправляя заявку, вы соглашаетесь с нашей <a class='link' href="#">политикой конфеденциальности</a>
</div>
<button type='submit' class="btn btn_red modal__btn">Купить в один клик</button>
</form>
JS
/*** ФОРМА ОТПРАВКИ ***/
function sendForm(event) {
event.preventDefault();
let data = new FormData(event.target);
//console.log(data)
$.ajax({
url: '/local/ajax/send.php',
method: 'post',
contentType: false,
processData: false,
dataType: 'html',
data: data,
success: function(data){
// ошибок нет
console.log(data);
},
error: function(data) {
// ошибка
console.log(data);
}
});
}
Обработчик
<? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
// подключаем модуль отправки данных
use Bitrix\Main\Mail\Event;
/*** Получаем данные из формы отправленные скриптом ***/
// перед присвоением в переменную, проверяем есть ли данные
if (!empty($_POST["userName"])) $name = $_POST['userName'];
if (!empty($_POST["userTel"])) $phone = $_POST['userTel'];
if (!empty($_POST["pageUrl"])) $pageUrl = $_POST['pageUrl'];
if (!empty($_POST["productId"])) $productId = $_POST['productId'];
// перекодировка для работы с кирилицей. На случай если сайт работает в кодировке windows-1251
// если сайт на UTF-8, закоментируй строку ниже
$_POST['userName'] = iconv('UTF-8', 'windows-1251', $_POST['userName']);
/*** Проверка данных ***/
if ($name && $phone) {
/** Оформление заказа **/
// подключаем библиотеки
CModule::IncludeModule("sale");
CModule::IncludeModule("catalog");
// функция заказа
function makeOrder($products)
{
// проверяем авторизацию пользователя
global $USER;
if ($USER->GetID() != 0) {
// если пользователь авторизован
$userId = $USER->GetID();
} else {
// если пользователь не авторизован, то выдаем ИД анонимного пользователя
// у меня в системе он был, если нет, создайте
// так же, можно авторизовать пользователя и выдать ему его ИД
$userId = \CSaleUser::GetAnonymousUserID();
}
// создадим объект корзины
$basket = Bitrix\Sale\Basket::create('s2');
foreach ($products as $product) {
$item = $basket->createItem("catalog", $product["PRODUCT_ID"]);
unset($product["PRODUCT_ID"]);
$item->setFields($product);
}
// создать сам заказ
$order = Bitrix\Sale\Order::create('s2', $userId);
$order->setPersonTypeId(1);
$order->setBasket($basket);
// создать отгрузки
$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem(
Bitrix\Sale\Delivery\Services\Manager::getObjectById(1)
);
// Наполним отгрузку товарами
$shipmentItemCollection = $shipment->getShipmentItemCollection();
foreach ($basket as $basketItem) {
$item = $shipmentItemCollection->createItem($basketItem);
$item->setQuantity($basketItem->getQuantity());
}
// создадим оплату
$paymentCollection = $order->getPaymentCollection();
$payment = $paymentCollection->createItem(
Bitrix\Sale\PaySystem\Manager::getObjectById(1)
);
// сохранить наш заказ
$result = $order->save();
if (!$result->isSuccess()) {
$result->getErrors();
}
// для проверки
//print_r($result);
}
// тут разбираемся, нажал пользователь купить в 1 клик на странице товара или в корзине
if ($productId) {
// если покупаем со страницы товара
// получаем инфы о товаре по ИД
$ar_res = CIBlockElement::GetByID($productId);
$arProd = $ar_res->GetNext(); // инфа
$arPrice = CPrice::GetBasePrice($productId); // цена товара по ИД
// формируем массив для отправки в функцию заказа
$products = array(
array(
'PRODUCT_ID' => $productId,
'NAME' => $arProd['NAME'],
'PRICE' => $arPrice['PRICE'],
'CURRENCY' => 'RUB',
'QUANTITY' => 1,
'PRODUCT_PROVIDER_CLASS' => '\Bitrix\Catalog\Product\CatalogProvider',
)
);
// отправляем в функцию
makeOrder($products);
} else {
// оформление всей корзины
// получение списка товаров корзины
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(Bitrix\Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
// формируем массив для отправки в функцию заказа
$basketItems = $basket->getBasketItems();
foreach ($basket as $basketItem) {
$products[] =
[
'PRODUCT_ID' => $basketItem->getField('PRODUCT_ID'),
'NAME' => $basketItem->getField('NAME'),
'PRODUCT_PROVIDER_CLASS' => '\Bitrix\Catalog\Product\CatalogProvider',
'PRICE' => $basketItem->getField('PRICE'),
'CURRENCY' => 'RUB',
'QUANTITY' => $basketItem->getField('QUANTITY')
];
}
// отправляем в функцию
makeOrder($products);
// очистка корзины
CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID());
}
// для проверки
// print_r($products);
/** сохранение данных в инфоблок **/
// подключаем модуль инфоблоков
CModule::IncludeModule('iblock');
// инициализируем
$elem = new CIBlockElement;
// берем все входящее данные и пихаем в строку
if (empty($_POST['userTel']))
$_POST['userTel'] = $_POST[0];
$text = '';
foreach ($_POST as $name => $val) {
$text .= $name . ' : ' . $val . '
';
}
// добавляем товары к этой строке
$productList = '';
foreach ($products as $product) {
$productList .= $product['NAME'] . ' - ' . round($product['QUANTITY']) . ';
';
}
$text .= $productList;
// все ид файлов присваиваем свойству, если есть, у меня нет)
$PROP['FILES'] = [];
// настройки
$arLoadProductArray = array(
"MODIFIED_BY" => 1,
"IBLOCK_SECTION_ID" => false, // элемент лежит в корне раздела
"IBLOCK_ID" => 29, // Ид инфоблока
"PREVIEW_TEXT" => $text, // массив со свойствами
"NAME" => $phone, // имя записи
"ACTIVE" => "Y",
);
// сохраняем
$PRODUCT_ID = $elem->Add($arLoadProductArray);
/*** Отправка данных ***/
Event::send(array(
"EVENT_NAME" => "SENDMESSAGE",
"LID" => "s2",
"C_FIELDS" => array(
"AUTHOR" => $_POST['userName'],
"PHONE" => $_POST['userTel'],
"URL" => $pageUrl,
"PRODUCTS" => $productList,
),
"FILE" => [],
));
}
?>
<? // опять проверки ?>
<? // print_r($_POST) ?>
<? // print_r($text) ?>
Комментарии