isFrozen()) { throw new \Exception('کیف پول شما مسدود است. لطفاً با پشتیبانی تماس بگیرید.'); } $transaction = DB::transaction(function () use ($wallet, $amount, $description, $user, $gateway) { $transaction = WalletTransaction::create([ 'wallet_id' => $wallet->id, 'amount' => $amount, 'balance_before' => $wallet->balance, 'balance_after' => $wallet->balance, // هنوز تغییر نکرده 'type' => TransactionType::DEPOSIT, 'status' => TransactionStatus::PENDING, 'gateway' => $gateway, 'description' => $description, 'created_by' => $user?->id ?? auth()->id(), 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), ]); // لاگ فعالیت WalletActivityLog::log( $wallet, 'deposit_requested', "درخواست شارژ {$amount} ریال از طریق {$gateway->label()}", null, ['transaction_id' => $transaction->id, 'amount' => $amount], $user ); return $transaction; }); Log::info('Wallet deposit requested', [ 'wallet_id' => $wallet->id, 'transaction_id' => $transaction->id, 'amount' => $amount, 'gateway' => $gateway->value, ]); return $transaction; } /** * تأیید و تکمیل تراکنش شارژ (بعد از callback درگاه) */ public function completeDeposit( WalletTransaction $transaction, string $gatewayReferenceId, ?User $admin = null ): WalletTransaction { if ($transaction->status !== TransactionStatus::PENDING) { throw new \Exception('این تراکنش قابل تأیید نیست.'); } return DB::transaction(function () use ($transaction, $gatewayReferenceId, $admin) { $wallet = $transaction->wallet; $oldBalance = $wallet->balance; // به‌روزرسانی موجودی کیف پول $wallet->increment('balance', $transaction->amount); $wallet->increment('total_deposited', $transaction->amount); // تأیید تراکنش $transaction->update([ 'status' => TransactionStatus::COMPLETED, 'gateway_reference_id' => $gatewayReferenceId, 'balance_after' => $wallet->balance, 'approved_by' => $admin?->id, 'approved_at' => now(), ]); // لاگ فعالیت WalletActivityLog::log( $wallet, 'deposit_completed', "شارژ {$transaction->amount} ریال با موفقیت تکمیل شد. کد پیگیری: {$gatewayReferenceId}", ['balance' => $oldBalance], ['balance' => $wallet->balance, 'reference_id' => $gatewayReferenceId], $admin ); Log::info('Wallet deposit completed', [ 'wallet_id' => $wallet->id, 'transaction_id' => $transaction->id, 'amount' => $transaction->amount, 'reference_id' => $gatewayReferenceId, ]); return $transaction->fresh(); }); } /** * شارژ دستی توسط ادمین (پرداخت تلفنی یا کارت به کارت) */ public function manualDeposit( Wallet $wallet, float $amount, string $description, User $admin, ?string $adminNotes = null ): WalletTransaction { if ($wallet->isFrozen()) { throw new \Exception('این کیف پول مسدود است.'); } return DB::transaction(function () use ($wallet, $amount, $description, $admin, $adminNotes) { $oldBalance = $wallet->balance; // به‌روزرسانی موجودی $wallet->increment('balance', $amount); $wallet->increment('total_deposited', $amount); // ایجاد تراکنش $transaction = WalletTransaction::create([ 'wallet_id' => $wallet->id, 'amount' => $amount, 'balance_before' => $oldBalance, 'balance_after' => $wallet->balance, 'type' => TransactionType::DEPOSIT, 'status' => TransactionStatus::COMPLETED, 'gateway' => PaymentGateway::MANUAL, 'description' => $description, 'admin_notes' => $adminNotes, 'created_by' => $admin->id, 'approved_by' => $admin->id, 'approved_at' => now(), 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), ]); // لاگ فعالیت WalletActivityLog::log( $wallet, 'manual_adjustment', "شارژ دستی {$amount} ریال توسط {$admin->name}. توضیحات: {$description}", ['balance' => $oldBalance], ['balance' => $wallet->balance, 'transaction_id' => $transaction->id], $admin ); Log::info('Manual wallet deposit', [ 'wallet_id' => $wallet->id, 'transaction_id' => $transaction->id, 'amount' => $amount, 'admin_id' => $admin->id, 'description' => $description, ]); return $transaction; }); } /** * کسر دستی توسط ادمین (بدهی مشتری یا جریمه) */ public function manualWithdrawal( Wallet $wallet, float $amount, string $description, User $admin, ?string $adminNotes = null ): WalletTransaction { if ($wallet->isFrozen()) { throw new \Exception('این کیف پول مسدود است.'); } if ($wallet->balance < $amount) { throw new \Exception('موجودی کیف پول کافی نیست.'); } return DB::transaction(function () use ($wallet, $amount, $description, $admin, $adminNotes) { $oldBalance = $wallet->balance; // به‌روزرسانی موجودی $wallet->decrement('balance', $amount); $wallet->increment('total_withdrawn', $amount); // ایجاد تراکنش (مبلغ منفی) $transaction = WalletTransaction::create([ 'wallet_id' => $wallet->id, 'amount' => -$amount, 'balance_before' => $oldBalance, 'balance_after' => $wallet->balance, 'type' => TransactionType::WITHDRAWAL, 'status' => TransactionStatus::COMPLETED, 'gateway' => PaymentGateway::MANUAL, 'description' => $description, 'admin_notes' => $adminNotes, 'created_by' => $admin->id, 'approved_by' => $admin->id, 'approved_at' => now(), 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), ]); // لاگ فعالیت WalletActivityLog::log( $wallet, 'manual_adjustment', "کسر دستی {$amount} ریال توسط {$admin->name}. توضیحات: {$description}", ['balance' => $oldBalance], ['balance' => $wallet->balance, 'transaction_id' => $transaction->id], $admin ); Log::info('Manual wallet withdrawal', [ 'wallet_id' => $wallet->id, 'transaction_id' => $transaction->id, 'amount' => $amount, 'admin_id' => $admin->id, 'description' => $description, ]); return $transaction; }); } /** * پرداخت سفارش از کیف پول */ public function payOrder( Wallet $wallet, float $amount, string $description, $order = null ): WalletTransaction { if ($wallet->isFrozen()) { throw new \Exception('کیف پول شما مسدود است.'); } if (!$wallet->hasSufficientBalance($amount)) { throw new \Exception('موجودی کیف پول کافی نیست.'); } return DB::transaction(function () use ($wallet, $amount, $description, $order) { $oldBalance = $wallet->balance; // به‌روزرسانی موجودی $wallet->decrement('balance', $amount); $wallet->increment('total_withdrawn', $amount); // ایجاد تراکنش $transaction = WalletTransaction::create([ 'wallet_id' => $wallet->id, 'amount' => -$amount, 'balance_before' => $oldBalance, 'balance_after' => $wallet->balance, 'type' => TransactionType::ORDER_PAYMENT, 'status' => TransactionStatus::COMPLETED, 'gateway' => PaymentGateway::SYSTEM, 'description' => $description, 'created_by' => auth()->id(), 'approved_by' => auth()->id(), 'approved_at' => now(), 'transactionable_type' => $order ? get_class($order) : null, 'transactionable_id' => $order?->id, 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), ]); // لاگ فعالیت WalletActivityLog::log( $wallet, 'withdrawal_completed', "پرداخت سفارش {$amount} ریال", ['balance' => $oldBalance], ['balance' => $wallet->balance, 'transaction_id' => $transaction->id] ); return $transaction; }); } /** * شکست تراکنش */ public function failTransaction( WalletTransaction $transaction, string $reason ): WalletTransaction { $transaction->fail($reason); // لاگ فعالیت WalletActivityLog::log( $transaction->wallet, $transaction->type === TransactionType::DEPOSIT ? 'deposit_failed' : 'withdrawal_failed', "تراکنش {$transaction->id} شکست خورد. دلیل: {$reason}", null, ['transaction_id' => $transaction->id, 'reason' => $reason] ); Log::warning('Wallet transaction failed', [ 'transaction_id' => $transaction->id, 'reason' => $reason, ]); return $transaction->fresh(); } }