pashynskyi/instashop

Maintainers

Package info

gitlab.com/pashynskyi/instashop

Issues

pkg:composer/pashynskyi/instashop

Transparency log

Statistics

Installs: 96

Dependents: 0

Suggesters: 0

Stars: 0

dev-main 2026-08-13 11:56 UTC

This package is not auto-updated.

Last update: 2026-08-13 08:57:06 UTC


README

Laravel-пакет для інтернет-магазину: каталог товарів (продукти, варіанти, категорії, групи, характеристики), кошик, список бажань, замовлення з оплатою (LiqPay) і доставкою (Нова Пошта / самовивіз), особистий кабінет, автентифікація (включно з соцмережами та SMS-кодами відновлення пароля), динамічне ціноутворення й upsell-рекомендації, XML-фіди (Google Merchant, Facebook), а також синхронізація каталогу й замовлень із віддаленим сервером (складом).

Пакет самодостатній: підключає власні роути, міграції, конфіги і переклади (uk/ru) через InstashopServiceProvider, а host-застосунок здебільшого лише публікує й кастомізує те, що потрібно.

Вимоги

  • PHP >= 8.0
  • Laravel >= 8.0
  • Розширення/пакети: mcamara/laravel-localization, laravel/socialite, intervention/image, daaner/turbosms, liqpay/liqpay, spatie/laravel-html, а також приватні пакети pashynskyi/localizable, pashynskyi/nova-poshta, pashynskyi/xml-builder

Встановлення

composer require pashynskyi/instashop

Провайдер (Pashynskyi\Instashop\Providers\InstashopServiceProvider) підключається автоматично через Laravel package discovery.

Опублікувати те, що потрібно кастомізувати в проєкті:

php artisan vendor:publish --tag=config      # config/instashop.php
php artisan vendor:publish --tag=options     # options/instashop/*.php (доставка, оплата, ціни, загальні)
php artisan vendor:publish --tag=migrations  # database/migrations/vendor/instashop
php artisan vendor:publish --tag=locales     # resources/lang/vendor/instashop
php artisan vendor:publish --tag=routes      # routes/instashop/web.php
php artisan vendor:publish --tag=instashop-assets

Змінні оточення (config/instashop.php читає їх напряму):

STOREHOUSE_SERVER=
STOREHOUSE_API_TOKEN=
STOREHOUSE_SITE_ID=

LIQPAY_PUBLIC_KEY=
LIQPAY_PRIVATE_KEY=

Структура пакету

ДиректоріяПризначення
src/ModelsEloquent-моделі: Product, Variant, ProductCategory, ProductGroup, Feature/FeatureValue, Order, User, Page, Setting, Visit, Localization тощо
src/Http/ControllersКонтролери каталогу, кошика, замовлень, платежів, автентифікації (включно з соцмережами), фідів, особистого кабінету
src/AppБізнес-логіка: Cart, Wishlist, Viewed, Price/PriceCalculator, Settings, SMS-нотифікації
src/App/PricingКонфігурована система знижок (умови/дії/правила, будуються з JSON-конфігу)
src/App/UpsellКонфігурований rule-based upsell (тригери, джерела кандидатів, пріоритетна каскадна видача)
src/RemoteСинхронізація з віддаленим сервером — SyncRegistry, Get/Set, StorehouseRemoteGetter/StorehouseRemoteSetter
src/ServicesOrderSyncService (синхронізація замовлення), CatalogCache, аналітика (Facebook Pixel, Google Analytics)
src/Console/Commandsinstashop:sync-orders — ретрай несинхронізованих замовлень
src/Configinstashop.php + дефолтні опційні конфіги (Options/deliveries.php, payments.php, price.php, general.php)
src/Database/MigrationsПовна схема БД магазину
src/UIДрібні UI-білдери для форм доставки/оплати (spatie/laravel-html)

Конфіг instashop.php

Головний конфіг пакету (src/Config/instashop.php, публікується тегом config): мета-дані сайту, контактні телефони, налаштування XML-фідів (Google/Facebook, включно з мапінгом категорій на зовнішні таксономії), соцмережі, remote (доступи Storehouse — див. нижче) і payments.liqpay.

