Documentation

Provisioning modules

The piece that separates selling a service from delivering it, so the billing core knows nothing about game panels or hypervisors.

Designed, not built

The interface is defined; the manual module ships with the instance, and Pterodactyl comes after.

1. What a module solves

When someone buys from your store, two things have to happen that have nothing to do with each other: charging and invoicing on one side, and delivering what was sold on the other. Delivering means creating a server on a panel, setting up an email account or simply letting you know so you can do it yourself.

A provisioning module is what connects the second to the first. The billing core doesn't know what a Pterodactyl egg is, or how much memory a plan comes with: that lives inside the module and in the product's configuration. It's the difference between a system that can sell anything and one that can only sell game servers.

It's also a deliberate fix of what we had before: in the system Payezz grew out of, the game panel's IDs were baked into the core schema, with their own columns in the users and orders tables. Here they move out of the core and stay in the module's configuration.

2. The interface

Every module implements the same interface, ProvisioningModule. Each operation receives the service and the product configuration, and returns an explicit result: it never throws an exception to say “couldn't do it”.

interface ProvisioningModule {
  id: string                 // 'manual', 'pterodactyl', ...

  provision(ctx):  Result    // sign-up: create what was sold
  suspend(ctx):    Result    // failed payment: cut off access
  unsuspend(ctx):  Result    // payment recovered: restore it
  changePlan(ctx): Result    // plan upgrade or downgrade
  terminate(ctx):  Result    // cancellation: destroy and release

  // Compare what Payezz believes with what actually exists
  // on the remote system, and propose fixes.
  reconcile(ctx):  Differences

  // Which actions the customer sees in their client area
  // (start, stop, reinstall, open console...).
  customerActions(ctx): Action[]
}

Operations are idempotent. Provisioning the same service twice doesn't create two servers: the second call recognizes what was already created and returns the same result. That isn't a luxury: retries are normal whenever there's a network in between.

3. Service states

The service, not the order, is what renews and what a module delivers. Its lifecycle is explicit, and every transition is logged with its reason, so months later you can answer “why was this canceled”.

StateWhat it meansModule call
pendingPaid for, not yet deliveredprovision
activeDelivered and runningNone
suspendedFailed payment or incident: no access, nothing deletedsuspend and unsuspend
cancelledCancellation requested, waiting for the end of the periodNone yet
terminatedDestroyed and releasedterminate

4. Reconciliation

Two systems talking over a network end up disagreeing: a server deleted by hand in the panel, a sign-up that failed halfway, a plan change applied in one place and not the other. Reconciliation compares what Payezz believes exists with what actually exists.

There's an inherited lesson here worth sharing: the system Payezz grew out of has a reconciliation screen that only diagnoses. It lists the differences and stops there; fixing them is manual work, one by one. A report that can't act ends up being a report nobody opens.

In Payezz, reconcile returns differences with a corrective action attached, which the provider applies from the admin panel, one at a time or all at once, and which is logged like any other admin action.

5. Planned modules

ModuleWhat it's forStatus
manualYou deliver the service by hand. Payezz creates the task, notifies you and tracks the status.Designed, not built
pterodactylGame servers: creation, suspension, plan changes and deletion on the panel.Designed, not built

The manual module isn't the poor relation: it's a first-class citizen, because a good share of what's sold in this industry is delivered by hand, and because it's what lets you use Payezz to sell something we never anticipated.

Other panels in the industry, such as cPanel, Plesk, Proxmox or VirtFusion, don't have a module today. That's exactly why the comparison on the home page marks them “coming soon”, even though competitors do have them.

6. Where the configuration lives

Each product stores its module_config, an object whose contents are defined by the module: for pterodactyl, the node or group, the egg, and the memory, disk and CPU limits; for manual, the task template and who to notify.

The core doesn't interpret that object: it stores it, validates it against the schema the module declares and passes it along in full on every call. That's why adding a new module never requires a database schema migration.

Need a module that isn't on the list? Tell us which one and what operations you need at hola@payezz.app.