Hooks and Filters

Avenia Digital Products exposes WordPress actions and filters so you can customize pricing, tax, checkout, subscriptions, templates, emails, and payment gateways without editing plugin files. Add your code in a child theme’s functions.php or a small custom plugin.

This article is the complete hook reference. Filters return a modified value. Actions run at a point in time and do not change core data unless you call other APIs yourself.

Before you start

  • Hook names are stable public API, treat signature changes like breaking changes.
  • aveniadp_checkout_order_data runs during front-end checkout only, not when you create a manual order in the admin.
  • aveniadp_before_order_complete and aveniadp_order_completed run whenever an order is completed (checkout, payment return, webhooks, manual orders).
  • aveniadp_email_sent runs only when the email type is enabled and wp_mail() is called.
  • Subscription cart items may include trial_days and setup_fee keys. Use aveniadp_cart_due_today or the billing-summary filters when you need the amount charged at checkout.

Plugin bootsrap

aveniadp_loaded (action)
When it runs: After the core plugin class is loaded (plugins_loaded, priority 5).
Purpose: Register services that must exist before init.
Arguments: none.

aveniadp_init (action)
When it runs: After plugin services are bootstrapped on init (priority 10).
Purpose: Hook into storefront, admin, or REST features once everything is ready.
Arguments: none.

Example:

add_action( 'aveniadp_init', function() {
   // Safe to call plugin helpers here.
} );

Pricing and cart

aveniadp_product_price (filter)
When it runs: Whenever the plugin resolves a product’s price for the cart or checkout.
Purpose: Adjust displayed or charged amounts per product, license tier, or billing period.
Arguments: $price (float), $product_id (int), $license_quantity (int), $billing_period (string: monthly, yearly, or empty for one-time).

Example:

add_filter( 'aveniadp_product_price', function( $price, $product_id, $license_quantity, $billing_period ) {
   if ( 123 === $product_id ) {
    return $price * 0.9;
   }
   return $price;
}, 10, 4 );

aveniadp_cart_line_item (filter)
When it runs: After a cart line item is normalized (includes trial_days and setup_fee for subscriptions).
Purpose: Add metadata or adjust subscription options on a line item before totals are calculated.
Arguments: $item (array), $product_id (int), $license_quantity (int), $billing_period (string).

aveniadp_cart_due_today (filter)
When it runs: After the cart total due at checkout is calculated (accounts for trials, $0 when only a free trial applies).
Purpose: Override the amount charged immediately at checkout.
Arguments: $total (float), $cart (array of cart items).

aveniadp_checkout_billing_summary (filter)
When it runs: When building the subscription billing schedule shown on checkout (trial, setup fee, recurring lines). Discount codes are applied to schedule amounts before this filter runs. Exclusive tax (when enabled) is applied to summary amounts via this filter.
Purpose: Change labels, lines, or summary amounts for subscription carts.
Arguments: $summary (array), $cart_items (array).

aveniadp_checkout_line_items (filter)
When it runs: Before Stripe Checkout session line items are sent to the API.
Purpose: Add or modify one-time line items (for example setup fees) on Stripe subscription checkouts.
Arguments: $line_items (array), $order_data (array).

Tax

aveniadp_tax_modes (filter)
When it runs: When building the Tax mode dropdown (Settings → General).
Purpose: Add or relabel tax modes.
Arguments: $modes (array of mode key => label). Built-in keys: none, inclusive, exclusive.

aveniadp_tax_mode (filter)
When it runs: Whenever the active tax mode is read.
Purpose: Override the store tax mode (none, inclusive, or exclusive).
Arguments: $mode (string).

aveniadp_calculate_tax (filter)
When it runs: After the flat exclusive tax amount is calculated for a taxable subtotal (after discounts).
Purpose: Adjust the tax amount or implement custom rules. Inclusive and no-tax modes start at 0 before this filter.
Arguments: $amount (float), $taxable_amount (float), $context (array; may include cart_totals).

Example:

add_filter( 'aveniadp_calculate_tax', function( $amount, $taxable_amount ) {
   // Cap tax at 50 currency units.
   return min( $amount, 50 );
}, 10, 2 );

Checkout and orders

aveniadp_checkout_order_data (filter)
When it runs: During checkout, after totals are calculated and before the pending order is saved.
Purpose: Inspect or adjust order data (for logging, integrations, or validation). Return the $order_data array.
Arguments: $order_data (array), $cart_items (array), $customer_id (int).

The array includes customer_id, total, discount_code_id, discount_amount, tax_amount, tax_rate, payment_method, status, and items. Subscription items may include trial_days, setup_fee, and billing_period.and billing_period.

Example:

add_filter( 'aveniadp_checkout_order_data', function( $order_data, $cart_items, $customer_id ) {
   error_log( sprintf( 'Checkout: customer %d, total %s', $customer_id, $order_data['total'] ) );
   return $order_data;
}, 10, 3 );

