Внешние скидки в 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);
Код достаточно подробно документирован, т.ч. нет особого смысла его как-то дополнительно обсуждать. Сразу скажу, что это демонстрационный код и в реальном проекте его можно и нужно совершенствовать. Другое дело, что его можно будет использовать, как основу для создания своего скрипта скидки.