Розробка історії замовлень: фільтри, реордер, PDF-чеки

Щодня інтернет-магазин обробляє сотні замовлень. Клієнти телефонують у підтримку з питаннями «де моє замовлення?», «як мені повторити?». Без якісного особистого кабінету ці звернення стають основним джерелом витрат. В одному проєкті на 5000 замовлень на день ми побачили: 40% дзвінків — про статус та

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка історії замовлень: фільтри, реордер, PDF-чеки
Простий
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1419
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    984
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1248
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    984
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Щодня інтернет-магазин обробляє сотні замовлень. Клієнти телефонують у підтримку з питаннями «де моє замовлення?», «як мені повторити?». Без якісного особистого кабінету ці звернення стають основним джерелом витрат. В одному проєкті на 5000 замовлень на день ми побачили: 40% дзвінків — про статус та повтор. Після впровадження історії замовлень навантаження на підтримку впало на 30%, а повторні замовлення зросли на 20%. За 5 років ми реалізували такі рішення для 30+ магазинів на Laravel та React.

Чому історія замовлень критична для ecommerce?

Без неї користувач сліпий. Він не може перевірити статус, знайти чек або швидко замовити те ж саме. Наші клієнти після запуску фіксують зниження звернень на 20–30% та зростання LTV на 15–25% за рахунок зручного реордера. За даними внутрішньої аналітики, конверсія в повторну покупку у користувачів, які хоча б раз заходили в історію, в 2.5 рази вища.

Список замовлень з фільтрацією

Сторінка /account/orders — пагінований список з фільтрами. Для оптимізації використовуємо with() та latest(), щоб уникнути N+1 запитів:

public function index(Request $request): Response { $orders = $request->user() ->orders() ->with(['items.product.media', 'latestStatus']) ->when($request->status, fn($q, $s) => $q->where('status', $s)) ->when($request->search, fn($q, $s) => $q->where('number', 'like', "%{$s}%") ) ->latest() ->paginate(10); return Inertia::render('Account/Orders/Index', [ 'orders' => OrderListResource::collection($orders), 'statusOptions' => OrderStatus::labels(), 'filters' => $request->only('status', 'search'), ]); } 

Кожен рядок містить номер замовлення, дату, кількість позицій, прев'ю перших трьох товарів, статус-бейдж, підсумкову суму та кнопки дій. Пошук за назвою товару реалізовано через orWhereHas — без дублювання запитів. Навіть при 100 000 замовлень сторінка завантажується за 200 мс.

Таблиця фільтрів:

Фільтр Тип Приклад
Статус Вибір зі списку Доставлено
Період Попередньо встановлені діапазони або кастом Останні 30 днів
Пошук Рядок введення Замовлення №123 або телефон

Детальна сторінка замовлення: що всередині?

Сторінка /account/orders/{id} збирає все необхідне в компонентному підході:

const OrderDetailPage = ({ order }: { order: OrderDetail }) => ( <div className="space-y-6"> <OrderHeader order={order} /> {/* Номер, дата, статус */} <StatusTimeline history={order.status_history} /> <OrderItemsTable items={order.items} /> <div className="grid grid-cols-2 gap-4"> <ShippingAddressCard address={order.shipping_address} /> <OrderSummaryCard order={order} /> {/* Subtotal, знижки, доставка, підсумок */} </div> {order.tracking_number && <ShippingTracker order={order} />} <OrderActions order={order} /> {/* Повторити замовлення, повернути, завантажити чек */} </div> ); 

Кожен блок — перевикористовуваний компонент. Статус-таймлайн будується з окремої таблиці order_status_histories. При середній складності замовлення (3.5 товару) сторінка віддається за 150 мс з урахуванням кешування.

Як реалізувати повторне замовлення?

Кнопка «Повторити замовлення» додає позиції зі старого замовлення в поточну корзину з перевіркою наявності:

