ml-connector
XeroWooCommerce

Xero and WooCommerce integration

Xero runs your accounting. WooCommerce runs your online store. Connecting the two keeps your financial records in sync with your sales. Each WooCommerce order becomes an invoice in Xero, customers sync as contacts, and payments recorded in WooCommerce can post back into Xero's cash accounts. ml-connector handles the authentication bridge, domain routing, and the round-trip mapping between e-commerce line items and Xero accounts.

How Xero works

Xero is a cloud-based accounting platform that exposes invoices, purchase orders, contacts, payments, accounts, and manual journals via a multi-tenant REST API at https://api.xero.com/api.xro/2.0/. Every request requires the Xero-tenant-id header to target a specific organization, and authentication uses OAuth2 with access tokens expiring every 30 minutes. Xero publishes webhooks for contacts, invoices, payments, and other key entities on CREATE and UPDATE events; the webhook payload contains only metadata, so ml-connector must follow up with a GET request to fetch the full record. Xero rate-limits at 5 concurrent calls and 60 per minute per tenant. For records not captured by webhooks, ml-connector can poll using If-Modified-Since to retrieve only changed records.

How WooCommerce works

WooCommerce is an open-source e-commerce plugin that runs on customer-hosted WordPress sites, each with its own unique domain (e.g. https://mystore.com/wp-json/wc/v3/). It exposes orders, refunds, customers, products, and coupons via REST API and supports webhooks for order, customer, and product events. Authentication uses API Key credentials (Consumer Key and Consumer Secret) delivered via HTTP Basic Auth. Every WooCommerce deployment is self-hosted, so ml-connector must accept the customer-specific domain as a configuration parameter. Webhooks are enabled per topic and must be manually re-enabled if they fail 5 consecutive times; webhook signatures use HMAC-SHA256 keyed with a secret derived from the creating user.

What moves between them

The primary flow runs from WooCommerce into Xero. Orders from WooCommerce sync into Xero as invoices, mapped to the customer contact and Xero accounts configured per product or order line. Customers from WooCommerce sync as Xero contacts, with billing and shipping addresses mapped to contact addresses. Payments recorded in WooCommerce can post back into Xero as bank transactions allocated to the corresponding invoice. Reference data such as tracking categories or account codes is configured once and then applied to incoming orders on every sync. The sync runs on a schedule you control and also responds to WooCommerce webhooks when available.

How ml-connector handles it

ml-connector stores WooCommerce API credentials (Consumer Key and Consumer Secret) encrypted and uses HTTP Basic Auth on every request. On the Xero side, it stores the OAuth2 client credentials and tenant ID, refreshes access tokens before they expire at 30 minutes, and includes the Xero-tenant-id header on every call. Because WooCommerce is self-hosted, ml-connector accepts the customer-specific store domain as a configuration parameter and constructs the full API URL per deployment. When an order arrives via WooCommerce webhook, ml-connector fetches the full order detail, maps each line item to a Xero account based on the product configuration, applies any tracking categories configured (up to 2 per organization), and posts the invoice to Xero. Customers are mapped by email address so repeat customers do not create duplicate contacts. WooCommerce webhook signatures are validated using HMAC-SHA256, and if validation fails ml-connector returns a 401 to signal the webhook provider to retry. For orders that arrive outside the webhook window, ml-connector polls WooCommerce on a configurable schedule and uses the If-Modified-Since header on Xero to avoid re-posting duplicate invoices. If a Xero call returns 429 (rate limit), ml-connector backs off and retries with jitter. Every order-to-invoice mapping carries an audit trail and can be replayed if a downstream call fails.

A real-world example

A small e-commerce business sells handmade crafts through a WooCommerce store on their own domain and uses Xero for accounting. Before integration, the store owner exported orders from WooCommerce each week, manually entered them into Xero as invoices, allocated line items to the correct income accounts and tax codes, and recorded payments by hand. With WooCommerce and Xero connected, each order posts as an invoice within minutes, customers auto-sync as contacts, and the reconciliation between store revenue and the Xero income account is automatic. The owner can now generate sales reports directly from Xero without manual export-and-re-entry.

What you can do

  • Sync WooCommerce orders into Xero as invoices, automatically mapped to customer contacts and revenue accounts.
  • Keep Xero contacts in sync with WooCommerce customers, matched by email address to prevent duplicates.
  • Apply Xero tracking categories and account codes to incoming orders based on product or order configuration.
  • Authenticate to WooCommerce via API Key and HTTP Basic Auth, and to Xero via OAuth2 with automatic token refresh.
  • Accept customer-specific WooCommerce store domains, poll on a schedule, validate webhook signatures, and replay failed orders on demand.

Questions

How does ml-connector handle the self-hosted nature of WooCommerce?
WooCommerce runs on each customer's own WordPress domain, not a shared Woo.com platform. ml-connector accepts the full store domain (e.g. https://mystore.com) as a configuration parameter, constructs the REST API URL per store, and routes all requests to the correct instance.
What happens if a WooCommerce order fails to post as an invoice in Xero?
ml-connector records the failure in its audit log with the WooCommerce order ID and Xero error response. The order can be replayed on demand without being re-posted twice; if Xero already has the invoice, ml-connector detects the duplicate by order ID and skips it.
Can ml-connector sync payments from WooCommerce back into Xero?
Yes. Payments recorded in WooCommerce can post into Xero as bank transactions, allocated to the matching invoice. The sync uses email matching to link WooCommerce customers to Xero contacts, so payments and invoices reconcile automatically.

Related integrations

Connect Xero and WooCommerce

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started