wordpress
WordPress Plugin Licensing System: How to Design a Licence Server
Selling a WordPress plugin means deciding how keys are activated, limited, revoked and renewed without punishing paying customers. Lessons from running our own licence server.
By AYM FlowPublished: Updated: 6 min read
Selling a premium WordPress plugin raises questions that free plugins never face. How does a customer activate a key? How many sites can use it? What happens when a licence expires or a payment is refunded? And how do you enforce all of it without locking honest customers out? This guide describes a licensing design that works in production, drawing on running our own licence server for AYM Multilingual.
What a licensing system should and should not do
A licence system exists to connect a purchase to entitlements: updates, support, premium features and a number of sites. It is not a perfect copy-protection tool. WordPress is licensed under the GPL, so determined people can always modify PHP code. Design the system to make the honest path easy and to protect your revenue from casual abuse, and never to damage the site of a paying customer.
Core architecture: key, activation, validation
The basic model has three parts: a licence record on your server, an activation call from the plugin, and a periodic validation.
- Issue keys at purchase, generated from a cryptographically secure random source and tied to a plan, an expiry date and a site limit. Store them server-side with hashed or otherwise protected lookups.
- Activate when the customer pastes the key. The plugin sends the key, the site domain and the plugin version over HTTPS. The server checks status, expiry and remaining slots, records the activation and returns a result.
- Validate periodically, for example once or twice a day through a scheduled event and a cached result, not on every page load. Each check confirms the licence is still valid for this domain.
- Gate premium behaviour on the stored result, so a brief network failure never changes how the site works.
Disclose exactly what is sent. Our own privacy policy states that the key, domain and plugin version are transmitted for validation, which is the minimum needed, and your customers deserve the same clarity in your documentation and privacy notice.
Keep the key format simple and human-friendly, because customers will copy it from an email, and make activation tolerant of stray spaces and line breaks. Store the activation result with a timestamp, the licence status and the expiry date it reported, so the plugin can decide locally what to do between checks. When activation fails, show a specific message such as 'key not found', 'no slots left' or 'licence expired', rather than a generic error, because vague failures create most licensing support tickets.
Domain limits and moving sites
Plans differ by site count: a single-site licence, or a multi-site licence for agencies, as in our pricing for AYM Multilingual, where one tier covers one site and another covers up to five. Practical rules that avoid support pain:
- Normalise domains before comparing: lowercase, no protocol, and a decision on www and subdomains.
- Do not count local and staging environments against the limit. Detect common development hostnames or give customers a clear staging rule.
- Let customers deactivate a site themselves and free the slot, from the plugin and from an account page. Domain changes and migrations are normal, not abuse.
- Show remaining slots and the activated domains so customers can self-serve instead of emailing you.
Revocation, expiry and the grace period
Model licence states explicitly: active, expired, revoked and refunded. Each should map to a defined plugin behaviour.
- Expired means no more updates and support, not a broken site. Features that the customer relied on should keep working, or degrade gently with a clear notice.
- Revoked or refunded removes premium features or updates, but never deletes customer content or data.
- Grace period. If your server is unreachable, assume the last known good state for a defined window, such as several days, before showing any warning. Fail open on network errors, fail closed only on an explicit negative answer.
- Renewal flow. Remind customers before expiry and let a renewed key work without reinstalling anything.
The golden rule is that your outage must never become your customer's outage.
Delivering updates to licensed sites
Updates are the main entitlement. A plugin can hook into WordPress's update checks to ask your server about new versions, following the conventions in the plugin developer handbook. The server should verify the licence before returning a package URL, and the URL should be signed and short-lived so it cannot be shared. Return the changelog and compatibility data so the update screen looks like any other. Keep your update endpoints rate-limited and cached, since every licensed site will poll them.
Plan for versioned compatibility too. Return the minimum supported WordPress and PHP versions with every release, so the plugin never offers an update that would break a customer's site, and consider letting customers roll back to the previous version if a release causes problems. Updates are where licensing is most visible to customers, so reliability here earns more goodwill than any feature.
Lessons from running our own licence server
Running licensing for AYM Multilingual taught us that most of the work is not cryptography but edge cases and support.
- Build admin tools first: search by key or domain, view activations, revoke, reassign and extend. Support requests are constant.
- Log every activation and check with the result, so you can answer 'why did my licence fail' within minutes.
- Handle cloned databases and changed domains gracefully, since site migrations happen all the time.
- Keep the plugin's licence code small, isolated and well tested, and never let a licence failure produce a PHP error.
- Use HTTPS everywhere and validate server responses, ideally signed, so the plugin cannot be tricked by a spoofed reply.
If you are planning a commercial plugin, start with the fundamentals in our WordPress plugin development guide. We design and build plugins, licence servers and update delivery through our WordPress plugin development service, and we can adapt what already runs in production for your product.
Frequently asked questions
How does a WordPress plugin licence key work?
The customer enters a key, the plugin sends it with the site domain to your licence server, and the server checks the plan, expiry and site limit. The result is stored and re-checked periodically.
Can WordPress licensing be cracked?
Code in a GPL-licensed plugin can always be modified, so licensing cannot be absolute protection. It protects updates, support and casual abuse. Value comes from updates, service and trust, not from lock-in.
What should happen when a licence expires?
The customer should lose updates and support but keep a working site. Premium features can degrade gracefully, and a renewal should restore everything without reinstalling.
Why use a grace period?
Servers go down and networks fail. A grace period prevents a temporary outage on your side from disabling features on a paying customer's site.
Related articles
wordpress
WooCommerce Speed and Conversion Optimization: A Practical Guide
A faster WooCommerce store converts better, but only if checkout is also easy. Cover caching, product pages, scripts, database health and checkout friction in the right order.
wordpress
How to Improve Core Web Vitals on WordPress: LCP, INP and CLS Fixes That Work
Passing Core Web Vitals on WordPress is mostly about images, JavaScript and layout discipline. Here is how to measure, prioritise and fix LCP, INP and CLS.
wordpress
How to Build a Custom WordPress Plugin: Structure, Hooks, Security and Testing
A practical walkthrough of custom WordPress plugin development: structure, hooks, security rules, REST endpoints and testing, based on what we ship in production.
