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

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'; } });