Розробка кастомної форми повернення товару в 1С-Бітрікс

Розробка кастомної заявки повернення товару в 1С-Бітрікс Ми часто зустрічаємо проєкти, де стандартний компонент `bitrix:sale.order.return.edit` не справляється з завданнями: у ньому немає завантаження фотографій дефекту, покрокового інтерфейсу та можливості вказати різні причини для кожної позиці
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
Розробка кастомної форми повернення товару в 1С-Бітрікс
Середній
~1-2 тижні

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

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

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1454
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    1017
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    759
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    879
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    802
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1162

Розробка кастомної заявки повернення товару в 1С-Бітрікс

Ми часто зустрічаємо проєкти, де стандартний компонент bitrix:sale.order.return.edit не справляється з завданнями: у ньому немає завантаження фотографій дефекту, покрокового інтерфейсу та можливості вказати різні причини для кожної позиції. При 50–100 зверненнях щодо повернень на день незручна заявка — це прямі втрати часу менеджерів на уточнення телефоном.

Уявіть: покупець отримав бракований товар. Він заходить в особистий кабінет, знаходить замовлення, але стандартна заявка повернення не дозволяє прикріпити фото дефекту. Доводиться телефонувати менеджеру, уточнювати причину, надсилати фото у відповідному листі. Це збільшує час обробки в середньому на 15 хвилин. При 100 поверненнях на день — втрата 25 людино-годин, що еквівалентно $1000 на день при середній зарплаті $40 на годину. Два менеджери витрачають пів дня на листування та дзвінки замість того, щоб обробляти інші заявки.

Ми розробляємо кастомні заявки повернення під ключ, скорочуючи час обробки на 30%. Наш досвід із Бітрікс — 10+ років, понад 50 проєктів з поверненнями. Гарантуємо відмовостійкість і відповідність 54-ФЗ. Впровадження такої заявки окупається протягом 1.5 днів: вартість розробки від $1500, а економія часу менеджерів приносить $1000 на день. При 100 поверненнях на день економія часу менеджерів приносить суттєву економію бюджету.

Чому wizard швидше за стандартну заявку?

Кастомний покроковий майстер обробляє повернення в 3 рази швидше штатної заявки — 4 хвилини замість 15. Покупець проходить 4 кроки, менеджер отримує повні дані без необхідності передзвонювати. Завдяки майстру, покупець витрачає у 3 рази менше часу порівняно зі стандартною заявкою.

Характеристика Стандартна заявка Кастомна заявка
Завантаження фото ні є (до 5 МБ)
Вибір причини по позиції ні є
Кількість кроків 1 4 (wizard)
Час заповнення ~15 хв ~4 хв
Інтеграція з 1С через обмін пряма через REST

Загалом кастомна заявка в 2 рази краща за стандартну за швидкістю заповнення.

Як реалізувати wizard-заявку?

Оптимальний UX для заявки повернення — 3–4 кроки:

  1. Вибір замовлення — покупець вибирає зі своєї історії замовлень, доступних для повернення.
  2. Вибір товарів і причин — галочками вибирає позиції, для кожної вказує причину та кількість.
  3. Додаткова інформація — коментар, завантаження фото/документів.
  4. Підтвердження — підсумковий екран із даними заявки та інструкціями.

Технічна реалізація: крок 1 — доступні для повернення замовлення

Повернення можливе лише за оплаченими замовленнями у визначений період (зазвичай 14 днів за законом). Завантажуємо список:

