12 KiB
WP Digital Download - Software Licensing Integration Guide
This guide shows developers how to integrate their WordPress plugins with the WP Digital Download licensing and update system.
Quick Start
1. Download the Integration Library
Download wpdd-plugin-updater.php
from your product page and include it in your plugin.
2. Basic Integration
<?php
/**
* Plugin Name: My Awesome Plugin
* Version: 1.0.0
*/
// Include the WPDD updater library
require_once plugin_dir_path(__FILE__) . 'includes/wpdd-plugin-updater.php';
class My_Awesome_Plugin {
private $updater;
public function __construct() {
$this->init_updater();
}
private function init_updater() {
// Only initialize updater in admin area
if (!is_admin()) {
return;
}
$license_key = get_option('my_plugin_license_key', '');
$this->updater = new WPDD_Plugin_Updater(
__FILE__, // Main plugin file
$license_key, // License key from user
'https://your-store.com', // Your store URL
array(
'add_settings_page' => true // Add license settings page
)
);
}
}
new My_Awesome_Plugin();
Advanced Integration
Custom License Settings Page
If you want to integrate license management into your existing settings:
class My_Plugin_Settings {
private $updater;
public function __construct() {
$this->init_updater();
add_action('admin_menu', array($this, 'add_settings_page'));
add_action('admin_init', array($this, 'handle_license_actions'));
}
private function init_updater() {
$license_key = get_option('my_plugin_license_key', '');
$this->updater = new WPDD_Plugin_Updater(
MY_PLUGIN_FILE,
$license_key,
'https://your-store.com',
array('add_settings_page' => false) // We'll handle settings ourselves
);
}
public function handle_license_actions() {
if (isset($_POST['activate_license'])) {
$license_key = sanitize_text_field($_POST['license_key']);
$result = $this->updater->activate_license($license_key);
if ($result['success']) {
update_option('my_plugin_license_key', $license_key);
add_settings_error('my_plugin', 'activated', 'License activated!', 'updated');
} else {
add_settings_error('my_plugin', 'error', $result['message'], 'error');
}
}
if (isset($_POST['deactivate_license'])) {
$result = $this->updater->deactivate_license();
if ($result['success']) {
delete_option('my_plugin_license_key');
add_settings_error('my_plugin', 'deactivated', 'License deactivated!', 'updated');
}
}
}
public function render_license_section() {
$license_key = get_option('my_plugin_license_key', '');
$is_valid = $this->updater->validate_license();
?>
<h3>License Settings</h3>
<table class="form-table">
<tr>
<th><label for="license_key">License Key</label></th>
<td>
<input type="text" id="license_key" name="license_key"
value="<?php echo esc_attr($license_key); ?>" class="regular-text" />
<?php if ($is_valid): ?>
<span style="color: green;">✓ Active</span>
<?php elseif (!empty($license_key)): ?>
<span style="color: red;">✗ Invalid</span>
<?php endif; ?>
<p class="description">
Enter your license key to receive automatic updates.
</p>
</td>
</tr>
</table>
<?php if (empty($license_key) || !$is_valid): ?>
<p>
<input type="submit" name="activate_license" class="button-primary" value="Activate License" />
</p>
<?php else: ?>
<p>
<input type="submit" name="deactivate_license" class="button-secondary" value="Deactivate License" />
</p>
<?php endif; ?>
<?php
}
}
Manual License Validation
For premium features or activation checks:
class My_Premium_Feature {
private $updater;
public function __construct() {
$license_key = get_option('my_plugin_license_key', '');
$this->updater = new WPDD_Plugin_Updater(
MY_PLUGIN_FILE,
$license_key,
'https://your-store.com'
);
// Only enable premium features if license is valid
if ($this->is_license_valid()) {
$this->enable_premium_features();
} else {
$this->show_license_notice();
}
}
private function is_license_valid() {
return $this->updater->validate_license();
}
private function enable_premium_features() {
// Add your premium functionality here
add_action('init', array($this, 'init_premium_features'));
}
private function show_license_notice() {
add_action('admin_notices', function() {
?>
<div class="notice notice-warning">
<p>
<strong>My Awesome Plugin:</strong>
Please <a href="<?php echo admin_url('options-general.php?page=my-plugin-settings'); ?>">
activate your license</a> to access premium features and receive updates.
</p>
</div>
<?php
});
}
}
API Reference
WPDD_Plugin_Updater Class
Constructor Parameters
new WPDD_Plugin_Updater($plugin_file, $license_key, $update_server, $args);
- $plugin_file (string) - Full path to your main plugin file
- $license_key (string) - The user's license key
- $update_server (string) - URL to your store (e.g., 'https://your-store.com')
- $args (array) - Optional arguments:
add_settings_page
(bool) - Auto-create license settings page (default: false)
Methods
validate_license()
Validates the current license with the server.
$is_valid = $updater->validate_license();
// Returns: boolean
activate_license($license_key)
Activates a license key for the current site.
$result = $updater->activate_license('XXXX-XXXX-XXXX-XXXX');
// Returns: array with 'success', 'message', and additional data
deactivate_license()
Deactivates the current license from this site.
$result = $updater->deactivate_license();
// Returns: array with 'success' and 'message'
Repository Setup (For Store Owners)
1. Create Software Product
- Go to your WordPress admin → Digital Products → Add New Product
- Select "Software License" as product type
- Fill in the software licensing fields:
- Git Repository URL
- License settings (max activations, duration)
- Version information
2. Configure Git Webhook
Add the generated webhook URL to your repository settings. The system receives webhook notifications FROM your Git platform when releases are published:
Gitea:
- Go to Settings → Webhooks
- Add webhook with the URL from your product page
- Set Content-Type to
application/json
- Select "Release events" as the trigger
- Ensure webhook is active
GitHub:
- Go to Settings → Webhooks
- Add webhook with the URL from your product page
- Set Content-Type to
application/json
- Select "Releases" events (or "Just the push event" for tag-based releases)
GitLab:
- Go to Settings → Webhooks
- Add the webhook URL
- Select "Tag push events" or "Releases events"
3. Release Process
Option 1: Using Git Platform Releases (Recommended for Gitea/GitHub)
-
Create a release through your Git platform's web interface:
- Navigate to Releases section
- Click "Create Release" or "New Release"
- Set tag name (e.g.,
v1.2.0
) - Add release notes in the description
- Publish the release
-
The webhook automatically receives the release notification and:
- Detects the new version from the release
- Clones the repository at the specific tag
- Creates distribution packages (removes dev files, creates ZIP)
- Stores version info and changelog in the database
- Makes update available to customers with active licenses
Option 2: Using Git Tags (Alternative)
-
Create and push a git tag:
git tag -a v1.2.0 -m "Version 1.2.0" git push origin v1.2.0
-
The webhook receives the tag push notification and processes the release similarly
API Endpoints
License Validation
POST /wp-json/wpdd/v1/validate-license
Body: {
"license_key": "XXXX-XXXX-XXXX-XXXX",
"product_slug": "my-plugin",
"site_url": "https://example.com"
}
Update Check
GET /wp-json/wpdd/v1/check-update/my-plugin?license_key=XXXX&version=1.0.0
Download Update
GET /wp-json/wpdd/v1/download-update/my-plugin?license_key=XXXX
Testing Your Integration
1. Local Testing
// Add this to your plugin for testing
if (defined('WP_DEBUG') && WP_DEBUG) {
add_action('admin_notices', function() {
$license_key = get_option('my_plugin_license_key', '');
$updater = new WPDD_Plugin_Updater(__FILE__, $license_key, 'https://your-store.com');
$is_valid = $updater->validate_license();
echo '<div class="notice notice-info">';
echo '<p>License Status: ' . ($is_valid ? 'Valid' : 'Invalid') . '</p>';
echo '</div>';
});
}
2. Force Update Check
// Add this temporarily to force update check
add_action('admin_init', function() {
if (isset($_GET['force_update_check'])) {
delete_transient('wpdd_update_my-plugin');
delete_site_transient('update_plugins');
wp_redirect(admin_url('plugins.php'));
exit;
}
});
Then visit: wp-admin/plugins.php?force_update_check=1
Best Practices
1. Error Handling
Always handle API failures gracefully:
$result = $updater->validate_license();
if ($result === false) {
// Network error or server down - allow functionality to continue
// but maybe show a notice
}
2. Caching
The updater automatically caches responses. Don't call validation on every page load:
// Good - check once per day
$last_check = get_option('my_plugin_license_check', 0);
if (time() - $last_check > DAY_IN_SECONDS) {
$is_valid = $updater->validate_license();
update_option('my_plugin_license_check', time());
update_option('my_plugin_license_valid', $is_valid);
} else {
$is_valid = get_option('my_plugin_license_valid', false);
}
3. Graceful Degradation
Design your plugin to work without a valid license, but with reduced functionality:
if ($this->is_license_valid()) {
// Full functionality
$this->enable_all_features();
} else {
// Basic functionality only
$this->enable_basic_features();
$this->show_upgrade_notice();
}
Troubleshooting
Common Issues
- Updates not showing: Check that the plugin slug matches the product slug in your store
- License validation fails: Ensure the update server URL is correct and accessible
- Download fails: Verify the license is activated and not expired
Debug Mode
Enable WordPress debug logging and check for WPDD Updater messages:
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
Check /wp-content/debug.log
for error messages.
Support
For integration support:
- Check the troubleshooting section above
- Enable debug logging and check for error messages
- Contact support with your store URL and plugin details
Example Files
Complete example plugins are available in the /examples/
directory of this package.