Falta agrupar por personas encargadas de comunidad el corte
This commit is contained in:
parent
12bb5c04a4
commit
c989d180fa
1403
data/plugin.log
1403
data/plugin.log
File diff suppressed because it is too large
Load Diff
108
public.php
108
public.php
@ -181,6 +181,25 @@ if (isset($_GET['action'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_GET['action'] === 'get_oxxo_history') {
|
||||||
|
if (ob_get_level()) ob_end_clean();
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$stripeCustomerId = $_GET['stripeCustomerId'] ?? '';
|
||||||
|
if (!$stripeCustomerId) {
|
||||||
|
echo json_encode(['error' => 'Missing stripeCustomerId']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$history = $stripeService->getLastOxxoPayments($stripeCustomerId);
|
||||||
|
echo json_encode(['history' => $history]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($_GET['action'] === 'search_stripe') {
|
if ($_GET['action'] === 'search_stripe') {
|
||||||
$q = $_GET['q'] ?? '';
|
$q = $_GET['q'] ?? '';
|
||||||
echo json_encode($stripeService->searchClients($q));
|
echo json_encode($stripeService->searchClients($q));
|
||||||
@ -1375,6 +1394,33 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- OXXO HISTORY CONTAINER -->
|
||||||
|
<div id="oxxoHistoryContainer" style="display: none; margin-top: 2rem;">
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="section-title" style="margin-bottom: 1rem;">Historial de Fichas OXXO (Últimas 5)</h3>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover" id="oxxoHistoryTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID Pago</th>
|
||||||
|
<th>Fecha</th>
|
||||||
|
<th>Monto</th>
|
||||||
|
<th>Ref. OXXO</th>
|
||||||
|
<th>Estatus</th>
|
||||||
|
<th>Ficha</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" style="text-align:center">Seleccione un cliente...</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1768,6 +1814,60 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
|
|||||||
document.getElementById('stripeResultModal').style.display = 'flex';
|
document.getElementById('stripeResultModal').style.display = 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadOxxoHistory(stripeCustomerId) {
|
||||||
|
const tbody = document.querySelector('#oxxoHistoryTable tbody');
|
||||||
|
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center">Cargando historial...</td></tr>';
|
||||||
|
try {
|
||||||
|
const res = await fetch(`?action=get_oxxo_history&stripeCustomerId=${stripeCustomerId}`);
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (data.error) {
|
||||||
|
tbody.innerHTML = `<tr><td colspan="6" style="text-align:center;color:var(--danger)">Error: ${data.error}</td></tr>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.history || data.history.length === 0) {
|
||||||
|
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center">No hay fichas recientes</td></tr>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML = data.history.map(p => {
|
||||||
|
let statusBadge = '';
|
||||||
|
switch (p.status) {
|
||||||
|
case 'succeeded':
|
||||||
|
statusBadge = '<span class="badge badge-success">Pagado</span>';
|
||||||
|
break;
|
||||||
|
case 'requires_action':
|
||||||
|
statusBadge = '<span class="badge badge-warning">Pendiente</span>';
|
||||||
|
break;
|
||||||
|
case 'canceled':
|
||||||
|
statusBadge = '<span class="badge badge-danger">Cancelado</span>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusBadge = `<span class="badge badge-secondary">${p.status}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = new Date(p.created * 1000).toLocaleString();
|
||||||
|
const voucherBtn = p.voucherUrl ?
|
||||||
|
`<a href="${p.voucherUrl}" target="_blank" class="btn btn-sm btn-outline-primary" style="padding: 2px 8px; font-size: 0.8rem;">Ver Ficha</a>` :
|
||||||
|
'-';
|
||||||
|
|
||||||
|
return `<tr>
|
||||||
|
<td><small style="font-family:monospace">${p.id.slice(-8)}</small></td>
|
||||||
|
<td>${date}</td>
|
||||||
|
<td>$${p.amount.toFixed(2)} ${p.currency}</td>
|
||||||
|
<td style="font-family:monospace">${p.oxxoNumber}</td>
|
||||||
|
<td>${statusBadge}</td>
|
||||||
|
<td>${voucherBtn}</td>
|
||||||
|
</tr>`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center;color:var(--danger)">Error de conexión</td></tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 3. OXXO SEARCH
|
// 3. OXXO SEARCH
|
||||||
let selectedOxxoClient = null;
|
let selectedOxxoClient = null;
|
||||||
setupSearch('oxxoSearch', 'oxxoResults', 'search_stripe', async (partialClient) => {
|
setupSearch('oxxoSearch', 'oxxoResults', 'search_stripe', async (partialClient) => {
|
||||||
@ -1788,6 +1888,14 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
|
|||||||
document.getElementById('oxxoResult').innerHTML = '';
|
document.getElementById('oxxoResult').innerHTML = '';
|
||||||
|
|
||||||
document.getElementById('oxxoDetailContainer').style.display = 'block';
|
document.getElementById('oxxoDetailContainer').style.display = 'block';
|
||||||
|
|
||||||
|
// Load History
|
||||||
|
if (data.stripeCustomerId) {
|
||||||
|
document.getElementById('oxxoHistoryContainer').style.display = 'block';
|
||||||
|
loadOxxoHistory(data.stripeCustomerId);
|
||||||
|
} else {
|
||||||
|
document.getElementById('oxxoHistoryContainer').style.display = 'none';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btnCreateOxxoIntent').onclick = async () => {
|
document.getElementById('btnCreateOxxoIntent').onclick = async () => {
|
||||||
|
|||||||
@ -168,6 +168,55 @@ class PaymentIntentService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLastOxxoPayments($stripeCustomerId, $limit = 5)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Fetch a bit more to allow for filtering
|
||||||
|
$collection = $this->stripeClient->paymentIntents->all([
|
||||||
|
'customer' => $stripeCustomerId,
|
||||||
|
'limit' => 20,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($collection->data as $payment) {
|
||||||
|
// Check if it's an OXXO payment
|
||||||
|
$isOxxo = false;
|
||||||
|
if (isset($payment->payment_method_types) && in_array('oxxo', $payment->payment_method_types)) {
|
||||||
|
$isOxxo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isOxxo) {
|
||||||
|
$oxxoNumber = $payment->next_action->oxxo_display_details->number ?? '-';
|
||||||
|
$pdfUrl = $payment->next_action->oxxo_display_details->hosted_voucher_url ?? null;
|
||||||
|
|
||||||
|
// Fallback for Succeeded payments (where next_action might be null)
|
||||||
|
if ($oxxoNumber === '-' && !empty($payment->charges->data)) {
|
||||||
|
$charge = $payment->charges->data[0];
|
||||||
|
if (isset($charge->payment_method_details->oxxo->number)) {
|
||||||
|
$oxxoNumber = $charge->payment_method_details->oxxo->number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = [
|
||||||
|
'id' => $payment->id,
|
||||||
|
'amount' => $payment->amount / 100,
|
||||||
|
'currency' => strtoupper($payment->currency),
|
||||||
|
'status' => $payment->status,
|
||||||
|
'created' => $payment->created,
|
||||||
|
'oxxoNumber' => $oxxoNumber, // Reference Number
|
||||||
|
'voucherUrl' => $pdfUrl
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($result) >= $limit) break;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->log("Error fetching OXXO payments: " . $e->getMessage());
|
||||||
|
return ['error' => $e->getMessage()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getCustomerCashBalance($stripeCustomerId)
|
public function getCustomerCashBalance($stripeCustomerId)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user