Hooks and Filters in WooCommerce PDF Invoice

The WooCommerce PDF Invoice Extension is fully localized but, occasionally, you might want to change one or two of the output strings so here is a list of available filters and examples :

Template filters ↑ Back to top

apply_filters( 'pdf_template_invoice_number_text', __( 'Invoice No. :', PDFLANGUAGE ) )
apply_filters( 'pdf_template_order_number_text', __( 'Order No. :', PDFLANGUAGE ) )
apply_filters( 'pdf_template_invoice_date_text', __( 'Invoice Date :', PDFLANGUAGE ) )
apply_filters( 'pdf_template_order_date_text', __( 'Order Date :', PDFLANGUAGE ) )
apply_filters( 'pdf_template_billing_details_text', __( '<h3>Billing Details</h3>', PDFLANGUAGE ) ) 
apply_filters( 'pdf_template_shipping_details_text', __( '<h3>Shipping Details</h3>', PDFLANGUAGE ) ) 
apply_filters( 'pdf_template_registered_name_text', __( 'Registered Name : ', PDFLANGUAGE ) ) 
apply_filters( 'pdf_template_registered_office_text', __( 'Registered Office : ', PDFLANGUAGE ) ) 
apply_filters( 'pdf_template_company_number_text', __( 'Company Number : ', PDFLANGUAGE ) ) 
apply_filters( 'pdf_template_vat_number_text', __( 'VAT Number : ', PDFLANGUAGE ) )

Example :

If you wanted to change ‘Vat Number : ‘ to ‘BTW No. : ‘ you would add the following to your theme functions.php file

add_filter( 'pdf_template_vat_number_text', 'custom_pdf_template_vat_number_text' );
function custom_pdf_template_vat_number_text() {
    return 'BTW No. : ';
}

Change ‘My Orders’ button label ↑ Back to top

/**
 * Change the button label for the PDF Button on the My Orders page
 * This will change the default label (PDF Invoice) to New PDF Label
 */
add_filter ( 'woocommerce_pdf_my_account_button_label' , 'custom_pdf_my_account_button_label' );
function custom_pdf_my_account_button_label() {
    return 'New PDF Label';
}

Other available actions and filters to make minor changes :

Add additional column to the PDF order items ↑ Back to top

For example you can add the product SKU to the headings and order lines

/**
* Add SKU to PDF order heading
*/
add_filter ( 'pdf_template_table_headings' , 'custom_pdf_table_headers' );
function custom_pdf_table_headers() {
$headers = '<table class="shop_table orderdetails" width="100%">' .
'<thead>' .
'<tr><th colspan="7" align="left"><h2>' . esc_html__('Order Details', PDFLANGUAGE) . '</h2></th></tr>' .
'<tr>' .
'<th width="5%" valign="top" align="right">' . __( 'Qty', PDFLANGUAGE ) . '</th>' .
'<th width="10%" valign="top" align="left">' . __( 'SKU', PDFLANGUAGE ) . '</th>' .
'<th width="40%" valign="top" align="left">' . __( 'Product', PDFLANGUAGE ) . '</th>' .
'<th width="9%" valign="top" align="right">' . __( 'Price Ex', PDFLANGUAGE ) . '</th>' .
'<th width="9%" valign="top" align="right">' . __( 'Total Ex.', PDFLANGUAGE ) . '</th>' .
'<th width="7%" valign="top" align="right">' . __( 'Tax', PDFLANGUAGE ) . '</th>' .
'<th width="10%" valign="top" align="right">' . __( 'Price Inc', PDFLANGUAGE ) . '</th>' .
'<th width="10%" valign="top" align="right">' . __( 'Total Inc', PDFLANGUAGE ) . '</th>' .
'</tr>' .
'</thead>' .
'</table>';
return $headers;
}
/**
* Add SKU to order line
*/
add_filter ( 'pdf_template_line_output' , 'custom_pdf_lines', 10, 2 );
function custom_pdf_lines ( $line, $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
// Check WC version – changes for WC 3.0.0
$pre_wc_30 = version_compare( WC_VERSION, '3.0', '<' );
$order_currency = $pre_wc_30 ? $order->get_order_currency() : $order->get_currency();
$pdflines = '<table width="100%">';
$pdflines .= '<tbody>';
if ( sizeof( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item ) {
if ( $item['qty'] ) {
$line = '';
// $item_loop++;
$_product = $order->get_product_from_item( $item );
$item_name = $item['name'];
$item_id = $pre_wc_30 ? $item['variation_id'] : $item->get_id();
$meta_display = '';
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$item_meta = new WC_Order_Item_Meta( $item );
$meta_display = $item_meta->display( true, true );
$meta_display = $meta_display ? ( ' ( ' . $meta_display . ' )' ) : '';
} else {
foreach ( $item->get_formatted_meta_data() as $meta_key => $meta ) {
$meta_display .= '<br /><small>(' . $meta->display_key . ':' . wp_kses_post( strip_tags( $meta->display_value ) ) . ')</small>';
}
}
if ( $meta_display ) {
$meta_output = apply_filters( 'pdf_invoice_meta_output', $meta_display );
$item_name .= $meta_output;
}
$line = '<tr>' .
'<td valign="top" width="5%" align="right">' . $item['qty'] . ' x</td>' .
'<td valign="top" width="10%">' . $_product->get_sku() . '</td>' .
'<td valign="top" width="40%">' . stripslashes( $item_name ) . '</td>' .
'<td valign="top" width="9%" align="right">' . wc_price( $item['line_subtotal'] / $item['qty'], array( 'currency' => $order_currency ) ) . '</td>' .
'<td valign="top" width="9%" align="right">' . wc_price( $item['line_subtotal'], array( 'currency' => $order_currency ) ) . '</td>' .
'<td valign="top" width="7%" align="right">' . wc_price( $item['line_subtotal_tax'] / $item['qty'], array( 'currency' => $order_currency ) ). '</td>' .
'<td valign="top" width="10%" align="right">' . wc_price( ( $item['line_subtotal'] + $item['line_subtotal_tax'] ) / $item['qty'], array( 'currency' => $order_currency ) ). '</td>' .
'<td valign="top" width="10%" align="right">' . wc_price( $item['line_subtotal'] + $item['line_subtotal_tax'], array( 'currency' => $order_currency ) ). '</td>' .
'</tr>';
$pdflines .= $line;
}
}
}
$pdflines .= '</tbody>';
$pdflines .= '</table>';
return $pdflines;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Or you can change the tax value to tax rate

