Внешние скидки в InSales
В SaaS платформе для разработки и эффективной эксплуатации Интернет-магазинов InSales сокрыто множество возможностей для успешных продаж в сети Интернет. Многие возможности требуют определенного исследования и разъяснения.
Нельзя не отметить, что встроенная система для скидок уже включена в большинство тарифных планов InSales и покрывает большую часть потребностей магазина. Кроме того, если встроенной системы скидок не хватает, для вас есть некоторое количество приложений в маркетплейсе интеграций, которые также позволяют делать скидочные программы в случаях, если встроенная система не до конца удовлетворяет вашим потребностям.
Однако, иногда может возникнуть необходимость в создании какой-либо нестандартной скидки именно для вашего магазина. В этой публикации мы расскажем, на конкретном примере, о создании внешних скидок для корзины, которые и призваны решать такие нестандартные задачи.
Что же такое внешняя ссылка? Это некий скрипт, написанный на любом языке программирования. Этот скрипт должен быть размещен на каком-либо сервере и доступен по URL для вашего магазина. Он будет получать от InSales данные корзины в формате JSON и должен будет возвращать ответ в том же формате.
Итак начнём. В административной панели вашего Интернет-магазина внешняя скидка добавляется в разделе Скидки. При добавлении в форму помещается ссылка на ваш скрипт и в общем-то все. Скидка начинает работать в корзине и форме оформления заказа (чекауте).

