Inicia sesión para acceder a tu panel de facturación integrado donde podrás consultar tus comprobantes oficiales de pago, gestionar tus métodos de pago guardados de forma segura y realizar el seguimiento de tus planes de financiamiento.
Historial
Consulta tus facturas y comprobantes en un solo lugar.
Tarjetas
Actualiza o elimina tus tarjetas de crédito o débito de forma segura.
Financiamiento
Planifica y mantente al día con tus planes de pago en cuotas.
Acceder a tu Cuenta
Introduce tus credenciales para continuar.
¿Aún no tienes cuenta? Visita nuestra tienda para adquirir tu material oficial.
// Set card as default
function setDefaultCard(cardId) {
const formData = new FormData();
formData.append('action', 'lumina_set_default_card');
formData.append('card_id', cardId); fetch(window.location.href, {
method: 'POST',
body: formData
})
.catch(err => console.error('Error setting default card on server:', err)); cardsModel.forEach(c => {
c.isDefault = (c.id === cardId);
});
persistCardsData();
renderCards();
renderGlobalStats();
showToast('success', 'Método predeterminado configurado correctamente.');
} // Delete card
function deleteCard(cardId) {
const cardToDelete = cardsModel.find(c => c.id === cardId);
if (!cardToDelete) return; if (cardToDelete.isDefault && cardsModel.length > 1) {
showToast('error', 'Por seguridad, no puedes eliminar la tarjeta predeterminada. Elige otra principal primero.');
return;
} const formData = new FormData();
formData.append('action', 'lumina_delete_card');
formData.append('card_id', cardId); fetch(window.location.href, {
method: 'POST',
body: formData
})
.catch(err => console.error('Error deleting card on server:', err)); cardsModel = cardsModel.filter(c => c.id !== cardId);
persistCardsData();
renderCards();
renderGlobalStats();
showToast('info', 'Tarjeta de pago removida con éxito.');
} // Add card modal visual mechanics
function openAddCardModal() {
const modal = document.getElementById('add-card-modal');
const container = document.getElementById('modal-container-elem');
// Set query string so that Stripe/WCPay front-end scripts detect the add-payment-method context
if (window.history && window.history.replaceState) {
const separator = window.location.search ? '&' : '?';
if (window.location.search.indexOf('add-payment-method') === -1) {
window.history.replaceState(null, '', window.location.pathname + window.location.search + separator + 'add-payment-method=true' + window.location.hash);
}
} // Remove hidden and toggle visibility/opacity transitions
modal.classList.remove('opacity-0', 'pointer-events-none', 'invisible');
modal.classList.add('opacity-100', 'pointer-events-auto', 'visible');
setTimeout(() => {
container.classList.remove('opacity-0', 'scale-95');
container.classList.add('opacity-100', 'scale-100');
// Esperar a que el modal sea 100% visible y tenga dimensiones en pantalla
setTimeout(() => {
initWooCommercePaymentFields();
}, 400); // 400ms da margen a la transición de Tailwind duration-300
}, 50);
} function closeAddCardModal() {
const modal = document.getElementById('add-card-modal');
const container = document.getElementById('modal-container-elem');
// Restore query string to remove add-payment-method=true
if (window.history && window.history.replaceState) {
let cleanSearch = window.location.search
.replace(/[\?&]add-payment-method=true/, '')
.replace(/^&/, '?');
window.history.replaceState(null, '', window.location.pathname + cleanSearch + window.location.hash);
} container.classList.add('opacity-0', 'scale-95');
container.classList.remove('opacity-100', 'scale-100');
setTimeout(() => {
modal.classList.add('opacity-0', 'pointer-events-none', 'invisible');
modal.classList.remove('opacity-100', 'pointer-events-auto', 'visible');
}, 280);
} // INVOICES & HISTORY CONTROLLER LAYER
function renderInvoicesList(filterText = '') {
const listContainer = document.getElementById('invoices-container');
if (!listContainer) return; const filtered = invoicesModel.filter(inv => {
const text = filterText.toLowerCase();
return (
inv.id.toLowerCase().includes(text) ||
inv.item.toLowerCase().includes(text) ||
inv.amount.toString().includes(text)
);
}); if (filtered.length === 0) {
listContainer.innerHTML = `