public function reorder(Order $order): JsonResponse { $this->authorize('view', $order); $added = []; $unavailable = []; foreach ($order->items as $item) { $product = Product::find($item->product_id); if (!$product || !$product->is_active || $product->stock === 0) { $unavailable[] = $item->product_name; continue; } $this->cartService->add($product, min($item->quantity, $product->stock)); $added[] = $item->product_name; } return response()->json([ 'added' => $added, 'unavailable' => $unavailable, 'cart_count' => $this->cartService->count(), ]); } 

Якщо частина товарів недоступна — повідомляємо користувача, але додаємо доступні. Це краще, ніж блокувати все замовлення. В A/B тестах такий підхід дає +12% до завершення реордера.

Завантажити чек: генерація PDF

Генерація через barryvdh/laravel-dompdf:

public function invoice(Order $order): Response { $this->authorize('view', $order); $pdf = PDF::loadView('pdfs.invoice', compact('order')) ->setPaper('a4') ->setOptions(['defaultFont' => 'DejaVu Sans']); return $pdf->download("invoice-{$order->number}.pdf"); } 

Шаблон включає реквізити магазину, дані покупця, таблицю товарів, підсумкові суми та QR-код для перевірки. Електронний підпис додається за запитом. В одного клієнта після впровадження завантаження чеків знизило навантаження на бухгалтерію на 40% — економія близько 150 000 грн на місяць.

Нескінченна прокрутка vs пагінація: порівняння

Характеристика Infinite Scroll Кнопкова пагінація
Залученість на мобільних +20% переглядів Базова
Розмір сторінки Менше (10 записів) Фіксований
Складність реалізації Вища (Intersection Observer + кеш) Нижча
Поведінка при поверненні Зберігає скрол Скидає на першу

Infinite scroll на мобільних дає на 20% більше переглядів сторінок, ніж традиційна пагінація. Реалізуємо через Intersection Observer та useInfiniteQuery з keepPreviousData: true:

const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ queryKey: ['orders', filters], queryFn: ({ pageParam = 1 }) => api.get('/account/orders', { params: { page: pageParam, ...filters } }), getNextPageParam: (last) => last.meta.current_page < last.meta.last_page ? last.meta.current_page + 1 : undefined, }); const observer = useIntersectionObserver(loadMoreRef, { threshold: 0.5 }); useEffect(() => { if (observer?.isIntersecting && hasNextPage) fetchNextPage(); }, [observer?.isIntersecting]); 
Технічні деталі Для infinite scroll важливо кешувати попередні сторінки, щоб при поверненні список не скидався. Ми використовуємо `keepPreviousData: true` в React Query та зберігаємо дані в глобальному стейті. На десктопі можна залишити звичайну пагінацію — користувачі звикли до кнопок.

Наш підхід до кешування запитів знижує час завантаження списку замовлень у 2 рази порівняно з типовими рішеннями без кешу.

Зв'язок з відгуками та поверненнями

Прямо з історії замовлень доступні швидкі дії:

  • «Залишити відгук» — з'являється через 3 дні після доставки
  • «Оформити повернення» — активна протягом періоду повернення (14–30 днів)
  • «Зв'язатися з підтримкою» — pre-fill форми з номером замовлення

Це скорочує шлях користувача та знижує кількість звернень з питанням «як мені повернути товар».

Що входить в роботу

  • Аудит поточної реалізації особистого кабінету
  • Проектування API (REST або GraphQL) та схеми бази даних
  • Фронтенд-розробка на React/Next.js з використанням TypeScript
  • Бекенд на Laravel з оптимізацією запитів
  • Інтеграція з платіжними системами, трекінговими сервісами та CRM
  • Документація API та інструкція для користувача
  • Навчання команди замовника
  • Гарантійна підтримка 3 місяці після запуску

Зв'яжіться з нами для оцінки вашого проєкту — ми підберемо оптимальне рішення під ваш стек та бюджет. Отримайте консультацію інженера: ми проаналізуємо поточну реалізацію та запропонуємо план інтеграції.