WooCommerce Customer / Order / Coupon Export developer documentation

Overview ↑ Back to top

This extension was designed to be as flexible as possible. To that end, filters are used to allow you to customize the generated output or replace it entirely.

When exporting as a CSV, we do have one major recommendation: We strongly recommend that you do not rely on the column ordering for the generated file. While we do our best to not change column ordering for default formats, sometimes we must do so and this will break any integrations that rely on a specific order. Instead, use the column names / keys, which are guaranteed to never change.

Please be aware that this document is meant for developers to use as a reference, and some of these code samples are structural samples rather than working snippets. We do not support or do plugin customizations as per our support policy. You can get in touch with an expert for help with customizations.

If you need help changing this code or extending it, we recommend getting in touch with a Woo Expert or a developer at Codeable.

Customization Best Practices ↑ Back to top

While you can use the filters / actions referenced in this document for doing basic customizations within your theme’s functions.php file, we strongly recommend creating a custom plugin so that if you switch themes you don’t lose your customizations.

For more information on creating a custom plugin for your WooCommerce store, read this article.

We also have several snippet examples available for reference that show you several filters in action.

File Name / Format Filters ↑ Back to top

File Name ↑ Back to top

apply_filters( 'wc_customer_order_export_{$output_type}_filename', $post_replace_filename, $pre_replace_filename, $ids );

Use this filter to change the generated file name for the specified $output_type which can be ‘csv’ or ‘xml’.

apply_filters( 'wc_customer_order_export_filename', $post_replace_filename, $pre_replace_filename, $ids );

Use this filter to change the generated file name for all output types.

Both these filters affect the file name for both downloads and uploads, but not HTTP POST (which has no file name). Here’s some sample code for changing the date/time format of the %%timestamp%% variable:

Here’s some sample code for adding a %%order_numbers%% filename variable so the order numbers support Sequential Order Numbers:

You can also add merge variables for the file name.

apply_filters( "wc_customer_order_export_{$output_type}_filename_variables", $variables, $ids, $export_type );

Use this filter to add variables into the array of accepted merge tag variables for the specified $output_type.

apply_filters( "wc_customer_order_export_filename_variables", $variables, $ids, $export_type );

Use this filter to add variables into the array of accepted merge tag variables for all output types.

Output Formats ↑ Back to top

Both output types have a filterable format definition that allows modifying the structure of the export. The format of the CSV will depend on an array of column headers, the resulting data array will then use this to populate each row of the CSV file. The format of the XML can be adjusted, or completely changed, to generate an entirely different kind of file.

apply_filters( 'wc_customer_order_export_format_definition', $definition, $export_type, $format, $output_type );

Use this filter to change the format definitions.

For example, if your XML requires special character support and you need to change the character encoding. See this example snippet as a starting point.

CSV Order Output ↑ Back to top

The CSV output also has specific filters to allow for changing the general format of the CSV file.

CSV Delimiter

apply_filters( 'wc_customer_order_export_csv_delimiter', ',', $this );

Use this filter to change the CSV delimiter. This is a comma (,) by default.

CSV Enclosure

apply_filters( 'wc_customer_order_export_csv_enclosure', '"', $this );

Use this filter to change the CSV enclosure. This is a double-quote (") by default.

Enabling BOM (byte-order mark)

apply_filters( 'wc_customer_order_export_csv_enable_bom', false, $this );

Use this filter to add a BOM at the start of every generated CSV file. This is disabled by default.

Here’s some example code:

XML Order Output ↑ Back to top

The XML output also has specific filters to allow for changing the general format of the XML file.

XML Version

apply_filters( 'wc_customer_order_export_xml_version', $xml_version );

Use this filter to change the XML version specified in the generated XML. This is 1.0 by default.

XML Encoding

apply_filters( 'wc_customer_order_export_xml_encoding', $xml_encoding );

Use this filter to change the XML encoding specified in the generated XML. This is UTF-8 by default. Here’s some sample code for changing to ISO-8859-1:

function wc_sample_xml_change_xml_encoding() {
    return 'ISO-8859-1';
}
add_filter( 'wc_customer_order_xml_export_suite_xml_encoding', 'wc_sample_xml_change_xml_encoding' );

Customizing Customer Output ↑ Back to top

The output of the export can be customized easily using the built-in custom format builder (version 4.0+). However, you may want to conditionally change a default format, for which the built-in filters are helpful. For instance, you can add columns in a particular location or to add additional information. View this code snippet to add both username and customer role in the exported CSV in particular locations.

Adjust Included Customers ↑ Back to top

By default, all non-employee purchasers are included in the customer export (if using WordPress 4.4+) — administrators and shop managers are excluded from the customer export. However, you could customize this to only include certain roles.

apply_filters( 'wc_customer_order_export_{$output_type}_user_query_args', $query_args );

Where $output_type refers to either ‘csv’ or ‘xml’.

apply_filters( 'wc_customer_order_export_user_query_args', $query_args, $output_type );

Use this to adjust the query regardless of output type.

Here’s an example to limit the customer CSV export to certain roles.

Adding Extra Customer Data ↑ Back to top

You can add customer data to the exported customer file, so long as this data is part of the WooCommerce customer data or accessible as part of the WP User object.

CSV Customer Output

You’d use the wc_customer_order_export_csv_customer_headers filter to add the column header / name, and the wc_customer_order_export_csv_customer_row to populate the data for that column. Here’s an example snippet for adding customer columns to your CSV.

XML Customer Output

You’d use the wc_customer_order_export_xml_customers_xml_data filter to add the tag / value before the XML is generated, and wc_customer_order_export_xml_customers_xml to edit the XML directly.

Rename, Re-order, or Remove Customer Data ↑ Back to top

You can customize what data is included and the respective order in the exported file. You can also remove unnecessary data. Here are some examples that can be used to remove, rename, or re-order customer export data:

Modifying CSV Output

Modifying XML Output

Customizing Order Output ↑ Back to top

The output of the order file can be customized easily using the built-in custom format builder (version 4.0+). However, you may want to conditionally change a default format, for which the built-in filters are helpful.

Adjust Included Orders ↑ Back to top

All orders will be included in your export, or the export query can be adjusted based on order status, products in the order, categories in the order, or the order date. If you need to make further adjustments to the orders included in the export, the query arguments can be filtered further:

apply_filters( 'wc_customer_order_export_{$output_type}_query_args', $query_args, $export_type, $output_type );

Where $output_type refers to either ‘csv’ or ‘xml’.

apply_filters( 'wc_customer_order_export_query_args', $query_args, $export_type, $output_type );

Use this to adjust the query regardless of output type.

Be sure to check that 'orders' === $export_type if scoping your code to order exports.

Here’s an example to limit order exports to only orders that have at least one refund associated with them.

Adding Extra Order Data ↑ Back to top

Due to the differences of output formats between XML and CSV, you will need to use different filters, depending on which output type you want to export.

Adding CSV Output

If you need to add additional columns to the order CSV export, you’ll use two filters — one to add the column headers and another to set the data for the columns for each row. Here’s a structural sample:

Since custom formats were added in version 4.0+, these may have a one row per item format. If you maintain a plugin that has compatibility with this format, you’ll want a way to check if this format is in use. Here’s an example:

/**
 * Helper function to check the export format
 *
 * @param \WC_Customer_Order_CSV_Export_Generator $csv_generator the generator instance
 * @return bool - true if this is a one row per item format
 */
function sv_wc_csv_export_is_one_row( $csv_generator ) {

    $one_row_per_item = false;

    if ( version_compare( wc_customer_order_csv_export()->get_version(), '4.0.0', '<' ) ) {
        // pre 4.0 compatibility
        $one_row_per_item = ( 'default_one_row_per_item' === $csv_generator->order_format || 'legacy_one_row_per_item' === $csv_generator->order_format );
    } elseif ( isset( $csv_generator->format_definition ) ) {
        // post 4.0 (4.0.3+)
        $one_row_per_item = 'item' === $csv_generator->format_definition['row_type'];
    }

    return $one_row_per_item;
}

You can then use this check within your plugin or custom code to ensure you’ve added your custom data correctly:

if ( sv_wc_csv_export_is_one_row( $csv_generator ) ) {
        foreach ( $order_data as $data ) {
                $new_order_data[] = array_merge( (array) $data, $custom_data );
        }
} else {
        $new_order_data = array_merge( $order_data, $custom_data );
}

However, this would only apply if you already have access to the CSV_Export_Generator instance in your filter / code. If for some reason you need to check the row type for a custom format outside of a filter that gives you access to this, you can check the format definition this way:

$format_definition = wc_customer_order_csv_export()->get_formats_instance()->get_format( 'orders', 'custom', 'csv' );

The $format_definition['row_type'] will be ‘item’ or ‘order’ for the custom format, letting you then act on the format from there. You may also want to use this for retrieving XML formats, by switching the output type to ‘xml’ instead.

Here are some more example scripts for adding additional data to the CSV order export:

Adding XML Output

The root element is taken from the export type by default, in this case, Orders. To adjust this you will need to use the following filter:

apply_filters( 'wc_customer_order_export_xml_root_element', ucfirst( $export_type ), $this );

where $this corresponds to the XML/CSV Generator instance.

If you need to add extra data directly to your XML order export, then you’ll need to use the following:

apply_filters( 'wc_customer_order_export_xml_get_orders_xml_data', array( 'Order' => $orders ), $orders );

This defines the data used for the Orders tag, by default this will be an array of Order tags and the individual XML for each order.

To add the extra data to the XML before it is generated, you’ll need to use:

apply_filters( 'wc_customer_order_export_xml_order_data', array(
    'OrderId'            => $order->id,
    'OrderNumber'        => $order->get_order_number(),
    // ...etc
), $order );

This defines the format for each individual order element and passes in an WC_Order order object for each order being exported.

If you’d like to have more fine grained control over the exported data, it is also possible to adjust line_items, shipping_items, fee_items, and tax_items separately too. As an example, to add data to an Order’s LineItems, the following filter can be used:

apply_filters( 'wc_customer_order_xml_export_suite_order_line_item', array(
    'SKU'       => $product->get_sku(),
    'Quantity'  => $item['qty'],
    'Price'     => $product->get_price(),
    'LineTotal' => $item['line_total'],
    'Meta'      => $item_meta
), $order, $item );

This defines the format for each individual line item within an order, and passes in the WC_Order order object for the line item’s order, and the $item array which contains the information about the line item.

The following filters can be used with a similar approach:

  • wc_customer_order_export_xml_order_shipping_item
  • wc_customer_order_export_xml_order_fee_item
  • wc_customer_order_export_xml_order_tax_item

It’s also possible to adjust the OrderNote format too:

apply_filters( 'wc_customer_order_export_xml_order_note', array(
    'Date'    => $note->comment_date,
    'Author'  => $note->comment_author,
    'Content' => str_replace( array( "\r", "\n" ), ' ', $note->comment_content ),
), $note, $order );

This defines the format for each order note within an order, and passes in the $note object, which contains order note comment object, along with the WC_Order order object for the order.

Here are some more example scripts for adding additional data to the XML order export:

Rename, Re-order, or Remove Order Data ↑ Back to top

Adjusting CSV Output

You can rename or reorder the columns using this filter:

apply_filters( 'wc_customer_order_export_csv_order_headers', $column_headers, $generator );

If you’d like to remove the CSV headers from the export entirely, however, you’ll need to remove the filter function that generates this for the output. There is an example snippet to remove the headers in our snippet repository.

Occasionally you might need to change the CSV after it’s already been generated though. To do this, you can use the following filter for each $export_type:

apply_filters( 'wc_customer_order_export_get_${export_type}_csv_output', $csv, $order_data, $ids, $export_format, $custom_export_format );

where the export type can be: ‘orders’, ‘customers’, or ‘coupons’.

When using the default format, you can add / remove / modify line item entries using the filter:

apply_filters( 'wc_customer_order_csv_export_order_line_item', $line_item, $item );

This passes in the existing line item entries along with the WC Order Item array.

Here’s some sample code for adding the product’s weight as item meta in the CSV export.

If you wanted to modify existing data, you can do so for the line items and columns using the column header keys. Here’s a working example that will change all prices from machine-readable values to localized price output for currency.

It’s also possible to separate data into multiple columns. For example, the ‘coupons’ column contains all coupon data, but this data could be expanded into individual columns with the Default formats. This sample code snippet will separate the ‘coupons’ column into 3 columns per coupon used: 'coupon_{$count}_name', 'coupon_{$count}_description', and 'coupon_{$count}_amount'.

Here’s a collection of some additional samples:

Adjusting XML Output

The XML is generated from an Array of XML tags, so you can adjust the order or remove tags by using this filter:

apply_filters( 'wc_customer_order_export_xml_order_data', array(
    'OrderId'            => $order->id,
    'OrderNumber'        => $order->get_order_number(),
    // ...etc
), $order );

Updating order status after export ↑ Back to top

You can update an order’s status after export by using the:

apply_filters( 'wc_customer_order_export_mark_order_exported', $mark_order_as_exported, $order, $method, $handler )

or by hooking into the wc_customer_order_export_{$output_type}_order_exported action.

Here are a couple examples of updating the status on every export, or only for paid orders. $output_type in this case can be either ‘csv’ or ‘xml’.

Additional Filters ↑ Back to top

HTTP POST Filters ↑ Back to top

If you’re using the automatic export over HTTP POST, there is a filter available to change the arguments used for wp_remote_post().

apply_filters( 'wc_customer_order_export_http_post_args', [
    'timeout'     => 60,
    'redirection' => 0,
    'httpversion' => '1.0',
    'sslverify'   => true,
    'blocking'    => true,
    'headers'     => [
        'accept'       => $content_type,
        'content-type' => $content_type,
    ],
    'body'        => $contents,
    'cookies'     => [],
    'user-agent'  => "WordPress " . $GLOBALS['wp_version'],
] );

For example, if the web service you’re posting to requires authentication, you could use this filter to add HTTP basic auth to the headers:

function wc_csv_export_add_http_post_basic_auth( $args ) {
    // you can set other HTTP headers using the format $args['headers']['Header Name'] = 'header value'
    $args['headers']['Authorization'] = 'Basic ' . base64_encode( 'your_username:your_password' );

    return $args;
}
add_filter( 'wc_customer_order_csv_export_http_post_args', 'wc_csv_export_add_http_post_basic_auth' );

Admin Filters ↑ Back to top

If you’d like to customize the query arguments that are used for selecting orders to export on the Export > Manual Export screen, use:

apply_filters( 'wc_customer_order_export_query_args', $query_args, $export_type, $output_type );

You can also customize query arguments used for the customer export using:

apply_filters( 'wc_customer_order_export_user_query_args', $query_args, $output_type )


Here’s an example that lets you determine which user roles are included as customers in the export.

Custom Data Stores ↑ Back to top

From v4.5.0 of the plugin, it is now possible to imnplement a custom data store. As standard, we include a database store which will stream the export results where possible, rather than processing and sending the whole file at once. This increases server efficiency, especially when downloading very large exports.

Database streaming does require the MySQLi extension to be enabled, and used, by WordPress. In some cases, MySQLi will be installed on the server but not put to use by WordPress. This can be remedied by adding define( 'WP_USE_EXT_MYSQL', false ); to the WordPress config file.

Here are just a few examples of things that would be possible with custom data stores:

  • Store exports in a separate MySQL database from the main WordPress instance.
  • Store exports in a completely different database engine such as PostgresSQL or MongoDB.
  • Store exports off-site, on a separate server, or with a storage service such as Amazon S3.
  • Perform transformations on the data as it is being stored/retrieved — i.e. file compression, or encryption.

To get started, you will need to implement the abstract WC_Customer_Order_CSV_Export_Data_Store and hook into the filter:

$data_store = apply_filters( "wc_customer_order_export_{$output_type}_custom_data_store", $type );

where $output_type will be either ‘csv’ or ‘xml’. You may also want to look at our included WC_Customer_Order_CSV_Export_Data_Store_Database class for further information.

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

Back to the top