Facturación
La facturación integrada de OPanel usa Stripe Checkout para el alta y el Stripe Customer Portal para la autogestión de facturación. Los datos de tarjeta nunca tocan tus servidores, lo que te mantiene dentro del alcance PCI SAQ-A. Si ya facturas con otro sistema, salteate Stripe por completo y maneja las suscripciones a través de la API.
1. Crea productos y precios en Stripe
Sección titulada «1. Crea productos y precios en Stripe»Para cada plan que vendas, crea un Producto en Stripe con uno o más Precios recurrentes
(mensual, anual, o ambos). Después, en Admin → Plans, agregale al plan un precio equivalente
con el ID de precio de Stripe (price_...), el intervalo y el monto, que debería coincidir con lo
que fijaste en Stripe.
2. Configurá OPanel
Sección titulada «2. Configurá OPanel»En Admin → Billing (o PATCH /api/v1/billing/settings):
| Campo | Notas |
|---|---|
| Proveedor | stripe |
| Clave secreta | Una clave restringida (rk_...) o secreta (sk_...). Usa una sk_test_... hasta verificar todo el flujo. |
| URL pública | El origen https:// que usan los clientes, por ejemplo https://panel.example.com — Stripe redirige acá después del checkout y desde el portal |
| Período de gracia | Días que una suscripción en mora sigue funcionando antes de suspenderse (7 por defecto) |
Las claves se cifran con la clave maestra de la instalación antes de guardarse.
3. Agrega el endpoint del webhook
Sección titulada «3. Agrega el endpoint del webhook»En Stripe → Developers → Webhooks, agrega un endpoint que apunte a
https://<dominio del panel>/api/v1/billing/stripe/webhook (la página de configuración de Billing
te muestra la URL exacta), suscripto a:
checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcustomer.subscription.pausedcustomer.subscription.resumedinvoice.paidinvoice.payment_failedCopia el secreto de firma del endpoint (whsec_...) en la configuración de Billing. Los eventos de
webhook se guardan antes de procesarse y se aplican exactamente una vez, así que los reintentos de
Stripe son inofensivos.
El ciclo de vida de la suscripción
Sección titulada «El ciclo de vida de la suscripción»| Evento de Stripe | Qué pasa |
|---|---|
checkout.session.completed |
Se crea el cliente, el comprador pasa a ser su owner, se crea la suscripción, se crea el primer sitio si se ingresó un dominio al momento del alta |
invoice.payment_failed |
La suscripción pasa a en mora; los sitios siguen funcionando durante el período de gracia |
| Se agota el período de gracia | La suscripción se suspende: los sitios muestran una página de suspensión, se deniega el SSH, los datos se conservan |
invoice.paid |
Las suscripciones en mora o suspendidas vuelven a estar activas |
customer.subscription.deleted |
La suscripción se cancela, programada para su finalización |
| Se agota el período de retención | La suscripción se finaliza y se eliminan sus sitios (los archivos y volcados de base de datos se conservan en la papelera durante la ventana de retención propia del nodo) |
Cada evento de Stripe se trata como una notificación, no como una orden: el controlador vuelve a leer el estado real de la suscripción desde Stripe y aplica eso, así que entregas de webhook tardías, duplicadas o fuera de orden nunca pueden hacer retroceder una suscripción. Una suscripción suspendida por el personal, o por falta de pago, permanece así hasta que el personal o el pago la resuelvan — los eventos de Stripe solos nunca la reactivan.
Facturación externa: WHMCS, Blesta y HostBill
Sección titulada «Facturación externa: WHMCS, Blesta y HostBill»Si ya usas alguno de estos, quédate con él: OPanel ofrece módulos de facturación para WHMCS,
Blesta y HostBill, y una API de aprovisionamiento para cualquier otro sistema. Las
suscripciones creadas de esta forma llevan billingProvider: external; OPanel no intenta cobrarlas,
y el sistema externo maneja cada transición del ciclo de vida — activación, suspensión,
cancelación — a través de los mismos endpoints de la API que usa el personal.
Apuntá el módulo de OPanel de tu sistema de facturación a la URL base de la API de tu panel y a un
token de API con los permisos customer:manage, billing:manage y site:create; el módulo se
encarga de aprovisionar un cliente, una suscripción y un sitio al recibir una orden, y de suspender
o finalizar ante la falta de pago, de la misma manera que lo hace la integración nativa con Stripe.
Cerrar la cuenta de un cliente
Sección titulada «Cerrar la cuenta de un cliente»Eliminar un cliente (DELETE /api/v1/customers/{id}) cierra la cuenta en lugar de borrarla — los
sitios, suscripciones y el registro de auditoría siguen referenciándola. Se rechaza mientras
cualquier suscripción esté activa, en período de prueba o en mora; cancelá esas primero. Un cliente
cerrado conserva acceso de lectura a lo que queda y se puede reabrir
(POST /api/v1/customers/{id}/reopen), lo cual no revive suscripciones que ya terminaron de
finalizarse.
Marcas revendedoras con su propia cuenta de Stripe
Sección titulada «Marcas revendedoras con su propia cuenta de Stripe»Una marca puede facturar a través de la cuenta de Stripe de la plataforma, o mediante una cuenta propia — ver Marcas.