---
url: https://docs.sunlicense.com/how-to/wordpress-plugin.md
description: >-
  How to add license keys to a WordPress plugin you sell - a license settings
  field, a check with the SunLicense PHP SDK cached in a transient, an admin
  notice on a rejection, per-site limits, prefixed dependencies, and why plugins
  on wordpress.org can't lock features behind a key.
---

# How to add license keys to a WordPress plugin

**Short answer:** add a "License key" field to your plugin's settings, check the key with the SunLicense PHP SDK in the
admin (cached in a transient for 12 hours, so pages stay fast), and when SunLicense says no, show an admin notice and
stop serving the Pro features or updates. A network error is not a no: keep working and check later.

```php
// composer require sunlicense/sunlicense, bundled (and prefixed, see below) in your plugin zip
add_action('admin_init', function () {
    $key = trim((string) get_option('myplugin_license_key', ''));
    if ($key === '' || get_transient('myplugin_license_ok') !== false) return;
    try {
        $client = new \SunLicense\SunLicenseClient('https://api.sunlicense.com', MYPLUGIN_API_KEY);
        $r = $client->validate($key, ['host' => hash('sha256', home_url())]);   // one site = one machine
        if ($r->getStatusCode() === 400) {           // EXPIRED, REVOKED, TOO_MANY_MACHINES…
            update_option('myplugin_license_error', $r->toArray()['code'] ?? 'INVALID');
            return;
        }
        delete_option('myplugin_license_error');
        set_transient('myplugin_license_ok', 1, 12 * HOUR_IN_SECONDS);
    } catch (\SunLicense\SunLicenseException $e) {
        set_transient('myplugin_license_ok', 1, HOUR_IN_SECONDS);   // unreachable: try again in an hour
    }
});
```

Your Pro features check `get_option('myplugin_license_error')` is empty; an `admin_notices` hook shows the error with a
link to the settings page.

**Or let your AI agent do it:** paste the [setup prompt](https://sunlicense.com/prompt) into Claude Code, Cursor or
Codex in your plugin's folder.

Free plan: 3 products, 100 licenses, no credit card. [Create a free account](https://sunlicense.com/start?ref=docs-howto-wordpress).

## Step by step

1. **In the dashboard:** a product, a policy where a machine is a **site** (for example "Single site" with *1 machine*,
   "Agency" with *25*) and an **API key**, which can only validate.
2. **Sites, not servers.** Send a hash of `home_url()` as `host`, so a site keeps its slot through server moves and a
   staging copy on another domain counts as another site (add an [exclusion](/guide/access-rules) or a bigger policy if
   you allow staging).
3. **Settings field.** `register_setting('myplugin', 'myplugin_license_key')` plus a field on your settings page; when
   the key changes, `delete_transient('myplugin_license_ok')` so it's checked at once.
4. **Prefix the SDK.** Every plugin shares one PHP process, so two plugins bundling different versions of
   `SunLicense\…` would clash. Prefix vendor namespaces with [Strauss](https://github.com/BrianHenryIE/strauss) or
   PHP-Scoper before you zip the plugin (`YourPlugin\Vendor\SunLicense\…`). The SDK needs PHP 8.0+ and uses cURL when
   the site has it.
5. **Your API key** as a constant in a generated file your release script writes (`MYPLUGIN_API_KEY`), never in git.
   It can only validate licenses, so it's fine inside the zip.
6. **Results:** 200 enables Pro, 400 shows the [reason](/guide/concepts#validation-result-codes) in an admin notice
   (mask the key: `AX8P-XXXX-XXXX-XXXX`), anything else keeps Pro running and retries in an hour.
7. **Updates and support** are what a key controls best on WordPress: check the license in your update server or
   download link too, so a revoked key stops getting new versions.

## wordpress.org and the GPL

* **Plugins hosted on wordpress.org can't lock features behind a license key**: the directory's guidelines ban
  trialware and locked features. Keep the free plugin complete on wordpress.org and sell Pro as a separate add-on
  plugin from your own site (WooCommerce, Lemon Squeezy, Payhip, Envato). Only the add-on checks the key, and its
  readme says it connects to SunLicense.
* **WordPress plugins are GPL**, so buyers may share the code. A license key controls what you provide: updates,
  support and any service your plugin calls. PHP source is readable; SunLicense's [obfuscation](/guide/obfuscation)
  doesn't cover PHP.

## Selling it

[WooCommerce](/integrations/woocommerce), [Lemon Squeezy](/integrations/lemon-squeezy), [Payhip](/integrations/payhip),
[Gumroad](/integrations/gumroad) and [Envato](/integrations/envato) (CodeCanyon purchase codes) issue a key per
purchase and revoke it on a refund. More on [licensing WordPress plugins](https://sunlicense.com/for/wordpress-plugins/).
Selling a whole PHP application? See [Laravel](/how-to/laravel-app).
