Сбор отзывов о покупке через email
Автоматический запрос отзыва после покупки — стандартная практика для e-commerce и SaaS. Письмо уходит через N дней после оплаты, содержит ссылку с прямой оценкой, форму для текстового отзыва и ведёт на платформу с отзывами (Google, Trustpilot, Яндекс).
Архитектура
Оплата → Job: ScheduleReviewRequest (delay: +14 дней)
→ Email с кнопками оценки
→ Клик → сохранение оценки → редирект на платформу
Backend: планирование и обработка
// При успешной оплате
class HandlePaymentSucceeded
{
public function handle(PaymentSucceeded $event): void
{
// Откладываем письмо на 14 дней — дать время воспользоваться продуктом
SendReviewRequestEmail::dispatch($event->order)->delay(now()->addDays(14));
}
}
// Job для отправки письма
class SendReviewRequestEmail implements ShouldQueue
{
public function handle(): void
{
// Не отправлять если уже оставил отзыв
if ($this->order->review()->exists()) return;
// Не отправлять если оформлял возврат
if ($this->order->refund()->exists()) return;
$token = ReviewToken::create([
'order_id' => $this->order->id,
'user_id' => $this->order->user_id,
'expires_at' => now()->addDays(30),
]);
Mail::to($this->order->user->email)->send(new ReviewRequestMail($this->order, $token));
}
}
Email-шаблон с прямой оценкой в письме
<!-- В письме — кнопки с оценкой прямо в теле -->
<p>Как вам покупка "{{ $order->product->name }}"?</p>
<table>
<tr>
@foreach([1,2,3,4,5] as $star)
<td>
<a href="{{ route('reviews.rate', ['token' => $token->id, 'score' => $star]) }}"
style="display:inline-block; padding:8px 12px; background:#f3f4f6; border-radius:4px; text-decoration:none;">
{{ str_repeat('★', $star) }}{{ str_repeat('☆', 5 - $star) }}
</a>
</td>
@endforeach
</tr>
</table>
Обработка клика по оценке
// ReviewController
public function rate(ReviewToken $token, int $score): View|RedirectResponse
{
if ($token->isExpired() || $token->isUsed()) {
return redirect()->route('home')->with('error', 'Ссылка устарела');
}
// Сохраняем предварительную оценку
session(['review_score' => $score, 'review_token' => $token->id]);
if ($score >= 4) {
// Высокая оценка → ведём на Google/Trustpilot для публичного отзыва
$token->markPartiallyUsed($score);
return redirect(config('reviews.google_url') . '?hl=ru');
}
// Низкая оценка → показываем форму для приватного отзыва
return view('reviews.form', compact('token', 'score'));
}
public function submit(Request $request, ReviewToken $token): JsonResponse
{
$request->validate(['score' => 'required|integer|min:1|max:5', 'comment' => 'nullable|string|max:2000']);
Review::create([
'order_id' => $token->order_id,
'user_id' => $token->user_id,
'score' => $request->score,
'comment' => $request->comment,
'is_public' => $request->score >= 4,
]);
$token->markUsed();
// Если низкая оценка — уведомление в поддержку
if ($request->score <= 2) {
Notification::route('slack', '#reviews')->notify(new LowReviewNotification($token->order, $request->score));
}
return response()->json(['success' => true]);
}
Платформы для внешних отзывов
| Платформа | URL для редиректа | Регион |
|---|---|---|
| Google Business | maps.google.com/maps?cid=...&action=write-review |
Глобально |
| Trustpilot | trustpilot.com/evaluate/site.com |
Глобально |
| Яндекс.Карты | yandex.ru/maps/org/.../reviews/add/ |
Россия/СНГ |
| 2ГИС | 2gis.ru/... |
Россия/СНГ |
Сроки
Система сбора отзывов с отложенной отправкой, прямой оценкой в письме и роутингом на платформы: 3–4 рабочих дня.







