-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #73 from Crudzaso/develop
Develop
- Loading branch information
Showing
15 changed files
with
643 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use Carbon\Carbon; | ||
use Illuminate\Http\Request; | ||
use Modules\Payment\Models\Payment; | ||
use Modules\Raffle\Models\Raffle; | ||
use Modules\Ticket\Models\Ticket; | ||
|
||
class PaymentController extends Controller | ||
{ | ||
public function create(Request $request) | ||
{ | ||
$raffle = Raffle::find($request->raffle_id); | ||
$user = auth()->user(); | ||
|
||
// Datos del pago | ||
$amount = $raffle->ticket_price; | ||
$nequiNumber = config('services.nequi.number'); // Número de Nequi de la plataforma | ||
|
||
// Generar enlace de pago | ||
$paymentLink = "https://recarga.nequi.com/$nequiNumber?amount=$amount"; | ||
|
||
return response()->json([ | ||
'paymentLink' => $paymentLink, | ||
'qrCode' => "https://api.qrserver.com/v1/create-qr-code/?data=$paymentLink", | ||
]); | ||
} | ||
|
||
public function store(Request $request) | ||
{ | ||
$user = auth()->user(); | ||
$raffle = Raffle::find($request->raffle_id); | ||
|
||
// Crear ticket | ||
$ticket = Ticket::create([ | ||
'raffle_id' => $raffle->id, | ||
'user_id' => $user->id, | ||
'ticket_number' => $request->ticket_number, | ||
'purchase_date' => Carbon::now(), | ||
'verification_code' => uniqid(), | ||
]); | ||
|
||
// Registrar pago | ||
$payment = Payment::create([ | ||
'user_id' => $user->id, | ||
'raffle_id' => $raffle->id, | ||
'amount' => $raffle->ticket_price, | ||
'payment_method' => 'Nequi', | ||
'payment_date' => Carbon::now(), | ||
]); | ||
|
||
return response()->json([ | ||
'message' => 'Pago registrado exitosamente', | ||
'ticket' => $ticket, | ||
'payment' => $payment, | ||
]); | ||
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use Illuminate\Http\Request; | ||
use App\Services\ImapService; | ||
|
||
class PaymentVerificationController extends Controller | ||
{ | ||
protected $imapService; | ||
|
||
public function __construct(ImapService $imapService) | ||
{ | ||
$this->imapService = $imapService; | ||
} | ||
|
||
public function verifyPayment(Request $request) | ||
{ | ||
$numeroComprobante = $request->input('referenceNumber'); | ||
$monto = $request->input('monto'); | ||
|
||
$result = $this->imapService->searchEmailByComprobante($numeroComprobante, $monto); | ||
|
||
if ($result['status'] === 'success') { | ||
return response()->json(['status' => 'success', 'message' => $result['message']]); | ||
} | ||
|
||
return response()->json(['status' => 'error', 'message' => $result['message']], 400); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
<?php | ||
|
||
namespace App\Services; | ||
|
||
use Illuminate\Support\Facades\Log; | ||
use PhpImap\Mailbox; | ||
use PhpImap\Exceptions\ConnectionException; | ||
use Carbon\Carbon; | ||
|
||
class ImapService | ||
{ | ||
protected $mailbox; | ||
|
||
public function __construct() | ||
{ | ||
// Configuración del mailbox | ||
$this->mailbox = new Mailbox( | ||
'{' . env('IMAP_HOST') . ':' . env('IMAP_PORT') . '/' . env('IMAP_ENCRYPTION') . '}INBOX', | ||
env('IMAP_USERNAME'), | ||
env('IMAP_PASSWORD'), | ||
null, | ||
'UTF-8', | ||
[ | ||
'imap_timeout' => 10, // Timeout en segundos | ||
'imap_timeout_read' => 10 | ||
] | ||
); | ||
} | ||
|
||
/** | ||
* Método para buscar el email por número de comprobante y monto. | ||
*/ | ||
public function searchEmailByComprobante($numeroComprobante, $montoTicket) | ||
{ | ||
try { | ||
Log::info("Buscando comprobante ingresado: {$numeroComprobante}"); | ||
Log::info("Monto del ticket ingresado: {$montoTicket}"); | ||
|
||
// Fecha y hora actual menos 5 minutos | ||
$sinceDateTime = Carbon::now()->subMinutes(5); | ||
Log::info("Buscando correos desde: {$sinceDateTime->format('d-M-Y H:i:s')}"); | ||
|
||
// Buscar correos desde la fecha ajustada | ||
$sinceDate = Carbon::now()->subMinutes(2)->format('d-M-Y'); | ||
$mailsIds = $this->mailbox->searchMailbox("SINCE \"$sinceDate\""); | ||
Log::info("Cantidad de correos encontrados: " . count($mailsIds)); | ||
|
||
if (!$mailsIds) { | ||
Log::warning("No se encontraron correos."); | ||
return ['status' => 'error', 'message' => 'No se encontraron correos recientes.']; | ||
} | ||
|
||
// Formatear el monto del ticket para comparación | ||
$formattedMontoTicket = number_format($montoTicket, 2, '.', ''); | ||
Log::info("Monto del ticket formateado: {$formattedMontoTicket}"); | ||
|
||
foreach ($mailsIds as $mailId) { | ||
$mail = $this->mailbox->getMail($mailId); | ||
|
||
// Verificar si el correo fue recibido en los últimos 5 minutos | ||
$mailDate = Carbon::parse($mail->date); | ||
Log::info("Fecha del correo: {$mailDate}"); | ||
if ($mailDate->lessThan($sinceDateTime)) { | ||
Log::info("Correo ignorado por estar fuera del rango de tiempo."); | ||
continue; | ||
} | ||
|
||
$textContent = trim($mail->textPlain); | ||
Log::info("Contenido del correo: {$textContent}"); | ||
|
||
// Extraer el número de comprobante y limpiar | ||
$comprobantePos = strpos($textContent, 'Ref:'); | ||
if ($comprobantePos === false) { | ||
Log::info("Referencia no encontrada en el correo."); | ||
continue; | ||
} | ||
$comprobante = trim(substr($textContent, $comprobantePos + 5, 10)); | ||
$comprobante = rtrim($comprobante, "."); | ||
$comprobante = mb_strtolower($comprobante, 'UTF-8'); | ||
Log::info("Comprobante extraído: {$comprobante}"); | ||
|
||
// Normalizar el comprobante ingresado | ||
$numeroComprobante = mb_strtolower(trim($numeroComprobante), 'UTF-8'); | ||
Log::info("Comprobante ingresado: {$numeroComprobante}"); | ||
|
||
// Extraer el monto del correo | ||
$montoPos = strpos($textContent, 'por $'); | ||
if ($montoPos === false) { | ||
Log::info("Monto no encontrado en el correo."); | ||
continue; | ||
} | ||
$montoEndPos = strpos($textContent, ' a ', $montoPos); | ||
$montoEncontrado = trim(substr($textContent, $montoPos + 5, $montoEndPos - $montoPos - 5)); | ||
$montoEncontrado = str_replace(['.', ','], ['', '.'], $montoEncontrado); | ||
$montoEncontrado = number_format((float)$montoEncontrado, 2, '.', ''); | ||
Log::info("Monto encontrado (normalizado): {$montoEncontrado}"); | ||
|
||
// Validar comprobante | ||
if ($comprobante !== $numeroComprobante) { | ||
Log::warning("El comprobante no coincide: {$comprobante} !== {$numeroComprobante}"); | ||
return ['status' => 'error', 'message' => 'Comprobante incorrecto.']; | ||
} | ||
|
||
// Validar monto encontrado con el monto del ticket | ||
if ($montoEncontrado !== $formattedMontoTicket) { | ||
Log::warning("El monto encontrado no coincide con el precio del ticket: {$montoEncontrado} !== {$formattedMontoTicket}"); | ||
return ['status' => 'error', 'message' => 'El monto no coincide con el precio del ticket.']; | ||
} | ||
|
||
Log::info("Pago verificado con éxito."); | ||
return ['status' => 'success', 'message' => 'Pago verificado con éxito.']; | ||
} | ||
|
||
Log::info("No se encontró el comprobante o el monto no coincide."); | ||
return ['status' => 'error', 'message' => 'No se encontró el comprobante o el monto no coincide.']; | ||
} catch (ConnectionException $e) { | ||
Log::error("Error al conectar con IMAP: " . $e->getMessage()); | ||
return ['status' => 'error', 'message' => 'Error al conectar con IMAP.']; | ||
} catch (\Exception $e) { | ||
Log::error("Error al buscar el comprobante: " . $e->getMessage()); | ||
return ['status' => 'error', 'message' => 'Error al buscar el comprobante.']; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,5 +56,9 @@ | |
'webhook_url' => env('DISCORD_WEBHOOK_URL'), | ||
], | ||
|
||
'nequi' => [ | ||
'number' => env('VITE_NEQUI_NUMBER'), | ||
], | ||
|
||
|
||
]; |
Oops, something went wrong.