/**
* Change Tax to Tax Rate
*/
add_filter ( 'pdf_template_table_headings' , 'custom_pdf_table_headers' );
function custom_pdf_table_headers() {
$headers = '<table class="shop_table orderdetails" width="100%">' .
'<thead>' .
'<tr><th colspan="7" align="left"><h2>' . esc_html__('Order Details', PDFLANGUAGE) . '</h2></th></tr>' .
'<tr>' .
'<th width="5%" valign="top" align="right">' . __( 'Qty', PDFLANGUAGE ) . '</th>' .
'<th width="50%" valign="top" align="left">' . __( 'Product', PDFLANGUAGE ) . '</th>' .
'<th width="9%" valign="top" align="right">' . __( 'Price Ex', PDFLANGUAGE ) . '</th>' .
'<th width="9%" valign="top" align="right">' . __( 'Total Ex.', PDFLANGUAGE ) . '</th>' .
'<th width="7%" valign="top" align="right">' . __( 'Tax Rate', PDFLANGUAGE ) . '</th>' .
'<th width="10%" valign="top" align="right">' . __( 'Price Inc', PDFLANGUAGE ) . '</th>' .
'<th width="10%" valign="top" align="right">' . __( 'Total Inc', PDFLANGUAGE ) . '</th>' .
'</tr>' .
'</thead>' .
'</table>';
return $headers;
}
/**
* Change Tax to Tax Rate
*/
add_filter ( 'pdf_template_line_output' , 'custom_pdf_lines', 10, 2 );
function custom_pdf_lines ( $line, $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
// Check WC version – changes for WC 3.0.0
$pre_wc_30 = version_compare( WC_VERSION, '3.0', '<' );
$order_currency = $pre_wc_30 ? $order->get_order_currency() : $order->get_currency();
$pdflines = '<table width="100%">';
$pdflines .= '<tbody>';
if ( sizeof( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item ) {
if ( $item['qty'] ) {
$line = '';
// $item_loop++;
$_product = $order->get_product_from_item( $item );
$item_name = $item['name'];
$item_id = $pre_wc_30 ? $item['variation_id'] : $item->get_id();
$meta_display = '';
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$item_meta = new WC_Order_Item_Meta( $item );
$meta_display = $item_meta->display( true, true );
$meta_display = $meta_display ? ( ' ( ' . $meta_display . ' )' ) : '';
} else {
foreach ( $item->get_formatted_meta_data() as $meta_key => $meta ) {
$meta_display .= '<br /><small>(' . $meta->display_key . ':' . wp_kses_post( strip_tags( $meta->display_value ) ) . ')</small>';
}
}
if ( $meta_display ) {
$meta_output = apply_filters( 'pdf_invoice_meta_output', $meta_display );
$item_name .= $meta_output;
}
$line = '<tr>' .
'<td valign="top" width="5%" align="right">' . $item['qty'] . ' x</td>' .
'<td valign="top" width="50%">' . stripslashes( $item_name ) . '</td>' .
'<td valign="top" width="9%" align="right">' . wc_price( $item['line_subtotal'] / $item['qty'], array( 'currency' => $order_currency ) ) . '</td>' .
'<td valign="top" width="9%" align="right">' . wc_price( $item['line_subtotal'], array( 'currency' => $order_currency ) ) . '</td>' .
'<td valign="top" width="7%" align="right">' . 100 * ( $item['line_subtotal_tax']/$item['line_subtotal'] ) . '%' . '</td>' .
'<td valign="top" width="10%" align="right">' . wc_price( ( $item['line_subtotal'] + $item['line_subtotal_tax'] ) / $item['qty'], array( 'currency' => $order_currency ) ). '</td>' .
'<td valign="top" width="10%" align="right">' . wc_price( $item['line_subtotal'] + $item['line_subtotal_tax'], array( 'currency' => $order_currency ) ). '</td>' .
'</tr>';
$pdflines .= $line;
}
}
}
$pdflines .= '</tbody>';
$pdflines .= '</table>';
return $pdflines;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Adding additional fields to the admin and output PDF ↑ Back to top

