From 92458e217e74b432b83801f492c6913e0eb498c7 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 7 Jul 2026 08:57:27 -0300 Subject: [PATCH] feat: enhance Telepagos webhook handling for transferencia and QR operations with improved purchase matching logic --- .../Services/TelepagosWebhookService.php | 79 ++++++++++++++----- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/app/Domains/Integration/Services/TelepagosWebhookService.php b/app/Domains/Integration/Services/TelepagosWebhookService.php index ceef23e..dc0b67d 100644 --- a/app/Domains/Integration/Services/TelepagosWebhookService.php +++ b/app/Domains/Integration/Services/TelepagosWebhookService.php @@ -3,6 +3,7 @@ namespace App\Domains\Integration\Services; use App\Domains\Purchase\Services\CheckoutService; +use App\Domains\Purchase\Models\Purchase; use App\Domains\Purchase\Models\TelepagosPayment; use App\Domains\Purchase\Models\TelepagosQr; use App\Domains\Tenant\Models\Tenant; @@ -38,33 +39,71 @@ class TelepagosWebhookService // Need to handle potential nested structures based on actual API $qrOrderId = $details['data']['qr_order_id'] ?? $details['qr_order_id'] ?? null; $amount = $details['data']['amount'] ?? $details['amount'] ?? 0; + $operationId = $details['data']['operation_id'] ?? $details['operation_id'] ?? null; - if (!$qrOrderId) { - Log::warning("Telepagos webhook: qr_order_id not found for cashin {$cashinId}"); - return; - } + $transferenciaOperationIds = [1, 3, 11]; + $qrOperationIds = [31, 37, 47]; - $telepagosQr = TelepagosQr::where('qr_order_id', $qrOrderId)->first(); + $compra = null; - if (!$telepagosQr) { - Log::warning("Telepagos webhook: QR {$qrOrderId} not found in database for cashin {$cashinId}"); - return; - } + if (in_array((int)$operationId, $transferenciaOperationIds, true)) { + $cuit = $details['data']['buyer']['cuit'] ?? $details['buyer']['cuit'] ?? null; + + if (!$cuit) { + Log::warning("Telepagos webhook: CUIT not found for Transferencia cashin {$cashinId}"); + return; + } + + // Extraer el DNI del cuit (sacando los primeros 2 y el último dígito) + $dni = substr($cuit, 2, -1); + + // Buscar la compra pendiente, con método transferencia, más reciente + $compras = Purchase::where('tenant_codigo', $tenantCodigo) + ->where('dni', $dni) + ->where('status', 'pendiente') + ->where('payment_method', 'transferencia') + ->latest() + ->get(); + + foreach ($compras as $c) { + if ($c->getTotalAmount() == $amount) { + $compra = $c; + break; + } + } + + if (!$compra) { + Log::warning("Telepagos webhook: No matching purchase found for DNI {$dni} and amount {$amount} for cashin {$cashinId}"); + return; + } + } elseif (in_array((int)$operationId, $qrOperationIds, true)) { + if (!$qrOrderId) { + Log::warning("Telepagos webhook: qr_order_id not found for QR cashin {$cashinId}"); + return; + } - $compra = $telepagosQr->compra; + $telepagosQr = TelepagosQr::where('qr_order_id', $qrOrderId)->first(); - if (!$compra) { - Log::warning("Telepagos webhook: Purchase not found for QR {$qrOrderId}"); - return; - } + if (!$telepagosQr) { + Log::warning("Telepagos webhook: QR {$qrOrderId} not found in database for cashin {$cashinId}"); + return; + } - $totalAmount = $compra->getTotalAmount(); + $compra = $telepagosQr->compra; - // Depending on precision, we might need a looser comparison, but == should work for floats here - if ($amount != $totalAmount) { - Log::warning("Telepagos webhook: Amount mismatch. Cashin amount: {$amount}, Purchase amount: {$totalAmount}"); - // In a real scenario, you might want to record a partial payment or flag it, - // but the instructions say to finalize ONLY if the amount is correct. + if (!$compra) { + Log::warning("Telepagos webhook: Purchase not found for QR {$qrOrderId}"); + return; + } + + $totalAmount = $compra->getTotalAmount(); + + if ($amount != $totalAmount) { + Log::warning("Telepagos webhook: Amount mismatch. Cashin amount: {$amount}, Purchase amount: {$totalAmount}"); + return; + } + } else { + Log::warning("Telepagos webhook: Unknown operation_id {$operationId} for cashin {$cashinId}"); return; }