v1.3.0

License For Envato

Easily integrate and manage Envato purchase-code license validation on your WordPress themes and plugins. Follow the three steps below to get started.

WordPress Plugin Envato API License Management REST API

Overview

License For Envato acts as a license server: it validates Envato purchase codes through the official Envato API and stores per-domain activation records in your database.

How It Works

1
Server Setup Install the plugin on your WordPress site and connect your Envato personal token.
2
Client Integration Copy the provided PHP class into your theme or plugin and set your site URL and item ID.
3
Display License Form Instantiate the class wherever you want to display the activation / deactivation form.
Your WordPress site (the server) communicates with the Envato API. Customer sites (the clients) communicate with your WordPress site via the REST API provided by this plugin.

1 Server Setup

Configure this plugin on the WordPress site that will act as your license server.

Install & Activate

  • Install and activate the License For Envato plugin on your WordPress site.
  • Navigate to License Envato → Settings → Envato tab.
  • Paste your Envato personal token and click Save Envato Token.

Create Your Envato Token

Your token needs the following minimum permissions:

Required Permission
View and search Envato sites
View your Envato Account username
View your email address
Verify purchases of your items
List purchases you've made
💡
Optionally set a Token Secret Key under the General settings tab for added token entropy.

Your Server URL

Use the following URL (your WordPress site URL) in your client integration (Step 2):

Your Site URL
https://YOUR_SITE_URL

2 Client Integration

Copy the class below into your theme or plugin. It handles license activation and deactivation by calling your server's REST API.

Setup Instructions

  • Copy the full class code below into your theme's functions.php or a dedicated file in your plugin.
  • Replace YOUR_SITE_URL with your server URL (shown in Step 1).
  • Replace TEXT_DOMAIN with your theme/plugin's text domain.
  • Replace YOUR_PREFIX with a unique prefix for your product (e.g. mytheme).
Each product should use a unique PREFIX to avoid collisions in the WordPress options table.

The Integration Class

PHP · class.license.php
<?php
/**
 * licenseCodeVerifyForm()
 */

class licenseCodeVerifyForm {

    const LICENCE_CALL_URL = "YOUR_SITE_URL";
    const PREFIX = "YOUR_PREFIX";

    private $licenceActivate_error;
    private $licenceDeactivate_error;

    public function __construct() {

        $this->licenceActivate_error = $this->licenceActivate();
        $this->licenceDeactivate_error = $this->licenceDeactivate();

        $this->LicenceHTMLForm();
    }

    public function LicenceHTMLForm(){ ?>
        <h2><?php esc_html_e('License Activation Form', 'TEXT_DOMAIN');?></h2>
        <?php
        $token = get_option(self::PREFIX.'_envato_token');
        $isActivated = get_option(self::PREFIX.'_envato_is_activated');

        if ($token && $isActivated) {
            ?>
            <?php
            if ($this->licenceDeactivate_error) {?>
                <p class="licence_error"><?php echo esc_html( $this->licenceDeactivate_error );?></p>
            <?php }?>
            <p><?php esc_html_e('You can click this button to deactivate your license code from this domain if you are going to transfer your website to some other domain or server.', 'TEXT_DOMAIN');?></p>
            <form method="post">
                <input type="hidden" name="envato_deactivate" value="1">
                <?php wp_nonce_field( 'submit_deactivate' ); ?>
                <?php submit_button( esc_html__( 'Deactivate', 'TEXT_DOMAIN' ), 'danger', 'submit_deactivate' ); ?>
            </form>
            <?php
        } else { ?>
            <?php
            if ($this->licenceActivate_error) {?>
                <p class="licence_error"><?php echo esc_html( $this->licenceActivate_error );?></p>
            <?php }?>
            <form method="post">
                <label for="purchase_code"><?php esc_html_e('Purchase code', 'TEXT_DOMAIN'); ?>
                    (<a href="https://help.market.envato.com/hc/en-us/articles/202822600-Where-Is-My-Purchase-Code-"
                       target="_blank"><?php esc_html_e('Where can I get my purchase code?', 'TEXT_DOMAIN');?></a>)
                </label>
                <input type="text" style="width:100%" id="purchase_code" name="purchase_code"
                       placeholder="Example: 1e71cs5f-13d9-41e8-a140-2cff01d96afb">
                <?php wp_nonce_field( 'submit_activate' ); ?>
                <?php submit_button( esc_html__( 'Activate', 'TEXT_DOMAIN' ), 'danger', 'submit_activate' ); ?>
            </form>
            <?php
        }
    }

