Billing systems
A billing system creates an account when an order is paid, suspends it when an invoice is overdue, and deletes it when the service is cancelled. It does that over the Server API with a server API key (API Keys), and it hands the new account holder the setup link the server answers with. Nothing is installed on the server for it. The billing system's module, such as the WHMCS module, is documented with the module: where to enter the server's hostname and the key, and how its products map to the account limits.
What the billing system needs
An admin user of its own, and a key that acts as it:
elpanctl server:admin-user:create <admin>
elpanctl server:api-key:create <admin> whmcs --scope=all:readwrite
The installer's closing message names these two commands as the way to link
to WHMCS. --scope=all:readwrite is needed because the default scope is
read-only and creating an account is a write (API Keys).
Give the system:
- the server's admin host,
https://admin.<server hostname>/, which is where/api/v1is (the bare hostname serves it too, see Server API); - the token,
espat_…, which the command prints once.
A key acts as its admin user, and what the key does is recorded against the
key (a deletion's requestedBy is api:<key id>). An admin user that
exists only for the billing system keeps its actions apart from yours, and
deleting that user revokes its keys in one step. server:admin-user:create
makes it passwordless; the API checks the key, not whether anyone finished
that user's setup link, so its keys work as they are.
What it calls
| Step in the billing system | Server API operation |
|---|---|
| Order paid: create the account | POST /api/v1/accounts with the username and the limits of the product (storageLimit, memoryLimit, cpuQuota, the mailing list and webhook limits, …). The response carries the account's single-use setup link and PIN. |
| Add the ordered domain | POST /api/v1/accounts/{username}/domains with the domain. It provisions the domain's services: identity, mail, website and the www alias. |
| Change of product | PATCH /api/v1/accounts/{username} with the limits that change. |
| Invoice overdue | POST /api/v1/accounts/{username}/suspension. Sign-in, mail, FTP, websites and databases stop; nothing is deleted. |
| Invoice paid | DELETE /api/v1/accounts/{username}/suspension. |
| Service cancelled | DELETE /api/v1/accounts/{username}: once to terminate, which starts the grace period, and again to purge once it has elapsed, or with immediate=true. |
| Cancellation withdrawn | DELETE /api/v1/accounts/{username}/termination. The account comes back suspended. |
| The holder lost their password | POST /api/v1/accounts/{username}/setup-links for a new setup link. |
| Sign in as the holder | POST /api/v1/accounts/{username}/impersonations for a one-shot URL. |
Suspend, terminate and delete an account explains the states, the grace period and what a purge removes; Limits explains each limit and its default.
The setup link
A new account has no password. The POST /api/v1/accounts response carries
a setupLink with a url the holder opens, a claimUrl with a pin for a
hand-off over the phone, and an expiresAt. It is shown in this response
only. The billing system's welcome message is where it belongs; if it is
lost, POST /api/v1/accounts/{username}/setup-links issues a new one and
invalidates the old.
A username that belonged to a deleted account is refused with 409. A
billing system that derives the username from the order must not expect to
recreate an account under the same name after a purge.
What it gets back
The server's Webhooks tell the billing system what happened
without polling. The account.* family is the one to subscribe:
account.created, account.suspended, account.unsuspended,
account.terminated, account.restored and account.removed, and
account.purge.succeeded or account.purge.failed when a deletion ends.
quota.threshold_crossed says that an account reached 80 %, 95 % or 100 %
of its storage.
elpanctl webhook:endpoint:create --server "WHMCS" https://billing.example.net/elpan-hook --event="account.*" --event="quota.*"
Inside the account
The server API stops at the account's border: it creates the account and
its first domain, but it does not create a mailbox or a database inside it.
A billing system that provisions more than that creates a key for the
account with POST /api/v1/accounts/{username}/api-keys and uses the
account API
with it, as the account holder would.