Разработка системы возвратов (RMA) для интернет-магазина

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка системы возвратов (RMA) для интернет-магазина
Средняя
~5 рабочих дней
Часто задаваемые вопросы

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

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка системы возвратов (RMA) для интернет-магазина

RMA (Return Merchandise Authorization) — формализованный процесс приёма и обработки возвратов. Без системы возвраты обрабатываются вручную через почту и мессенджеры, теряются, задерживаются и вызывают недовольство. Разработка RMA занимает 5–8 рабочих дней — это полноценный workflow с несколькими участниками.

Бизнес-логика возвратов

Перед разработкой необходимо зафиксировать правила:

  • Срок подачи заявки на возврат (14 дней по закону РФ; магазин может расширить)
  • Возвращаемые категории товаров (ПО, нижнее бельё, персонализированные товары — не возвращаются)
  • Причины возврата (брак, не подошёл, пришёл не тот товар, передумал)
  • Способы компенсации: возврат денег / обмен / кредит на счёт
  • Нужна ли отправка товара обратно или достаточно фото

Схема данных

CREATE TABLE returns (
    id BIGSERIAL PRIMARY KEY,
    rma_number VARCHAR(20) UNIQUE NOT NULL, -- RMA-2024-001234
    order_id BIGINT REFERENCES orders(id),
    user_id BIGINT REFERENCES users(id),
    status VARCHAR(30) NOT NULL DEFAULT 'pending',
    -- pending → approved → items_received → resolved / rejected
    reason VARCHAR(50) NOT NULL,
    comment TEXT,
    resolution VARCHAR(20), -- 'refund', 'exchange', 'store_credit'
    refund_amount NUMERIC(12,2),
    created_at TIMESTAMP DEFAULT NOW(),
    resolved_at TIMESTAMP
);

CREATE TABLE return_items (
    id BIGSERIAL PRIMARY KEY,
    return_id BIGINT REFERENCES returns(id) ON DELETE CASCADE,
    order_item_id BIGINT REFERENCES order_items(id),
    quantity INT NOT NULL,
    condition VARCHAR(30), -- 'unopened', 'opened', 'damaged'
    photos JSONB DEFAULT '[]' -- массив URL фото
);

Форма заявки на возврат

Покупатель заполняет форму в личном кабинете. Шаги:

  1. Выбор заказа → выбор позиций и количества
  2. Указание причины для каждой позиции
  3. Загрузка фотографий (если требуется)
  4. Выбор способа компенсации
  5. Подтверждение и получение RMA-номера
const ReturnForm = ({ order }: { order: OrderDetail }) => {
  const form = useForm<ReturnFormData>({
    resolver: zodResolver(returnSchema),
    defaultValues: { items: [], reason: '', resolution: 'refund' },
  });

  return (
    <form onSubmit={form.handleSubmit(submitReturn)}>
      <h2 className="font-semibold mb-4">Выберите товары для возврата</h2>
      {order.items.map(item => (
        <ReturnItemRow key={item.id} item={item} form={form} />
      ))}

      <Select name="reason" label="Причина возврата" options={returnReasons} />
      <Textarea name="comment" label="Комментарий (необязательно)" />
      <PhotoUploader name="photos" maxFiles={5} />

      <RadioGroup name="resolution" label="Способ компенсации">
        <RadioItem value="refund">Возврат денег</RadioItem>
        <RadioItem value="exchange">Обмен на другой товар</RadioItem>
        <RadioItem value="store_credit">Кредит на счёт магазина</RadioItem>
      </RadioGroup>

      <Button type="submit">Отправить заявку</Button>
    </form>
  );
};

Загрузка фотографий

Фото подтверждают состояние товара и необходимы для возвратов по причине «брак» или «повреждение при доставке». Загрузка через S3-совместимое хранилище:

public function uploadPhoto(Request $request): JsonResponse
{
    $request->validate([
        'photo' => 'required|image|mimes:jpeg,png,webp|max:5120',
    ]);

    $path = $request->file('photo')->store('returns/photos', 's3');
    $url = Storage::disk('s3')->url($path);

    return response()->json(['url' => $url]);
}

Максимум 5 фото, каждое до 5 МБ. Превью отображается сразу после загрузки.

Workflow обработки в admin-панели

Менеджер видит очередь заявок с фильтрами по статусу, дате, сумме. Для каждой заявки доступны действия:

  • Одобрить — статус approved, покупатель получает инструкции по отправке
  • Отклонить — статус rejected с обязательным комментарием
  • Отметить товар получен — статус items_received, старт проверки качества
  • Провести возврат — инициировать рефанд через платёжного провайдера, статус resolved
class ReturnController extends Controller
{
    public function approve(Return $return, Request $request): void
    {
        $return->transitionTo(Approved::class);
        $return->update(['approved_by' => $request->user()->id]);

        Notification::send($return->user, new ReturnApproved($return));
        // Письмо с инструкцией по отправке и адресом склада
    }

    public function processRefund(Return $return): void
    {
        $payment = $return->order->payment;
        $this->paymentGateway->refund($payment->gateway_id, $return->refund_amount);

        $return->transitionTo(Resolved::class);
        $return->update(['resolved_at' => now()]);
        Notification::send($return->user, new RefundProcessed($return));
    }
}

Автоматическое одобрение

Для снижения нагрузки на поддержку — правила автоодобрения:

class AutoApprovalService
{
    public function shouldAutoApprove(Return $return): bool
    {
        // Сумма заказа до 2000 ₽ и причина "не подошёл" — автоодобрение
        return $return->order->total <= 2000
            && $return->reason === 'not_suitable'
            && $return->created_at->diffInDays($return->order->delivered_at) <= 14;
    }
}

Настраивается в admin-панели, не в коде.

Возврат денег через платёжный провайдер

Рефанды проходят через API платёжного провайдера. Для ЮKassa:

$client = new \YooKassa\Client();
$client->setAuth($shopId, $secretKey);

$refund = $client->createRefund([
    'payment_id' => $order->payment->yookassa_payment_id,
    'amount'     => ['value' => $return->refund_amount, 'currency' => 'RUB'],
    'description' => "Возврат по RMA #{$return->rma_number}",
]);

Частичный возврат (только часть позиций) поддерживается стандартно — сумма refund_amount рассчитывается как сумма возвращаемых позиций с пропорциональным включением скидок.

Аналитика возвратов

Отчёт по возвратам в admin: процент возвратов по категориям, топ причин, среднее время обработки, сумма возвращённых средств за период. Это позволяет выявлять системные проблемы: если конкретный товар возвращается чаще 15% — сигнал к проверке описания, фото или качества.