To add a new field to the bottom of the settings form you can make use of the action (it is not possible to insert a new field anywhere else at this time)

This code will add a new text field called custom_text to the settings form

add_action ( 'woocommerce_pdf_invoice_additional_fields_admin' , 'custom_woocommerce_pdf_admin_field' );
function custom_woocommerce_pdf_admin_field() {

    $woocommerce_pdf_invoice_options = get_option('woocommerce_pdf_invoice_settings');
    ?>

            <!-- Custom PDF Field -->
            <tr valign="top">
                <th scope="row" class="titledesc">
                    <label for="woocommerce_pdf_invoice_settings[custom_text]">Custom text for invoice</label>
                    <img class="help_tip" data-tip="Add some custom text to your invoice" src="<?php echo plugins_url( 'woocommerce/assets/images/help.png' );?>" height="16" width="16" />                 
                </th>
                <td class="forminp forminp-number">
                    <input id="woocommerce_pdf_invoice_settings[custom_text]" 
                    name="woocommerce_pdf_invoice_settings[custom_text]" 
                    type="text" 
                    value="<?php if ( isset($woocommerce_pdf_invoice_options['custom_text']) ) { echo $woocommerce_pdf_invoice_options['custom_text']; }?>"
                    placeholder="" style="width: 350px;"/>                     
                </td>
            </tr>
    <?php

}

Once this code is added to your theme functions.php you will see Screen Shot 2013-04-02 at 08.24.57

To add this field to the PDF file you need to add a placeholder – [[CUSTOMFIELD]] – to the template file. Once you have the placeholder added you will need to hook in to the output function.

add_action ( 'pdf_content_additional_content' , 'custom_pdf_additional_content' );
function custom_pdf_additional_content( $content ) {
    global $woocommerce;
    $woocommerce_pdf_invoice_options = get_option( 'woocommerce_pdf_invoice_settings' );

    $content = str_replace( '[[CUSTOMFIELD]]', $woocommerce_pdf_invoice_options['custom_text'], $content );

    return $content;
}

Examples of adding additional content to the invoice ↑ Back to top

In all cases you need to edit template.php and add your tag in the desired place then add the code to your theme functions.php

Example template.php file used for the adding terms and conditions area example ↑ Back to top

This file should be copied and saved to ‘wp-content/themes/YOUR_THEME/pdf_templates/template.php’

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
@page {
margin: 480px 50px 150px 50px;
}
#header {
position: fixed;
left: 0px;
top: -460px;
right: 0px;
height: 480px; /* must match the 1st margin setting in @page */
text-align: center;
}
#footer {
position: fixed;
left: 0px;
bottom: -200px;
right: 0px;
height: 150px; /* must match the 3rd margin setting in @page */
font-size:11px;
text-align: center;
}
#content {
font-size:11px;
}
</style>
<body>
<div id="header">
<table table width="100%">
<tr>
<td valign="top" colspan="2">[[PDFLOGO]]</td>
<td valign="top" colspan="2">[[PDFCOMPANYNAME]]<br />[[PDFCOMPANYDETAILS]]<br /></td>
</tr>
<tr>
<td width="20%" valign="top"><?php echo apply_filters( 'pdf_template_invoice_number_text', __( 'Invoice No. :', PDFLANGUAGE ) ); ?></td>
<td width="30%" valign="top">[[PDFINVOICENUM]]</td>
<td width="20%" valign="top"><?php echo apply_filters( 'pdf_template_order_number_text', __( 'Order No. :', PDFLANGUAGE ) ); ?></td>
<td width="30%" valign="top">[[PDFORDERENUM]]</td>
</tr>
<tr>
<td valign="top"><?php echo apply_filters( 'pdf_template_invoice_date_text', __( 'Invoice Date :', PDFLANGUAGE ) ); ?></td>
<td valign="top">[[PDFINVOICEDATE]]</td>
<td valign="top"><?php echo apply_filters( 'pdf_template_order_date_text', __( 'Order Date :', PDFLANGUAGE ) ); ?></td>
<td valign="top">[[PDFORDERDATE]]</td>
</tr>
<tr>
<td valign="top"><?php echo apply_filters( 'pdf_template_payment_method_text', __( 'Payment Method :', PDFLANGUAGE ) ); ?></td>
<td valign="top">[[PDFINVOICEPAYMENTMETHOD]]</td>
<td valign="top">&nbsp;</td>
<td valign="top">&nbsp;</td>
</tr>
<tr>
<td valign="top" colspan="2">
<?php echo apply_filters( 'pdf_template_billing_details_text', __( '<h3>Billing Details</h3>', PDFLANGUAGE ) ); ?>
[[PDFBILLINGADDRESS]]<br />
[[PDFBILLINGTEL]]<br />
[[PDFBILLINGEMAIL]]
</td>
<td valign="top" colspan="2">
<?php echo apply_filters( 'pdf_template_shipping_details_text', __( '<h3>Shipping Details</h3>', PDFLANGUAGE ) ); ?>
[[PDFSHIPPINGADDRESS]]
</td>
</tr>
</table>
</div>
<div id="footer">
<div class="copyright"><?php echo apply_filters( 'pdf_template_registered_name_text', __( 'Registered Name : ', PDFLANGUAGE ) ); ?>[[PDFREGISTEREDNAME]] <?php echo apply_filters( 'pdf_template_registered_office_text', __( 'Registered Office : ', PDFLANGUAGE ) ); ?>[[PDFREGISTEREDADDRESS]]</div>
<div class="copyright"><?php echo apply_filters( 'pdf_template_company_number_text', __( 'Company Number : ', PDFLANGUAGE ) ); ?>[[PDFCOMPANYNUMBER]] <?php echo apply_filters( 'pdf_template_vat_number_text', __( 'VAT Number : ', PDFLANGUAGE ) ); ?>[[PDFTAXNUMBER]]</div>
</div>
<div id="content">
[[ORDERINFOHEADER]]
[[ORDERINFO]]
<table table width="100%">
<tr>
<td width="70%" valign="top">
[[PDFORDERNOTES]]
</td>
<td width="30%" valign="top" align="right">
<table width="100%">
[[PDFORDERSUBTOTAL]]
[[PDFORDERTAX]]
[[PDFORDERSHIPPING]]
[[PDFORDERDISCOUNT]]
[[PDFORDERTOTAL]]
</table>
</td>
</tr>
</table>
<table table width="100%">
<tr>
<td width="100%" valign="top">
[[PDFTERMSCONDITIONS]]
</td>
</tr>
</table>
</div>
</body>
</html>

view raw
gistfile1.txt
hosted with ❤ by GitHub

Adding terms and conditions area to the invoice ↑ Back to top

/**
* Adding terms and conditions area to the invoice
*
* Uses template tag [[PDFTERMSCONDITIONS]]
*
* settings field name : woocommerce_pdf_invoice_settings[invoice_terms]
*
* 1 – Edit template.php and add the tag in the desired place
* 2 – add code to the theme functions.php file
* 3 – add text in PDF Invoice settings
*/
add_action ( 'woocommerce_pdf_invoice_additional_fields_admin' , 'additional_fields_admin_terms' );
function additional_fields_admin_terms() {
$woocommerce_pdf_invoice_options = get_option('woocommerce_pdf_invoice_settings');
?>
<!– Terms and Conditions –>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="woocommerce_pdf_invoice_settings[invoice_terms]">Invoice Terms and Conditions</label>
<img class="help_tip" data-tip="Add some custom text to your invoice" src="<?php echo plugins_url( 'woocommerce/assets/images/help.png' );?>" height="16" width="16" />
</th>
<td class="forminp forminp-number">
<textarea id="woocommerce_pdf_invoice_settings[invoice_terms]"
name="woocommerce_pdf_invoice_settings[invoice_terms]"
value=""
placeholder="" style="width: 350px;"/><?php if ( isset($woocommerce_pdf_invoice_options['invoice_terms']) ) { echo $woocommerce_pdf_invoice_options['invoice_terms']; }?></textarea>
</td>
</tr>
<?php
}
add_filter ( 'pdf_content_additional_content' , 'pdf_additional_content_terms' );
function pdf_additional_content_terms( $content ) {
$woocommerce_pdf_invoice_options = get_option('woocommerce_pdf_invoice_settings');
if ( isset($woocommerce_pdf_invoice_options['invoice_terms']) ) :
$content = str_replace( '[[PDFTERMSCONDITIONS]]', $woocommerce_pdf_invoice_options['invoice_terms'], $content );
endif;
return $content;
}
/* Close terms and conditions */

view raw
gistfile1.php
hosted with ❤ by GitHub

Add Bank Details to footer from WooCommerce BACS settings ↑ Back to top

