Cobranza y suscripciones
Abonos por organización con pago por MercadoPago o transferencia bancaria, avisos automáticos de vencimiento y bloqueo escalado cuando hay deuda.
¿Qué hace?
Cada organización tiene una suscripción con un plan y un próximo vencimiento. El sistema:
- Genera facturas automáticamente cuando se acerca el vencimiento.
- Avisa con banners y emails al Titular cuando una factura está por vencer, vencida, o cuando el servicio queda suspendido.
- Bloquea operaciones de escritura cuando una factura excede el período de gracia.
- Permite pagar online por MercadoPago o subir un comprobante de transferencia bancaria.
- Emite un recibo PDF interno por cada pago confirmado.
No es factura electrónica AFIP. Los recibos del sistema son comprobantes internos. La facturación A/B/C se gestiona por fuera (ej. sistema contable, LibreFactura).
Planes y suscripciones
| Concepto | Detalle |
|---|---|
| Plan | Catálogo global con nombre, precio mensual y precio anual. Cada organización tiene asignado un plan. |
| Suscripción | Vincula la organización con el plan. Puede sobrescribir precio y/o cuotas individualmente (útil para precios negociados). |
| Período | Mensual o Anual. Configurable por suscripción. |
| Cuotas (opcional) | Por plan se pueden definir topes de usuarios, puestos, personas, registros por día o por mes. Por defecto las cuotas son informativas — para que actúen como restricción se activa enforce_quotas en el plan o se sobrescribe en la suscripción. |
Estados del servicio
El estado se calcula automáticamente a partir del vencimiento de la próxima factura:
| Estado | Cuándo | Qué pasa |
|---|---|---|
| Al día | Sin factura pendiente. | Sin banner. Operación normal. |
| Por vencer | Factura pendiente, vence en los próximos N días (configurable, por defecto 7). | Banner amarillo "Tu suscripción vence en X días". Operación normal. |
| Vencida | Factura pendiente, vencida hace menos del período de gracia (configurable, por defecto 3 días). | Banner rojo "Suscripción vencida hace X días". Operación normal pero con urgencia visible. |
| Suspendida | Vencida hace más del período de gracia. | Banner rojo + bloqueo. Las operaciones de escritura quedan deshabilitadas para toda la organización. Sólo el Titular puede ingresar a la pantalla de cobranza para regularizar. |
Los umbrales son configurables globalmente vía variables de entorno.
Avisos automáticos
Una vez al día (cron / tarea programada), el sistema:
- Genera la próxima factura si entra en la ventana de aviso.
- Manda email al Titular para cada cambio de estado: factura creada, próxima a vencer, vencida, suspendida, pago confirmado.
- Actualiza el estado denormalizado de la suscripción (Activa / Vencida / Suspendida) para que el panel de administración lo refleje.
Cada notificación se manda una sola vez por estado — la idempotencia se garantiza a nivel de base de datos.
Recordatorios de mora (dunning). Además del aviso único "factura vencida", se pueden configurar recordatorios extra en días puntuales de atraso vía BILLING_OVERDUE_REMINDER_DAYS (p.ej. [3,5,7]). Cada día configurado dispara un recordatorio como máximo una vez (idempotente por día). Vacío (default) = sin recordatorios extra.
Pagar por MercadoPago
El Titular ve la factura pendiente en /entry/billing/ y clickea "Pagar con MercadoPago":
- El sistema crea una preferencia de pago en MercadoPago.
- Redirige al checkout hospedado de MercadoPago.
- El Titular paga con tarjeta, dinero en cuenta, RapiPago, Pago Fácil, etc.
- MercadoPago notifica al sistema vía webhook con firma HMAC validada.
- El sistema re-consulta a la API de MercadoPago como defensa adicional (nunca confía sólo en el payload del webhook).
- Si el pago se aprobó: la factura pasa a Pagada, el próximo vencimiento avanza un período, llega el recibo PDF por email.
Pago Fácil / Rapipago (efectivo) ya vienen incluidos. La preferencia no restringe payment_methods, así que MercadoPago ofrece todo el menú del comprador, incluidos los cupones de pago en efectivo. Estos son asíncronos: MercadoPago avisa pending cuando se genera el cupón y approved recién cuando el comprador paga en la sucursal (horas o días después). El mismo webhook maneja ambas fases sobre la misma fila de pago — no hay que hacer nada especial. Para habilitarlos basta activarlos en la cuenta MercadoPago del cobrador; no requiere código.
Limpieza de checkouts abandonados. Si el Titular clickea "Pagar" pero no completa el checkout, la fila PENDING queda sin
mp_payment_id. La tarea diaria la marca como Rechazada trasBILLING_MP_PENDING_EXPIRY_HOURS(24 h por defecto). Los cupones en efectivo sí tienenmp_payment_idy nunca se expiran por este mecanismo. Volver a clickear "Pagar" reutiliza la fila pendiente en vez de acumular filas nuevas.
Pagar por transferencia
Alternativa cuando MercadoPago no aplica (montos grandes, costumbre del cliente):
- El Titular ve los datos bancarios (CBU, alias, titular) en
/entry/billing/invoices/<id>/pay/transfer/. - Transfiere desde su banco y sube el comprobante (JPG, PNG, WEBP o PDF, máximo 5 MB).
- Opcionalmente agrega un número de referencia y notas.
- El administrador de plataforma recibe un email con un link directo al pago en
/admin/billing/payment/<id>/change/. - El administrador abre el pago en el Django admin, revisa el archivo adjunto y cambia el estado de Pendiente a Confirmado (o Rechazado) — la transición dispara automáticamente: factura Pagada, próximo vencimiento avanzado, email de confirmación al Titular con recibo PDF adjunto.
Recibos PDF
Por cada pago confirmado el sistema genera un comprobante en PDF (A4) descargable desde el historial de facturas. Incluye:
- Número interno del recibo y de la factura.
- Período facturado, vencimiento, monto.
- Método de pago y referencia (ID MercadoPago o número de transferencia).
- Aclaración explícita de que no es factura electrónica AFIP.
Quién hace qué
| Acción | Quién |
|---|---|
| Crea planes del catálogo | Administrador de plataforma (is_staff) |
| Asigna plan a la organización | Administrador de plataforma |
| Configura cuotas y enforcement | Administrador de plataforma |
| Ve banners de estado | Cualquier usuario de la organización |
| Inicia pagos (MercadoPago o transferencia) | Titular únicamente |
| Aprueba/rechaza transferencias | Administrador de plataforma (vía /admin/billing/payment/) |
| Descarga recibos PDF | Cualquier usuario de la organización (sólo de su propia org) |
Los Supervisores y Operadores ven los banners de estado y pueden descargar recibos del historial, pero no pueden iniciar pagos. Esa responsabilidad queda atada al rol Titular.
Checklist de credenciales para producción
Set mínimo de variables de entorno para cobrar en producción:
| Variable | Para qué | Obligatoria |
|---|---|---|
MERCADOPAGO_ACCESS_TOKEN |
Crear preferencias + consultar pagos | Sí (para MP) |
MERCADOPAGO_PUBLIC_KEY |
Checkout | Sí (para MP) |
MERCADOPAGO_WEBHOOK_SECRET |
Validar firma HMAC del webhook | Sí en prod |
RESEND_API_KEY (+ EMAIL_BACKEND, EMAIL_ASYNC, ASYNC_EMAIL_INNER_BACKEND) |
Envío de emails | Sí |
BILLING_BANK_HOLDER / BILLING_BANK_CBU / BILLING_BANK_ALIAS |
Datos para transferencia manual | Sí (para transferencia) |
BILLING_ADMIN_NOTIFY_EMAILS |
Aviso al staff de transferencias a revisar | Sí (para transferencia) |
BILLING_NOTIFICATIONS_FROM |
Remitente de los mails de cobro | Opcional (cae a DEFAULT_FROM_EMAIL) |
BILLING_MP_PENDING_EXPIRY_HOURS |
Limpieza de checkouts abandonados | Opcional (default 24) |
BILLING_OVERDUE_REMINDER_DAYS |
Recordatorios de mora | Opcional (default sin recordatorios) |
AFIP_* |
Factura electrónica | Pendiente de credenciales ARCA — ver runbook |
AFIP está apagado (
AFIP_ENABLED=False) hasta tener las credenciales de ARCA. Mientras tanto se emiten recibos internos con la aclaración "no es factura AFIP". El paso a paso para encenderlo está en el runbook de AFIP.
La tarea diaria (python manage.py send_billing_notifications) debe correr por cron/qcluster: genera facturas, manda avisos + recordatorios, limpia checkouts abandonados y reintenta CAEs pendientes. Es idempotente.
Multi-organización
Todo está scoped por organización: una organización jamás ve facturas, pagos o cuotas de otra. Las consultas al webhook de MercadoPago también validan el external_reference contra la organización del pago para evitar cross-tenant.
Términos comerciales
Las cláusulas comerciales completas (planes, precios, mora, suspensión, baja, propiedad intelectual, jurisdicción) están en los Términos y Condiciones del Servicio. El tratamiento de los datos personales que cada organización carga en el sistema se regula en el Anexo II — DPA.