|
|
@@ -2,10 +2,12 @@
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
-use App\Enums\CartStatusEnum;
|
|
|
+use App\Enums\ServicePackageStatusEnum;
|
|
|
use App\Enums\PaymentSplitStatusEnum;
|
|
|
use App\Enums\PaymentStatusEnum;
|
|
|
-use App\Models\Cart;
|
|
|
+use App\Exceptions\PaymentFailedException;
|
|
|
+use App\Exceptions\PaymentException;
|
|
|
+use App\Models\ServicePackage;
|
|
|
use App\Models\ClientPaymentMethod;
|
|
|
use App\Models\Payment;
|
|
|
use App\Models\PaymentSplit;
|
|
|
@@ -15,6 +17,7 @@ use Carbon\Carbon;
|
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
|
use Illuminate\Support\Collection as SupportCollection;
|
|
|
+use Illuminate\Support\Facades\Auth;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
|
@@ -27,7 +30,7 @@ class PaymentService
|
|
|
public function getAll(): Collection
|
|
|
{
|
|
|
return Payment::query()
|
|
|
- ->with(['client.user', 'provider.user', 'schedule', 'cart.items.schedule'])
|
|
|
+ ->with(['client.user', 'provider.user', 'schedule', 'servicePackage.items.schedule'])
|
|
|
->orderBy('created_at', 'desc')
|
|
|
->get();
|
|
|
}
|
|
|
@@ -35,7 +38,7 @@ class PaymentService
|
|
|
public function findById(int $id): ?Payment
|
|
|
{
|
|
|
return Payment::query()
|
|
|
- ->with(['client.user', 'provider.user', 'schedule', 'cart.items.schedule'])
|
|
|
+ ->with(['client.user', 'provider.user', 'schedule', 'servicePackage.items.schedule'])
|
|
|
->find($id);
|
|
|
}
|
|
|
|
|
|
@@ -77,29 +80,55 @@ class PaymentService
|
|
|
|
|
|
//
|
|
|
|
|
|
- public function payAcceptedSchedule(
|
|
|
- Schedule $schedule, string $paymentMethod, ?int $clientPaymentMethodId = null, array $options = []
|
|
|
+ public function paySchedule(
|
|
|
+ int $scheduleId,
|
|
|
+ string $paymentMethod,
|
|
|
+ ?int $clientPaymentMethodId = null,
|
|
|
+ array $options = [],
|
|
|
+ ): Payment {
|
|
|
+ $schedule = Schedule::query()
|
|
|
+ ->with(['client', 'provider', 'customSchedule.serviceType'])
|
|
|
+ ->findOrFail($scheduleId);
|
|
|
+
|
|
|
+ if ($schedule->client?->user_id !== (int) Auth::id()) {
|
|
|
+ throw new AuthorizationException;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->processAcceptedSchedulePayment(
|
|
|
+ schedule: $schedule,
|
|
|
+ paymentMethod: $paymentMethod,
|
|
|
+ clientPaymentMethodId: $clientPaymentMethodId,
|
|
|
+
|
|
|
+ options: $options,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function processAcceptedSchedulePayment(
|
|
|
+ Schedule $schedule,
|
|
|
+ string $paymentMethod,
|
|
|
+ ?int $clientPaymentMethodId = null,
|
|
|
+ array $options = [],
|
|
|
): Payment {
|
|
|
$schedule->loadMissing(['client', 'provider', 'customSchedule.serviceType']);
|
|
|
|
|
|
if ($schedule->status !== 'accepted') {
|
|
|
- throw new \InvalidArgumentException('Agendamento precisa estar aceito para ser pago.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if (! in_array($paymentMethod, ['credit_card', 'pix'], true)) {
|
|
|
- throw new \InvalidArgumentException('Forma de pagamento invalida.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if (! $schedule->provider_id || ! $schedule->provider) {
|
|
|
- throw new \InvalidArgumentException('Agendamento precisa ter prestador confirmado para gerar pagamento.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if ((float) $schedule->total_amount <= 0) {
|
|
|
- throw new \InvalidArgumentException('Agendamento precisa ter valor maior que zero para gerar pagamento.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if (empty($schedule->provider->recipient_id)) {
|
|
|
- throw new \InvalidArgumentException('Prestador precisa ter recipient_id do Pagar.me para receber split.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$this->ensureScheduleCanBePaidIndividually($schedule);
|
|
|
@@ -138,7 +167,7 @@ class PaymentService
|
|
|
|
|
|
else {
|
|
|
if ($existingPayment->payment_method !== $paymentMethod && $existingPayment->status !== PaymentStatusEnum::PAID) {
|
|
|
- throw new \InvalidArgumentException('Ja existe um pagamento em andamento para este agendamento.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$this->syncScheduleStatusAfterPayment($schedule, $existingPayment);
|
|
|
@@ -151,8 +180,8 @@ class PaymentService
|
|
|
$cardId = null;
|
|
|
|
|
|
if ($paymentMethod === 'credit_card') {
|
|
|
- if (! $clientPaymentMethodId && empty($options['card_id'])) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento ou card_id e obrigatorio.');
|
|
|
+ if (! $clientPaymentMethodId && empty(data_get($options, 'card_id'))) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if ($clientPaymentMethodId) {
|
|
|
@@ -163,14 +192,14 @@ class PaymentService
|
|
|
->first();
|
|
|
|
|
|
if (! $clientPaymentMethod) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento nao encontrado ou inativo para este cliente.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $cardId = $options['card_id'] ?? $clientPaymentMethod?->gateway_card_id ?? null;
|
|
|
+ $cardId = data_get($options, 'card_id', $clientPaymentMethod?->gateway_card_id);
|
|
|
|
|
|
if (empty($cardId)) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento invalido ou sem gateway_card_id do Pagar.me.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -191,17 +220,17 @@ class PaymentService
|
|
|
'gateway_code' => 'payment-'.(string) Str::uuid(),
|
|
|
'payment_method' => $paymentMethod,
|
|
|
'status' => PaymentStatusEnum::PENDING,
|
|
|
- 'gross_amount' => $amounts['gross_amount'],
|
|
|
+ 'gross_amount' => data_get($amounts, 'gross_amount'),
|
|
|
'gateway_fee_amount' => 0,
|
|
|
- 'platform_fee_amount' => $amounts['platform_fee_amount'],
|
|
|
- 'net_amount' => $amounts['gross_amount'],
|
|
|
+ 'platform_fee_amount' => data_get($amounts, 'platform_fee_amount'),
|
|
|
+ 'net_amount' => data_get($amounts, 'gross_amount'),
|
|
|
'currency' => 'BRL',
|
|
|
'installments' => 1,
|
|
|
'expires_at' => $paymentMethod === 'pix' ? Carbon::now()->addMinutes(30) : null,
|
|
|
|
|
|
'metadata' => [
|
|
|
- 'service_amount' => number_format($amounts['service_amount'], 2, '.', ''),
|
|
|
- 'platform_fee' => number_format($amounts['platform_fee_amount'], 2, '.', ''),
|
|
|
+ 'service_amount' => number_format(data_get($amounts, 'service_amount'), 2, '.', ''),
|
|
|
+ 'platform_fee' => number_format(data_get($amounts, 'platform_fee_amount'), 2, '.', ''),
|
|
|
],
|
|
|
]);
|
|
|
|
|
|
@@ -221,7 +250,7 @@ class PaymentService
|
|
|
],
|
|
|
]);
|
|
|
|
|
|
- $schedule->ensureCustomerPhone($options['phone'] ?? null);
|
|
|
+ $schedule->ensureCustomerPhone(data_get($options, 'phone'));
|
|
|
|
|
|
try {
|
|
|
$orderResponse = $this->pagarmePaymentService->processPayment(
|
|
|
@@ -249,46 +278,47 @@ class PaymentService
|
|
|
|
|
|
$this->syncScheduleStatusAfterPayment($schedule, $payment);
|
|
|
|
|
|
+ if ($payment->status === PaymentStatusEnum::FAILED) {
|
|
|
+ throw new PaymentFailedException;
|
|
|
+ }
|
|
|
+
|
|
|
return $payment;
|
|
|
}
|
|
|
|
|
|
- public function payCart(
|
|
|
- Cart $cart,
|
|
|
- int $userId,
|
|
|
+ public function payServicePackage(
|
|
|
+ int $servicePackageId,
|
|
|
string $paymentMethod,
|
|
|
- ?int $clientPaymentMethodId = null,
|
|
|
- array $options = [],
|
|
|
+ ?int $clientPaymentMethodId = null,
|
|
|
+ array $options = [],
|
|
|
): Payment {
|
|
|
- if ($cart->client?->user_id !== $userId) {
|
|
|
- throw new AuthorizationException;
|
|
|
- }
|
|
|
+ $userId = (int) Auth::id();
|
|
|
|
|
|
if (! in_array($paymentMethod, ['credit_card', 'pix'], true)) {
|
|
|
- throw new \InvalidArgumentException('Forma de pagamento invalida.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$paymentData = DB::transaction(function () use (
|
|
|
- $cart,
|
|
|
+ $servicePackageId,
|
|
|
$userId,
|
|
|
$paymentMethod,
|
|
|
$clientPaymentMethodId,
|
|
|
$options,
|
|
|
): array {
|
|
|
- $cart = Cart::query()
|
|
|
+ $servicePackage = ServicePackage::query()
|
|
|
->lockForUpdate()
|
|
|
->with(['client', 'provider', 'items.schedule.client', 'items.schedule.provider', 'items.schedule.customSchedule.serviceType'])
|
|
|
- ->findOrFail($cart->id);
|
|
|
+ ->findOrFail($servicePackageId);
|
|
|
|
|
|
- if ($cart->client?->user_id !== $userId) {
|
|
|
+ if ($servicePackage->client?->user_id !== $userId) {
|
|
|
throw new AuthorizationException;
|
|
|
}
|
|
|
|
|
|
- $schedules = $cart->items->pluck('schedule')->filter()->values();
|
|
|
+ $schedules = $servicePackage->items->pluck('schedule')->filter()->values();
|
|
|
|
|
|
- $this->validateCartForPayment($cart, $schedules);
|
|
|
+ $this->validateServicePackageForPayment($servicePackage, $schedules);
|
|
|
|
|
|
$existingPayment = Payment::query()
|
|
|
- ->where('cart_id', $cart->id)
|
|
|
+ ->where('service_package_id', $servicePackage->id)
|
|
|
->whereIn('status', [
|
|
|
PaymentStatusEnum::PENDING->value,
|
|
|
PaymentStatusEnum::PROCESSING->value,
|
|
|
@@ -311,109 +341,113 @@ class PaymentService
|
|
|
->update(['status' => PaymentSplitStatusEnum::FAILED]);
|
|
|
} elseif ($this->isStaleIncompleteGatewayPayment($existingPayment)) {
|
|
|
if ($existingPayment->payment_method !== $paymentMethod) {
|
|
|
- throw new \InvalidArgumentException('Ja existe um pagamento em andamento para este carrinho.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
[, $cardId] = $this->resolveCard(
|
|
|
- clientId: $cart->client_id,
|
|
|
+ clientId: $servicePackage->client_id,
|
|
|
paymentMethod: $paymentMethod,
|
|
|
clientPaymentMethodId: $clientPaymentMethodId ?? $existingPayment->client_payment_method_id,
|
|
|
- cardId: $options['card_id'] ?? null,
|
|
|
+ cardId: data_get($options, 'card_id'),
|
|
|
);
|
|
|
|
|
|
- $this->cartPaymentTotals($schedules, $paymentMethod);
|
|
|
+ $this->servicePackagePaymentTotals($schedules, $paymentMethod);
|
|
|
|
|
|
return [
|
|
|
- 'payment' => $existingPayment,
|
|
|
+ 'payment' => $existingPayment,
|
|
|
'schedules' => $schedules,
|
|
|
'cardId' => $cardId,
|
|
|
];
|
|
|
} else {
|
|
|
if ($existingPayment->payment_method !== $paymentMethod && $existingPayment->status !== PaymentStatusEnum::PAID) {
|
|
|
- throw new \InvalidArgumentException('Ja existe um pagamento em andamento para este carrinho.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
return ['existing' => $existingPayment];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ($cart->status !== CartStatusEnum::OPEN) {
|
|
|
- throw new \InvalidArgumentException('Carrinho precisa estar aberto para ser pago.');
|
|
|
+ if ($servicePackage->status !== ServicePackageStatusEnum::OPEN) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
[$clientPaymentMethod, $cardId] = $this->resolveCard(
|
|
|
- clientId: $cart->client_id,
|
|
|
- paymentMethod: $paymentMethod,
|
|
|
+ clientId: $servicePackage->client_id,
|
|
|
+ paymentMethod: $paymentMethod,
|
|
|
clientPaymentMethodId: $clientPaymentMethodId,
|
|
|
- cardId: $options['card_id'] ?? null,
|
|
|
+ cardId: data_get($options, 'card_id'),
|
|
|
);
|
|
|
|
|
|
- $totals = $this->cartPaymentTotals($schedules, $paymentMethod);
|
|
|
+ $totals = $this->servicePackagePaymentTotals($schedules, $paymentMethod);
|
|
|
|
|
|
$payment = Payment::create([
|
|
|
'schedule_id' => null,
|
|
|
- 'cart_id' => $cart->id,
|
|
|
- 'client_id' => $cart->client_id,
|
|
|
- 'provider_id' => $cart->provider_id,
|
|
|
+ 'service_package_id' => $servicePackage->id,
|
|
|
+ 'client_id' => $servicePackage->client_id,
|
|
|
+ 'provider_id' => $servicePackage->provider_id,
|
|
|
'client_payment_method_id' => $paymentMethod === 'credit_card' ? $clientPaymentMethod?->id : null,
|
|
|
'gateway_provider' => 'pagarme',
|
|
|
'gateway_code' => 'payment-'.(string) Str::uuid(),
|
|
|
'payment_method' => $paymentMethod,
|
|
|
'status' => PaymentStatusEnum::PENDING,
|
|
|
- 'gross_amount' => $totals['gross_amount'],
|
|
|
+ 'gross_amount' => data_get($totals, 'gross_amount'),
|
|
|
'gateway_fee_amount' => 0,
|
|
|
- 'platform_fee_amount' => $totals['platform_fee_amount'],
|
|
|
- 'net_amount' => $totals['gross_amount'],
|
|
|
+ 'platform_fee_amount' => data_get($totals, 'platform_fee_amount'),
|
|
|
+ 'net_amount' => data_get($totals, 'gross_amount'),
|
|
|
'currency' => 'BRL',
|
|
|
'installments' => 1,
|
|
|
'expires_at' => $paymentMethod === 'pix' ? Carbon::now()->addMinutes(30) : null,
|
|
|
- 'metadata' => [
|
|
|
- 'cart_id' => (string) $cart->id,
|
|
|
- 'schedule_ids' => $schedules->pluck('id')->map(fn ($id) => (string) $id)->all(),
|
|
|
- 'service_amount' => number_format($totals['service_amount'], 2, '.', ''),
|
|
|
- 'platform_fee' => number_format($totals['platform_fee_amount'], 2, '.', ''),
|
|
|
+
|
|
|
+ 'metadata' => [
|
|
|
+ 'service_package_id' => (string) $servicePackage->id,
|
|
|
+ 'schedule_ids' => $schedules->pluck('id')->map(fn ($id) => (string) $id)->all(),
|
|
|
+ 'service_amount' => number_format(data_get($totals, 'service_amount'), 2, '.', ''),
|
|
|
+ 'platform_fee' => number_format(data_get($totals, 'platform_fee_amount'), 2, '.', ''),
|
|
|
],
|
|
|
]);
|
|
|
|
|
|
PaymentSplit::create([
|
|
|
'payment_id' => $payment->id,
|
|
|
- 'provider_id' => $cart->provider_id,
|
|
|
+ 'provider_id' => $servicePackage->provider_id,
|
|
|
'gateway_provider' => 'pagarme',
|
|
|
- 'gateway_transfer_target_reference' => $cart->provider->recipient_id,
|
|
|
+ 'gateway_transfer_target_reference' => $servicePackage->provider->recipient_id,
|
|
|
'gateway_transfer_target_label' => 'recipient',
|
|
|
'status' => PaymentSplitStatusEnum::PENDING,
|
|
|
- 'gross_amount' => $totals['service_amount'],
|
|
|
+ 'gross_amount' => data_get($totals, 'service_amount'),
|
|
|
'gateway_fee_amount' => 0,
|
|
|
- 'net_amount' => $totals['service_amount'],
|
|
|
- 'metadata' => [
|
|
|
- 'cart_id' => (string) $cart->id,
|
|
|
- 'schedule_ids' => $schedules->pluck('id')->map(fn ($id) => (string) $id)->all(),
|
|
|
+ 'net_amount' => data_get($totals, 'service_amount'),
|
|
|
+
|
|
|
+ 'metadata' => [
|
|
|
+ 'service_package_id' => (string) $servicePackage->id,
|
|
|
+ 'schedule_ids' => $schedules->pluck('id')->map(fn ($id) => (string) $id)->all(),
|
|
|
],
|
|
|
]);
|
|
|
|
|
|
return compact('payment', 'schedules', 'cardId');
|
|
|
});
|
|
|
|
|
|
- if (isset($paymentData['existing'])) {
|
|
|
- $existingPayment = $paymentData['existing'];
|
|
|
+ if (data_get($paymentData, 'existing')) {
|
|
|
+ $existingPayment = data_get($paymentData, 'existing');
|
|
|
+
|
|
|
$this->syncPaymentTargets($existingPayment);
|
|
|
|
|
|
- return $existingPayment->fresh(['client.user', 'provider.user', 'cart.items.schedule']);
|
|
|
+ return $existingPayment->fresh(['client.user', 'provider.user', 'servicePackage.items.schedule']);
|
|
|
}
|
|
|
|
|
|
/** @var Payment $payment */
|
|
|
- $payment = $paymentData['payment'];
|
|
|
+ $payment = data_get($paymentData, 'payment');
|
|
|
+
|
|
|
/** @var SupportCollection $schedules */
|
|
|
- $schedules = $paymentData['schedules'];
|
|
|
+ $schedules = data_get($paymentData, 'schedules');
|
|
|
|
|
|
try {
|
|
|
- $schedules->first()->ensureCustomerPhone($options['phone'] ?? null);
|
|
|
+ $schedules->first()->ensureCustomerPhone(data_get($options, 'phone'));
|
|
|
|
|
|
- $orderResponse = $this->pagarmePaymentService->processCartPayment(
|
|
|
+ $orderResponse = $this->pagarmePaymentService->processServicePackagePayment(
|
|
|
payment: $payment,
|
|
|
schedules: $schedules,
|
|
|
paymentMethod: $paymentMethod,
|
|
|
- cardId: $paymentData['cardId'],
|
|
|
+ cardId: data_get($paymentData, 'cardId'),
|
|
|
options: $options,
|
|
|
);
|
|
|
} catch (\Throwable $e) {
|
|
|
@@ -426,7 +460,11 @@ class PaymentService
|
|
|
|
|
|
$this->syncPaymentTargets($payment);
|
|
|
|
|
|
- return $payment->fresh(['client.user', 'provider.user', 'cart.items.schedule']);
|
|
|
+ if ($payment->status === PaymentStatusEnum::FAILED) {
|
|
|
+ throw new PaymentFailedException;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $payment->fresh(['client.user', 'provider.user', 'servicePackage.items.schedule']);
|
|
|
}
|
|
|
|
|
|
//
|
|
|
@@ -479,7 +517,7 @@ class PaymentService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return $this->payAcceptedSchedule(
|
|
|
+ return $this->processAcceptedSchedulePayment(
|
|
|
schedule: $schedule,
|
|
|
paymentMethod: 'pix',
|
|
|
);
|
|
|
@@ -525,7 +563,7 @@ class PaymentService
|
|
|
$schedule->update(['status' => 'paid']);
|
|
|
}
|
|
|
|
|
|
- $this->syncCartsForSchedule($schedule);
|
|
|
+ $this->syncServicePackagesForSchedule($schedule);
|
|
|
}
|
|
|
|
|
|
public function syncPaymentTargets(Payment $payment): void
|
|
|
@@ -534,23 +572,23 @@ class PaymentService
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if ($payment->cart_id) {
|
|
|
+ if ($payment->service_package_id) {
|
|
|
DB::transaction(function () use ($payment): void {
|
|
|
- $cart = Cart::query()->lockForUpdate()->with('items')->find($payment->cart_id);
|
|
|
+ $servicePackage = ServicePackage::query()->lockForUpdate()->with('items')->find($payment->service_package_id);
|
|
|
|
|
|
- if (! $cart) {
|
|
|
+ if (! $servicePackage) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- $scheduleIds = $cart->items->pluck('schedule_id')->filter()->unique();
|
|
|
+ $scheduleIds = $servicePackage->items->pluck('schedule_id')->filter()->unique();
|
|
|
|
|
|
Schedule::query()
|
|
|
->whereIn('id', $scheduleIds)
|
|
|
->where('status', 'accepted')
|
|
|
->update(['status' => 'paid']);
|
|
|
|
|
|
- if ($cart->status !== CartStatusEnum::PAID) {
|
|
|
- $cart->update(['status' => CartStatusEnum::PAID->value]);
|
|
|
+ if ($servicePackage->status !== ServicePackageStatusEnum::PAID) {
|
|
|
+ $servicePackage->update(['status' => ServicePackageStatusEnum::PAID->value]);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -564,20 +602,20 @@ class PaymentService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private function syncCartsForSchedule(Schedule $schedule): void
|
|
|
+ private function syncServicePackagesForSchedule(Schedule $schedule): void
|
|
|
{
|
|
|
- Cart::query()
|
|
|
+ ServicePackage::query()
|
|
|
->whereHas('items', fn ($query) => $query->where('schedule_id', $schedule->id))
|
|
|
->with('items')
|
|
|
->get()
|
|
|
- ->each(fn (Cart $cart) => $this->syncCartStatusAfterPayments($cart));
|
|
|
+ ->each(fn (ServicePackage $servicePackage) => $this->syncServicePackageStatusAfterPayments($servicePackage));
|
|
|
}
|
|
|
|
|
|
- private function syncCartStatusAfterPayments(Cart $cart): void
|
|
|
+ private function syncServicePackageStatusAfterPayments(ServicePackage $servicePackage): void
|
|
|
{
|
|
|
- $cart->loadMissing('items');
|
|
|
+ $servicePackage->loadMissing('items');
|
|
|
|
|
|
- $scheduleIds = $cart->items
|
|
|
+ $scheduleIds = $servicePackage->items
|
|
|
->pluck('schedule_id')
|
|
|
->filter()
|
|
|
->unique()
|
|
|
@@ -596,45 +634,45 @@ class PaymentService
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if ($cart->status !== CartStatusEnum::PAID) {
|
|
|
- $cart->update(['status' => CartStatusEnum::PAID->value]);
|
|
|
+ if ($servicePackage->status !== ServicePackageStatusEnum::PAID) {
|
|
|
+ $servicePackage->update(['status' => ServicePackageStatusEnum::PAID->value]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private function validateCartForPayment(Cart $cart, SupportCollection $schedules): void
|
|
|
+ private function validateServicePackageForPayment(ServicePackage $servicePackage, SupportCollection $schedules): void
|
|
|
{
|
|
|
- if (! in_array($cart->status, [CartStatusEnum::OPEN, CartStatusEnum::PAID], true)) {
|
|
|
- throw new \InvalidArgumentException('Carrinho precisa estar aberto para ser pago.');
|
|
|
+ if (! in_array($servicePackage->status, [ServicePackageStatusEnum::OPEN, ServicePackageStatusEnum::PAID], true)) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if ($schedules->isEmpty()) {
|
|
|
- throw new \InvalidArgumentException('Carrinho precisa ter ao menos um agendamento.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$providerIds = $schedules->pluck('provider_id')->filter()->unique()->values();
|
|
|
$clientIds = $schedules->pluck('client_id')->unique()->values();
|
|
|
|
|
|
- if (! $cart->provider_id || $providerIds->count() !== 1 || (int) $providerIds->first() !== $cart->provider_id) {
|
|
|
- throw new \InvalidArgumentException('Todos os agendamentos do carrinho precisam ser do mesmo prestador.');
|
|
|
+ if (! $servicePackage->provider_id || $providerIds->count() !== 1 || (int) $providerIds->first() !== $servicePackage->provider_id) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
- if ($clientIds->count() !== 1 || (int) $clientIds->first() !== $cart->client_id) {
|
|
|
- throw new \InvalidArgumentException('Todos os agendamentos do carrinho precisam ser do mesmo cliente.');
|
|
|
+ if ($clientIds->count() !== 1 || (int) $clientIds->first() !== $servicePackage->client_id) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
- if (empty($cart->provider?->recipient_id)) {
|
|
|
- throw new \InvalidArgumentException('Prestador precisa ter recipient_id do Pagar.me para receber split.');
|
|
|
+ if (empty($servicePackage->provider?->recipient_id)) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
foreach ($schedules as $schedule) {
|
|
|
- $expectedStatus = $cart->status === CartStatusEnum::PAID ? 'paid' : 'accepted';
|
|
|
+ $expectedStatus = $servicePackage->status === ServicePackageStatusEnum::PAID ? 'paid' : 'accepted';
|
|
|
|
|
|
if ($schedule->status !== $expectedStatus) {
|
|
|
- throw new \InvalidArgumentException("Agendamento {$schedule->id} precisa estar aceito para o carrinho ser pago.");
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
if ((float) $schedule->total_amount <= 0) {
|
|
|
- throw new \InvalidArgumentException("Agendamento {$schedule->id} precisa ter valor maior que zero para gerar pagamento.");
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -650,7 +688,7 @@ class PaymentService
|
|
|
}
|
|
|
|
|
|
if (! $clientPaymentMethodId && empty($cardId)) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento ou card_id e obrigatorio.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$clientPaymentMethod = $clientPaymentMethodId
|
|
|
@@ -662,19 +700,19 @@ class PaymentService
|
|
|
: null;
|
|
|
|
|
|
if ($clientPaymentMethodId && ! $clientPaymentMethod) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento nao encontrado ou inativo para este cliente.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
$cardId = $cardId ?: $clientPaymentMethod?->gateway_card_id;
|
|
|
|
|
|
if (empty($cardId)) {
|
|
|
- throw new \InvalidArgumentException('Cartao de pagamento invalido ou sem gateway_card_id do Pagar.me.');
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
|
|
|
return [$clientPaymentMethod, $cardId];
|
|
|
}
|
|
|
|
|
|
- private function cartPaymentTotals(SupportCollection $schedules, string $paymentMethod): array
|
|
|
+ private function servicePackagePaymentTotals(SupportCollection $schedules, string $paymentMethod): array
|
|
|
{
|
|
|
return $schedules->reduce(function (array $totals, Schedule $schedule) use ($paymentMethod): array {
|
|
|
$amounts = $this->pagarmePaymentService->calculatePaymentAmounts(
|
|
|
@@ -683,12 +721,12 @@ class PaymentService
|
|
|
schedule: $schedule,
|
|
|
);
|
|
|
|
|
|
- $schedule->setAttribute('payment_gross_amount', $amounts['gross_amount']);
|
|
|
+ $schedule->setAttribute('payment_gross_amount', data_get($amounts, 'gross_amount'));
|
|
|
|
|
|
return [
|
|
|
- 'service_amount' => round($totals['service_amount'] + $amounts['service_amount'], 2),
|
|
|
- 'platform_fee_amount' => round($totals['platform_fee_amount'] + $amounts['platform_fee_amount'], 2),
|
|
|
- 'gross_amount' => round($totals['gross_amount'] + $amounts['gross_amount'], 2),
|
|
|
+ 'service_amount' => round(data_get($totals, 'service_amount') + data_get($amounts, 'service_amount'), 2),
|
|
|
+ 'platform_fee_amount' => round(data_get($totals, 'platform_fee_amount') + data_get($amounts, 'platform_fee_amount'), 2),
|
|
|
+ 'gross_amount' => round(data_get($totals, 'gross_amount') + data_get($amounts, 'gross_amount'), 2),
|
|
|
];
|
|
|
}, [
|
|
|
'service_amount' => 0.0,
|
|
|
@@ -712,14 +750,14 @@ class PaymentService
|
|
|
|
|
|
private function ensureScheduleCanBePaidIndividually(Schedule $schedule): void
|
|
|
{
|
|
|
- $belongsToMultiItemCart = Cart::query()
|
|
|
- ->where('status', CartStatusEnum::OPEN->value)
|
|
|
+ $belongsToMultiItemServicePackage = ServicePackage::query()
|
|
|
+ ->where('status', ServicePackageStatusEnum::OPEN->value)
|
|
|
->whereHas('items', fn ($query) => $query->where('schedule_id', $schedule->id))
|
|
|
->whereHas('items', null, '>', 1)
|
|
|
->exists();
|
|
|
|
|
|
- if ($belongsToMultiItemCart) {
|
|
|
- throw new \InvalidArgumentException('Agendamento pertencente a carrinho com múltiplos itens deve ser pago pelo checkout do carrinho.');
|
|
|
+ if ($belongsToMultiItemServicePackage) {
|
|
|
+ throw new PaymentException;
|
|
|
}
|
|
|
}
|
|
|
}
|