Files
wp-digital-download/docs/developer-integration-guide.md
2025-08-29 18:54:14 -07:00

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

  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:

$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

  1. Updates not showing: Check that the plugin slug matches the product slug in your store
  2. License validation fails: Ensure the update server URL is correct and accessible
  3. 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.