aveniadp_before_order_complete (action)
When it runs: At the start of order completion, before status changes, downloads, licenses, subscriptions, or emails.
Purpose: Last-chance logging or preparation. This is an action, you cannot cancel completion from here.
Arguments: $order_id (int), $payment_result (array), $options (array with send_emails, create_account).

Example:

add_action( 'aveniadp_before_order_complete', function( $order_id, $payment_result, $options ) {
   error_log( 'Completing order ' . $order_id );
}, 10, 3 );

aveniadp_order_completed (action)
When it runs: After an order is fully completed (downloads, licenses, subscriptions, emails, and account creation when applicable).
Purpose: Integrate with CRM, analytics, Slack, or custom post-purchase logic.
Arguments: $order_id (int), $order (object), $payment_result (array).

Example:

add_action( 'aveniadp_order_completed', function( $order_id, $order ) {
   wp_remote_post(
      'https://hooks.example.com/new-sale',
      array(
         'body' => wp_json_encode(
          array(
             'order_id' => $order_id,
             'total' => $order->total,
             'email' => $order->customer_id,
          )
     ),
   )
);
}, 10, 2 );

Subscriptions

aveniadp_subscription_create_data (filter)
When it runs: Before a subscription row is inserted after checkout.
Purpose: Adjust stored subscription fields (status, dates, gateway IDs) or add custom metadata via allowed columns.
Arguments: $insert_data (array), $order_id (int), $data (array from the order item).

aveniadp_subscription_grants_access (filter)
When it runs: Whenever the plugin checks whether a subscription allows downloads or license validation.
Purpose: Override access during trial, past due, or custom business rules.
Arguments: $grants (bool), $subscription (object).

aveniadp_subscription_created (action)
When it runs: After a subscription record is created.
Purpose: Run onboarding, external provisioning, or analytics for new subscribers.
Arguments: $subscription_id (int), $insert_data (array).

Example:

add_action( 'aveniadp_subscription_created', function( $subscription_id, $data ) {
   // Custom onboarding for new subscriptions.
}, 10, 2 );

Payment gateways

aveniadp_stripe_checkout_session_args (filter)
When it runs: Before the Stripe Checkout Session is created.
Purpose: Adjust session parameters (metadata, trial length, line items, success URL).
Arguments: $body (array), $order_data (array).

Example:

add_filter( 'aveniadp_stripe_checkout_session_args', function( $body, $order_data ) {
   $body['metadata']['source'] = 'my-theme';
   return $body;
}, 10, 2 );

aveniadp_paypal_plan_args (filter)
When it runs: Before a PayPal billing plan is created or updated for a subscription product.
Purpose: Customize PayPal plan cycles, trial tenure, or setup fee handling.
Arguments: $body (array), $product_id (int), $billing_period (string), $options (array with trial_days, setup_fee, and related fields).

aveniadp_paypal_log (action)
When it runs: When the PayPal gateway records a debug event.
Purpose: Capture PayPal-specific troubleshooting data.
Arguments: $entry (array with context, data).

Example:

add_action( 'aveniadp_paypal_log', function( $entry ) {
   if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
       error_log( 'PayPal: ' . $entry['context'] );
   }
} );

Product admin

aveniadp_product_meta_fields (filter)
When it runs: When the product editor builds meta field definitions.
Purpose: Register additional product meta fields for subscription or one-time products.
Arguments: $fields (array), $product_type (string: one-time or subscription).

Storefront and templates

aveniadp_use_custom_single_product_layout (filter)
When it runs: On single product pages, before the plugin decides whether to render its own layout.
Purpose: Return false to use your theme’s single-product template instead of the plugin layout.
Arguments: $use_layout (bool), $product_id (int).

Example:

add_filter( 'aveniadp_use_custom_single_product_layout', '__return_false' );

See Templates and Overrides for PHP overrides and block theme HTML starter code.

aveniadp_before_main_content (action)
When it runs: After get_header() in classic theme shell templates (product catalog, single product, category/tag archives).
Purpose: Output opening content wrapper markup around plugin content. The plugin hooks aveniadp_output_content_wrapper() here by default at priority 10.
Arguments: none.

aveniadp_after_main_content (action)
When it runs: Before get_footer() in the same classic shell templates.
Purpose: Output closing wrapper markup. The plugin hooks aveniadp_output_content_wrapper_end() here by default at priority 10.
Arguments: none.

Example: replace default wrappers to match your theme’s page.php:

