- Ahora la versión visual coincide correctamente con la versión actual definida en el `manifest.json` (4.6.0).
129 lines
4.1 KiB
PHP
129 lines
4.1 KiB
PHP
<?php
|
|
$initialDir = getcwd();
|
|
chdir(__DIR__ . '/../');
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
use Ubnt\UcrmPluginSdk\Service\PluginConfigManager;
|
|
use Stripe\StripeClient;
|
|
use Stripe\Exception\ApiErrorException;
|
|
|
|
function logMessage($message)
|
|
{
|
|
$logFile = __DIR__ . '/audit_incomplete_pi.log';
|
|
$timestamp = date('Y-m-d H:i:s');
|
|
file_put_contents($logFile, "[$timestamp] $message\n", FILE_APPEND);
|
|
if (php_sapi_name() === 'cli') {
|
|
fwrite(STDERR, "[$timestamp] $message\n");
|
|
}
|
|
}
|
|
|
|
// -- Initialization --
|
|
$config = PluginConfigManager::create()->loadConfig();
|
|
$stripeApiKey = $config['tokenstripe'] ?? '';
|
|
|
|
if (empty($stripeApiKey)) {
|
|
logMessage("Error: Stripe Secret Key is missing in plugin configuration.");
|
|
exit(1);
|
|
}
|
|
|
|
$stripeClient = new StripeClient($stripeApiKey);
|
|
|
|
logMessage("Iniciando auditoría de Intenciones de Pago (SPEI/Transferencia) incompletas...");
|
|
|
|
$hasMore = true;
|
|
$nextPage = null;
|
|
$totalIncomplete = 0;
|
|
$customersWithIncomplete = [];
|
|
$pisToReview = [];
|
|
|
|
while ($hasMore) {
|
|
try {
|
|
$queryParams = [
|
|
'query' => 'status:"requires_payment_method" OR status:"requires_action"',
|
|
'limit' => 100
|
|
];
|
|
|
|
if ($nextPage) {
|
|
$queryParams['page'] = $nextPage;
|
|
}
|
|
|
|
$results = $stripeClient->paymentIntents->search($queryParams);
|
|
|
|
foreach ($results->data as $pi) {
|
|
// Filtrar y proteger explícitamente los pagos OXXO
|
|
$paymentMethodTypes = $pi->payment_method_types ?? [];
|
|
$isOxxo = in_array('oxxo', $paymentMethodTypes);
|
|
|
|
// Si es un pago de OXXO vigente (o en general para estar seguros), lo saltamos
|
|
if ($isOxxo) {
|
|
continue;
|
|
}
|
|
|
|
// Filtrar solo las que son de Transferencia Bancaria real (SPEI)
|
|
$isBankTransfer = in_array('customer_balance', $paymentMethodTypes);
|
|
$tipoPago = $pi->metadata['tipoPago'] ?? '';
|
|
|
|
// Garantizar que solo tocamos las transferencias bancarias
|
|
if ($isBankTransfer || ($tipoPago === 'Transferencia Bancaria' && !$isOxxo)) {
|
|
$totalIncomplete++;
|
|
$customerId = $pi->customer;
|
|
|
|
if (!isset($customersWithIncomplete[$customerId])) {
|
|
$customersWithIncomplete[$customerId] = 0;
|
|
}
|
|
$customersWithIncomplete[$customerId]++;
|
|
|
|
$pisToReview[] = [
|
|
'id' => $pi->id,
|
|
'customer' => $customerId,
|
|
'amount' => $pi->amount / 100,
|
|
'currency' => $pi->currency,
|
|
'status' => $pi->status,
|
|
'created' => date('Y-m-d H:i:s', $pi->created)
|
|
];
|
|
}
|
|
}
|
|
|
|
$hasMore = $results->has_more;
|
|
$nextPage = $results->next_page;
|
|
|
|
// Pausa breve para evitar Rate Limits de Stripe
|
|
usleep(500000); // 0.5s
|
|
|
|
} catch (ApiErrorException $e) {
|
|
logMessage("Error en la API de Stripe: " . $e->getMessage());
|
|
break;
|
|
} catch (\Exception $e) {
|
|
logMessage("Error inesperado: " . $e->getMessage());
|
|
break;
|
|
}
|
|
}
|
|
|
|
logMessage("=== RESULTADOS DE LA AUDITORÍA ===");
|
|
logMessage("Total de Intenciones de Pago Incompletas (SPEI): " . $totalIncomplete);
|
|
logMessage("Total de Clientes afectados: " . count($customersWithIncomplete));
|
|
|
|
$csvFile = __DIR__ . '/audit_incomplete_pi_results.csv';
|
|
$fp = fopen($csvFile, 'w');
|
|
if ($fp) {
|
|
fputcsv($fp, ['PaymentIntent_ID', 'Stripe_Customer', 'Amount', 'Currency', 'Status', 'Created_At']);
|
|
foreach ($pisToReview as $pi) {
|
|
fputcsv($fp, [
|
|
$pi['id'],
|
|
$pi['customer'],
|
|
$pi['amount'],
|
|
$pi['currency'],
|
|
$pi['status'],
|
|
$pi['created']
|
|
]);
|
|
}
|
|
fclose($fp);
|
|
logMessage("Se ha generado un archivo CSV con el detalle completo en: $csvFile");
|
|
}
|
|
|
|
echo "\nResumen:\n";
|
|
echo "1. Intenciones huérfanas encontradas: $totalIncomplete\n";
|
|
echo "2. Clientes afectados: " . count($customersWithIncomplete) . "\n";
|
|
echo "-> Verifica el log y el archivo CSV para los detalles.\n";
|