/**
* Add Bank Details to footer from WooCommerce BACS settings
*
* Uses template tag [[PDFBANKDETAILS]]
*
* 1 – Add the template tag to template.php
* 2 – Add this code to the theme functions.php
* 3 – check invoice layout and modify CSS in template.php as necessary
*/
add_filter ( 'pdf_content_additional_content', 'pdf_additional_content_bank_details_footer', 10, 2 );
function pdf_additional_content_bank_details_footer( $content, $order_id ) {
// Get order and store in $order.
$order = wc_get_order( $order_id );
$has_details = false;
// Get sortcode label in the $locale array and use appropriate one.
$sortcode = __( 'Sort code', 'woocommerce' );
$bacs_accounts = get_option( 'woocommerce_bacs_accounts' );
if ( ! empty( $bacs_accounts ) ) {
$account_html = '<table>';
foreach ( $bacs_accounts as $bacs_account ) {
$bacs_account = (object) $bacs_account;
if ( $bacs_account->account_name ) {
$account_html .= '<tr><td class="wc-bacs-bank-details-account-name">' . wp_kses_post( wp_unslash( $bacs_account->account_name ) ) . ':</td>' . PHP_EOL;
}
// $account_html .= '<tr class="wc-bacs-bank-details order_details bacs_details">' . PHP_EOL;
// BACS account fields shown on the thanks page and in emails.
$account_fields = apply_filters(
'woocommerce_bacs_account_fields', array(
'bank_name' => array(
'label' => __( 'Bank', 'woocommerce' ),
'value' => $bacs_account->bank_name,
),
'account_number' => array(
'label' => __( 'Account number', 'woocommerce' ),
'value' => $bacs_account->account_number,
),
'sort_code' => array(
'label' => $sortcode,
'value' => $bacs_account->sort_code,
),
'iban' => array(
'label' => __( 'IBAN', 'woocommerce' ),
'value' => $bacs_account->iban,
),
'bic' => array(
'label' => __( 'BIC', 'woocommerce' ),
'value' => $bacs_account->bic,
),
), $order_id
);
foreach ( $account_fields as $field_key => $field ) {
if ( ! empty( $field['value'] ) ) {
$account_html .= '<td class="' . esc_attr( $field_key ) . '">' . wp_kses_post( $field['label'] ) . ': <strong><br />' . wp_kses_post( wptexturize( $field['value'] ) ) . '</strong></td>' . PHP_EOL;
$has_details = true;
}
}
$account_html .= '</tr>';
}
$account_html .= '</table>';
}
if ( $has_details ) {
$pdfbankdetails = '<section class="woocommerce-bacs-bank-details">' . esc_html__( 'Our bank details', 'woocommerce' ) . '' . wp_kses_post( PHP_EOL . $account_html ) . '</section>';
$content = str_replace( '[[PDFBANKDETAILS]]', $pdfbankdetails, $content );
} else {
$content = str_replace( '[[PDFBANKDETAILS]]', '', $content );
}
return $content;
}

view raw
gistfile1.php
hosted with ❤ by GitHub

Add Bank Details under notes section from WooCommerce BACS settings ↑ Back to top

