Steuerberater Modul tax
This commit is contained in:
parent
0f82fea88a
commit
245c281541
22 changed files with 1489 additions and 139 deletions
238
app/Services/AboRetryPaymentService.php
Normal file
238
app/Services/AboRetryPaymentService.php
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Cron\UserMakeOrder;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Services\Incentive\IncentiveTracker;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AboRetryPaymentService
|
||||
{
|
||||
/**
|
||||
* @return array{success: bool, message: string, order_id?: int}
|
||||
*/
|
||||
public function retry(UserAbo $userAbo): array
|
||||
{
|
||||
if ($userAbo->status !== 3) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_only_hold'),
|
||||
];
|
||||
}
|
||||
|
||||
if (! $userAbo->active) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_only_active'),
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->alreadyPaidToday($userAbo)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_already_paid_today'),
|
||||
];
|
||||
}
|
||||
|
||||
\Log::channel('abo_order')->info('AboRetryPaymentService: Starte erneuten Zahlungsversuch', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'email' => $userAbo->email,
|
||||
'payone_userid' => $userAbo->payone_userid,
|
||||
]);
|
||||
|
||||
AboHelper::ensureUserAboItemsFromLatestOrder($userAbo);
|
||||
|
||||
$shoppingOrder = null;
|
||||
$paymentAttemptRecorded = false;
|
||||
$userOrder = new UserMakeOrder($userAbo);
|
||||
|
||||
try {
|
||||
if (! $userOrder->createShoppingUser()) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_error_shopping_user'),
|
||||
];
|
||||
}
|
||||
|
||||
$shoppingOrder = $userOrder->makeShoppingOrder();
|
||||
if (! $shoppingOrder) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_error_order'),
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->normalizePaymentResponse($userOrder->makePayment());
|
||||
|
||||
if (($response['status'] ?? null) === 'APPROVED') {
|
||||
$this->markAboSuccess($userAbo, $shoppingOrder);
|
||||
$paymentAttemptRecorded = true;
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => __('abo.retry_success', ['order' => $shoppingOrder->id]),
|
||||
'order_id' => $shoppingOrder->id,
|
||||
];
|
||||
}
|
||||
|
||||
$this->logPaymentError($userAbo, $shoppingOrder, $response);
|
||||
$this->markAboError($userAbo, $shoppingOrder);
|
||||
$paymentAttemptRecorded = true;
|
||||
$this->sendPaymentErrorMail($userOrder, $shoppingOrder, $response);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_failed', [
|
||||
'error' => $this->formatPaymentError($response),
|
||||
'order' => $shoppingOrder->id,
|
||||
]),
|
||||
'order_id' => $shoppingOrder->id,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
\Log::channel('abo_order')->error('AboRetryPaymentService: Exception beim erneuten Zahlungsversuch', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder?->id,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
if ($shoppingOrder && ! $paymentAttemptRecorded) {
|
||||
$this->markAboError($userAbo, $shoppingOrder);
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => __('abo.retry_exception', ['error' => $e->getMessage()]),
|
||||
'order_id' => $shoppingOrder?->id,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private function alreadyPaidToday(UserAbo $userAbo): bool
|
||||
{
|
||||
return UserAboOrder::where('user_abo_id', $userAbo->id)
|
||||
->whereDate('created_at', now()->toDateString())
|
||||
->where('paid', true)
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function normalizePaymentResponse(mixed $response): array
|
||||
{
|
||||
if (is_object($response)) {
|
||||
return (array) $response;
|
||||
}
|
||||
|
||||
return is_array($response) ? $response : [];
|
||||
}
|
||||
|
||||
private function markAboSuccess(UserAbo $userAbo, mixed $shoppingOrder): void
|
||||
{
|
||||
DB::transaction(function () use ($userAbo, $shoppingOrder): void {
|
||||
$userAbo->update([
|
||||
'status' => 2,
|
||||
'active' => true,
|
||||
'next_date' => AboHelper::setNextDate(now(), $userAbo->abo_interval),
|
||||
'last_date' => now(),
|
||||
]);
|
||||
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $userAbo->id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'status' => 1,
|
||||
'paid' => true,
|
||||
]);
|
||||
});
|
||||
|
||||
try {
|
||||
IncentiveTracker::trackAboActivated($shoppingOrder);
|
||||
} catch (\Throwable $e) {
|
||||
\Log::channel('abo_order')->error('AboRetryPaymentService: Incentive-Tracking nach erfolgreichem Retry fehlgeschlagen', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function markAboError(UserAbo $userAbo, mixed $shoppingOrder): void
|
||||
{
|
||||
DB::transaction(function () use ($userAbo, $shoppingOrder): void {
|
||||
$userAbo->update([
|
||||
'status' => 3,
|
||||
'last_date' => now(),
|
||||
]);
|
||||
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $userAbo->id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'status' => 3,
|
||||
'paid' => false,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $response
|
||||
*/
|
||||
private function logPaymentError(UserAbo $userAbo, mixed $shoppingOrder, array $response): void
|
||||
{
|
||||
\Log::channel('abo_order')->error('AboRetryPaymentService: Zahlungsfehler beim erneuten Versuch', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'response' => $response,
|
||||
]);
|
||||
|
||||
MyLog::writeLog(
|
||||
'userabo',
|
||||
'error',
|
||||
'Error:AboRetryPaymentService::retry / makePayment Error',
|
||||
$response
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $response
|
||||
*/
|
||||
private function sendPaymentErrorMail(UserMakeOrder $userOrder, mixed $shoppingOrder, array $response): void
|
||||
{
|
||||
$shoppingPayment = $userOrder->getShoppingPayment();
|
||||
if (! $shoppingPayment) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Payment::paymentStatusSendMail($shoppingOrder, $shoppingPayment, [
|
||||
'mode' => $shoppingPayment->mode,
|
||||
'txaction' => 'error',
|
||||
'send_link' => false,
|
||||
'payment_error' => $response,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
\Log::channel('abo_order')->error('AboRetryPaymentService: Fehlermail nach Zahlungsfehler konnte nicht gesendet werden', [
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'payment_id' => $shoppingPayment->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $response
|
||||
*/
|
||||
private function formatPaymentError(array $response): string
|
||||
{
|
||||
$errorCode = $response['errorcode'] ?? null;
|
||||
$errorMessage = $response['errormessage'] ?? $response['customermessage'] ?? ($response['status'] ?? __('payment.unknown'));
|
||||
|
||||
if ($errorCode) {
|
||||
return '['.$errorCode.'] '.$errorMessage;
|
||||
}
|
||||
|
||||
return (string) $errorMessage;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue