wp-freemius — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited wp-freemius (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Model note: SDK bootstrap and basic feature-gating are pattern-matching (haiku). Trialware compliance audit and pricing-plan architecture decisions require careful judgment — usesonnetfor those.
Integrate Freemius into a WordPress plugin for commercial distribution: SDK bootstrap, free/pro feature gating, license management, trials, pricing page, and the Freemius dashboard. Freemius handles payments, license keys, update delivery, and analytics.
Not for: General WooCommerce payment flows — use wp-woocommerce. WP.org trialware compliance (Freemius-powered upsells must follow WP.org Guideline 5 — use wp-org-submission, which contains references/trialware-compliance.md).
https://freemius.comVia Composer (recommended):
composer require freemius/wordpress-sdkManual: Download from https://github.com/Freemius/wordpress-sdk and place in vendor/freemius/.
Create includes/freemius.php (the Freemius singleton init file):
<?php
if ( ! function_exists( 'my_plugin_fs' ) ) {
function my_plugin_fs() {
global $my_plugin_fs;
if ( ! isset( $my_plugin_fs ) ) {
// Include the Freemius SDK
require_once plugin_dir_path( __FILE__ ) . '../vendor/freemius/wordpress-sdk/start.php';
$my_plugin_fs = fs_dynamic_init( [
'id' => '12345', // Plugin ID from dashboard
'slug' => 'my-plugin', // WP.org slug
'type' => 'plugin',
'public_key' => 'pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // Public key
'is_premium' => false, // true if this IS the premium build
'has_premium_version' => true, // true if premium version exists
'has_addons' => false,
'has_paid_plans' => true,
'trial' => [
'days' => 14,
'is_require_payment' => false, // true = credit card required
],
'menu' => [
'slug' => 'my-plugin',
'contact' => false,
'support' => false,
],
] );
}
return $my_plugin_fs;
}
// Init Freemius
my_plugin_fs();
// Hook Freemius after initial plugin setup
do_action( 'my_plugin_fs_loaded' );
}Load from main plugin file:
// At the top of my-plugin.php, before any premium-gated code
require_once plugin_dir_path( __FILE__ ) . 'includes/freemius.php';Gate premium features consistently throughout the codebase:
// Check if user has an active paid plan (or trial)
if ( my_plugin_fs()->can_use_premium_code() ) {
// Show/run premium feature
require_once plugin_dir_path( __FILE__ ) . 'includes/class-premium-feature.php';
}
// Check if the premium code file is loaded (for the __premium_only__ pattern)
if ( my_plugin_fs()->is__premium_only() ) {
// Always true when premium file is present
}
// Specific plan check
if ( my_plugin_fs()->is_plan( 'professional', true ) ) {
// $true = or_greater: matches 'professional' and any higher plan
}
// Trial check
if ( my_plugin_fs()->is_trial() ) {
echo 'Trial active: ' . my_plugin_fs()->get_trial_plan()->title;
}
// Free user upsell prompt
if ( ! my_plugin_fs()->is_paying() ) {
// Show upgrade CTA
$upgrade_url = my_plugin_fs()->get_upgrade_url();
}`__premium_only__` file pattern — Freemius strips these files from the free build:
my-plugin/
├── includes/
│ ├── class-core.php # Free + premium
│ └── premium/ # Only in premium zip
│ └── class-advanced.php__premium_only__Freemius generates a hosted pricing page. Embed in the plugin's admin:
add_action( 'my_plugin_fs_loaded', function() {
my_plugin_fs()->add_submenu_link_item(
__( 'Upgrade', 'my-plugin' ),
my_plugin_fs()->get_upgrade_url(),
'upgrade',
'manage_options',
51,
'dashicons-star-filled',
true // is_external: opens pricing in new tab
);
} );
// Or embed the pricing page directly inside WP admin
function my_plugin_pricing_page() {
echo my_plugin_fs()->get_pricing_js_tag( true );
}Freemius prompts users to opt into anonymous data collection on activation. Customise the dialog:
$my_plugin_fs = fs_dynamic_init( [
// ...
'opt_in' => [
'type' => 'dialog', // 'dialog', 'inline', or 'none'
'is_enabled' => true,
'anonymous_mode_enabled' => true, // allow "skip" without opting in
],
'is_org_compliant' => true, // WP.org: must allow "skip"
] );
// Skip opt-in programmatically (for white-label / privacy-first)
add_action( 'my_plugin_fs_loaded', function() {
my_plugin_fs()->skip_connection();
} );Configure in fs_dynamic_init():
'is_premium' => false,
'has_premium_version' => true,
'license_key_grace_period' => 7, // days after expiry before locking
'bundle_id' => null, // set if part of a bundle
'network_key_type' => 'per-site', // 'per-site', 'per-domain', 'unlimited'Options:
per-site — each subsite needs its own license activationper-domain — one license covers all subsites on the same domainunlimited — one license covers allKey dashboard pages to configure:
SDK update delivery — authenticated users receive updates via the Freemius API (not WP.org). The SDK hooks into WP's update mechanism automatically:
// No extra code needed — Freemius handles wp_update_plugins transparentlyOpt-in dialog not showing:
'opt_in' => [ 'type' => 'dialog' ] in init configmanage_options capabilityfs_accounts option: delete_option( 'fs_accounts' )"Invalid API Secret Key" error:
Premium features visible without license:
can_use_premium_code() wraps ALL premium code paths__premium_only__ filesSDK conflicts with other Freemius plugins:
$fs_active_plugins object. Conflicts resolved by SDK auto-loader — ensure only one copy of the SDK is loaded (use if ( ! function_exists( 'fs_dynamic_init' ) )).is_org_compliant must be true for WP.org–hosted plugins. Without it, the opt-in dialog blocks deactivation — a violation of WP.org guidelines.__premium_only__ suffix.can_use_premium_code() returns false but the plugin must remain fully functional in free mode.references/feature-gating.md — Freemius feature gating patterns: can_use_premium_code(), is_paying(), plan-level checks, and free-tier fallback patternsreferences/freemius-config.md — fs_dynamic_init() full parameter reference: all config keys, common configurations, and multi-plugin setupreferences/pricing-page.md — Freemius pricing page URLs, checkout flow, upgrade redirect patterns, and dashboard link generation~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.