Hooks Reference
LicenceForge exposes WordPress actions and filters on both the server (your LicenceForge installation) and the client (the distributed plugin or theme). Use these hooks to extend, customise, or integrate with external systems without modifying core files.
Note
Server-side hooks fire on the WordPress installation where LicenceForge is installed. Client-side hooks fire on end-user sites where your plugin or theme (with the bundled client library) is active. Make sure you place your hook code in the correct location.
Quick reference
| Hook | Type | Side | Description |
|---|---|---|---|
wplf_license_created_from_stripe |
Action | Server | After Stripe checkout creates a licence |
wplf_license_created_from_woocommerce |
Action | Server | After WooCommerce order creates a licence |
wplf_client_api_args |
Filter | Client | Modify API request arguments |
wplf_client_is_valid |
Filter | Client | Override validation result |
wplf_client_cache_duration |
Filter | Client | Customise cache TTL |
wplf_client_has_feature |
Filter | Client | Override feature check |
wplf_trust_proxy_headers |
Filter | Client | Trust X-Forwarded-For for IP detection |
wplf_client_activated |
Action | Client | After successful activation |
wplf_client_deactivated |
Action | Client | After deactivation |
wplf_client_license_invalid |
Action | Client | On permanent validation error |
wplf_client_update_available |
Action | Client | When an update is available |
Server-side actions
These actions fire on your LicenceForge server when licences are created through payment integrations.
wplf_license_created_from_stripe
Fires immediately after a new licence is created as a result of a completed Stripe Checkout session. Use this hook to send custom notifications, sync licence data to external CRMs, or trigger third-party workflows.
Parameters
| Parameter | Type | Description |
|---|---|---|
$result |
array |
The licence creation result, containing keys: license_id, license_key, product_slug, customer_email, customer_name, activation_limit, status, and current_period_end. |
$session |
array |
The raw Stripe Checkout Session object (as an associative array), including id, subscription, customer, metadata, and all other session fields. |
Example
add_action( 'wplf_license_created_from_stripe', 'my_sync_to_crm', 10, 2 );
function my_sync_to_crm( array $result, array $session ) {
// Send the new licence data to an external CRM via HTTP
wp_remote_post( 'https://crm.example.com/api/licences', array(
'body' => wp_json_encode( array(
'email' => $result['customer_email'],
'name' => $result['customer_name'],
'product' => $result['product_slug'],
'license_id' => $result['license_id'],
'stripe_session' => $session['id'],
) ),
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . CRM_API_KEY,
),
) );
}
Warning
This action fires during webhook processing. Keep your callback fast and non-blocking. If you need to perform slow operations, schedule them with wp_schedule_single_event() instead of executing them inline.
wplf_license_created_from_woocommerce
Fires immediately after a new licence is created as a result of a completed WooCommerce order. This is the WooCommerce equivalent of the Stripe hook above.
Parameters
| Parameter | Type | Description |
|---|---|---|
$license_data |
array |
The licence creation data, containing keys: license_id, license_key, product_slug, customer_email, customer_name, activation_limit, status, and current_period_end. |
$order |
WC_Order |
The WooCommerce order object. Provides access to billing details, order items, meta data, and all standard WC_Order methods. |
Example
add_action( 'wplf_license_created_from_woocommerce', 'my_log_wc_licence', 10, 2 );
function my_log_wc_licence( array $license_data, WC_Order $order ) {
// Add an order note with the licence key for admin reference
$order->add_order_note( sprintf(
'LicenceForge: Licence %s created for product "%s" (limit: %d).',
substr( $license_data['license_key'], 0, 9 ) . '...',
$license_data['product_slug'],
$license_data['activation_limit']
) );
// Store the licence ID as order meta for later retrieval
$order->update_meta_data( '_wplf_license_id', $license_data['license_id'] );
$order->save();
}
Client-side filters
These filters fire on end-user sites where your plugin or theme (with the bundled LicenceForge client library) is active. They allow end users or integrators to customise client behaviour without modifying the client library files.
wplf_client_api_args
Filters the arguments passed to wp_remote_request() before every API call to the LicenceForge server. Use this to add custom headers, adjust timeouts, or configure proxy settings.
Parameters
| Parameter | Type | Description |
|---|---|---|
$args |
array |
The arguments array for wp_remote_request(). Includes keys such as headers, body, timeout, method, and sslverify. |
Example
add_filter( 'wplf_client_api_args', 'my_custom_api_args' );
function my_custom_api_args( $args ) {
// Increase timeout for slow connections
$args['timeout'] = 30;
// Add a custom header for server-side logging
$args['headers']['X-Client-Version'] = '1.5.0';
return $args;
}
wplf_client_is_valid
Filters the boolean result of a licence validation check. Runs after the API response is received and parsed. Use this to implement custom validation logic, such as domain whitelisting or development environment bypasses.
Parameters
| Parameter | Type | Description |
|---|---|---|
$is_valid |
bool |
The current validation result. true if the server confirmed the licence is valid. |
$response |
array |
The full decoded API response body from the validation endpoint. |
Example
add_filter( 'wplf_client_is_valid', 'my_dev_bypass', 10, 2 );
function my_dev_bypass( $is_valid, $response ) {
// Always treat local development sites as valid
$host = wp_parse_url( home_url(), PHP_URL_HOST );
if ( in_array( $host, array( 'localhost', '127.0.0.1' ), true ) ) {
return true;
}
// Allow .test and .local TLDs for development
if ( preg_match( '/\.(test|local)$/', $host ) ) {
return true;
}
return $is_valid;
}
Warning
Returning true unconditionally from this filter effectively disables licence enforcement. Use it only for well-scoped development bypasses and never in production builds.
wplf_client_cache_duration
Filters the number of seconds that a validation result is cached in a WordPress transient before the client re-checks with the server. The default is 3600 seconds (1 hour).
Parameters
| Parameter | Type | Description |
|---|---|---|
$duration |
int |
Cache duration in seconds. Default: 3600. |
Example
add_filter( 'wplf_client_cache_duration', 'my_custom_cache_ttl' );
function my_custom_cache_ttl( $duration ) {
// Cache for 12 hours instead of the default 1 hour
return 43200;
}
Tip
Shorter durations mean more frequent API calls and faster status changes. Longer durations reduce server load but delay revocation detection. A value of 3600 to 43200 is recommended for most use cases.
wplf_client_has_feature
Filters the result of a feature check performed via WPLF_Client::has_feature(). Use this to grant or revoke access to specific features based on custom logic.
Parameters
| Parameter | Type | Description |
|---|---|---|
$has_feature |
bool |
Whether the current licence tier includes the requested feature. |
$feature_slug |
string |
The slug of the feature being checked (e.g. priority-support, white-label). |
Example
add_filter( 'wplf_client_has_feature', 'my_beta_feature_gate', 10, 2 );
function my_beta_feature_gate( $has_feature, $feature_slug ) {
// Grant beta features to users who have opted in via a constant
if ( 'beta-features' === $feature_slug && defined( 'MY_PLUGIN_BETA' ) && MY_PLUGIN_BETA ) {
return true;
}
return $has_feature;
}
wplf_trust_proxy_headers
Filters whether the client library should trust the X-Forwarded-For header when detecting the site's IP address. Defaults to false. Enable this only if your site is behind a trusted reverse proxy or load balancer.
Parameters
| Parameter | Type | Description |
|---|---|---|
$trust |
bool |
Whether to trust proxy headers. Default: false. |
Example
add_filter( 'wplf_trust_proxy_headers', '__return_true' );
Warning
Enabling proxy header trust on a server that is not behind a trusted proxy allows attackers to spoof their IP address. Only enable this filter if you are certain your infrastructure sets X-Forwarded-For reliably.
Client-side actions
These actions fire on end-user sites during key licence lifecycle events.
wplf_client_activated
Fires immediately after a licence is successfully activated on the current site. Use this to trigger post-activation setup, display welcome messages, or log the event.
Parameters
| Parameter | Type | Description |
|---|---|---|
$response |
array |
The decoded API response from the activation endpoint. Contains activated, activation_id, site_url, activation_count, activation_limit, and activated_at. |
Example
add_action( 'wplf_client_activated', 'my_post_activation_setup' );
function my_post_activation_setup( $response ) {
// Set a flag so the plugin shows a welcome banner on next page load
update_option( 'my_plugin_show_welcome', true );
// Log activation for internal analytics
error_log( sprintf(
'My Plugin activated: site %s, activation %d of %d.',
$response['site_url'],
$response['activation_count'],
$response['activation_limit']
) );
}
wplf_client_deactivated
Fires immediately after a licence is deactivated on the current site. Use this to clean up plugin data, disable premium features, or notify the user.
Parameters
| Parameter | Type | Description |
|---|---|---|
$response |
array |
The decoded API response from the deactivation endpoint. Contains deactivated, site_url, activation_count, and activation_limit. |
Example
add_action( 'wplf_client_deactivated', 'my_cleanup_on_deactivation' );
function my_cleanup_on_deactivation( $response ) {
// Remove cached premium template data
delete_transient( 'my_plugin_premium_templates' );
// Revert to free-tier settings
update_option( 'my_plugin_tier', 'free' );
}
wplf_client_license_invalid
Fires when a licence validation check returns a permanent error -- specifically HTTP 401, 403, or 404 responses. This indicates the licence has been revoked, deleted, or the key is fundamentally invalid, as opposed to a transient network error.
Parameters
| Parameter | Type | Description |
|---|---|---|
$error |
array |
The error response from the API, containing code (string), message (string), and data (array with status HTTP code). |
Example
add_action( 'wplf_client_license_invalid', 'my_handle_invalid_licence' );
function my_handle_invalid_licence( $error ) {
// Disable premium functionality immediately
update_option( 'my_plugin_premium_active', false );
// Store the error for display in admin notices
update_option( 'my_plugin_license_error', array(
'code' => $error['code'],
'message' => $error['message'],
'time' => current_time( 'mysql' ),
) );
// Notify the site administrator
wp_mail(
get_option( 'admin_email' ),
'My Plugin: Licence Invalid',
sprintf( 'Your licence is no longer valid. Reason: %s', $error['message'] )
);
}
wplf_client_update_available
Fires when the update checker detects that a newer version of your product is available. Use this to display custom update banners, log update availability, or trigger pre-update tasks.
Parameters
| Parameter | Type | Description |
|---|---|---|
$update_data |
array |
Update information from the server. Contains new_version, package (download URL), package_hash, tested (WordPress version), requires (minimum WordPress), requires_php, and sections (changelog HTML). |
Example
add_action( 'wplf_client_update_available', 'my_notify_update' );
function my_notify_update( $update_data ) {
// Store update info for a custom admin banner
update_option( 'my_plugin_update_available', array(
'version' => $update_data['new_version'],
'requires_php' => $update_data['requires_php'],
'checked_at' => current_time( 'mysql' ),
) );
}
Tip
This action fires during the WordPress transient update cycle (typically twice daily). It does not fire on every page load. If you need real-time update awareness, reduce the cache duration via the wplf_client_cache_duration filter.
Related pages
- Extending LicenceForge -- Full examples of customisation using hooks
- REST API Reference -- Complete endpoint documentation
- Database Schema -- Table structures for context on hook data
- Client Library -- Integration overview for the bundled PHP classes