Selling hosting
KLYRN has a storefront, a checkout, orders, payments, customers, services and renewals built in, running on your own server. It exists for the provider who has no billing system and wants to sell a plan this afternoon.
What it is, and what it deliberately is not
A hosting business needs a page that lists plans, a way to take money, and something that turns a payment into a working account. That is what this is. It runs on the same server as the hosting itself: there is no external service in the path, and no monthly fee to a billing vendor before you have a single customer.
It is deliberately small, and the list of what it will not become is part of the design rather than a roadmap:
- Not a ticketing system
- No helpdesk, no queues, no SLAs
- Not a registrar
- KLYRN never sells or renews a domain name
- Not a CRM
- Customers, not pipelines
- Not an accounting or tax engine
- It records what was charged; your accountant owns the rest
A provider who needs those runs WHMCS, and KLYRN ships an integration so they can. This is for everyone else, and for the first year of everyone who will eventually need WHMCS.
The two rules that make it safe
Billing systems cause damage in two specific ways, and both are closed here by structure rather than by care.
It never provisions anything itself. A successful payment creates a durable job that fills in a provisioning request and hands it to the one provisioning engine, the same one the panel and the CLI use. There is no second implementation of "make an account" in the billing code and there must never be one, because a billing system with its own idea of how to create a Unix account is exactly how one customer ends up with two accounts.
It never trusts a browser about money. An order becomes paid for one of two reasons: a payment provider's verified callback said so, or an administrator looked at their bank and said so. A request that merely claims it has been paid is a request, not a fact, and is treated as one.
Products, terms and coupons
A product is a plan you sell: a name, a price, a billing term, and the hosting package it provisions. Three terms are supported, and the constant list is short on purpose so that adding half-yearly later is a constant and a case rather than an architecture change:
- Monthly
- Advances the due date by 1 month
- Quarterly
- Advances by 3 months
- Yearly
- Advances by 12 months
Renewal dates advance in months, not days, and the day of the month is preserved. A monthly service bought on the 31st stays on the 31st in months that have one, and lands on the last day of the month in months that do not. Naive date arithmetic turns 31 February into 3 March; this does not.
Coupons are percentage or fixed amount, can be limited by use count and expiry, and are validated at checkout rather than trusted from the page that offered them.
Getting paid
Payment methods are pluggable. The one that ships with every install is manual payment: bank transfer, cash, or invoice on account. Any method where a person confirms the money arrived.
It reports itself as not automated, and that is the whole design. Nothing in it claims
to know when money moved. A human says so, and until they do, the order sits in
pending_payment where everyone can see it.
KLYRN ships no bank details, not even an example. There is no IBAN, no placeholder and nothing that could be mistaken for a real account anywhere in the payment instructions, because a payment instruction is yours and inventing one is how money goes to the wrong place. The field ships empty and the readiness check tells you it is empty before you publish.
What happens after checkout
An order moves through a state machine that is visible in the panel at every step, so a customer asking "where is my hosting" has an answer that is a state rather than a guess:
- draft
- Started, not submitted
- pending_payment
- Waiting on money
- paid
- Money confirmed, by callback or by a person
- provisioning
- Handed to the provisioning engine
- active
- The account exists and works
- failed
- Provisioning did not finish, and the reason is recorded
- cancelled
- Stopped before it became a service
- refunded
- Money returned, recorded against the order
What the order becomes is a service, which has its own longer life and
its own states: pending, provisioning, active,
provision_failed, suspended, cancel_pending,
cancelled, termination_pending and terminated.
The split between "cancel pending" and "cancelled", and between "termination pending" and "terminated", is deliberate: a customer cancelling at the end of their paid term is a different thing from their data being deleted, and collapsing the two is how hosting providers delete data somebody had still paid for.
The customer portal
Customers get their own view: their orders, their services, their profile, and the ability to change or cancel a plan without emailing you. A plan change is previewed before it is applied, so the customer sees what it will cost and what it changes before they commit, and a pending change can be cancelled.
"Manage hosting" takes them from the portal into the panel. Most of the time that is an
ordinary link, because a customer in the portal and a customer in the panel are the same
person with the same session. The exception is a storefront published on its own
hostname, where the panel's SameSite=Strict session cookie does not travel;
for that case KLYRN issues a single-use hand-off ticket rather than loosening the cookie
for everybody.
Publishing the storefront
The storefront can serve on its own hostname with its own certificate, or at
/shop on the panel's hostname until DNS for a dedicated name is pointed
here. KLYRN tells you which of those is currently true rather than leaving you to
discover it.
A readiness check runs before you publish and names what is not finished: no payment instructions, no products, no hostname, a hostname whose certificate has not been issued yet. It is a list of specific missing things, not a score.
Renewals, overdue and suspension
A billing run generates what is due, advances the dates, and moves services that have not been paid for into overdue and then suspended, on a schedule you set. Suspension is reversible and does not delete anything; termination is the separate, later, deliberate step.
Every one of those transitions is a recorded event with a time and a reason, because the question a hosting provider actually gets asked is "why was my site turned off", and "the system did it" is not an answer.