remove_action( 'aveniadp_before_main_content', 'aveniadp_output_content_wrapper', 10 );
remove_action( 'aveniadp_after_main_content', 'aveniadp_output_content_wrapper_end', 10 );
add_action( 'aveniadp_before_main_content', 'my_theme_aveniadp_wrapper_start', 10 );
add_action( 'aveniadp_after_main_content', 'my_theme_aveniadp_wrapper_end', 10 );

function my_theme_aveniadp_wrapper_start() {
   echo '<div id="content" class="site-content"><main id="primary">';
}

function my_theme_aveniadp_wrapper_end() { 
   echo '</main></div>';
}

See Templates and Overrides for which templates fire these hooks and the default wrapper markup.

aveniadp_main_content_classes (filter)
When it runs: When the default content wrapper builds the <main> class attribute.
Purpose: Change or extend classes on the default wrapper without replacing aveniadp_output_content_wrapper().
Arguments: $classes (string[]).

Example:

add_filter( 'aveniadp_main_content_classes', function( $classes ) {
   $classes[] = 'my-theme-main';
   return $classes;
} );

aveniadp_locate_template (filter)
When it runs: While resolving which PHP template file to load.
Purpose: Point a template at a custom path outside the default theme override folder.
Arguments: $template (path), $template_name, $template_path, $default_path.

Example:

add_filter( 'aveniadp_locate_template', function( $template, $template_name ) {
   if ( 'checkout.php' === $template_name ) {
      return get_stylesheet_directory() . '/custom-aveniadp/checkout.php';
   }
   return $template;
}, 10, 2 );

aveniadp_get_template_args (filter)
When it runs: After the template path is found, before variables are extracted into the template.
Purpose: Add or change data available inside a template file.
Arguments: $args (array), $template_name, $template_path, $default_path.

Example:

add_filter( 'aveniadp_get_template_args', function( $args, $template_name ) {
      if ( 'checkout.php' === $template_name ) {
          $args['support_email'] = 'email address';
      }
      return $args;
  }, 10, 2 );

aveniadp_before_get_template (action)
When it runs: Immediately before a template file is included.
Purpose: Run setup code (enqueue assets, logging) for a specific template.
Arguments: $template_name, $template_path, $located, $args.

Example:

add_action( 'aveniadp_before_get_template', function( $template_name ) {
   if ( 'account.php' === $template_name ) {
      wp_enqueue_style( 'my-account-extras', get_stylesheet_directory_uri() . '/account.css' );
   }
} );

aveniadp_after_get_template (action)
When it runs: Immediately after a template file is included.
Purpose: Run cleanup or footer output tied to a template.
Arguments: $template_name, $template_path, $located, $args.

Example:

add_action( 'aveniadp_after_get_template', function( $template_name ) {
   if ( 'cart.php' === $template_name ) {
      echo '';
   }
} );

Email

aveniadp_email_replacements (filter)
When it runs: Before placeholders are swapped into an email body.
Purpose: Add custom placeholders or change built-in values.
Arguments: $replacements (array, keys without braces), $email_type (string), $context (array).

Email types: order_confirmation, download_link, license_key, account_confirmation, subscription_renewal, subscription_payment_failed.

Context may include order_id, order, customer, product_id, download_url, license_key, user_id, email, subscription_id, or subscription depending on the email.bscription_renewal.

Example:

add_filter( 'aveniadp_email_replacements', function( $replacements, $email_type ) {
   $replacements['store_phone'] = '(555) 123-4567';
   return $replacements;
}, 10, 2 );

Then add {store_phone} to the email body under Settings → Emails.

aveniadp_email_sent (action)
When it runs: After wp_mail() is called for a transactional email.
Purpose: Log delivery, mirror to another system, or debug SMTP issues.
Arguments: $email_type (string), $to (string), $subject (string), $sent (bool).

Example:

add_action( 'aveniadp_email_sent', function( $email_type, $to, $subject, $sent ) {
   error_log( sprintf( 'AveniaDP email %s to %s: %s', $email_type, $to, $sent ? 'sent' : 'failed' ) );
}, 10, 4 );

Licensing

aveniadp_license_api_trusted_proxies (filter)
When it runs: When the license REST API resolves the client IP for rate limiting.
Purpose: Allow trusted reverse proxies (load balancers) to pass the real client IP via forwarded headers.
Arguments: $trusted_proxies (array of IP strings). Default: empty (use REMOTE_ADDR only).

Example:

add_filter( 'aveniadp_license_api_trusted_proxies', function( $proxies ) {
   $proxies[] = '203.0.113.10';
   return $proxies;
} );

Logging and debugging

aveniadp_log_entry (action)
When it runs: Whenever the plugin logs an event through its logger.
Purpose: Send plugin logs to your own system.
Arguments: $entry (array with channel, message, context).

Example:

add_action( 'aveniadp_log_entry', function( $entry ) {
   error_log( '[AveniaDP ' . $entry['channel'] . '] ' . $entry['message'] );
} );