38703-vm/app/Services/PurchaseService.php
Flatlogic Bot e4e5346c0f sad
2026-02-23 15:47:04 +00:00

98 lines
3.6 KiB
PHP

<?php
namespace App\Services;
use App\Repositories\CarRepository;
use App\Repositories\PurchaseRepository;
use App\Repositories\SettingRepository;
use Exception;
class PurchaseService {
protected $carRepo;
protected $purchaseRepo;
protected $settingRepo;
protected $paymentService;
public function __construct() {
$this->carRepo = new CarRepository();
$this->purchaseRepo = new PurchaseRepository();
$this->settingRepo = new SettingRepository();
$this->paymentService = new PaymentService();
}
public function reserveCar($carId, $userId) {
$this->carRepo->beginTransaction();
try {
$car = $this->carRepo->find($carId, true); // Lock for update
if (!$car) throw new Exception("Car not found.");
if ($car['status'] !== 'approved') throw new Exception("Car is not available for sale.");
if ($car['user_id'] == $userId) throw new Exception("You cannot buy your own car.");
// Check if already reserved by someone else and not expired
if ($car['reserved_by'] && $car['reserved_by'] != $userId && strtotime($car['reservation_expires_at']) > time()) {
throw new Exception("This car is currently reserved by another buyer.");
}
$this->carRepo->reserve($carId, $userId);
$this->carRepo->commit();
return true;
} catch (Exception $e) {
$this->carRepo->rollBack();
throw $e;
}
}
public function calculateFees($price) {
$feePercent = $this->settingRepo->get('marketplace_fee_percentage', 5);
$taxPercent = $this->settingRepo->get('tax_percentage', 10);
$fee = ($price * $feePercent) / 100;
$tax = ($price * $taxPercent) / 100;
$total = $price + $fee + $tax;
return [
'base_price' => $price,
'fee' => $fee,
'tax' => $tax,
'total' => $total
];
}
public function initiatePurchase($carId, $userId, $buyerData) {
$this->purchaseRepo->beginTransaction();
try {
$car = $this->carRepo->find($carId, true);
if (!$car) throw new Exception("Car not found.");
$costs = $this->calculateFees($car['price']);
$transactionId = $this->paymentService->generateUUID();
$ref = $this->purchaseRepo->generateUniqueReference();
$token = $this->paymentService->generateVerificationToken($transactionId, $costs['total']);
$purchaseId = $this->purchaseRepo->create([
'transaction_id' => $transactionId,
'reference_number' => $ref,
'verification_token' => $token,
'car_id' => $carId,
'user_id' => $userId,
'buyer_name' => $buyerData['name'],
'buyer_email' => $buyerData['email'],
'buyer_phone' => $buyerData['phone'],
'base_price' => $costs['base_price'],
'marketplace_fee' => $costs['fee'],
'tax' => $costs['tax'],
'total_amount' => $costs['total'],
'status' => 'initiated',
'escrow_status' => 'awaiting_verification',
'payment_method' => $buyerData['payment_method'],
'expires_at' => date('Y-m-d H:i:s', strtotime("+1 hour"))
]);
$this->purchaseRepo->commit();
return $transactionId;
} catch (Exception $e) {
$this->purchaseRepo->rollBack();
throw $e;
}
}
}