/**
* Add Bank Details under notes section from WooCommerce BACS settings
*
* Uses template tag [[PDFBANKDETAILS]]
*
* 1 – Add the template tag to template.php
* 2 – Add this code to the theme functions.php
* 3 – check invoice layout and modify CSS in template.php as necessary
*/
add_filter ( 'pdf_content_additional_content' , 'pdf_additional_content_bank_details' );
function pdf_additional_content_bank_details( $content ) {
$woocommerce_bacs_settings = get_option( 'woocommerce_bacs_settings' );
$pdfbankdetails = '<h2>Bank Details</h2>';
$pdfbankdetails .= '<table width="100%">';
if( $woocommerce_bacs_settings['account_name'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">Account Name</td><td width="50%">' .$woocommerce_bacs_settings['account_name']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
if( $woocommerce_bacs_settings['account_number'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">Account Number</td><td width="50%">' .$woocommerce_bacs_settings['account_number']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
if( $woocommerce_bacs_settings['sort_code'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">Sort Code</td><td width="50%">' .$woocommerce_bacs_settings['sort_code']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
if( $woocommerce_bacs_settings['bank_name'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">Bank Name</td><td width="50%">' .$woocommerce_bacs_settings['bank_name']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
if( $woocommerce_bacs_settings['iban'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">IBAN</td><td width="50%">' .$woocommerce_bacs_settings['iban']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
if( $woocommerce_bacs_settings['bic'] ) :
$pdfbankdetails.= '<tr>';
$pdfbankdetails.= '<td width="50%">BIC</td><td width="50%">' .$woocommerce_bacs_settings['bic']. '</td>';
$pdfbankdetails.= '</tr>';
endif;
$pdfbankdetails.= '</table>';
$content = str_replace( '[[PDFBANKDETAILS]]', $pdfbankdetails, $content );
return $content;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Add a custom field from the order ↑ Back to top

If you are adding custom fields to your checkout, for example Mobile Number, you might want to include this in the invoice. You will need a template tag in the template (see above for examples on how to add template tags), for example [[PDFBILLINGMOBILE]]. Once you have your edited template in place you will need a custom function to replace the template tag when the invoice is generated.

// Add billing field to Billing section, eg mobile number.
// Uses a placeholder [[PDFBILLINGMOBILE]] in the template file
add_filter( 'pdf_content_additional_content', 'custom_pdf_content_additional_content', 10, 2 );
function custom_pdf_content_additional_content( $content, $order_id ) {
$content = str_replace( '[[PDFBILLINGMOBILE]]', get_post_meta( $order_id,'mobile',TRUE ), $content );
return $content;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Add billing and or shipping title to the address area ↑ Back to top

This code assumes that you have already included the necessary field on the checkout and have stored it in the order, you can use the WooCommerce Checkout Field Editor plugin for that. The title field should be called billing_title or shipping_title.

// Add a field to the customer's address, eg title
add_filter( 'woocommerce_order_formatted_billing_address', 'pdf_invoice_woocommerce_order_formatted_billing_address', 10, 2 );
function pdf_invoice_woocommerce_order_formatted_billing_address( $address, $order ) {
// Add the post meta from the order
$billing_title = get_post_meta( $order->get_id(), 'billing_title', TRUE );
// Add $billing title to the beginning of the address
$address = array( "billing_title" => $billing_title ) + $address;
// Return the address
return $address;
}
add_filter('woocommerce_formatted_address_replacements', 'pdf_invoice_add_woocommerce_formatted_address_replacements', 10, 2);
function pdf_invoice_add_woocommerce_formatted_address_replacements($replace, $args) {
$replace['{title}'] = $args['title'];
$replace['{name}'] = $args['title']." ".$args['first_name']." ".$args['last_name']; //show title along with name
return $replace;
}
add_filter( 'woocommerce_order_formatted_billing_address', 'pdf_invoice_update_formatted_billing_address', 10, 2);
function pdf_invoice_update_formatted_billing_address( $address, $order ){
$address_fields = array(
'title',
'first_name',
'last_name',
'company',
'address_1',
'address_2',
'city',
'state',
'postcode',
'country'
);
if( is_array($address_fields) ) {
foreach( $address_fields as $address_field ){
$field = "get_billing_" . $address_field;
if( method_exists( $order, $field ) ) {
$address[$address_field] = $order->$field();
} else {
$address[$address_field] = $order->{'billing_'.$address_field};
}
}
}
return $address;
}
add_filter( 'woocommerce_order_formatted_shipping_address', 'pdf_invoice_update_formatted_shipping_address', 10, 2);
function pdf_invoice_update_formatted_shipping_address( $address, $order ){
$address_fields = array(
'title',
'first_name',
'last_name',
'company',
'address_1',
'address_2',
'city',
'state',
'postcode',
'country'
);
if( is_array($address_fields) ) {
foreach( $address_fields as $address_field ){
$field = "get_shipping_" . $address_field;
if( method_exists( $order, $field ) ) {
$address[$address_field] = $order->$field();
} else {
$address[$address_field] = $order->{'shipping_'.$address_field};
}
}
}
return $address;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Modifying the invoice table headers and content ↑ Back to top

/**
* Modifying Headers
*
* Add to your theme functions.php
*/
add_filter( 'pdf_template_table_headings','custom_pdf_template_table_headings' );
function custom_pdf_template_table_headings( $headers ) {
$headers = '<table class="shop_table orderdetails" width="100%">' .
'<thead>' .
'<tr><th colspan="7" align="left"><h2>' . esc_html__('Order Details', PDFLANGUAGE) . '</h2></th></tr>' .
'<tr>' .
'<th width="10%" valign="top" align="right">' . __( 'Qty', PDFLANGUAGE ) . '</th>' .
'<th width="54%" valign="top" align="left">' . __( 'Product', PDFLANGUAGE ) . '</th>' .
'<th width="18%" valign="top" align="right">' . __( 'Price Inc', PDFLANGUAGE ) . '</th>' .
'<th width="18%" valign="top" align="right">' . __( 'Total Inc', PDFLANGUAGE ) . '</th>' .
'</tr>' .
'</thead>' .
'</table>';
return $headers;
}
add_filter( 'pdf_template_line_output' , 'custom_pdf_template_line_output', 10, 2 );
function custom_pdf_template_line_output( $pdflines, $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
$order_currency = $pre_wc_30 ? $order->get_order_currency() : $order->get_currency();
$pdflines = '<table width="100%">';
$pdflines .= '<tbody>';
if ( sizeof( $order->get_items() ) > 0 ) :
foreach ( $order->get_items() as $item ) {
if ( $item['qty'] ) {
$line = '';
// $item_loop++;
$_product = $order->get_product_from_item( $item );
$item_name = $item['name'];
$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );
if ( $meta = $item_meta->display( true, true ) )
$item_name .= ' ( ' . $meta . ' )';
$line = '<tr>' .
'<td valign="top" width="10%" align="right">' . $item['qty'] . ' x</td>' .
'<td valign="top" width="54%">' . $item_name . '</td>' .
'<td valign="top" width="18%" align="right">' . wc_price( ( $item['line_subtotal'] + $item['line_tax'] ) / $item['qty'], array( 'currency' => $order_currency ) ) . '</td>' .
'<td valign="top" width="18%" align="right">' . wc_price( $item['line_subtotal'] + $item['line_tax'], array( 'currency' => $order_currency ) ) . '</td>' .
'</tr>' ;
$pdflines .= $line;
}
}
endif;
$pdflines .= '</tbody>';
$pdflines .= '</table>';
return $pdflines;
}
/* Close Modifying Headers */

view raw
gistfile1.php
hosted with ❤ by GitHub

Changes In Version 1.3.0 ↑ Back to top

In previous versions of PDF Invoice each section of the totals area at the bottom of the invoice was handled separately. In version 1.3.0 the totals are handled in one section of code, it can still be filtered if necessary. If you are using the old filters and have not copied the template file to your theme then your filters will no longer work. If you have copied the template to your theme folder then your modifications will remain

This is the new function for outputting the totals section

/**
* [get_pdf_order_totals description]
* New for Version 1.3.0, replaces several functions with one looped function
* @param [type] $order_id [description]
* @return [type] [description]
*/
function get_pdf_order_totals( $order_id ) {
global $woocommerce;
if (!$order_id) return;
$order = new WC_Order( $order_id );
$order_item_totals = $order->get_order_item_totals();
unset( $order_item_totals['payment_method'] );
$output = '';
foreach ( $order_item_totals as $order_item_total ) {
$output .= '<tr>' .
'<td align="right">' .
'<strong>' . $order_item_total['label'] . '</strong></td>' .
'<td align="right"><strong>' . $order_item_total['value'] . '</strong></td>' .
'</tr>' ;
}
$output = apply_filters( 'pdf_template_order_totals' , $output, $order_id );
return $output;
}

view raw
gistfile1.php
hosted with ❤ by GitHub

Reorder the invoice totals section ↑ Back to top

Using the [[PDFORDERTOTALS]] Tag ↑ Back to top

This is the default template tag and the function below will let you re-order the totals section without modifying the template

/**
* Reorder the totals output
*
* Shipping
* Subtotal
* Taxes
* Total
*
* Changes the SubTotal to include the shipping cost
*/
add_filter( 'pdf_template_order_totals', 'custom_totals_layout_pdf_template_order_totals', 10, 2 );
function custom_totals_layout_pdf_template_order_totals( $output, $order_id ){
global $woocommerce;
if (!$order_id) return;
$order = new WC_Order( $order_id );
// Check WC version – changes for WC 3.0.0
$pre_wc_30 = version_compare( WC_VERSION, '3.0', '<' );
$order_currency = $pre_wc_30 ? $order->get_order_currency() : $order->get_currency();
$order_item_totals = $order->get_order_item_totals();
// Clean up shipping value
// Use this line if you just want the shipping value, without the description
// $order_item_totals['shipping']['value'] = wc_price( round( $order->get_shipping_total(), wc_get_price_decimals() ), array( 'currency' => $order_currency ) );
// Grab the basics
$cart_subtotal = $order_item_totals['cart_subtotal'];
$shipping = $order_item_totals['shipping'];
$order_total = $order_item_totals['order_total'];
// Modify the subtotal to include shipping
$subtotal = $order->get_subtotal();
$shipping_cost = $order->get_shipping_total();
$new_subtotal = wc_price( round( ($subtotal + $shipping_cost), wc_get_price_decimals() ), array( 'currency' => $order_currency ) );
$replace_subtotal = wc_price( $subtotal, array( 'currency' => $order_currency ) );
// Update the subtotal array
$cart_subtotal = str_replace( $replace_subtotal, $new_subtotal, $cart_subtotal );
// Remove everything except taxes
unset( $order_item_totals['cart_subtotal'] );
unset( $order_item_totals['shipping'] );
unset( $order_item_totals['payment_method'] );
unset( $order_item_totals['order_total'] );
// Start building a new array in the right order
$new_order_item_totals['shipping'] = $shipping;
$new_order_item_totals['cart_subtotal'] = $cart_subtotal;
// Taxes
foreach ( $order_item_totals as $key => $value ) {
$new_order_item_totals[$key] = $value;
}
$new_order_item_totals['order_total'] = $order_total;
$output = '';
foreach ( $new_order_item_totals as $order_item_total ) {
$output .= '<tr>' .
'<td align="right">' .
'<strong>' . $order_item_total['label'] . '</strong></td>' .
'<td align="right"><strong>' . $order_item_total['value'] . '</strong></td>' .
'</tr>' ;
}
if( $order->get_total_refunded() > 0 ) {
$output .= '<tr>' .
'<td align="right">' .
'<strong>Amount Refunded:</strong></td>' .
'<td align="right"><strong>' . wc_price( $order->get_total_refunded(), array( 'currency' => $order_currency ) ) . '</strong></td>' .
'</tr>' ;
}
return $output;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Using the individual template tags ↑ Back to top

You can edit the template file and replace [[PDFORDERTOTALS]] with the individual tags

[[PDFORDERSUBTOTAL]]
[[PDFORDERSHIPPING]]
[[PDFORDERDISCOUNT]]
[[PDFORDERTAX]]
[[PDFORDERTOTAL]]

And use them in any order you like. If you need to edit the output of any section there are filters available

$output = apply_filters( 'pdf_template_order_subtotal' , $output, $order_id );
$output = apply_filters( 'pdf_template_order_shipping' , $output, $order_id );
$output = apply_filters( 'pdf_template_order_discount' , $output, $order_id );
$output = apply_filters( 'pdf_template_order_tax' , $output, $order_id );
$output = apply_filters( 'pdf_template_order_total' , $output, $order_id );

view raw
gistfile1.txt
hosted with ❤ by GitHub

Full List Of Available Filters ↑ Back to top

/**
* Modify the $order_status_array and add your own order status
* add_filter ( 'pdf_invoice_order_status_array', 'add_custom_order_status_to_pdf_invoice_order_status_array', 99, 2 );
*
* function add_custom_order_status_to_pdf_invoice_order_status_array ( $order_status_array ) {
* $order_status_array[] = 'dispensing';
* return $order_status_array;
* }
*
* Modify the $order_status_array and replace it with own array
* add_filter ( 'pdf_invoice_order_status_array', 'add_custom_order_status_to_pdf_invoice_order_status_array', 99, 2 );
*
* function add_custom_order_status_to_pdf_invoice_order_status_array ( $order_status_array ) {
* $order_status_array = array('dispensing');
* return $order_status_array;
* }
*
*/
$order_status_array = apply_filters( 'pdf_invoice_order_status_array', $order_status_array );
/**
* add_filter( 'woocommerce_pdf_my_account_button_label', 'change_pdf_my_account_button_label' );
*
* function change_pdf_my_account_button_label( $lable ) {
* return 'Download your invoice';
* }
*/
apply_filters('woocommerce_pdf_my_account_button_label', __( 'PDF Invoice', 'woocommerce-pdf-invoice' ) )
// Allow $user_id to be filtered
$user_id = apply_filters( 'pdf_invoice_download_user_id', $user_id, $current_user, $orderid );
// Add an invoice link to the thank you page
apply_filters( 'pdf_invoice_invoice_link_thanks', $invoice_link_thanks, $order_id );
// Add a filter for the array
$email_ids = apply_filters( 'pdf_invoice_email_ids', $email_ids, $order );
// Apply a filter to modify the PDF if required
$pdf = apply_filters( 'pdf_invoice_modify_attachment', $pdf, $id, $order );
// Filter the filename
$filename = apply_filters( 'pdf_output_filename', $filename, $order_id );
// filter the meta output
$meta_output = apply_filters( 'pdf_invoice_meta_output', $meta_display );
/**
* Allow additional info to be added to the $item_name
*
* add_filter( 'pdf_invoice_item_name', 'add_product_description_pdf_invoice_item_name', 10, 4 );
*
* function add_product_description_pdf_invoice_item_name( $item_name, $item, $product, $order ) {
*
* // Use $product->get_id() if you want to get the post id for the product.
* $item_name .= '<p>' . $product->get_description() . '</p>';
* return $item_name;
*
* }
*/
$item_name = apply_filters( 'pdf_invoice_item_name', $item_name, $item, $_product, $order );
// Modify the Products setion of the invoice
$pdf = apply_filters( 'pdf_template_line_output', $pdflines, $order_id );
// Modify the order note
$output = apply_filters( 'pdf_template_order_notes' , $output, $order_id );
/**
* Not used by default
*/
// Modify the Subtotal
$output = apply_filters( 'pdf_template_order_subtotal' , $output, $order_id );
// Modify the shipping
$output = apply_filters( 'pdf_template_order_shipping' , $output, $order_id );
// Modify the coupons
$output = apply_filters( 'pdf_template_order_coupons' , $output, $order_id );
// Modify the discount
$output = apply_filters( 'pdf_template_order_discount' , $output, $order_id );
// Modify the taxes
$output = apply_filters( 'pdf_template_order_tax' , $output, $order_id );
// Modify the order total
$output = apply_filters( 'pdf_template_order_total' , $output, $order_id );
/**
* Used by default
*/
// Modify the order totals
$output = apply_filters( 'pdf_template_order_totals' , $output, $order_id );
// Modify the table headings
apply_filters( 'pdf_template_table_headings', $headers, $order_id );
// Modify $content
$content = apply_filters( 'pdf_content_additional_content' , $content , $order_id );
/**
* Filter the $page_id for reasons, for example, chage the terms page based on products in the order of the order language.
*/
$page_id = apply_filters( 'pdf_invoice_terms_page_id', $page_id, $order_id );
// Filter the content of the T&Cs as per any other WordPress page
$terms = apply_filters( 'the_content', $post->post_content );
// Template Filters.
// These filters are rarely used, if you need to translate these outputs and don't want to edit the template then Loco Translate is a better option.
apply_filters( 'pdf_template_invoice_number_text', __( 'Invoice No. :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_order_number_text', __( 'Order No. :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_invoice_date_text', __( 'Invoice Date :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_order_date_text', __( 'Order Date :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_payment_method_text', __( 'Payment Method :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_shipping_method_text', __( 'Shipping Method :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_payment_status_text', __( 'Payment Status :', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_billing_details_text', __( 'Billing Details', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_shipping_details_text', __( 'Shipping Details', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_registered_name_text', __( 'Registered Name : ', 'woocommerce-pdf-invoice' ) );
echo apply_filters( 'pdf_template_registered_office_text', __( 'Registered Office : ', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_company_number_text', __( 'Company Number : ', 'woocommerce-pdf-invoice' ) );
apply_filters( 'pdf_template_vat_number_text', __( 'VAT Number : ', 'woocommerce-pdf-invoice' ) );
// Modify the settings
do_action( 'woocommerce_pdf_invoice_settings_action' );

view raw
gistfile1.txt
hosted with ❤ by GitHub

Feedback and feature requests ↑ Back to top

For feedback on the PDF Invoice extension, this documentation or for feature requests please email support@chromeorange.co.uk

WooCommerce - the most customizable eCommerce platform for building your online business.

Back to the top