Обо всём этом подробно рассказано в официальной документации на сайте InSales. А вот детали реализации возможно требуют некоторых пояснений и примеров.
Давайте создадим скрипт для скидки на сумму цены самого дешевого товара в корзине при 2 и более наименований товаров, добавленных покупателем в корзину.
Шаг первый
Посмотрим, что нам передает магазин и передает ли вообще. Для этого создадим простой скрипт, который будет сохранять полученный данные в файл.
Код скрипта:
<?php
// Сохранить пришедшие данные в log.
// По идее переменная $HTTP_RAW_POST_DATA устарела
// и в новых версиях PHP нужно использовать конструкцию
// $postdata = file_get_contents("php://input");
file_put_contents(
'discount.log',
sprintf("%s\t%s" . PHP_EOL, date('c'), $HTTP_RAW_POST_DATA),
FILE_APPEND
);
// Мы должны вернуть магазину JSON объект с информацией о скидке.
// Пока вернем 0, потом это переделаем, пока это заглушка.
header('Content-Type: application/json', true, 200);
echo '{
"discount": 0,
"discount_type": "MONEY",
"title": "Скидка на самый дешевый товар в корзине"
}';
Сохранив этот скрипт на сервере и подключив его с как внешнюю ссылку добавим несколько товаров в корзину и перейдем в нее. Мы должны увидеть в корзине, перед итогом по корзине строчку «Скидка на самый дешевый товар в корзине: 0». Если увидели значит все ок, если нет надо писать в техподдержку InSales. :)
Если же все работает, то стоит посмотреть на сервер, где рядом с нашим скриптом должен появится файл «discount.log». В нем сохранен объект полученный нами от магазина. Внутри этого файла появилась строка с JSON объектом, который нам передан от магазина. Там есть данные о клиенте, доставках и конечно же данные о товарах, которые добавлены в корзину. Вот именно эта часть объекта нам нужна для решения нашей задачи.
"order_lines": [{
"id": null,
"order_id": null,
"sale_price": 37083,
"full_sale_price": 37083,
"total_price": 37083,
"full_total_price": 37083,
"discounts_amount": 0,
"quantity": 1,
"reserved_quantity": null,
"weight": null,
"dimensions": null,
"variant_id": 133666502,
"product_id": 78161350,
"sku": null,
"barcode": null,
"title": "DELL INSPIRON 5720",
"unit": "pce",
"comment": "",
"updated_at": null,
"created_at": null,
"bundle_id": null,
"vat": -1
}, {
"id": null,
"order_id": null,
"sale_price": 26670,
"full_sale_price": 26670,
"total_price": 26670,
"full_total_price": 26670,
"discounts_amount": 0,
"quantity": 1,
"reserved_quantity": null,
"weight": null,
"dimensions": null,
"variant_id": 133666506,
"product_id": 78161353,
"sku": "17743",
"barcode": null,
"title": "LCD телевизор BBK LT4219HDU black",
"unit": "pce",
"comment": "",
"updated_at": null,
"created_at": null,
"bundle_id": null,
"vat": -1
}, {
"id": null,
"order_id": null,
"sale_price": 491,
"full_sale_price": 491,
"total_price": 491,
"full_total_price": 491,
"discounts_amount": 0,
"quantity": 1,
"reserved_quantity": null,
"weight": null,
"dimensions": null,
"variant_id": 142054998,
"product_id": 83680232,
"sku": "OZ490",
"barcode": null,
"title": "Обработка заказа",
"unit": "pce",
"comment": "Сервисный товар",
"updated_at": null,
"created_at": null,
"bundle_id": null,
"vat": -1
}]
В данном случае у нас в корзине три товара. Дальше дело техники, — пишем код который находит самый дешевый товар и делает на него скидку.
Шаг второй, заключительный
Код тестового скрипта внешней скидки:
<?php
/** * Файл содержит демонстрационный пример скрипта внешней скидки InSales * @package InSales-Api * @author Константин Тарасов <info@insales-studio.ru> * @category InSales * @copyright Copyright (c) 2006-2018 InSales Studio. (https://insales-studio.ru) * @license MIT License * */ /** * Сообщения об ошибках */ define('NO_ITEMS', 'Товары не обнаружены'); define('LESS_ITEMS', 'Скидка невозможна, поскольку товаров в корзине меньше 2'); define(
'NIL_ITEMS',
'Скидка невозможна, поскольку товаров с ненулевой ценой в корзине меньше 2'
);
/**
* Cервисный объект для построения отправляемого в магазин JSON со скидкой
*/
class ResponceDiscount {
public $discount;
public $discount_type;
public $title;
/**
* Конcтруктор объект ответа со скидкой
* @param $discount - сумма/процент скидки
* @param $discount_type - тип скидки MONEY/PERCENT
* @param $discount - название скидки для отображения в корзине/чекауте
*/
public function __construct($discount = 0, $discount_type = 'MONEY', $title = 'Скидка на самый дешевый товар в корзине') {
$this->title = $title;
$this->discount = $discount;
$this->discount_type = $discount_type;
}
}
/**
* Cервисный объект для построения отправляемого в магазин JSON с ошибкой
*/
class ResponceError {
public $errors;
/**
* Конcтруктор объект ответа с ошибкой
* @param $error_msg - сообщение об ошибке/массив строк с ошибками
*/
public function __construct($error_msg = null) {
$this->errors = array();
if($error_msg) $this->addError($error_msg);
}
public function addError($error_msg) {
if(is_array($error_msg)) {
$this->errors = array_merge($this->errors, $error_msg);
} elseif (is_string($error_msg)) {
$this->errors[] = $error_msg;
}
}
}
function LogEntry($msg) {
file_put_contents('count-discount.log',
sprintf("%s\t%s" . PHP_EOL, date('c'),
(is_scalar($msg) ? $msg : print_r($msg, true))
),
FILE_APPEND
);
}
function process_items($items) {
if(!is_array($items))
return new ResponceError(NO_ITEMS);
$items_count = count($items);
if($items_count < 2)
return new ResponceError(LESS_ITEMS);
// создадим массив цен
$prices = array();
foreach ($items as $item) {
if($item->sale_price == 0)
continue;
$prices[] = $item->sale_price;
}
if(count($prices) < 2)
return new ResponceError(NIL_ITEMS);
// сортируем массив цен товаров в корзине
sort($prices, SORT_NUMERIC);
// создадим объект ответа с минимальной ценой из массива
return new ResponceDiscount($prices[0]);
}
// получаем тело запроса и его отправим сразу в лог
LogEntry($HTTP_RAW_POST_DATA);
// декодируем объект, полученный от InSales
$cart = json_decode($HTTP_RAW_POST_DATA);
// проверим наличие строк корзины в полученном объекте
$items = isset($cart->order_lines) ? $cart->order_lines : null;
$response = process_items($items);
unset($cart, $items);
header('Content-Type: application/json', true, 200);
echo json_encode($response);
Код достаточно подробно документирован, т.ч. нет особого смысла его как-то дополнительно обсуждать. Сразу скажу, что это демонстрационный код и в реальном проекте его можно и нужно совершенствовать. Другое дело, что его можно будет использовать, как основу для создания своего скрипта скидки.