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

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

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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка системы вопросов-ответов к товарам для интернет-магазина
Простая
~2-3 рабочих дня
Часто задаваемые вопросы

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

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

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

  • 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

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

Блок Q&A на странице товара снижает количество обращений в поддержку и увеличивает конверсию: покупатель получает ответ прямо на странице товара, не уходя на другие ресурсы. Вопросы, накопленные со временем, формируют уникальный пользовательский контент, полезный для SEO. Разработка блока занимает 2–3 рабочих дня.

Схема данных

CREATE TABLE product_questions (
    id BIGSERIAL PRIMARY KEY,
    product_id BIGINT NOT NULL REFERENCES products(id) ON DELETE CASCADE,
    user_id BIGINT REFERENCES users(id),
    guest_name VARCHAR(100),
    guest_email VARCHAR(255),
    question TEXT NOT NULL,
    status VARCHAR(20) DEFAULT 'pending', -- pending, published, spam
    answer_count INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE product_answers (
    id BIGSERIAL PRIMARY KEY,
    question_id BIGINT REFERENCES product_questions(id) ON DELETE CASCADE,
    user_id BIGINT REFERENCES users(id),
    is_store_reply BOOLEAN DEFAULT FALSE, -- ответ магазина
    body TEXT NOT NULL,
    helpful_count INT DEFAULT 0,
    status VARCHAR(20) DEFAULT 'approved',
    created_at TIMESTAMP DEFAULT NOW()
);

Публикация вопроса

Вопросы могут задавать как авторизованные, так и гостевые пользователи. Гостю нужен email — для уведомления об ответе:

public function store(Request $request, Product $product): JsonResponse
{
    $request->validate([
        'question'   => 'required|string|min:10|max:500',
        'guest_name' => Rule::requiredIf(!$request->user()),
        'guest_email'=> [Rule::requiredIf(!$request->user()), 'email'],
    ]);

    $question = $product->questions()->create([
        'question'    => $request->question,
        'user_id'     => $request->user()?->id,
        'guest_name'  => $request->guest_name,
        'guest_email' => $request->guest_email,
        'status'      => 'pending',
    ]);

    // Уведомить менеджеров о новом вопросе
    Notification::route('mail', config('shop.support_email'))
        ->notify(new NewProductQuestion($question));

    return response()->json([
        'message' => 'Ваш вопрос отправлен. Мы ответим в течение 24 часов.',
    ], 201);
}

Ответ от магазина

Менеджер отвечает через admin-панель. Ответ помечается как официальный и отображается первым:

public function answer(Request $request, ProductQuestion $question): JsonResponse
{
    $request->validate(['body' => 'required|string|min:5|max:1000']);

    $answer = $question->answers()->create([
        'user_id'        => $request->user()->id,
        'body'           => $request->body,
        'is_store_reply' => true,
        'status'         => 'approved',
    ]);

    $question->update([
        'status'       => 'published',
        'answer_count' => $question->answer_count + 1,
    ]);

    // Уведомить автора вопроса
    $notifiable = $question->user ?? Notification::route('mail', $question->guest_email);
    $notifiable->notify(new QuestionAnswered($question, $answer));

    return response()->json(new AnswerResource($answer), 201);
}

Ответы от покупателей

Другие покупатели также могут отвечать на вопросы (peer-to-peer). Их ответы проходят автомодерацию и сортируются после официального ответа магазина.

Отображение на странице товара

const ProductQA = ({ productId }: { productId: number }) => {
  const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
    queryKey: ['product-questions', productId],
    queryFn: ({ pageParam = 1 }) =>
      api.get(`/products/${productId}/questions`, { params: { page: pageParam, per_page: 5 } }),
    getNextPageParam: (last) => last.meta.next_page,
  });

  const questions = data?.pages.flatMap(p => p.data) ?? [];

  return (
    <section>
      <h2 className="text-xl font-semibold mb-4">Вопросы и ответы</h2>

      <AskQuestionForm productId={productId} />

      <div className="mt-6 space-y-4">
        {questions.map(q => (
          <QuestionCard key={q.id} question={q} />
        ))}
        {hasNextPage && (
          <button onClick={() => fetchNextPage()} className="text-blue-600 text-sm">
            Показать ещё вопросы
          </button>
        )}
        {questions.length === 0 && (
          <p className="text-gray-500">Вопросов пока нет. Задайте первым!</p>
        )}
      </div>
    </section>
  );
};

Поиск по вопросам

Если вопросов накопилось много, добавляем поиск по тексту:

$questions = $product->questions()
    ->published()
    ->when($request->q, fn($query, $search) =>
        $query->where('question', 'ilike', "%{$search}%")
              ->orWhereHas('answers', fn($q2) =>
                  $q2->where('body', 'ilike', "%{$search}%")
              )
    )
    ->withCount('answers')
    ->latest()
    ->paginate(10);

Полезность ответов

Кнопки «Было полезно» / «Не помогло» под каждым ответом — как в системе отзывов. Сортировка ответов по helpful_count выводит наиболее ценные ответы первыми.

SEO-ценность

Вопросы и ответы индексируются поисковиками как часть страницы товара. Для дополнительного SEO-эффекта — микроразметка FAQPage:

<script type="application/ld+json">{JSON.stringify({
  '@context': 'https://schema.org',
  '@type': 'FAQPage',
  mainEntity: questions.map(q => ({
    '@type': 'Question',
    name: q.question,
    acceptedAnswer: q.answers[0]
      ? { '@type': 'Answer', text: q.answers[0].body }
      : undefined,
  })).filter(q => q.acceptedAnswer),
})}</script>

Это даёт шанс на появление в блоке «Часто задаваемые вопросы» прямо в поиске Google — rich snippet без дополнительных затрат.

Антиспам

Для фильтрации спама в вопросах: ограничение по IP (3 вопроса в час), honeypot-поле в форме, проверка на стоп-слова. Для высоконагруженных магазинов — интеграция с reCAPTCHA v3 (невидимая, не мешает UX).