Guia de proceso
Facturación y cobros automatizados con n8n: Reduce morosidad 40%
Dificultad: Avanzado
Persona: Consultor
Ahorro estimado: 15 horas/mes
Escenario: Un consultor pierde 15 horas/mes gestionando facturas y tiene 20% de morosidad
Guia de proceso
Dificultad: Avanzado
Persona: Consultor
Ahorro estimado: 15 horas/mes
Escenario: Un consultor pierde 15 horas/mes gestionando facturas y tiene 20% de morosidad
Paso 1 de 3
Define los campos que activan tu automatizacion.
Paso 2 de 3
Conecta triggers, enrichment y asignacion de tareas.
Paso 3 de 3
Entrega mensaje al cliente y crea su ficha comercial.
CRM español con integración nativa de WhatsApp y automatización para solopreneurs.
Precio: Desde 49 EUR/mes
Analisis de n8n para crear flujos de negocio con control tecnico y buen coste.
Precio: Desde 20 EUR/mes
Un flujo documentado, medible y conectado con herramientas que puedas mantener sin depender de memoria manual.
Como consultor o solopreneur, probablemente enfrentas:
Esta guía te enseñará a automatizar todo el ciclo de facturación con n8n + Stripe + Clientify.
Fecha de facturación → n8n detecta → Crea factura → Envía email → Stripe procesa → WhatsApp confirma → Recordatorios automáticos
// Schedule trigger para día 1 de cada mes a las 9:00
const monthlyBilling = {
schedule: {
cron: '0 9 1 * *', // Día 1 de cada mes a las 9:00
timezone: 'Europe/Madrid'
}
};
// Función para obtener clientes activos
const getActiveClients = async () => {
const clients = await clientifyAPI.getContacts({
tags: ['cliente-activo'],
customFields: ['plan-precio', 'frecuencia-facturacion', 'metodo-pago']
});
return clients.filter(client => {
return client.customFields['frecuencia-facturacion'] === 'mensual' &&
client.customFields['metodo-pago'] === 'stripe';
});
};
const activeClients = await getActiveClients();
// Crear factura para cada cliente
const createInvoice = async (client) => {
const invoiceData = {
customer: client.stripeCustomerId,
currency: 'eur',
description: `Servicios de consultoría - ${new Date().toLocaleDateString('es-ES', { month: 'long', year: 'numeric' })}`,
line_items: [{
quantity: 1,
price_data: {
currency: 'eur',
unit_amount: client.customFields['plan-precio'] * 100, // Convertir a centavos
product_data: {
name: 'Servicios de consultoría mensual',
description: client.serviceDescription
}
}
}],
collection_method: 'send_invoice',
days_until_due: 30,
metadata: {
client_id: client.id,
client_name: client.name,
billing_period: `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`
}
};
return await stripeAPI.invoices.create(invoiceData);
};
const sendInvoiceEmail = async (invoice, client) => {
const emailTemplate = {
to: client.email,
subject: `Factura ${invoice.number} - ${client.companyName}`,
template: 'invoice-sent',
variables: {
clientName: client.name,
invoiceNumber: invoice.number,
invoiceAmount: formatCurrency(invoice.total / 100),
dueDate: new Date(invoice.due_date).toLocaleDateString('es-ES'),
invoiceLink: invoice.hosted_invoice_url,
paymentLink: invoice.payment_url
}
};
await emailService.send(emailTemplate);
};
const sendWhatsAppNotification = async (invoice, client) => {
const whatsappMessage = {
to: client.phone,
template: 'invoice_notification',
language: 'es',
components: [{
type: 'body',
parameters: [
{ type: 'text', text: client.name.split(' ')[0] },
{ type: 'text', text: invoice.number },
{ type: 'text', text: formatCurrency(invoice.total / 100) },
{ type: 'text', text: new Date(invoice.due_date).toLocaleDateString('es-ES') }
]
}]
};
await clientifyAPI.sendWhatsApp(whatsappMessage);
};
// Configurar recordatorios automáticos
const setupReminders = async (invoice, client) => {
const reminders = [
{ days: 7, channel: 'email', template: 'reminder-7-days' },
{ days: 3, channel: 'whatsapp', template: 'reminder-3-days' },
{ days: 1, channel: 'both', template: 'reminder-1-day' },
{ days: 0, channel: 'both', template: 'due-today' },
{ days: -3, channel: 'email', template: 'overdue-3-days' },
{ days: -7, channel: 'email', template: 'overdue-1-week' },
{ days: -14, channel: 'email', template: 'overdue-2-weeks' }
];
reminders.forEach(reminder => {
const reminderDate = new Date(invoice.due_date);
reminderDate.setDate(reminderDate.getDate() + reminder.days);
// Programar recordatorio
n8nAPI.scheduleWorkflow({
workflowId: 'payment-reminder',
triggerDate: reminderDate,
data: {
invoiceId: invoice.id,
clientId: client.id,
channel: reminder.channel,
template: reminder.template
}
});
});
};
// Webhook para eventos de Stripe
const handleStripeWebhook = async (event) => {
switch (event.type) {
case 'invoice.payment_succeeded':
await handlePaymentSucceeded(event.data.object);
break;
case 'invoice.payment_failed':
await handlePaymentFailed(event.data.object);
break;
case 'invoice.finalized':
await handleInvoiceFinalized(event.data.object);
break;
}
};
const handlePaymentSucceeded = async (invoice) => {
// Actualizar estado en Clientify
await clientifyAPI.updateContact(invoice.metadata.client_id, {
tags: ['factura-pagada'],
customFields: {
'ultimo-pago': new Date().toISOString(),
'estado-facturacion': 'al-dia'
}
});
// Enviar confirmación
await sendPaymentConfirmation(invoice);
// Registrar en Google Sheets
await sheetsAPI.appendRow({
spreadsheetId: 'FINANCIAL_TRACKING',
range: 'Pagos!A:G',
values: [
invoice.id,
invoice.metadata.client_name,
invoice.total / 100,
new Date().toISOString(),
'stripe',
'completed',
invoice.metadata.billing_period
]
});
};
// Métricas financieras clave
const getFinancialMetrics = async () => {
const currentMonth = new Date().toISOString().slice(0, 7);
const invoices = await stripeAPI.invoices.list({
created: { gte: `${currentMonth}-01` },
limit: 100
});
const metrics = {
totalInvoiced: invoices.data.reduce((sum, inv) => sum + inv.total, 0) / 100,
totalPaid: invoices.data
.filter(inv => inv.status === 'paid')
.reduce((sum, inv) => sum + inv.total, 0) / 100,
totalPending: invoices.data
.filter(inv => inv.status === 'open')
.reduce((sum, inv) => sum + inv.total, 0) / 100,
totalOverdue: invoices.data
.filter(inv => inv.status === 'uncollectible')
.reduce((sum, inv) => sum + inv.total, 0) / 100,
paymentRate: (invoices.data.filter(inv => inv.status === 'paid').length / invoices.data.length) * 100,
averagePaymentTime: calculateAveragePaymentTime(invoices.data)
};
return metrics;
};
const createPaymentPlan = async (client, totalAmount, installments) => {
const installmentAmount = Math.round(totalAmount / installments);
for (let i = 0; i < installments; i++) {
const dueDate = new Date();
dueDate.setMonth(dueDate.getMonth() + i);
await stripeAPI.invoices.create({
customer: client.stripeCustomerId,
currency: 'eur',
description: `Plan de pago - Cuota ${i + 1}/${installments}`,
line_items: [{
quantity: 1,
price_data: {
currency: 'eur',
unit_amount: installmentAmount * 100,
product_data: {
name: `Plan de pago - Cuota ${i + 1}/${installments}`
}
}
}],
due_date: Math.floor(dueDate.getTime() / 1000),
metadata: {
payment_plan_id: `plan-${client.id}-${Date.now()}`,
installment_number: i + 1,
total_installments: installments
}
});
}
};
const handleWriteOff = async (invoice, reason) => {
// Marcar factura como no cobrable
await stripeAPI.invoices.update(invoice.id, {
status: 'uncollectible',
metadata: {
write_off_reason: reason,
write_off_date: new Date().toISOString()
}
});
// Actualizar cliente
await clientifyAPI.updateContact(invoice.metadata.client_id, {
tags: ['factura-cancelada'],
customFields: {
'estado-facturacion': 'con-morosidad',
'ultima-cancelacion': new Date().toISOString()
}
});
// Notificar internamente
await slackAPI.postMessage({
channel: '#finanzas',
text: `⚠️ Factura ${invoice.number} cancelada por ${reason}. Monto: ${formatCurrency(invoice.total / 100)}`
});
};
✅ Reducción 40% de morosidad con recordatorios automáticos
✅ Ahorro 15+ horas mensuales en tareas administrativas
✅ Cash flow predecible con facturación consistente
✅ Mejor experiencia cliente con comunicación proactiva
✅ Datos en tiempo real para toma de decisiones
Con este sistema, transformarás la facturación de una carga manual a un proceso automatizado que mejora tu cash flow y libera tiempo para actividades de alto valor.