WooCommerce and Xero are a very common combination for UK ecommerce businesses — WooCommerce handling the storefront and orders, Xero handling the accounting. The challenge is keeping them in sync. Every WooCommerce order needs to become a Xero invoice. Every payment needs to be reconciled. Every refund needs to appear as a credit note. Manually, this is a daily task that gets more burdensome as order volume grows. A custom Xero WooCommerce integration automates the entire flow.
What a Xero WooCommerce integration does
When an order is placed on WooCommerce and reaches a configured status (typically “Processing” for paid orders or “Completed” for digital products), the integration creates the corresponding Xero invoice. The invoice contains the customer’s contact details, the order line items with correct descriptions and amounts, the appropriate VAT treatment for each item, and the order reference number.
If the customer already exists in Xero, the invoice is created under their existing contact record. If not, a new contact is created automatically. The integration checks for an existing contact by email address before creating a new one, preventing duplicate contact records building up in Xero over time.
When payment is confirmed — through Stripe, PayPal, bank transfer or any other WooCommerce payment gateway — the payment is applied to the Xero invoice automatically. The invoice moves to Paid status in Xero. When a refund is processed in WooCommerce, a credit note is created in Xero against the original invoice.
Handling VAT correctly in WooCommerce to Xero sync
VAT handling is the area where WooCommerce to Xero sync most commonly goes wrong, and where the consequences are most significant. Getting VAT wrong on automated invoices at volume creates compliance problems that are painful to unwind.
WooCommerce stores products with tax classes — standard rate, zero rate, reduced rate or no tax. Xero has its own tax rates configured in the organisation’s chart of accounts. The integration maps WooCommerce tax classes to the correct Xero tax rate codes. Standard rate products in WooCommerce map to the 20% VAT rate in Xero. Zero-rated products map to Zero Rated Sales. Shipping, if taxable, maps to the correct Xero tax treatment for delivery charges.
For businesses selling internationally — EU customers post-Brexit, rest of world — tax treatment in WooCommerce and the corresponding Xero treatment needs careful mapping. Sales to EU B2C customers may need specific VAT handling depending on whether the business is OSS-registered. Sales to VAT-registered EU businesses need reverse charge treatment. The integration handles these cases based on the shipping destination and customer VAT number held on the WooCommerce order.
Xero plugins vs custom integration for WooCommerce
Several WooCommerce Xero plugins exist. The most common are Xero for WooCommerce by WooCommerce.com and third-party alternatives. They handle basic order-to-invoice sync for simple setups. The limitations become apparent quickly when your requirements go beyond that.
Tax handling. Plugins apply tax based on simple product-to-tax-rate mappings that work for single-rate businesses. Businesses with multiple VAT rates, OSS registrations, reverse charge B2B sales or mixed supply rules need logic that no plugin implements correctly.
Account code mapping. Plugins typically hardcode or minimally configure account code mapping. Businesses with multiple revenue streams that need to post to different Xero accounts — product sales vs digital downloads vs service fees vs shipping — need custom mapping that a plugin can’t provide.
Multi-currency. Plugins handle multi-currency inconsistently. The exchange rate applied to the Xero invoice may not match the exchange rate Stripe or PayPal applied to the actual payment, creating reconciliation discrepancies.
Subscription orders. WooCommerce Subscriptions creates recurring orders that have a different lifecycle to one-time orders. Plugins designed for standard orders often don’t handle subscription renewals, failed payments and cancellations correctly in Xero.
Custom order data. Businesses that pass additional data through WooCommerce orders — project codes, tracking category values, custom reference numbers — need that data mapped to the corresponding Xero fields. Plugins have no mechanism for this.
Subscription and recurring order handling
For WooCommerce stores using WooCommerce Subscriptions, the Xero integration needs to handle the subscription lifecycle. An initial order creates an invoice and applies the first payment. Renewal orders create new invoices for each billing period and apply the renewal payments. Failed renewal payments create invoices that stay in Awaiting Payment status until the payment is collected or the subscription is cancelled. Subscription cancellations don’t need a Xero action for already-invoiced periods but should prevent future invoice creation.
For platforms where subscription payments are taken via Stripe directly (rather than through WooCommerce Subscriptions), the Stripe-to-Xero reconciliation handles the payment side, and WooCommerce webhook events handle the subscription status changes.
What the build involves
A standard WooCommerce-Xero integration uses WooCommerce webhooks to trigger the sync. When an order status changes to the configured trigger status, WooCommerce fires a webhook to the integration endpoint. The integration reads the full order from the WooCommerce REST API (to ensure it gets the complete, current order data), creates or updates the Xero invoice, and stores the Xero invoice ID against the WooCommerce order.
The Xero invoice ID is stored in WooCommerce order meta, making it visible in the WooCommerce order detail page for reference. A sync status indicator shows whether each order has been synced to Xero, when the sync ran and whether it succeeded. Failed syncs are flagged for review.
For the full service and pricing, see the Xero API integration service. For how Stripe payments reconcile with Xero, see Xero and Stripe integration. For invoice automation specifically, see how to automate invoices with the Xero API. For what the integration costs, see the Xero API integration cost guide.
Related posts
- Xero API integration: a complete guide
- How to automate invoices with the Xero API
- Xero and Stripe integration: automating payment reconciliation
- Xero API integration cost
Bulk sync for existing orders
When a WooCommerce-Xero integration is first deployed on a live store, there are typically existing historical orders that need to be synced retrospectively. A one-time bulk sync job processes the backlog: fetching orders from the WooCommerce API in batches, creating Xero invoices for each one, applying payments for orders that are already paid, and storing the Xero invoice IDs back to WooCommerce.
The bulk sync needs to respect Xero’s rate limits — 60 API calls per minute — and handle the case where some historical orders may have already been manually entered in Xero. Deduplication logic checks whether a Xero invoice already exists with a matching reference number before creating a new one, avoiding duplicates in the retrospective sync.
For stores with years of order history, the bulk sync may cover thousands of orders. The approach is to process the most recent orders first — the ones most relevant to current accounting — and work backwards. A configurable date range allows the sync to be scoped to a specific period rather than attempting to sync every order from the beginning of time.
Reporting and visibility
The integration should give the business owner and accounts team clear visibility into the sync status without requiring them to check Xero manually. A simple admin page in WooCommerce showing the last sync run time, the number of orders synced, any errors, and a per-order sync status indicator is the minimum useful visibility.
For businesses where the accounts team needs to know about sync status without accessing WooCommerce, a daily summary email listing new orders synced, any errors and total synced revenue gives them the information they need. Errors should trigger immediate alerts rather than waiting for the daily summary, since an unsynced order means an invoice that doesn’t exist in Xero until the issue is resolved.
If you need help with a custom API integration for your website or business application, I can help. I build bespoke API integrations for UK businesses. See API integration pricing or get in touch to discuss your project.
Need help with your website?
I work directly with small businesses on web design, WordPress fixes, Shopify support and local SEO. No agency overhead.
Get in touch →