<?php namespace Local\Returns; class ReturnableOrdersProvider { private int $userId; private int $returnWindowDays; public function __construct(int $userId, int $returnWindowDays = 14) { $this->userId = $userId; $this->returnWindowDays = $returnWindowDays; } public function getReturnableOrders(): array { \Bitrix\Main\Loader::includeModule('sale'); $dateFrom = new \Bitrix\Main\Type\Date(); $dateFrom->add('-' . $this->returnWindowDays . ' days'); $result = \Bitrix\Sale\OrderTable::getList([ 'filter' => [ 'USER_ID' => $this->userId, 'PAYED' => 'Y', '>=DATE_PAY' => $dateFrom, '!STATUS_ID' => ['CANCELED', 'RETURNED'], ], 'select' => ['ID', 'ACCOUNT_NUMBER', 'DATE_INSERT', 'PRICE', 'CURRENCY', 'STATUS_ID'], 'order' => ['DATE_INSERT' => 'DESC'], ]); $orders = []; while ($row = $result->fetch()) { if (!$this->hasFullReturn($row['ID'])) { $orders[] = $row; } } return $orders; } private function hasFullReturn(int $orderId): bool { $existing = \Bitrix\Sale\OrderReturnTable::getList([ 'filter' => ['ORDER_ID' => $orderId, 'STATUS_ID' => ['APPROVED', 'RECEIVED', 'REFUND']], 'select' => ['ID'], 'limit' => 1, ])->fetch(); return (bool)$existing; } } 

Технічна реалізація: крок 2 — позиції замовлення з вибором причини

<?php class OrderItemsProvider { public function getReturnableItems(int $orderId, int $userId): array { $order = \Bitrix\Sale\Order::load($orderId); if (!$order || $order->getUserId() !== $userId) { throw new \RuntimeException('Order not found or access denied'); } $items = []; foreach ($order->getBasket() as $item) { $returnedQty = $this->getReturnedQuantity($orderId, $item->getId()); $availableQty = $item->getQuantity() - $returnedQty; if ($availableQty <= 0) continue; $items[] = [ 'basket_id' => $item->getId(), 'product_id' => $item->getProductId(), 'name' => $item->getField('NAME'), 'quantity' => $item->getQuantity(), 'available_qty' => $availableQty, 'price' => $item->getFinalPrice(), 'image' => $this->getProductImage($item->getProductId()), 'article' => $item->getField('ARTICLE'), ]; } return $items; } private function getReturnedQuantity(int $orderId, int $basketItemId): float { $result = \Bitrix\Sale\OrderReturnBasketTable::getList([ 'filter' => [ 'ORDER_RETURN.ORDER_ID' => $orderId, 'BASKET_ID' => $basketItemId, 'ORDER_RETURN.STATUS_ID' => ['WAIT', 'REVIEW', 'APPROVED', 'RECEIVED', 'REFUND'], ], 'runtime' => [ new \Bitrix\Main\ORM\Fields\ExpressionField('TOTAL_QTY', 'SUM(%s)', 'QUANTITY'), ], 'select' => ['TOTAL_QTY'], ])->fetch(); return (float)($result['TOTAL_QTY'] ?? 0); } } 

Клієнтська частина: step-by-step заявка

React-компонент для покрокової заявки (або Vue — за вибором):

