Купить товар в один клик в 1с-битрикс бесплатно

Задачу покупки одного товара можно решить, купив плагин на маркетплейсе.
Но есть люди, как я, которые хотят побольше делать своими руками.
Давайте сформируем краткое ТЗ:

  1. Заказ оформляется в всплывающем окне (AJAX)
  2. Перед оформлением заказа создается новый пользователь, если не авторизован
  3. После создания авторизуется автоматически
  4. Создается полноценный заказ в админке
  5. В корзине после покупки в один клик остаются прежние товары

Итак начнем!

Вешаем на кнопку:

<a class="one_click_buy" href="/one_click_order?product_id=100500">
Купить в один клик
</a>

событие jQuery:

$(".one_click_buy").click(function(event) {
	event.preventDefault();
	$( "#modal_window" ).load( $(this).attr("href"), function() {
		order_handler();
	});
});​

function order_handler()
{
	$("#one_click_form").submit(function(){
		if (
			$('[name="fio"]').val() == '' ||
			$('[name="phone"]').val() == '' ||
			$('[name="email"]').val() == ''
		){
			alert('Заполните поля со звездочками.');
		}
		else{
			 var str = $(this).serialize();
			 $.post($(this).attr('action'), str, function (data) {
				if (data == 'ok'){
					alert('Заказ успешно оформлен');
					window.location.href='';
				}else{
				alert(data);
				}				
			});
		}
}

Создаем в корне сайта папку one_click_order, в ней файлы index.php и handler.php
В index.php будет проверка существования товара с ID равным

$_GET['product_id']

и html-верстка формы заказа:

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
if(CModule::IncludeModule("catalog")){
	$ID = intval($_GET['product_id']);
	$ar_res = CCatalogProduct::GetByIDEx($ID);
	if (is_array($ar_res)){
		global $USER;			
		$rsUser = CUser::GetByID($USER->GetID()); 
		$arUser = $rsUser->Fetch();			
		?>
		<a href="<?=$ar_res['DETAIL_PAGE_URL']?>"><?=$ar_res['NAME']?></a>
		<form id="one_click_form" name="one_click_form" action="/one_click_order/handler.php" method="POST">
			<input type="hidden" name="product_id" value="<?= $ID ?>">
			ФИО: <input type="text" name="fio" value="<?=$USER->GetFullName()?>" ><br/>
			Телефон: <input type="text" name="phone" value="<?=$arUser['PERSONAL_PHONE']?>"><br/>
			E-mail: <input type="text" name="email" value="<?=$USER->GetEmail()?>"><br/>
			Комментарий к заказу: <textarea class="inputtext" name="message" value="""></textarea><br/>
			<input type="submit" value="Отправить">		
		</form>
	<?
	}
}

Далее опишем файл /one_click_order/handler.php. В нем будет создание и авторизация пользователя, создание заказа, добавление товара к заказу и его сохранения.

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");	
$is_error=true;
$error_text = '';
if (isset($_POST['product_id']) && isset($_POST['fio']) && isset($_POST['phone']) && isset($_POST['email']) ){
	if(CModule::IncludeModule("catalog") && CModule::IncludeModule("sale")){		
		$product_id = intval($_POST['product_id']);
		$ar_res = CCatalogProduct::GetByIDEx($product_id);
		if ($ar_res){
			$is_error=false;
			global $USER;
			$user_id = $USER->GetID();
			if(!$user_id )
			{
				//пароль для нового пользователя
				$pass = rand(100000, 999999);
				//группы, в которых он будет состоять
				$groups = array(3,4,5);			
				$user_id = $USER->Add(array(
					"NAME"              => $_POST['fio'],
					"EMAIL"             => $_POST['email'],
					"LOGIN"             => $_POST['email'],
					"PERSONAL_PHONE"     => $_POST['phone'],
					"LID"               => "ru",
					"ACTIVE"            => "Y",
					"GROUP_ID"          => $groups,
					"PASSWORD"          => $pass,
					"CONFIRM_PASSWORD"  => $pass,
				));
				$USER->Authorize($user_id);
				$error_text = $USER->LAST_ERROR;
			}
			if ($user_id > 0){
				//PAY_SYSTEM_ID, PRICE_DELIVERY, DELIVERY_ID, DISCOUNT_VALUE, TAX_VALUE можно не указывать
				$arFields = array(
					"LID" => SITE_ID,
					"PERSON_TYPE_ID" => 1,
					// Вместо ### укажите конкретный ID цены
					"PRICE" => $ar_res['PRICES'][###]['PRICE'],
					"PAYED" => "N",
					"CANCELED" => "N",
					"STATUS_ID" => "N",				   
					"CURRENCY" => "RUB",
					"USER_ID" => $user_id,				   
					"USER_DESCRIPTION" => $_POST['message']
				);
				$ORDER_ID = IntVal(CSaleOrder::Add($arFields));
				if ($ORDER_ID > 0){
					$arProps = array();
					 $arFields = array(
						"PRODUCT_ID" => $ar_res['ID'],
						// Вместо ### укажите конкретный ID цены
						"PRICE" => $ar_res['PRICES'][###]['PRICE'],
						"CURRENCY" => "RUB",
						"WEIGHT" => $ar_res['PRODUCT']['WEIGHT'],
						"QUANTITY" => 1,
						"DELAY" => "N",
						"LID" => $ar_res['LID'],
						"CAN_BUY" => "Y",
						"ORDER_ID" => $ORDER_ID,
						"NAME" => $ar_res['NAME'],
						"MODULE" => "catalog",
						"NOTES" => "",
						"DETAIL_PAGE_URL" => $ar_res['DETAIL_PAGE_URL'],
					);
					$add = CSaleBasket::Add($arFields);
					if (intval($add) > 0)
						echo 'ok';
				}
			}
		}
	}
}
if ($error_text != '')
	echo str_replace('<br>', "\n", $error_text);
else if ($is_error){
	echo 'ошибка';
}

В общем этого должно быть достаточно. Функционал можно развивать, например каптчу поставить или сделать отправку e-mail сообщений администратору и покупателю.

Купить товар в один клик в 1с-битрикс бесплатно: 22 комментария

    1. nikki Автор записи

      100500 это число для примера, у вас для каждого товара будет свой ID
      событие jQuery можно вставить в /bitrix/templates/имя_вашего_шаблона/footer.php

      $(document).ready(function () {
      здесь код из поста..
      });

      1. Тони

        Я извиняюсь за незнание PHP, но очень хочется поставить это решение. Если товаров тысячи, можно как то автоматически id подставлять? и другой вопрос. почему то форма открывается на на странице а вместо нее и при нажатии отправить ничего не происходит кроме перехода на страницу /one_click_order/handler.php. и она просто пустая. В чем может быть проблема?

        1. Тони

          С подстановкой ID разобрался.
          Ссылка имеет вид:
          $too = $arResult[‘ID’];
          <a class="one_click_buy" href="/one_click_order?product_id=»>

          Далее есть проблема, форма открывается некорректно в новом окне и без форматирования. после нажатия кнопки оформить переходит на страницу /one_click_order/handler.php. и она просто пустая.

          1. Тони


            $too = $arResult['ID'];
            <a class="one_click_buy" href="/one_click_order?product_id=">

          2. nikki Автор записи

            Скиньте на mail@tamismani.ru адрес вашего сайта,
            если делаете на локалке, то понять почему белый экран поможет debug.

            После каждой строчки делаете вывод, например

            echo 'test';

            остальное комментируете. Когда на экране перестанет отображаться test, вы поймете, что портит вам жизнь.

  1. OlolO

    такая реализация будет плодить дубли зарегистрированных юзеров, потому что нет проверки по мылу не зареган ли уже юзер с таким email.
    Еще момент — если юзер гулял по сайту и насовал себе в корзину n товаров, а затем вдруг решил заказать через «Один клик», то в заказ попадут все товары из корзины плюс текущий товар.
    Ну а в остальном все вроде нормально.

  2. Ольга

    Добрый день!
    Подключаю скрипт. Форма открывается. handler.php запускается. Заказы создаются.
    Не открывается только модальное окно, форма открывается на отдельной странице.
    Что нужно сделать, чтобы открывалось модальное окно?

  3. draff

    Не будет клонировать пользователей, если в настройках Битрикса включить проверку на уникальность эмэйл,в вкладке Авторизация.
    Автору- а почему не фильтруется данные с массива POST ? Ну хотя бы просто
    $email = htmlspecialchars(trim($_POST[’email’]));
    Автору спасибо за направление на путь ))

  4. Игорь

    Добрый день!
    Подключаю скрипт. Форма открывается. handler.php запускается. Заказы создаются.
    Не открывается только модальное окно, форма открывается на отдельной странице.
    Что нужно сделать, чтобы открывалось модальное окно?

    Ольга, у вас скорее всего ошибка в js

    А можно по подробнее рассказать или написать как разобраться что бы открывало именно в модальном окне, или с помощью плагина fancybox
    У меня достаточно старая версия Битрикс Управление сайтом 9.5 возможно модальные окна «#modal_window» у меня не срабатывают.
    Спасибо

  5. Валера Решалов

    Все работает, кроме почтовых событий — в массиве, уходящем в почтовое событие, нет имени товара и дополнительных свойств заказа.

  6. Артур

    Здравствуйте!
    я в битриксе новичок.. все сделал как написано:
    1) создал папку в корне сайта /one_click_order/
    2) в ней создал два файла как написано выше
    3) проблемс)
    разместил ссылку в детальной карте товара …
    но как понимаю она не правильная у меня…
    Купить в один клик

    скажите что точно в ней писать
    если можете напишите на почту a13z2005@yandex.ru
    всем спасибо

  7. Petr

    не работает что-то код (не привязывает товары к заказу)
    не подскажете, куда копать? выдает такой дебаг:

    [Bitrix\Main\NotSupportedException] 
     (150)
    /www/bitrix/modules/sale/lib/shipment.php:512
    #0: Bitrix\Sale\Shipment->setField(string, double)
    	/www/bitrix/modules/sale/lib/order.php:2716
    #1: Bitrix\Sale\Order->applyDiscount(array)
    	/www/bitrix/modules/sale/lib/order.php:3024
    #2: Bitrix\Sale\Order->doFinalAction(boolean)
    	/www/bitrix/modules/sale/lib/internals/entitycollection.php:190
    #3: Bitrix\Sale\Internals\EntityCollection->doFinalAction(boolean)
    	/www/bitrix/modules/sale/lib/internals/collectableentity.php:121
    #4: Bitrix\Sale\Internals\CollectableEntity->doFinalAction(boolean)
    	/www/bitrix/modules/sale/lib/internals/entity.php:185
    #5: Bitrix\Sale\Internals\Entity->setField(string, string)
    	/www/bitrix/modules/sale/lib/basketitembase.php:162
    #6: Bitrix\Sale\BasketItemBase->setField(string, string)
    	/www/bitrix/modules/sale/lib/basketitem.php:89
    #7: Bitrix\Sale\BasketItem->setField(string, string)
    	/www/bitrix/modules/sale/lib/basketitembase.php:226
    #8: Bitrix\Sale\BasketItemBase->setFields(array)
    	/www/bitrix/modules/sale/lib/compatible/basketcompatibility.php:471
    #9: Bitrix\Sale\Compatible\BasketCompatibility::add(array)
    	/www/bitrix/modules/sale/mysql/basket.php:458
    #10: CSaleBasket::Add(array)
    	/www/ajax/send_popup_form.php:97
    

Добавить комментарий