    private function licenceActivate() {
        if ( ! isset( $_POST['submit_activate'] ) ) {
            return;
        }
        if ( ! isset( $_POST['purchase_code'] ) || empty( $_POST['purchase_code'] ) ) {
            return 'Please Enter Purchase Code.';
        }
        // Unslash and sanitize nonce
        $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : '';
        if ( ! wp_verify_nonce( $nonce, 'submit_activate' ) ) {
            wp_die( 'Are you cheating?' );
        }
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( 'Are you cheating?' );
        }
        // Unslash and sanitize purchase_code
        $purchase_code = isset( $_POST['purchase_code'] )
            ? sanitize_text_field( wp_unslash( $_POST['purchase_code'] ) )
            : '';

        if ( $purchase_code ) {
            $url    = self::LICENCE_CALL_URL . "/wp-json/licenseenvato/v1/active";
            $domain = $this->domain();
            $itemid = get_option( self::PREFIX . '_envato_itemid' );

            $response = $this->apicall( $url, $purchase_code, $domain, $itemid );
            $data     = json_decode( $response );

            $token  = isset( $data->token )  ? $data->token  : '';
            $itemid = isset( $data->itemid ) ? $data->itemid : '';
            if ( $token ) {
                update_option( self::PREFIX . '_envato_is_activated_' . $itemid, true );
                update_option( self::PREFIX . '_envato_token', $token );
                update_option( self::PREFIX . '_envato_purchase_code', $purchase_code );
                update_option( self::PREFIX . '_envato_itemid', $itemid );
            } else {
                $statusCode    = isset( $data->code )    ? $data->code    : '';
                $statusMessage = isset( $data->message ) ? $data->message : '';
                if ( $statusCode ) {
                    return $statusMessage;
                }
            }
        }
    }

    private function domain() {
        $domain = get_option( 'siteurl' );
        $domain = str_replace( 'http://',  '', $domain );
        $domain = str_replace( 'https://', '', $domain );
        $domain = str_replace( 'www',      '', $domain );
        return urlencode( $domain );
    }

    private function licenceDeactivate() {
        $code = get_option( self::PREFIX . '_envato_token' );
        if ( ! isset( $_POST['submit_deactivate'] ) ) {
            return;
        }
        // Unslash and sanitize nonce
        $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : '';
        if ( ! wp_verify_nonce( $nonce, 'submit_deactivate' ) ) {
            wp_die( 'Are you cheating?' );
        }
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( 'Are you cheating?' );
        }
        // Unslash and sanitize envato_deactivate
        $envato_deactivate = isset( $_POST['envato_deactivate'] )
            ? sanitize_text_field( wp_unslash( $_POST['envato_deactivate'] ) )
            : '';

        if ( $envato_deactivate ) {
            $url      = self::LICENCE_CALL_URL . "/wp-json/licenseenvato/v1/deactive";
            $response = $this->apicall( $url, $code );
            $date     = json_decode( $response );

            $statusCode    = isset( $date->code )    ? $date->code    : '';
            $statusMessage = isset( $date->message ) ? $date->message : '';

            if ( $statusCode === 'already_deactivated' ) {
                delete_option( self::PREFIX . '_envato_is_activated' );
                delete_option( self::PREFIX . '_envato_token' );
                delete_option( self::PREFIX . '_envato_purchase_code' );
                delete_option( self::PREFIX . '_envato_itemid' );
            } elseif ( $statusCode ) {
                return $statusMessage;
            } else {
                delete_option( self::PREFIX . '_envato_is_activated' );
                delete_option( self::PREFIX . '_envato_token' );
                delete_option( self::PREFIX . '_envato_purchase_code' );
                delete_option( self::PREFIX . '_envato_itemid' );
            }
        }
    }

    private function apicall( $url, $purchase_code, $domain = null, $itemid = null ) {
        if ( $domain ) {
            $body = array(
                'code'   => $purchase_code,
                'domain' => $domain,
                'itemid' => $itemid,
            );
        } else {
            $body = array(
                'token' => $purchase_code,
            );
        }

        $headers  = array( 'Content-Type' => 'application/json' );
        $response = wp_remote_post( $url, array(
            'method'  => 'POST',
            'headers' => $headers,
            'body'    => json_encode( $body ),
        ) );

        return $response['body'];
    }
}
?>

3 Display the License Form

Once the class is in place, call it wherever you want to render the activation / deactivation form — for example, on your plugin's settings page.

PHP · function-call.php
<?php new licenseCodeVerifyForm(); ?>
🎉
That's it! Customers can now activate and deactivate their Envato purchase codes directly from your theme or plugin settings page.

REST API Reference

The plugin exposes two public REST endpoints under the namespace licenseenvato/v1.

Activate License

Endpoint https://YOUR_SITE_URL/wp-json/licenseenvato/v1/active
Method POST
Auth Public (no authentication required)

Activate — Parameters

Parameter Type Required Description
code string Envato purchase code
domain string Customer's domain (URL-encoded)
itemid string Envato item / product ID

