Pagos SPEI
🏦 Genera referencias de transferencia bancaria para que tus clientes paguen vía SPEI
🏦
Selecciona un cliente para generar una referencia de pago SPEI
Generar Intención de Pago
Generar Intención de Pago
Historial de Intenciones de Pago por transferencia
Saldo Stripe: $0.00 MXN
Estado
Importe
Descripción
Fecha
ID
document.addEventListener('DOMContentLoaded', () => {
// 2. STRIPE SEARCH
let selectedStripeClient = null;
setupSearch('stripeSearch', 'stripeResults', 'search_stripe', async (partialClient) => {
const res = await fetch(`${window.SIIP_STRIPE_PATH || ''}?action=get_stripe_details&id=${partialClient.id}`);
const data = await res.json();
selectedStripeClient = data;
document.getElementById('stripeClientName').textContent = data.fullName;
document.getElementById('stripeClientIdDisplay').textContent = `ID: #${data.id}`;
// Saldo en CRM: usar accountBalance (crédito a favor) o accountOutstanding (adeudo)
const crmCredit = parseFloat(data.accountBalance || 0);
const crmOwed = parseFloat(data.accountOutstanding || 0);
const balanceBadge = document.getElementById('stripeBalanceBadge');
if (crmCredit > 0) {
balanceBadge.textContent = `$${crmCredit.toFixed(2)} MXN`;
balanceBadge.style.color = 'var(--success)';
} else if (crmOwed > 0) {
balanceBadge.textContent = `-$${crmOwed.toFixed(2)} MXN`;
balanceBadge.style.color = 'var(--danger)';
} else {
balanceBadge.textContent = '$0.00 MXN';
balanceBadge.style.color = 'inherit';
}
document.getElementById('stripeCustomerIdDisplay').textContent = data.stripeCustomerId || 'No disponible';
document.getElementById('stripeClabeDisplay').textContent = data.clabeInterbancaria || 'No disponible';
document.getElementById('stripeAmount').value = crmOwed > 0 ? crmOwed : '';
document.getElementById('btnVerEnCrm').href = `${store.publicUrl}/client/${data.id}`;
// Mostrar domicilio del cliente
const addrEl = document.getElementById('stripeClientAddressDisplay');
if (data.fullAddress) {
addrEl.textContent = '📍 ' + data.fullAddress;
addrEl.style.display = 'block';
} else {
addrEl.style.display = 'none';
}
document.getElementById('stripeDetailContainer').style.display = 'block';
document.getElementById('stripePlaceholder').style.display = 'none';
if (data.stripeCustomerId) loadStripeHistory(data.stripeCustomerId);
else document.getElementById('stripeHistoryContainer').style.display = 'none';
});
document.getElementById('btnCreateIntent').onclick = async () => {
if (!selectedStripeClient?.stripeCustomerId) return showToast('Error: Cliente sin Stripe ID', true);
const amt = parseFloat(document.getElementById('stripeAmount').value);
if (!amt || amt < 10) return showToast('Mínimo 10 MXN', true);
const btn=document.getElementById('btnCreateIntent');
btn.disabled=true;
btn.textContent='Procesando...' ;
const fd=new FormData();
fd.append('action', 'create_intent' );
fd.append('clientId', selectedStripeClient.id);
fd.append('amount', amt);
fd.append('stripeCustomerId', selectedStripeClient.stripeCustomerId);
fd.append('adminId', document.getElementById('stripeAdminSelect').value || store.defaultStripeAdminId);
try {
const res=await fetch(`${window.SIIP_STRIPE_PATH || '' }?`, {
method: 'POST' ,
body: fd
});
const d=await res.json();
if (d.success) showStripeResult(d);
else showToast(d.error, true);
} catch (e) {
showToast('Error de conexión', true);
}
btn.disabled=false;
btn.innerHTML=`
Generar Intención de Pago`;
};
async function loadStripeHistory(stripeCustomerId) {
const container = document.getElementById('stripeHistoryContainer');
const tbody = document.querySelector('#stripeHistoryTable tbody');
const cashBadge = document.getElementById('stripeCashBalanceBadge');
const cashText = document.getElementById('stripeCashBalanceText');
try {
container.style.display = 'block';
tbody.innerHTML = `
Cargando historial...
`;
const res = await fetch(`${window.SIIP_STRIPE_PATH || ''}?action=get_stripe_history&customerId=${stripeCustomerId}`);
const d = await res.json();
if (d.cashBalance !== undefined) {
const balanceMxn = (d.cashBalance / 100).toFixed(2);
// Solo actualizar badge del historial (saldo en caja de Stripe)
// El badge principal (#stripeBalanceBadge) muestra el saldo del CRM, no lo tocamos
cashBadge.style.display = 'flex';
cashText.textContent = `Saldo en caja Stripe: $${balanceMxn} MXN`;
}
if (!d.payments || d.payments.length === 0) {
tbody.innerHTML = `
No hay intenciones de pago recientes
`;
return;
}
tbody.innerHTML = d.payments.map(p => {
let statusColor = 'var(--text-muted)';
let statusLabel = p.status.toUpperCase();
if (p.status === 'succeeded') { statusColor = 'var(--success)'; statusLabel = 'PAGADO'; }
if (p.status === 'processing') { statusColor = 'var(--warning)'; statusLabel = 'PENDIENTE'; }
// Badge construido con concatenación para evitar falsos errores del CSS linter
const badgeHtml = '' + statusLabel + ' ';
return `
${badgeHtml}
$${p.amount.toFixed(2)}
${p.description}
${p.date}
${p.id}
`;
}).join('');
} catch (e) {
console.error(e);
tbody.innerHTML = `
Error de conexión
`;
}
}
function showStripeResult(data) {
const c = document.getElementById('stripeResultContent');
let html = `
¡Referencia Creada!
Monto: $${data.amount} MXN
`;
if (data.next_action?.display_bank_transfer_instructions) {
const instr = data.next_action.display_bank_transfer_instructions;
const spei = instr.financial_addresses[0]?.spei;
if (spei) {
html += `
Institución Bancaria
${spei.bank_name}
CLABE Interbancaria
${spei.clabe}
Realiza tu transferencia vía SPEI con estos datos. El pago se registrará automáticamente al recibirse.
`;
} else {
html += `
Se generó la intención pero no se encontraron datos de transferencia SPEI. Por favor, revisa el historial para ver si ya existe una CLABE asignada.
`;
}
} else if (data.status === 'succeeded') {
html += `
✅
Pago procesado automáticamente
El saldo disponible en la caja de Stripe cubrió el monto completo. No se requiere transferencia bancaria.
`;
} else if (data.status === 'processing') {
html += `
⏳
Pago en proceso
La transacción se está procesando. Revisa el historial en unos momentos.
`;
} else {
html += `
Estado: ${data.status || 'Desconocido'}. No se encontró información de transferencia. Por favor, revisa el historial.
`;
}
c.innerHTML = html;
document.getElementById('stripeResultModal').style.display = 'flex';
}
});