Blog ·
Automatizar la facturación y el aprovisionamiento en HestiaCP
De un pedido pagado a una cuenta HestiaCP activa, y de una factura vencida a una suspendida. Los comandos, las trampas medidas y dónde vive la factura.
Por Provibr
Un producto de alojamiento automatizado tiene exactamente tres momentos en los que el dinero y las máquinas se tocan:
- El pedido se paga. Una cuenta debe existir, con el paquete correcto, en cuestión de segundos.
- La factura está vencida. La cuenta debe apagarse, y volver en cuanto se pague.
- La suscripción termina. La cuenta debe eliminarse, de verdad, datos incluidos.
HestiaCP tiene un comando para cada uno de esos momentos. Lo que no tiene es nada que decida cuándo ejecutarlos. Esta página trata de conectar las dos mitades, y de los lugares concretos donde la API de HestiaCP responde de una forma que romperá en silencio un primer intento.
Los tres momentos y los comandos que hay debajo
| Momento | HestiaCP | Respuesta en caso de éxito |
|---|---|---|
| Pedido pagado | v-add-user y luego v-add-web-domain | 204, cuerpo vacío (dos veces) |
| Vencido | v-suspend-user | 204, cuerpo vacío |
| Pagado al final | v-unsuspend-user | 204, cuerpo vacío |
| Subida / bajada de plan | v-change-user-package | 204, cuerpo vacío |
| Cancelación | v-delete-user | 204, cuerpo vacío |
Fíjese en la columna de respuestas. Una mutación con éxito en HestiaCP es HTTP 204 sin nada en el cuerpo. No 200. Un cliente escrito bajo la suposición de que el éxito es 200 rechaza cada llamada que funcionó, y luego normalmente reintenta, que es cómo una integración que funciona se convierte en una bloqueada (véase más abajo).
La respuesta de verdad vive en una cabecera de respuesta, Hestia-Exit-Code, que lleva un número sacado de una tabla fija. El estado HTTP se deriva de él y colapsa unos veinte códigos sobre cuatro estados. Lea la cabecera; trate el estado como una pista.
La suspensión no es simétrica, y aquí importa más que en ningún otro sitio
Esta es la trampa que golpea específicamente a una integración de facturación, porque una integración de facturación es lo único que suspende la misma cuenta dos veces.
Medido, sobre la misma cuenta:
v-suspend-user on an active account → 204, exit 0
v-suspend-user on a suspended account → 401, exit 5 ("user X is suspended")
v-unsuspend-user on a suspended account → 204, exit 0
v-unsuspend-user on an active account → 204, exit 0Reactivar es idempotente. Suspender no lo es. Y el fallo que produce es HTTP 401, el mismo estado que se obtiene por un secreto erróneo, una clave fuera de alcance y una dirección bloqueada.
Así que un ciclo de reclamación de pago que suspende todo lo vencido, incluidas cosas que ya suspendió ayer, informará de fallos de autenticación para cuentas que están exactamente en el estado que se quería. El código de salida 5 en v-suspend-user significa «ya estaba así» y hay que leerlo como un éxito.
Nunca reintentar tras un error de autenticación
HestiaCP bloquea una dirección tras cinco inicios de sesión rechazados, usando fail2ban con maxretry = 5 y un DROP de iptables. Una vez que eso se dispara, las llamadas dejan de expirar a nivel de aplicación y empiezan a expirar a nivel de red: la monitorización dice que el panel es inalcanzable, y nada en los registros apunta a un problema de credenciales.
Para una integración de facturación esto importa más que para cualquier otra cosa, porque una integración de facturación es lo que corre sin supervisión de noche. Dos consecuencias:
- Los códigos de salida 9, 10 y 21 nunca deben desencadenar un reintento automático. Son, respectivamente, secreto erróneo, permiso denegado y API deshabilitada. Ninguno es un fallo pasajero, y los tres cuentan para el bloqueo.
- Un comando fuera de los permisos de la clave también cuenta como un inicio de sesión fallido. Eso no es evidente: se escribe la misma línea de registro para un secreto erróneo y para una clave válida que tiende la mano hacia un comando que no tiene permiso de ejecutar. Una clave acotada con el conjunto de permisos
billingque trae HestiaCP de serie carece dev-list-user-packagesyv-list-web-domains, así que un ciclo de sondeo que lee paquetes y dominios agota el contador del bloqueo a la hora prevista. Use una clave sin acotar para el usuario administrador.
Levantar un bloqueo requiere una consola en el host del panel: v-delete-firewall-ban <address> HESTIA. Si el software que construye no sabe decir esa frase, quien esté de guardia a las tres de la madrugada pasará la noche con el problema equivocado.
Un pedido pagado cuesta dos llamadas, así que necesita una reversión
HestiaCP no tiene ningún comando que cree un usuario y le adjunte un dominio a la vez. Eso deja una ventana:
v-add-user provibrtest1 … → 204, exit 0
v-add-web-domain provibrtest1 "not a valid domain" → 422, exit 2
v-list-user provibrtest1 → the account exists, with zero domainsUn usuario unix de verdad, con un directorio personal, sin sitio web, y una fila en cada recuento. Si el dominio del cliente ya estaba ocupado en su panel (lo que ocurre, porque los clientes se mudan), el pedido falla y queda medio cuenta que nadie notará jamás.
La regla es sencilla y tiene que estar incorporada: si el segundo paso falla, elimine el usuario e informe del error original. Un dominio rechazado nunca debe dejar media cuenta detrás.
Provibr hace exactamente eso, y el error que ve el cliente es el que dio HestiaCP por el dominio, no un error secundario sobre una limpieza.
Dónde vive realmente la factura
Vale la pena ser explícito, porque es el malentendido más común: Provibr no factura a sus clientes. No les envía una factura, no los persigue, y no sabe qué les cobra. Esa relación es suya.
Lo que Provibr factura es su propia capacidad reservada: cuántas cuentas de alojamiento puede hacer correr a la vez, al mes, a un precio unitario por tramos. Lo que cobra a sus propios clientes por una cuenta HestiaCP, y cómo, se queda enteramente dentro de su propio sistema de facturación.
Hay dos maneras de conectar las dos mitades:
Un módulo de WHMCS. Si ya hace correr WHMCS, instale el módulo de aprovisionamiento de Provibr y haga que un producto de WHMCS apunte a un plan web de Provibr. Un pedido pagado crea la cuenta; una suspensión en WHMCS la suspende; una cancelación la elimina. Su cliente conserva una cuenta, una factura y un inicio de sesión. El módulo es un simple zip que instala por su cuenta, y corre dentro de su WHMCS. No hay nada que habilitar por nuestro lado.
La API REST. Si hace correr FOSSBilling, Blesta, algo propio, o una hoja de cálculo y una tarea programada, gobiérnelo directamente. Una clave, una URL base, y exactamente los permisos que ya tiene el miembro detrás de la clave.
La única regla para gobernarlo desde su propio código
Todo lo que toca una máquina es asíncrono, y tiene que serlo. Su infraestructura solo es alcanzable a través del agente que está dentro de su propia red, y ese agente marca hacia fuera. Así que un endpoint que cambia una cuenta no puede responder con el resultado. Responde que el pedido fue aceptado y le entrega un comando a seguir, que se lee hasta que su estado sea definitivo: terminado, fallido, expirado o cancelado. Un comando fallido lleva el propio código de error del agente con sus argumentos, el mismo que el panel muestra en pantalla.
La lectura nunca funciona así. Un inventario, una dirección o una factura responde de inmediato, porque esa respuesta viene de una base de datos y no de su host.
La consecuencia práctica para un gancho de facturación: no marque el pedido como completo sobre la respuesta de aceptación. En HestiaCP, v-add-user tarda alrededor de un segundo y v-delete-user alrededor de tres, así que la espera es corta, pero la respuesta que obtiene primero es «lo hemos enviado», no «funcionó».
La suspensión es también su propio control de costes
Una conexión fácil de pasar por alto. En Provibr un servidor suspendido no cuenta para su capacidad, y para una cuenta de alojamiento no existe un «detenido»: hay activo y suspendido.
Así que la acción de reclamación de pago que ya quería ejecutar por razones comerciales es también la que libera la plaza que está pagando. Suspenda una cuenta vencida y deja de contar de inmediato; elimínela y también deja de contar; déjela corriendo e impagada y la está pagando.
Lo que esto no automatiza
Provibr gestiona cuentas, no el panel. No instala HestiaCP, no lo actualiza, no cambia los ajustes del servidor, y no toca el DNS, los buzones ni las bases de datos: un cliente que elimina su propio buzón a través de HestiaCP lo hace sin que nada por encima lo sepa ni le importe. No hay consola para una cuenta de alojamiento. Y no hay suspensión parcial: una cuenta está activa o no lo está.
Si también vende VPS, servidores de juego o cuentas cPanel, los mismos tres momentos se aplican a todos ellos, y pueden vivir en un solo inventario. Provibr hace correr hoy sus paneles de control, sus hipervisores y sus paneles de juego unos junto a otros, con un único conjunto de permisos y un único registro de actividad sobre el conjunto.