Deactivate License

Endpoint https://YOUR_SITE_URL/wp-json/licenseenvato/v1/deactive
Method POST
Auth Public (no authentication required)

Deactivate — Parameters

Parameter Type Required Description
token string License token returned during activation

Example Request (Activate)

PHP · wp_remote_post
$response = wp_remote_post( 'https://YOUR_SITE_URL/wp-json/licenseenvato/v1/active', [
    'headers' => [ 'Content-Type' => 'application/json' ],
    'body'    => json_encode( [
        'code'   => $purchase_code,
        'domain' => urlencode( $domain ),
        'itemid' => $item_id,
    ] ),
] );
$data = json_decode( wp_remote_retrieve_body( $response ) );
// $data->token — store this token; you will need it for deactivation

Code Reference

A quick reference for the key constants and methods inside the integration class.

Constants

Constant Description
LICENCE_CALL_URL Base URL of your license server (your WordPress site URL).
PREFIX Unique prefix used for wp_options keys. Change this per product to avoid collisions.

Key Methods

Method Visibility Description
LicenceHTMLForm() public Renders the activate / deactivate form HTML.
licenceActivate() private Handles the activation POST, calls REST API, stores token.
licenceDeactivate() private Handles deactivation POST, calls REST API, clears options.
apicall() private Sends POST request to the server REST endpoint.
domain() private Returns the current site's domain (URL-encoded).

wp_options Keys (Client-side)

Option Key Description
{PREFIX}_envato_token Stored license token returned by the server on activation.
{PREFIX}_envato_is_activated Boolean — whether the license is currently active.
{PREFIX}_envato_purchase_code The raw Envato purchase code entered by the customer.
{PREFIX}_envato_itemid Envato item ID associated with the activated license.
Replace {PREFIX} with the value you set for the PREFIX constant — for example, if your prefix is mytheme, the token key would be mytheme_envato_token.

License For Envato Pro

A paid add-on that installs alongside this free plugin and unlocks activation limits, automatic updates for your own products, webhooks, blacklisting, activity logs and more — all through the same license server you already set up.

🚀
Get it at https://codeholt.com/products/license-envato-pro/. Install it next to License For Envato, activate your Pro license under Settings → Pro License, and the extra admin pages below appear automatically.

Free vs Pro

Everything in Free is included in Pro, plus the rows below.

Feature Free Pro
Envato purchase code verification
Per-domain license activation & deactivation
REST API endpoints + copy-paste client class
Admin license list with search
Secure encrypted token storage
Multiple domain activations per license (configurable limits)
Support expiry enforcement with Envato renewal re-sync
Email notifications + daily expiry-warning digest
Webhooks with signed payloads
Purchase code & domain blacklist
Activity log with CSV export
Manual & bulk license issuance
Automatic update delivery for your themes/plugins
Analytics dashboard
Priority support

Pro Admin Pages

Once Pro is active and licensed, these pages appear under the License Envato menu.

PageWhat it does
All UsersNow shows every activated domain per license (not just the first), each with its own deactivate action, and enforces your configured domain limit per purchase code.
UpdatesManage the latest version, changelog and update ZIP for each of your own Envato item IDs — this is what powers Automatic Update Delivery below.
Issue LicensesManually or bulk-issue license keys that work without an Envato purchase — useful for pre-sales, reissues or support cases.
BlacklistBlock a purchase code or a domain from activating; blocked activation attempts are rejected with a 403 from the REST API.
AnalyticsDashboard view of activations, deactivations and license activity over time.
Settings → Pro LicenseActivate/deactivate your own License For Envato Pro purchase code on this site; also where email notifications and webhook URLs are configured.

Automatic Update Delivery

Pro turns your license server into an update server too, so your customers get one-click updates from their WordPress Plugins screen — no separate hosting needed.

How It Works

  • Upload each product's latest version, changelog and ZIP under License Envato → Updates.
  • Ship the drop-in client-sample/update-checker.php class (included with Pro) inside your own theme or plugin.
  • The client polls your server's token-authenticated REST endpoints and WordPress core handles the rest — update notice, changelog popup, one-click install.
Update checkPOST /wp-json/licenseenvato/v1/update-check — body: token, itemid, version
DownloadGET /wp-json/licenseenvato/v1/download — query: token, itemid
PHP · your-plugin-main-file.php
require_once __DIR__ . '/update-checker.php';
new My_Prefix_Update_Checker(
    __FILE__,                          // plugin main file
    '1.0.0',                           // current version
    '12345678',                        // your Envato item ID
    'https://YOUR_LICENSE_SERVER_URL'  // this WordPress site
);
The token comes from the same activation flow as Step 2 — whatever your client class stores after a successful /active call. Only activated, non-expired licenses can check for and download updates.