Use these examples to change how WooCommerce Xero builds invoices and handles refunds. Add custom PHP through a small site-specific plugin or a code-snippet manager, test it on a staging site with a separate Xero app, and keep a way to disable the code if an error prevents access to WordPress.
Note:
This is a Developer level doc. If you are unfamiliar working with code and resolving potential conflicts, we recommend you work with a Woo Agency Partner for larger projects, or find a WooCommerce developer on Codeable for smaller customizations. We are unable to provide support for customizations under our Support Policy.
Before using these examples
Customizations can change accounting records. Replace example values, test the complete invoice and payment flow, and have an accountant confirm that the result meets your reporting requirements.
Use the current date for invoices and due dates
↑ Back to topWooCommerce Xero normally uses the order date for the invoice date and uses the connected Xero organization’s payment terms to calculate the due date. This example replaces both values with the date on which the invoice is sent. Priority 20 ensures the due-date callback runs after the extension’s payment-terms callback.
/**
* Use today's date for Xero invoice and due dates.
*
* @return string
*/
function your_prefix_xero_use_current_date() {
return wp_date( 'Y-m-d' );
}
add_filter( 'woocommerce_xero_invoice_date', 'your_prefix_xero_use_current_date', 20, 0 );
add_filter( 'woocommerce_xero_invoice_due_date', 'your_prefix_xero_use_current_date', 20, 0 );
Disable automatic voiding after a full refund
↑ Back to topBy default, the extension attempts to void the associated Xero invoice when an order becomes fully refunded. Use this filter when another accounting workflow will handle the invoice. Paid invoices still need to be adjusted in Xero.
add_filter( 'woocommerce_xero_disable_auto_void_invoices', '__return_true' );
Send invoices to Xero as drafts
↑ Back to topThe extension sends invoices with an AUTHORISED status. This example changes only the invoice status element to DRAFT.
/**
* Send WooCommerce Xero invoices as drafts.
*
* @param string $xml Invoice XML.
* @return string
*/
function your_prefix_xero_use_draft_status( $xml ) {
return str_replace(
'<Status>AUTHORISED</Status>',
'<Status>DRAFT</Status>',
$xml
);
}
add_filter( 'woocommerce_xero_invoice_to_xml', 'your_prefix_xero_use_draft_status' );
Payment behavior
Xero accepts payments only for authorized invoices. Set Send Payments to Manual, review and authorize each draft in Xero, then record or send the payment through the accounting workflow you use.
Let Xero generate the invoice number
↑ Back to topReturning null from the invoice-number filter omits InvoiceNumber from the request, allowing Xero to assign the next number in its sequence. Test this with your invoice prefix and reconciliation process before using it on live orders.
add_filter( 'woocommerce_xero_invoice_invoice_number', '__return_null' );
Understand account-code customization limits
↑ Back to topThe woocommerce_xero_line_item_account_code filter can replace an account code, and its line-item object exposes the associated order. It does not expose the original WooCommerce order item or product. A reliable product- or category-based mapping therefore needs additional custom code that preserves that relationship earlier in the invoice-building process. Do not infer a product from the line description because names are not guaranteed to be unique.
Filter reference
↑ Back to topwoocommerce_xero_invoice_date— Filters the invoice date string. Also receives theWC_XR_Invoiceobject.woocommerce_xero_invoice_due_date— Filters the due date string. Also receives theWC_XR_Invoiceobject.woocommerce_xero_invoice_invoice_number— Filters the invoice number. Returnnullto omit it. Also receives theWC_XR_Invoiceobject.woocommerce_xero_invoice_to_xml— Filters the complete invoice XML string. Also receives theWC_XR_Invoiceobject.woocommerce_xero_invoice_request_settings— Filters theWC_XR_Settingsobject used for the request. Also receives theWC_XR_Invoiceobject.woocommerce_xero_disable_auto_void_invoices— Filters whether the extension attempts to void an invoice after a full refund.woocommerce_xero_line_item_account_code— Filters the account-code string. Also receives theWC_XR_Line_Itemobject.woocommerce_xero_line_item_description— Filters the description string. Also receives theWC_XR_Line_Itemobject.woocommerce_xero_create_unique_tax_label— Filters whether the tax percentage is appended to make a tax label unique.woocommerce_xero_payment_invoice_id— Filters the Xero invoice ID associated with a payment. Also receives theWC_XR_Paymentobject.woocommerce_xero_payment_date— Filters the payment date string. Also receives theWC_XR_Paymentobject.
Raw XML
The woocommerce_xero_invoice_to_xml filter receives the complete invoice payload. Return valid XML and change only the intended element; malformed XML prevents the invoice from being sent.