Skip to content

Hooks & filters

Easy Invoice exposes a large surface of apply_filters() and do_action() calls so you can extend behaviour without touching plugin files. This page lists the most useful hooks grouped by area, with file:line references for source-of-truth.

The list below is representative, not exhaustive — Easy Invoice fires hundreds of hooks across both plugins. For a full grep, run rg "apply_filters\|do_action" includes/ from each plugin root.

Bootstrap & lifecycle

HookTypeWhenFile:line
easy_invoice_loadedactionAfter the free plugin and constants are loaded.easy-invoice.php:106
easy_invoice_after_admin_scriptsactionAfter admin assets are enqueued.easy-invoice.php:152
php
add_action( 'easy_invoice_loaded', function () {
    // Safe place to register custom gateways or settings.
} );

Settings

HookTypeUse
easy_invoice_settings_fields_configfilterAdd / modify settings sections and fields.
easy_invoice_settings_for_displayfilterMutate settings before rendering.
easy_invoice_settings_tabsfilterRegister new top-level settings tab.
easy_invoice_settings_email_placeholdersfilterAdd merge tags to the email editor.
easy_invoice_settings_template_pathfilterOverride the settings template file.
easy_invoice_after_settings_pageactionRender extra HTML after the settings form.
php
add_filter( 'easy_invoice_settings_fields_config', function ( $config ) {
    $config['advanced']['fields']['my_custom_toggle'] = [
        'label'   => 'Enable my feature',
        'type'    => 'checkbox',
        'default' => '0',
    ];
    return $config;
} );

Invoice model

HookTypeUse
easy_invoice_model_to_arrayfilterTransform invoice when serialising.
easy_invoice_invoice_totalfilterOverride how totals are computed.
easy_invoice_invoice_query_argsfilterModify WP_Query args for the invoice list.
easy_invoice_invoice_createdactionNew invoice saved.
easy_invoice_invoice_updatedactionExisting invoice updated.
easy_invoice_invoice_deletedactionInvoice trashed.

Quote model

Same pattern with easy_invoice_quote_* prefix:

  • easy_invoice_quote_created / _updated / _deleted
  • easy_invoice_quote_accepted / _declined
php
add_action( 'easy_invoice_quote_accepted', function ( $quote_id ) {
    // Auto-create a kickoff invoice when a quote is accepted.
} );

Payments

HookTypeUse
easy_invoice_payment_completedactionFired after a payment is marked completed.
easy_invoice_before_process_paymentactionBefore gateway processes (good for validation).
easy_invoice_should_update_invoice_statusfilterDecide whether the parent invoice status should change.
easy_invoice_pro_recurring_generatedactionFires after a recurring invoice is generated (Pro).
easy_invoice_pro_receipt_generatedactionFires after a receipt is generated (Pro).
php
add_action( 'easy_invoice_payment_completed', function ( $payment_id ) {
    // Notify external CRM that we got paid.
} );

Emails

HookTypeUse
easy_invoice_email_sentactionAfter successful wp_mail.
easy_invoice_email_failedactionWhen wp_mail returns false.
easy_invoice_email_attachmentsfilterAdd / remove email attachments.
easy_invoice_email_headersfilterAdd custom From / Reply-To / BCC.
php
add_filter( 'easy_invoice_email_attachments', function ( $attachments, $type, $invoice_id ) {
    if ( $type === 'invoice_available' ) {
        $attachments[] = WP_CONTENT_DIR . '/uploads/terms.pdf';
    }
    return $attachments;
}, 10, 3 );

Gateways

Custom gateways register against:

  • easy_invoice_payment_gateways — array of gateway instances.
  • easy_invoice_before_process_payment — pre-process hook.
  • easy_invoice_{gateway}_payment_complete — gateway-specific complete action.

Pro-specific:

  • easy_invoice_authorizenet_payment_complete (AuthorizeNetGateway.php:470+).
  • easy_invoice_stripe_payment_complete.
  • etc.
php
add_action( 'easy_invoice_stripe_payment_complete', function ( $payment_id, $charge_id ) {
    // Custom post-payment logic.
}, 10, 2 );

Frontend templates

HookTypeUse
easy_invoice_headactionInside <head> of the public invoice / quote single.
easy_invoice_footeractionBefore closing </body>.
easy_invoice_listing_rowactionInside each row of the public listing.
single_templatefilter (WP core)Override which file renders single invoice.
php
add_action( 'easy_invoice_head', function () {
    echo '<meta name="robots" content="noindex,nofollow">';
} );

Pro-only extensions

HookTypeUse
easy_invoice_pro_templatesfilterRegister extra template builder templates.
easy_invoice_pro_export_fieldsfilterAdd columns to CSV export.
easy_invoice_pro_is_client_invoicefilterDecide whether a request is "client-context" (portal).
easy_invoice_can_download_pdffilterPrivacy gate for PDF download.
easy_invoice_can_view_invoicefilterPrivacy gate for the public invoice view.
easy_invoice_display_totalfilterOverride what's rendered in the total area (used by Partial Payments).
php
add_filter( 'easy_invoice_can_download_pdf', function ( $can, $invoice_id, $user ) {
    if ( ! $user ) return false;
    return user_can( $user, 'manage_options' ) || $can;
}, 10, 3 );

Repository / data layer

HookTypeUse
easy_invoice_invoice_repository_argsfilterModify repo query args.
easy_invoice_client_repository_argsfilterSame for clients.
easy_invoice_payment_repository_argsfilterSame for payments.

Reports

HookTypeUse
easy_invoice_reports_datafilterMutate the data passed to Chart.js.
easy_invoice_reports_template_pathfilterUse your own report template.

Naming convention

  • Free plugin prefixes hooks with easy_invoice_*.
  • Pro plugin uses easy_invoice_pro_* for new hooks added by Pro modules; reuses free hooks for shared behaviour.

Tip: discover all hooks at runtime

For exhaustive coverage in a specific install, drop this in wp-content/mu-plugins/easy-invoice-hooks.php:

php
<?php
add_action( 'all', function ( $hook_name ) {
    if ( strpos( $hook_name, 'easy_invoice' ) === 0 ) {
        error_log( "[Easy Invoice hook] $hook_name" );
    }
} );

This logs every Easy Invoice hook that fires during a request.

Where to go next