UnknownSec Bypass
403
:
/
mnt
/
lmsestudio-instance-vol002
/
lms_5b407a0408d2
/
app
/
Console
/
Commands
/ [
drwxr-xr-x
]
Menu
Upload
Mass depes
Mass delete
Terminal
Info server
About
name :
RecurringBoleto.php
<?php namespace EstudioLMS\Console\Commands; use Carbon\Carbon; use EstudioLMS\Cart\Cart; use EstudioLMS\Events\RecurringNotification; use EstudioLMS\Repositories\Financial\RecurringInterface; use EstudioLMS\Repositories\Subscription\PeriodicityInterface; use EstudioLMS\Services\PagarMeService; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Event; /** * Class RecurringBoleto * @package EstudioLMS\Console\Commands */ class RecurringBoleto extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'recurring:boleto'; /** * The console command description. * * @var string */ protected $description = 'Processa as recorrências das assinaturas com forma de pagamento boleto (API v5)'; /** * @var RecurringInterface */ private $recurring; /** * @var PeriodicityInterface */ private $periodicity; /** * @var PagarMeService */ private $pagarMeService; /** * Create a new command instance. * * @param RecurringInterface $recurring * @param PeriodicityInterface $periodicity * @param PagarMeService $pagarMeService */ public function __construct( RecurringInterface $recurring, PeriodicityInterface $periodicity, PagarMeService $pagarMeService ) { parent::__construct(); $this->recurring = $recurring; $this->periodicity = $periodicity; $this->pagarMeService = $pagarMeService; } /** * Execute the console command. * * Os seguintes status serão considerados, para o processamento das recorrências. * 0 - Registro sem processamento, deve ser feita a cobrança; * 1 - Registro processado; * 2 - Houve falha na cobrança - Cartão de Crédito - Será cobrado novamente em X dias; * 3 - Boleto emitido e ainda não pago; * 4 - Cancelamento solicitado. Ao invés de cobrar, deve marcar a assinatura como cancelada; * 5 - Registro de cancelamento processado; * 6 - Cancelado por falta de pagamento; * * @return void */ public function handle() { $paymentType = 'boleto'; $addDays = 5; $today = Carbon::now()->format('Y-m-d'); Log::info('Iniciando processamento de recorrências de boleto - API v5', [ 'date' => $today, 'payment_type' => $paymentType, 'add_days' => $addDays ]); $recurrings = $this->recurring->getDueRecurrences($paymentType, $addDays); //dd($recurrings); Log::info('Recorrências encontradas para processamento', [ 'count' => (is_array($recurrings) || $recurrings instanceof \Countable) ? count($recurrings) : 0 ]); foreach ($recurrings as $key => $recurring) { try { Log::info('Processando recorrência', [ 'recurring_id' => $recurring->id, 'user_id' => $recurring->user_id, 'subscription_hash' => $recurring->subscription_hash, 'gross_amount' => $recurring->gross_amount ]); // Validações básicas if (!$recurring->hire_subscription) { Log::error('HireSubscription não encontrada para recurring', ['recurring_id' => $recurring->id]); continue; } if (!$recurring->hire_subscription->subscription) { Log::error('Subscription não encontrada para recurring', ['recurring_id' => $recurring->id]); continue; } // Validar se o valor é positivo if ($recurring->gross_amount <= 0) { Log::error('Valor inválido para recorrência', [ 'recurring_id' => $recurring->id, 'gross_amount' => $recurring->gross_amount ]); continue; } $periodicity = $this->periodicity->find($recurring->hire_subscription->periodicity_id); if (!$periodicity) { Log::error('Periodicidade não encontrada', [ 'recurring_id' => $recurring->id, 'periodicity_id' => $recurring->hire_subscription->periodicity_id ]); continue; } // Montar Cart com validações $cart = new Cart(); $cart->addItem( $recurring->hire_subscription->subscription_id, // course_id (mapeamento correto) $recurring->hire_subscription->subscription->title, $recurring->hire_subscription->subscription_id, // plan_id $periodicity, $recurring->gross_amount, // price null, // image 0.00, // discount 0.00, // extra_amount 0, // shipping_code 0.00, // shipping_price true // subscription flag ); // Log do estado do cart antes do processamento Log::info('Estado do cart para recorrência', [ 'recurring_id' => $recurring->id, 'cart_data' => $cart->getCart(), 'gross_amount' => $cart->getGrossAmount(), 'discount_amount' => $cart->getDiscountAmount(), 'shipping_amount' => $cart->getShippingAmount(), 'calculated_price' => ($cart->getGrossAmount() - $cart->getDiscountAmount()) + $cart->getShippingAmount() ]); // CORREÇÃO: Usar boletoSubscriptionTransaction (API v5) em vez de boletoTransaction (API v4) $boleto = $this->pagarMeService->boletoSubscriptionTransaction( $cart, $recurring->subscription_hash, $recurring->user_id ); if (!$boleto) { Log::error('Falha na criação do boleto', ['recurring_id' => $recurring->id]); continue; } // Atualizar status da recorrência $recurring->status = 3; // Boleto emitido $recurring->attempts = 0; $recurring->payment_code = $boleto->getId(); $recurring->save(); // CRÍTICO: Atualizar payment_code na tabela hire_subscriptions para boleto // (mantém histórico da última transação - mesmo que ainda não paga) try { $hireSubscription = $recurring->hire_subscription; // Fallback: buscar diretamente se relacionamento não estiver carregado if (!$hireSubscription) { $hireSubscription = app('EstudioLMS\Repositories\Financial\HireSubscriptionInterface') ->findByField('subscription_hash', $recurring->subscription_hash)->first(); } if ($hireSubscription) { $hireSubscription->payment_code = $boleto->getId(); $hireSubscription->save(); Log::info('✅ Payment_code atualizado na assinatura (boleto)', [ 'subscription_id' => $hireSubscription->id, 'subscription_hash' => $recurring->subscription_hash, 'old_payment_code' => $hireSubscription->getOriginal('payment_code'), 'new_payment_code' => $boleto->getId() ]); } else { Log::error('❌ HireSubscription não encontrada para atualizar payment_code (boleto)', [ 'recurring_id' => $recurring->id, 'subscription_hash' => $recurring->subscription_hash ]); } } catch (\Exception $e) { Log::error('Erro ao atualizar payment_code na assinatura (boleto)', [ 'recurring_id' => $recurring->id, 'subscription_hash' => $recurring->subscription_hash, 'error' => $e->getMessage() ]); } // Disparar evento de notificação Event::fire(new RecurringNotification('boleto-issued', $boleto)); Log::info('Boleto de recorrência criado com sucesso', [ 'recurring_id' => $recurring->id, 'payment_code' => $boleto->getId(), 'boleto_url' => method_exists($boleto, 'getBoletoUrl') ? $boleto->getBoletoUrl() : 'N/A' ]); // Output para console $this->info("Boleto criado para recorrência ID: {$recurring->id} - Código: {$boleto->getId()}"); } catch (\Exception $e) { Log::error('Erro ao processar recorrência de boleto', [ 'recurring_id' => $recurring->id ?? 'N/A', 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); $this->error("Erro ao processar recorrência ID: " . ($recurring->id ?? 'N/A') . " - " . $e->getMessage()); // Continuar com a próxima recorrência em caso de erro continue; } } // Log final de execução $recurringCount = (is_array($recurrings) || $recurrings instanceof \Countable) ? count($recurrings) : 0; Log::useDailyFiles(storage_path() . '/logs/command.log'); Log::alert('recurring:boleto - Executado com API v5 - ' . date('Y-m-d H:i:s') . ' - Processadas: ' . $recurringCount); $this->info("Comando concluído. Processadas " . $recurringCount . " recorrências."); } }
Copyright © 2026 - UnknownSec