Files
wp-digital-download/docs/developer-integration-guide.md
jknapp cec5daa0b0
All checks were successful
Create Release / build (push) Successful in 3s
removing unneeded files from repo and plugin
2025-09-10 06:02:50 -07:00

15 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. Minimal Integration

For the simplest integration with automatic license management:

<?php
/**
 * Plugin Name: My Plugin
 * Version: 1.0.0
 */

// Initialize updater with automatic settings page
if (!class_exists('WPDD_Plugin_Updater') && is_admin()) {
    require_once plugin_dir_path(__FILE__) . 'includes/wpdd-plugin-updater.php';
    
    new WPDD_Plugin_Updater(
        __FILE__,
        get_option('my_plugin_license_key', ''),
        'https://your-store.com',
        array('add_settings_page' => true)
    );
}

This creates a license settings page under Settings → My Plugin License.

3. Full Integration

<?php
/**
 * Plugin Name: My Awesome Plugin
 * Version: 1.0.0
 */

// Include the WPDD updater library (check if class exists to avoid conflicts)
if (!class_exists('WPDD_Plugin_Updater')) {
    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() {
        // Check if updater class exists
        if (!class_exists('WPDD_Plugin_Updater')) {
            return;
        }
        
        $license_key = get_option('my_plugin_license_key', '');
        
        $this->updater = new WPDD_Plugin_Updater(
            MY_PLUGIN_FILE,                             // Define this constant to your main 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 ? $this->updater->validate_license() : false;
        
        ?>
        <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() {
        // Include updater if not already loaded
        if (!class_exists('WPDD_Plugin_Updater')) {
            require_once plugin_dir_path(__FILE__) . 'includes/wpdd-plugin-updater.php';
        }
        
        $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() {
        // Check if updater exists and validate license
        return $this->updater ? $this->updater->validate_license() : false;
    }
    
    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

Requirements

  • WordPress: 5.0 or higher
  • PHP: 7.0 or higher
  • Plugin Version Header: Your main plugin file must include a Version header

Constructor Parameters

new WPDD_Plugin_Updater($plugin_file, $license_key, $update_server, $args);
  • $plugin_file (string) - Full path to your main plugin file (typically __FILE__)
  • $license_key (string) - The user's license key (can be empty string)
  • $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

  1. Go to your WordPress admin → Digital Products → Add New Product
  2. Select "Software License" as product type
  3. 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:

  1. Go to Settings → Webhooks
  2. Add webhook with the URL from your product page
  3. Set Content-Type to application/json
  4. Select "Release events" as the trigger
  5. Ensure webhook is active

GitHub:

  1. Go to Settings → Webhooks
  2. Add webhook with the URL from your product page
  3. Set Content-Type to application/json
  4. Select "Releases" events (or "Just the push event" for tag-based releases)

GitLab:

  1. Go to Settings → Webhooks
  2. Add the webhook URL
  3. Select "Tag push events" or "Releases events"

3. Release Process

Option 1: Using Git Platform Releases (Recommended for Gitea/GitHub)

  1. 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
  2. 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)

  1. Create and push a git tag:

    git tag -a v1.2.0 -m "Version 1.2.0"
    git push origin v1.2.0
    
  2. 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:

// Check if updater was initialized properly
if (!$this->updater) {
    // Handle initialization failure
    error_log('WPDD Updater failed to initialize');
    return;
}

$result = $updater->validate_license();
if ($result === false) {
    // Network error or server down - allow functionality to continue
    // but maybe show a notice
    error_log('License validation failed - network or server issue');
}

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();
}

What's New in Version 1.1.0

The updated wpdd-plugin-updater.php includes several improvements:

Enhanced Error Handling

  • Better HTTP request error handling with status code checking
  • JSON validation to prevent parsing errors
  • Improved timeout handling (30 seconds default)
  • More detailed error logging for debugging

Improved Compatibility

  • Better API response structure handling
  • Flexible URL checking for package downloads
  • Support for different server configurations
  • Fallback values for missing data fields

Security Enhancements

  • SSL verification enabled by default
  • Proper input validation in constructor
  • Safe handling of network failures

Performance Improvements

  • 12-hour caching for update checks
  • Optimized HTTP requests with proper headers
  • Reduced unnecessary API calls

Troubleshooting

Common Issues

  1. Updates not showing:

    • Check that the plugin slug matches the product slug in your store
    • Verify the plugin file has a proper Version header
    • Clear update transients using the force update check method
  2. License validation fails:

    • Ensure the update server URL is correct and accessible
    • Check that the license key is properly formatted
    • Verify SSL certificates are valid on your server
  3. Download fails:

    • Verify the license is activated and not expired
    • Check activation limits haven't been exceeded
    • Ensure the package file exists on the server

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.