Xero and ShipStation integration
Xero runs your accounting. ShipStation runs your fulfillment. Connecting them keeps your revenue ledger synchronized with actual shipments. New orders from ShipStation automatically create contacts and invoices in Xero, so your accounts receivable stays current, and shipment updates trigger revenue recognition entries in your general ledger. ml-connector bridges the different authentication methods and moves data on a schedule you define.
What moves between them
Orders flow from ShipStation into Xero. As orders are placed in ShipStation, ml-connector reads each order and the customer email, creates or updates a contact record in Xero, and posts a draft invoice for that order. When a shipment is marked as shipped in ShipStation, ml-connector posts a manual journal into Xero to recognize revenue and cost of goods sold against the corresponding accounts. Shipment status updates continue to flow from ShipStation into Xero at the frequency you configure.
How ml-connector handles it
ml-connector stores ShipStation API keys and Xero OAuth2 credentials encrypted at rest and refreshes the Xero access token when a call returns 401. On the ShipStation side, it subscribes to order and shipment webhooks, but because ShipStation webhook payloads contain only resource pointers, ml-connector fetches the full order record by making an authenticated GET request to the resource URL. For orders created before the webhook is registered, ml-connector polls ShipStation at a configurable interval using the modifyDate filter to catch any orders missed. When creating contacts in Xero, it uses the ShipStation customer email as a unique key and deduplicates on update. Every invoice posted to Xero includes the ShipStation order number as a reference, and every shipment update is tracked in the audit log so a failed revenue journal can be replayed if needed. ShipStation enforces a 40-request-per-minute limit on V1 API calls, so ml-connector respects the rate limit headers and backs off when limit approaches. Because Xero rate-limits to 60 calls per minute per tenant, ml-connector batches customer and invoice creates into single transactions where possible.
A real-world example
A small e-commerce business selling crafts through multiple online marketplaces uses ShipStation to aggregate orders and print labels, and Xero for accounting. Before the integration, the owner manually exported orders from ShipStation each day and re-entered customer and invoice data into Xero by hand, then manually adjusted revenue entries when orders shipped. The process took 30 to 45 minutes daily and error-prone during peak seasons. With ShipStation and Xero connected, each new order automatically lands in Xero as a draft invoice, shipment status automatically triggers revenue recognition in the general ledger, and the owner only reviews and approves invoices before sending them to customers. The manual data entry step is eliminated and revenue stays in sync with fulfillment.
What you can do
- Create or update Xero contacts automatically from ShipStation customer data, deduplicating by email.
- Post draft invoices to Xero for each ShipStation order with line items, quantities, and pricing.
- Recognize revenue in Xero via manual journal entries when orders are marked shipped in ShipStation.
- Handle OAuth2 token refresh on Xero and API key authentication on ShipStation, with encrypted credential storage.
- Poll ShipStation for missed orders and subscribe to webhooks for real-time order and shipment notifications.
Questions
- Which direction does data move between Xero and ShipStation?
- Orders flow primarily from ShipStation into Xero. ml-connector reads new orders and shipment events from ShipStation and posts customer contacts and invoices into Xero. Shipment status updates are mirrored back into Xero as revenue recognition entries. Xero payments do not flow back to ShipStation.
- How does ml-connector handle ShipStation's webhook pointer pattern?
- ShipStation webhook payloads contain only the resource URL and type, not the full order or shipment data. When a webhook fires, ml-connector immediately makes an authenticated GET request to the resource URL to fetch the complete record. For orders created before the webhook listener was active, ml-connector polls ShipStation using the modifyDate filter to catch them.
- What happens if a revenue journal fails to post to Xero?
- Every order and shipment update is recorded in the audit log with its full payload and the result of each API call. If a revenue journal fails, the record is marked as failed and can be manually replayed from the audit log without re-reading or modifying the original order in ShipStation.
Related integrations
More Xero integrations
Other systems that connect to ShipStation
Connect Xero and ShipStation
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started