# 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
<?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:

```php
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:

```php
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

```php
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.
```php
$is_valid = $updater->validate_license();
// Returns: boolean
```

##### activate_license($license_key)
Activates a license key for the current site.
```php
$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.
```php
$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:
   ```bash
   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

```php
// 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

```php
// 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:

```php
$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:

```php
// 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:

```php
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:

```php
// 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.