Appearance
Auto Updates
Enable automatic updates for your WordPress plugin using PackEdge.
Installation
bash
composer require packedge-sdk/licenseQuick Setup
php
use PackEdge\License;
$license = License::init('pk_your_public_key', __FILE__);
$license->updater();That's it. The SDK hooks into WordPress's update system automatically.
How It Works
- WordPress checks for updates periodically
- The SDK queries PackEdge's update-check endpoint for the product's stable release (the version you mark stable in the console; publishing a new version makes it stable automatically, and you can roll back to an earlier one)
- If a newer version exists, it appears in the WordPress updates screen — even for unlicensed sites, as a nudge to activate
- When the user clicks "Update", WordPress downloads the ZIP from PackEdge — but the download URL is only handed out to a valid, licensed, active site. Unlicensed or deactivated sites see the update but can't download it
- The SDK fixes folder names to match your plugin slug
Show the update, gate the download
The update notice is intentionally always shown; only the package (ZIP) URL is license-gated. So a site with no license, an expired/invalid license, or a deactivated activation still sees "update available" — clicking Update just fails until they activate a valid license.
When the stored license changes (activated, deactivated, disabled), the SDK clears WordPress's update_plugins transient so the Plugins/Updates screen re-checks entitlement immediately instead of waiting out the ~12h cache.
Complete Example
php
<?php
/**
* Plugin Name: My Plugin
* Version: 1.0.0
*/
require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
use PackEdge\License;
$license = License::init('pk_your_public_key', __FILE__);
// Enable auto-updates. The update notice shows regardless of license state;
// the download is only served to a valid, licensed, active site.
$license->updater();What the Updater Does
The Updater class hooks into three WordPress filters:
1. Update Check
pre_set_site_transient_update_plugins — Checks if a new version is available.
2. Plugin Info
plugins_api — Shows version details in the "View Details" popup.
3. Folder Fix
upgrader_source_selection — Renames the extracted folder to match your plugin slug.
Requirements
- Valid license key saved in WordPress options
- Release uploaded to PackEdge console
- Plugin slug matches your product slug
Manual Integration
If you prefer not to use the SDK, hook into WordPress directly:
php
add_filter('pre_set_site_transient_update_plugins', function($transient) {
// license_key is optional — without it the update still shows, the API just
// omits the package so the download is gated.
$license_key = get_option('my_plugin_license')['key'] ?? '';
$response = wp_remote_get(add_query_arg(array_filter([
'slug' => 'my-plugin',
'license_key' => $license_key,
'version' => MY_PLUGIN_VERSION,
'site' => site_url(),
]), 'https://api.packedge.dev/public/v1/wp/update-check'), [
'headers' => ['X-Public-Key' => 'pk_your_public_key'],
]);
if (is_wp_error($response)) return $transient;
$update = json_decode(wp_remote_retrieve_body($response));
if (isset($update->version) && version_compare(MY_PLUGIN_VERSION, $update->version, '<')) {
// Always surfaced as available; $update->package is empty for
// unlicensed/deactivated sites, so WP shows it but the download fails.
$transient->response['my-plugin/my-plugin.php'] = (object) [
'slug' => $update->slug,
'new_version' => $update->version,
'package' => $update->package ?? '',
];
}
return $transient;
});Troubleshooting
Updates not showing
The update notice does not require a license — if it's missing entirely:
- Verify a release is published and marked stable in the PackEdge console
- Check the installed version is older than the stable release version
- Confirm the plugin slug matches the product slug
- Clear WordPress update transients:
delete_site_transient('update_plugins')
Update shows but "Update" fails / no download
This is the license gate working as intended — the package URL is only served to a valid, licensed, active site:
- Check the license is valid:
$license->is_valid() - Confirm the site's activation hasn't been deactivated in the console
- Confirm the license isn't expired
Wrong folder name after update
The SDK automatically fixes this, but if using manual integration, add:
php
add_filter('upgrader_source_selection', function($source, $remote_source, $upgrader, $hook_extra) {
if (!isset($hook_extra['plugin']) || $hook_extra['plugin'] !== 'my-plugin/my-plugin.php') {
return $source;
}
$correct_path = trailingslashit($remote_source) . 'my-plugin';
if ($source !== $correct_path) {
rename($source, $correct_path);
return $correct_path;
}
return $source;
}, 10, 4);