import React, { useState } from 'react'; function ReturnWizard({ orderId }) { const [step, setStep] = useState(1); const [selectedItems, setSelectedItems] = useState([]); const [files, setFiles] = useState([]); const returnReasons = [ { id: 'defect', label: 'Виробничий брак' }, { id: 'wrong_item', label: 'Надіслали не той товар' }, { id: 'damaged', label: 'Пошкоджено при доставці' }, { id: 'not_fit', label: 'Не підійшов' }, { id: 'other', label: 'Інша причина' }, ]; const canProceed = selectedItems.some(item => item.selected && item.reason); async function submitReturn() { const formData = new FormData(); formData.append('order_id', orderId); formData.append('sessid', BX.bitrix_sessid()); formData.append('items', JSON.stringify(selectedItems.filter(i => i.selected))); files.forEach((file, i) => formData.append(`files[${i}]`, file)); const res = await fetch('/local/api/return-submit.php', { method: 'POST', body: formData, }); const data = await res.json(); if (data.success) { setStep(4); // Success screen } } // ... рендер кроків } 

Серверний обробник фінального надсилання

<?php // /local/api/return-submit.php require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'); header('Content-Type: application/json'); if (!\CUser::IsAuthorized()) { http_response_code(401); exit(json_encode(['error' => 'Unauthorized'])); } if (!\bitrix_sessid_check($_POST['sessid'] ?? '')) { http_response_code(403); exit(json_encode(['error' => 'Invalid session'])); } $orderId = (int)($_POST['order_id'] ?? 0); $items = json_decode($_POST['items'] ?? '[]', true); $userId = (int)\CUser::GetID(); $validator = new \Local\Returns\ReturnValidator($userId); if (!$validator->canReturnOrder($orderId)) { exit(json_encode(['success' => false, 'error' => 'Замовлення недоступне для повернення'])); } $fileIds = []; $uploader = new \Local\Upload\FileUploader(); foreach ($_FILES as $key => $file) { if (strpos($key, 'files') === 0 && $file['error'] === UPLOAD_ERR_OK) { try { $result = $uploader->handle($file); $fileIds[] = $result['id']; } catch (\Exception $e) { } } } $manager = new \Local\Returns\ReturnManager(); $returnId = $manager->createReturn($orderId, $items, 'MONEY'); if ($fileIds) { \Local\Returns\ReturnAttachments::attach($returnId, $fileIds); } \Local\Returns\Notifications::sendToCustomer($returnId); \Local\Returns\Notifications::sendToManager($returnId); exit(json_encode([ 'success' => true, 'return_id' => $returnId, 'message' => 'Заявка #' . $returnId . ' створена. Розглянемо протягом 2 робочих днів.', ])); 

Вкладення до заявки: розширення таблиці

Стандартна система повернень Бітрікс не зберігає прикріплені файли. Розширюємо через Highload-блок:

<?php class ReturnAttachmentTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'local_return_attachments'; } public static function getMap(): array { return [ new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new \Bitrix\Main\ORM\Fields\IntegerField('RETURN_ID'), new \Bitrix\Main\ORM\Fields\IntegerField('FILE_ID'), new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'), ]; } } 

Як забезпечити безпеку обробки заявок?

Критично захистити AJAX-обробник від XSS та CSRF-атак. По-перше, перевіряємо сесію через bitrix_sessid_check. По-друге, валідуємо, що замовлення належить поточному користувачеві. По-третє, фільтруємо завантажувані файли за типом і розміром — тільки зображення до 5 МБ, решту відхиляємо.

Як інтегрувати заявку повернення з 1С?

Інтеграція з 1С здійснюється через CommerceML або REST API. Ми налаштовуємо автоматичне створення документів повернення в 1С при схваленні заявки. Це виключає подвійне введення даних і пришвидшує процес повернення. Докладніше — у REST API Бітрікс.

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

  • Аудит поточного процесу повернень та узгодження логіки
  • Розробка wizard-заявки з 4 кроками (React/Vue)
  • Серверна частина: API для створення та статусів повернень
  • Інтеграція з поштовими сповіщеннями (покупець + менеджер)
  • Сторінка "Мої повернення" в особистому кабінеті
  • Документація по кожному компоненту
  • Навчання співробітників (до 2 годин)
  • Технічна підтримка 1 місяць після запуску

Які типові помилки виникають при інтеграції?

  • Забувають перевіряти сесію в AJAX-обробнику — веде до XSS.
  • Не враховують часткові повернення: потрібно рахувати вже повернену кількість.
  • При завантаженні фото не перевіряють розмір — файли можуть бути більше 5 МБ.

Терміни орієнтовно

Повна заявка з wizard та завантаженням файлів — від 2 до 4 тижнів. Складніші інтеграції (1С, кастомні бізнес-процеси) — до 6 тижнів. Вартість розраховується індивідуально. Оцінимо ваш проєкт — напишіть.

Замовте розробку заявки повернення вже сьогодні — отримайте безкоштовний аудит поточних процесів. Ми гарантуємо коректну роботу при високих навантаженнях (1000+ повернень на день) та відповідність вимогам 54-ФЗ для фіскалізації. Зв'яжіться з нами для консультації — покажемо демо-заявку.