public function buyProduct($id){
$product = Product::where('id',$id)->get();
Ну тут как бы можно сразу получать в параметре готовый объект модели.
Но даже если получать по айди, то не лучше ли использовать один из методов группы find..()?
Вывод: Знания ларки околонулевые.
Идем дальше
$userId = Auth::user()->id;
$sellerUserId = $product->first()->seller_user_id;
$sellerUserIdBalance = User::where('id',$sellerUserId)->get()->first()->balance;
То есть мы сначала
получаем юзера, берем его айди, потом ищем по этому айди юзера в базе (а ведь мы его уже получили ранее) и получаем снова, чтобы дернуть оттуда баланс.
Вывод: Знания ларки околонулевые.
User::where('id', $sellerUserId)->update(array('balance' => $sellerUserIdBalance+$productPrice));
А тут мы еще раз обращаемся к таблице пользователей. Зачем? Мы уже пару раз получили пользователя...
-------------------
А в целом по вопросу, мне кажется норм.
Именно в контроллере определяем, может ли данный юзер осуществить покупку.
Ну или как вариант, можно закинуть это в миддлвэр. При условии, что данные проверки могут выполняться в саброутах. Если проверка только в этом маршруте, то норм.