Software Licensing - Activating, Checking and Deactivating License Keys in WordPress Plugins

Important Note

This documentation is not needed if using the Software Licensing API Updater. Only refer to this document if you are not using the updater or if this is for reference:
See our documentation about how to integrate automatic upgrades for your WordPress  plugins.
See our documentation about how to integrate automatic upgrades for your WordPress themes.

Table of Contents

Activating

With Software Licensing, in order for a license key to be fully utilized, it must be activated. This can happen in one of two ways:

  1. A site admin can manually click the "Activate" link for the license from the Downloads → Licenses page
  2. The buyer can remotely activate the license via a system in your plugin/theme/software that uses the API to trigger the activation

Note: the sample plugin and the implementation shown in this document are purely samples. The best implementations of Software Licensing take these samples and integrate them seamlessly into the existing settings page of your plugin.

In this documentation, we're going to show you how to activate a license remotely via a system added to your WordPress plugin. The sample code we're showing you in this example is the same exact code that is included with the sample plugin and themes, available for download after purchasing the extension.

There are two main components to activating a license remotely:

  1. Saving the license key in the data (a theme or plugin option)
  2. Sending the stored license key through the API to the store website for verification and activation

When a license is remotely activated, the status of the license in your site's dashboard will be updated from "inactive" (the default state) to "active".

Let's first look at creating a simple options page to store our license.

This code sets up a sub-menu item in the Plugins menu called "Plugin License". We're using a plugins page in this example, but the code is identical for themes.

There are two lines at the top of the code:

The first is the license itself and the second is the status of the license. Once we have activated our license, we will change the status (on our local site) to "active". This is so that we can show an "Activate License" button if the license has not yet been activated, and hide the button if it has. See the screenshot below:

The idea here is that we first enter a license key and click "Save Changes", which causes the license key to be stored in our plugin/theme options. Once the option is stored, we click the "Activate License" button to trigger the API call.

The activate button is just a simple input field with a type of "submit" and a name attribute that is different than our save button. The names must be different so that we can know when the activate license button was clicked.

In order to activate the license, we just need to "watch" for when the activate button is clicked. The way that we do this is by setting up a function that is hooked to the "admin_init" hook, like so:

If everything runs okay after clicking the "Activate License" button, the activate button will be replaced with the word "active", and the license status will reflect the newly activated state in your EDD store's dashboard. If there is an error when activating the license key, the page will be reloaded and an error and message parameter will be added to the URL. We can then use the admin_notices hook (or any other applicable method) to display the error to the customer:

For example, if a customer enters an invalid license key, an error message will be displayed:

Checking

With Software Licensing you can easily check if a license key is valid at any time. You may want to do this in order to limit certain functionality in the theme or plugin to only users with a valid license key.

Checking a license key's validity is quite simple; all it requires is that we perform a remote request to our store website with a couple of specific parameters. See the function below:

function edd_sample_theme_check_license() {
	$store_url = 'http://yoursite.com';
	$item_name = 'Your Item Name';
	$license = '834bbb2d27c02eb1ac11f4ce6ffa20bb';
	$api_params = array(
		'edd_action' => 'check_license',
		'license' => $license,
		'item_name' => urlencode( $item_name ),
		'url' => home_url()
	);
	$response = wp_remote_post( $store_url, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) );
  	if ( is_wp_error( $response ) ) {
		return false;
  	}

	$license_data = json_decode( wp_remote_retrieve_body( $response ) );

	if( $license_data->license == 'valid' ) {
		echo 'valid';
		exit;
		// this license is still valid
	} else {
		echo 'invalid';
		exit;
		// this license is no longer valid
	}
}

Note: if you are consistently checking the validity of a license key, perhaps to block usage of the plugin or theme when the license expires, you MUST cache the results of the check so that the request is not performed with every page load. The Transients API is a great way to cache API responses.

Deactivating

With Software Licensing, after a license has been been activated, it can also be deactivated remotely (since v1.3). Usually the reason to deactivate a license is to permit a license to be activated on an additional site once the activation limit has been reached.

The deactivation process is nearly identical to the activation process. We perform a remote request and send the details of the license key we are deactivating. The remote request is done like so:

// data to send in our API request
$api_params = array(
	'edd_action' => 'deactivate_license',
	'license'    => '2ec66bae356be570236531ccba06a45b',
	'item_name'  => 'Sample Plugin', // the name of our product in EDD
	'url'        => home_url()
);
// Send the remote request
$response = wp_remote_post( 'http://yoursite.com', array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) );

The $response var will be a json object that tells us whether the deactivation request was successful or not. If it is successful, the response will be:

Note: The date/time is a timestamp unlike other json responses which will be date time.

{
	"success": true,
	"license": "deactivated",
	"item_name": "Sample Plugin",
	"expires": 1556150399,
	"payment_id": 2444,
	"customer_name": "John Doe",
	"customer_email": "john@sample.com"
}

If the license fails to be deactivated, the response will be:

{
	"success": false,
	"license": "failed",
	"item_name": "Sample Plugin",
	"expires": 1556150399,
	"payment_id": 2444,
	"customer_name": "John Doe",
	"customer_email": "john@sample.com"
}

Once a license has been successfully deactivated, the Site Count column in Downloads → Licenses will be decremented and an entry will be recorded in the log so that admins can see where a license was deactivated from.