BASIC

License on Hosted Plugin

Turn on Licensed on a Download and its updates only reach sites with a valid licence. This page covers the licences you manage on your Hoster site and the code that goes into your plugin or theme.

Licences

Licences live under Downloads → Hoster Licenses. Each licence is its own post, with the settings in the License Details box. It has two parts: the licence settings and the list of used sites.

License details

Info
Hoster doesn't take payments. It gives you hooks to create and update licences, so WooCommerce, Easy Digital Downloads, Stripe or any other payment system can create them (see Hooks below).

Licence settings

License settings

Related Download

The plugin or theme this licence is for. You can change it manually.

User

The WordPress user who owns the licence. This user can download the product with the download buttons and manage the licence's sites with the [hoster_user_licenses] shortcode or the User Licenses block.

License Key

Generated automatically and can't be edited.

License Status

  • Active — the licence works.
  • Expired — the expiry date has passed, for example when a subscription wasn't renewed.
  • Invalid — the licence is turned off, for example after a failed payment or a refund.

Only Active licences get updates and downloads. You can change the status manually.

Enable Activation Limit and Activation Limit

By default a licence can be activated on any number of sites. Turn on Enable Activation Limit and enter the Activation Limit to allow only that many sites.

Expiry Date

Optional. Once the date has passed, the licence is set to Expired. A daily WP-Cron job does this for all licences, and every licence check does it for that licence right away. To run the daily job by hand, use WP-CLI:

wp hoster_expire_licenses

Used Sites

Used sites

The sites where this licence is activated. You can search the list, add a site, or remove one.

How sites are compared

Hoster stores and compares sites by their host name only:

  • https://example.com, http://www.example.com/ and example.com are the same site.
  • A path is ignored: example.com/shop is the same site as example.com.
  • A subdomain is a separate site: shop.example.com needs its own activation.
  • A port other than 80 or 443 is kept: localhost:8881 is its own site.

Activation rules

A site can only be activated when the licence is Active, hasn't expired, the site isn't activated yet, and the activation limit (if on) isn't reached. The same rules apply to activations from your product and to sites added with the [hoster_user_licenses] shortcode. Sites you add yourself in the Used Sites list are not checked against them.

Add licensing to your plugin or theme

  1. Go to Downloads → Resources and choose the licensed Download.
  2. Open the License tab (it only appears for licensed Downloads).
  3. Save hoster-license-handler.php as inc/hoster-license-handler.php in your product.
  4. Use the License functions to use code where your product handles the licence key, for example on its settings page.

How the updater gets the licence key

For a licensed Download, the generated inc/hoster.php passes the key to the updater from an option named after the Download's slug:

get_option( 'my_plugin_license_key', '' )

For the slug my-plugin the option is my_plugin_license_key; the License tab shows the exact name. Your code saves the key there after a successful activation and deletes it on deactivation. The updater sends the key and the site URL with every update check, and Hoster only returns a package link when that licence is activated for that site.

The generated licence code

For a Download with the slug my-plugin and the ID 27, the License tab generates this code:

<?php
$plugin_prefix = 'MYPLUGIN';
require_once (constant($plugin_prefix . '_PATH') . 'inc/hoster-license-handler.php');

$className = $plugin_prefix . '_LicenseHandler';
$license_handler = new $className();
$license_key = 'YOUR-LICENSE-HERE';

// Activate License Example
$response = $license_handler->activate_license(27, $license_key, home_url());
if (!empty($response['success'])) {
    // The updater reads the key from this option to download licensed updates.
    update_option('my_plugin_license_key', $license_key, false);
}
echo "<pre>"; print_r($response); echo "</pre>";

// Deactivate License Example
$response = $license_handler->deactivate_license(27, $license_key, home_url());
if (!empty($response['success'])) {
    delete_option('my_plugin_license_key');
}
echo "<pre>"; print_r($response); echo "</pre>";

// Check License Example
$response = $license_handler->check_license(27, $license_key, home_url());
echo "<pre>"; print_r($response); echo "</pre>";

Replace YOUR-LICENSE-HERE with the key your customer enters, and the print_r lines with your own messages.

What the licence functions return

All three functions return an array with success (true or false) and a message.

  • activate_license() — on success also license_id, expiry_date, used_activations and remaining_activations (a number, or Unlimited). Possible errors: "Invalid license.", "Site already activated.", "Activation limit reached.", "License is not active." and "License has expired." The response also has a token field; the 2.x updater doesn't use it.
  • deactivate_license() — on success also license_id. Error: "Site not found in activations."
  • check_license() — license_id, status (active, expired or invalid), expiry_date, site_activated (whether the site you passed is activated), used_activations and remaining_activations.

After 10 failed attempts from one IP address within a minute, the licence functions get "Too many attempts. Please try again in a minute."

The licence endpoints

The handler calls these endpoints on your Hoster site with a JSON body of download_id, license_key and site_url:

POST https://your-site.com/wp-json/hoster/v1/hoster-activate-license/
POST https://your-site.com/wp-json/hoster/v1/hoster-deactivate-license/
POST https://your-site.com/wp-json/hoster/v1/hoster-check-license/

Let customers manage their sites

Add the [hoster_user_licenses] shortcode to a page, for example a "My account" page:

[hoster_user_licenses]

In the block editor you can use the User Licenses block (in the Widgets category) instead. It shows the same table on the front end; in the editor it only shows a placeholder.

Logged-in customers see a Your Licenses table with each licence's Download, key, status and activated sites. They can remove a site, for example before moving to a new domain, and add one with Add Site.

  • Only the licence's owner (its User) and administrators can change a licence.
  • Adding a site follows the same activation rules as your product.
  • Visitors who aren't logged in get a link to log in.

Hooks

Create a licence

Call this from your payment system when an order is paid.

$response = apply_filters(
    'hoster_create_new_license',
    null,          // always null
    27,            // download ID (the Download's post ID)
    1,             // user ID of the customer
    'active',      // status: active, expired or invalid
    true,          // enable the activation limit
    5,             // activation limit
    '2027-09-29'   // expiry date as YYYY-MM-DD, or '' for no expiry
);

// $response:
// [ 'success' => true, 'message' => 'License successfully created.', 'license_id' => 123, 'license_key' => '…' ]

Send the returned license_key to your customer.

Update a licence

Change the status, expiry date or activation limit, for example when a subscription is renewed or cancelled.

$response = apply_filters('hoster_update_license', null, 123, [
    'status'           => 'expired',
    'expiry_date'      => '2027-05-15',
    'activation_limit' => 10,
]);

// $response:
// [ 'success' => true, 'message' => 'License details updated successfully.', 'license_id' => 123, 'updated_fields' => [ … ] ]

The first argument is always null and the second is the licence ID. Only status, expiry_date and activation_limit can be changed. The activation limit only applies to licences with Enable Activation Limit on.