Опційні конфіги (options/instashop/*.php)

Окремий шар конфігів, публікується тегом options, читається через options('файл.ключ', 'instashop'); пакет постачає дефолти (src/Config/Options/*.php), поки застосунок не опублікує власні:

  • deliveries.php — способи доставки (self/np/ukr), кожен — обʼєкт Delivery з полями форми, ціною, порогом безкоштовної доставки, комісією за накладений платіж.
  • payments.php — способи оплати (liqpay/cash), обʼєкт Payment з передоплатою/повною сумою.
  • general.php — статус нового замовлення (order_status) і головне меню сайту (menu, будується з ProductGroup).
  • price.php — не редагується руками, генерується автоматично з CRM-конфігу через PricingConfigService (див. "Ціноутворення").

Синхронізація зі Storehouse (CRM)

Каталог, сторінки, ціни/upsell-конфіги та замовлення синхронізуються із зовнішньою CRM Storehouse (~/Projects/general/storehouse) через її HTTP API. Модулі реєструються в SyncRegistry під час boot() провайдера: product, order, category, group, page, price_config, upsell_config. StorehouseRemoteGetter тягне дані з CRM (матчинг по remote_id), StorehouseRemoteSetter надсилає клієнтів і замовлення.

Для синхронізації потрібен токен і ID сайту з боку CRM:

  1. У CRM-адмінці (/admin/sites) створити сайт для сторефронту — вказати Callback url (домен) і придумати Token (унікальний рядок, задається вручну, автогенерації немає).
  2. Взяти id створеного сайту.
  3. Прописати в .env сторефронту:
    STOREHOUSE_SERVER=https://<домен-crm>/api/v1/
    STOREHOUSE_API_TOKEN=<token із кроку 1>
    STOREHOUSE_SITE_ID=<id сайту із кроку 2>
    

CRM перевіряє пару api_token+site_id проти активного Site (і активності його Shop) на кожному запиті (App\Http\Middleware\Remote у Storehouse) — без збігу повертає {"success": false, ...}.

Синхронізація замовлень і ретрай

OrderSyncService::sync(Order $order) надсилає замовлення на CRM під час створення (OrderController@create). Якщо CRM недоступна або повернула помилку — замовлення не падає, а зберігається з remote_id = null і причиною відмови в remote_fail. Ознака "не синхронізовано" — саме remote_id IS NULL, окремого поля для цього не заведено.

Несинхронізовані замовлення підхоплює консольна команда:

php artisan instashop:sync-orders

Вона сама реєструється в шедулері (everyFiveMinutes(), withoutOverlapping()) — жодних змін у Kernel.php host-застосунку не потрібно. Помилка на одному замовленні (виняток чи невдала відповідь сервера) не зупиняє обробку решти черги.

Ціноутворення (Pricing)

PricingConfigService будує з JSON-конфігу (options/instashop/price.php) список знижок і промокодів:

  • Знижки — пара умова (Conditions: категорія, група, роль користувача, наявність опт-ціни, діапазон дат, значення характеристики, або комбінація правил) + дія (Actions: відсоток мінус, відсоток мінус за мапою). Знижки сортуються за priority, кожна може бути stackable (продовжити застосовувати наступні) або ні.
  • Промокоди — застосовуються до підсумкової ціни (Price), підтримують лише відсоткову знижку.

Upsell-рекомендації

UpsellConfigService::resolve() — пріоритетна каскадна видача: правила з конфігу (options/instashop/general.php чи окремий upsell-конфіг) перевіряються по черзі за priority, перше правило, чий тригер спрацював і має що показати, "виграє" весь блок (повідомлення + список товарів не змішуються з двох різних правил).

  • Тригери (Triggers): завжди, поріг суми кошика, категорія/група в кошику, поріг кількості, конкретний товар.
  • Джерела кандидатів (Sources): усі доступні, за мапінгом категорій, за мапінгом груп, вручну заданий список.
  • Кандидати фільтруються за ціною (для fill_to_threshold — не дорожче суми, що бракує до порогу, з підлогою min_price_cap), деревом категорій (щоб не пропонувати той самий підрозділ, що вже в кошику), уже купленим, уже в кошику/показаним на попередній сторінці, збігом характеристик; максимум один варіант на товар.
  • loadMore() довантажує наступну сторінку кандидатів того самого правила, що виграло першу.

Консольні команди

КомандаОпис
instashop:sync-ordersПовторно надсилає на віддалений сервер замовлення без remote_id

Тестування

Пакет має власний набір тестів на orchestra/testbench (SQLite in-memory, RefreshDatabase).

composer install
vendor/bin/phpunit

Феєрчастина тестового оточення (tests/TestCase.php) сама піднімає провайдер пакету, БД і потрібні конфіги; HTTP-рівневі тести (OrderControllerCreateTest) додатково підміняють ISetter фейком (tests/Support/FakeOrderSetter), щоб не ходити в реальну мережу.

Автор

Alexander Pashynskyi — pashynskyi@gmail.com