Hooks & Filters
The ID Payment Link Generator exposes several WordPress actions and filters that allow you to extend its behavior without modifying plugin code directly. This page is a comprehensive reference of every available hook, with usage examples for each.
Actions
Actions let you execute your own code at specific points during the plugin’s execution. Use add_action() to attach your callback functions.
idplg_generator_before_buttons
Fires immediately before the Generate and Send buttons are rendered on the payment link generator page. This is the primary extension point for adding custom UI elements to the generator form.
- Parameters: None
- Context: Runs inside the generator form, after the standard input fields and before the action buttons.
- Used by: The Pro version uses this hook to inject the customer search/select dropdown and the email template selector.
<?php
/**
* Add a custom message field before the generator buttons.
*/
add_action( 'idplg_generator_before_buttons', 'my_custom_generator_field' );
function my_custom_generator_field() {
?>
<div class="idplg-custom-field" style="margin-bottom: 15px;">
<label for="my-internal-reference">
<strong>Internal Reference</strong>
</label>
<input type="text"
id="my-internal-reference"
name="internal_reference"
class="regular-text"
placeholder="e.g., INV-2025-001" />
<p class="description">Optional reference number for your records.</p>
</div>
<?php
}
idplg_after_email_sent
Fires after an email send attempt completes (whether successful or failed). Use this hook to log results, trigger notifications, sync with external services, or perform follow-up actions after an email is dispatched.
- Parameters:
$sent(bool) — Whetherwp_mail()returnedtrue(success) orfalse(failure).$email_data(array) — Associative array containing all the email details:customer_id(int) — The customer ID (Pro) or 0.first_name(string) — Recipient’s first name.last_name(string) — Recipient’s last name.email(string) — Recipient’s email address.amount(string) — Payment amount (may be empty).payment_link(string) — The full generated payment link URL.email_subject(string) — The email subject line used.auto_save(bool) — Whether auto-save customer was enabled (Pro).
- Used by: The Pro version uses this hook to log emails to the
idplg_logtable and auto-save new customer records.
<?php
/**
* Send a Slack notification when a payment link email is sent.
*/
add_action( 'idplg_after_email_sent', 'my_slack_notify_on_email', 10, 2 );
function my_slack_notify_on_email( $sent, $email_data ) {
// Only notify on successful sends.
if ( ! $sent ) {
return;
}
$message = sprintf(
'Payment link sent to %s %s (%s) for %s',
$email_data['first_name'],
$email_data['last_name'],
$email_data['email'],
$email_data['amount'] ? '$' . $email_data['amount'] : 'no specific amount'
);
wp_remote_post( 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL', array(
'body' => wp_json_encode( array( 'text' => $message ) ),
'headers' => array( 'Content-Type' => 'application/json' ),
) );
}
/**
* Log failed email attempts to a custom log file.
*/
add_action( 'idplg_after_email_sent', 'my_log_failed_emails', 10, 2 );
function my_log_failed_emails( $sent, $email_data ) {
if ( $sent ) {
return;
}
$log_entry = sprintf(
"[%s] FAILED: Email to %s (%s) - Subject: %s\n",
current_time( 'mysql' ),
$email_data['email'],
$email_data['first_name'] . ' ' . $email_data['last_name'],
$email_data['email_subject']
);
error_log( $log_entry, 3, WP_CONTENT_DIR . '/idplg-email-failures.log' );
}
idplg_fs_loaded
Fires after the Freemius SDK has been initialized. Use this hook if you need to interact with the Freemius instance (e.g., check license status, add custom Freemius hooks, or conditionally load code based on the plan).
- Parameters: None
- Context: Fires during plugin initialization, after
idplg_fs()is available.
<?php
/**
* Add a custom Freemius opt-in message filter after SDK loads.
*/
add_action( 'idplg_fs_loaded', 'my_customize_freemius' );
function my_customize_freemius() {
idplg_fs()->add_filter( 'connect_message', function( $message ) {
return $message . '<p>We appreciate your support!</p>';
} );
}
/**
* Conditionally load integration code only for Pro users.
*/
add_action( 'idplg_fs_loaded', 'my_load_pro_integration' );
function my_load_pro_integration() {
if ( idplg_fs()->can_use_premium_code() ) {
require_once __DIR__ . '/my-pro-integration.php';
}
}
Filters
Filters let you modify data as it passes through the plugin. Use add_filter() to attach your callback functions. Always return the modified (or unmodified) value.
idplg_admin_page_hooks
Modify which admin page hooks receive the plugin’s enqueued scripts and styles. By default, the plugin only loads its assets on its own admin pages. Use this filter to add your own custom admin pages that need the plugin’s CSS or JavaScript.
- Parameters:
$hooks(array) — Array of admin page hook suffixes (e.g.,'toplevel_page_idplg-generator').
- Return: (array) — Modified array of page hook strings.
<?php
/**
* Load IDPLG styles on a custom admin page.
*/
add_filter( 'idplg_admin_page_hooks', 'my_add_custom_page_hook' );
function my_add_custom_page_hook( $hooks ) {
// Add your custom admin page hook so plugin assets load there too.
$hooks[] = 'toplevel_page_my-custom-dashboard';
return $hooks;
}
idplg_localize_data
Modify the JavaScript localized data that is passed to the plugin’s front-end scripts via wp_localize_script(). This lets you add custom data, modify URLs, or extend the internationalization strings available in JavaScript.
- Parameters:
$data(array) — Associative array with the following keys:baseUrl(string) — The base URL of the selected payment page.ajaxUrl(string) — The WordPress AJAX URL (admin-ajax.php).nonce(string) — The security nonce for AJAX requests.logoUrl(string) — URL of the configured logo image.params(array) — The field mapping parameter names.i18n(array) — Translatable UI strings used in JavaScript.
- Return: (array) — Modified associative array.
<?php
/**
* Add custom data and extra i18n strings to the JS localization object.
*/
add_filter( 'idplg_localize_data', 'my_extend_localize_data' );
function my_extend_localize_data( $data ) {
// Add custom data for your extension's JavaScript.
$data['myExtension'] = array(
'apiEndpoint' => rest_url( 'my-extension/v1/' ),
'enabled' => true,
);
// Add additional translatable strings.
$data['i18n']['customLabel'] = __( 'My Custom Label', 'my-extension' );
$data['i18n']['customConfirm'] = __( 'Are you sure?', 'my-extension' );
return $data;
}
idplg_email_subject
Filter the email subject line before the email is sent. Use this to dynamically modify subjects based on form data, add prefixes, or apply conditional logic.
- Parameters:
$subject(string) — The email subject line.$post(array) — The sanitized form POST data array (includes first_name, last_name, email, amount, etc.).
- Return: (string) — The modified subject line.
<?php
/**
* Add the payment amount to the email subject line.
*/
add_filter( 'idplg_email_subject', 'my_add_amount_to_subject', 10, 2 );
function my_add_amount_to_subject( $subject, $post ) {
if ( ! empty( $post['amount'] ) ) {
$subject .= ' - $' . sanitize_text_field( $post['amount'] );
}
return $subject;
}
/**
* Prefix all subjects with the site name.
*/
add_filter( 'idplg_email_subject', 'my_prefix_subject', 10, 2 );
function my_prefix_subject( $subject, $post ) {
return '[' . get_bloginfo( 'name' ) . '] ' . $subject;
}
idplg_email_body
Filter the email body HTML before the email is sent. Use this to inject custom content, modify the layout, add tracking pixels, or append disclaimers.
- Parameters:
$body(string) — The full HTML email body.$post(array) — The sanitized form POST data array.
- Return: (string) — The modified HTML body.
<?php
/**
* Append a legal disclaimer to all payment link emails.
*/
add_filter( 'idplg_email_body', 'my_add_email_disclaimer', 10, 2 );
function my_add_email_disclaimer( $body, $post ) {
$disclaimer = '<div style="margin-top: 30px; padding-top: 15px; border-top: 1px solid #eee; font-size: 11px; color: #999;">';
$disclaimer .= '<p>This email was sent by ' . esc_html( get_bloginfo( 'name' ) ) . '. ';
$disclaimer .= 'If you received this in error, please disregard this message.</p>';
$disclaimer .= '</div>';
// Insert before the closing body tag if present, otherwise append.
if ( strpos( $body, '</body>' ) !== false ) {
$body = str_replace( '</body>', $disclaimer . '</body>', $body );
} else {
$body .= $disclaimer;
}
return $body;
}
/**
* Add a tracking pixel to sent emails.
*/
add_filter( 'idplg_email_body', 'my_add_tracking_pixel', 20, 2 );
function my_add_tracking_pixel( $body, $post ) {
$tracking_id = md5( $post['email'] . time() );
$pixel = '<img src="' . esc_url( home_url( '/track/?id=' . $tracking_id ) ) . '" width="1" height="1" alt="" />';
$body .= $pixel;
return $body;
}
Best Practices for Using Hooks
- Always use a unique function prefix for your callback functions to avoid naming collisions.
- Specify the priority (third parameter of
add_action/add_filter) if order matters. The default priority is 10; lower numbers run earlier. - Specify the number of accepted arguments (fourth parameter) when the hook passes more than one parameter.
- Always return a value from filter callbacks, even if you don’t modify it. Forgetting to return will cause the filtered value to become
null. - Avoid heavy processing inside hooks that fire on every page load. Use transients or caching for expensive operations.
