The situation
Orders were read off the Shopify admin and typed into Zoho Inventory by hand. That was slow, and it was fragile in a way that only showed up later: a mistyped SKU turned into a fulfilment problem days afterwards, once the wrong item had been picked or the stock count had drifted from what the store was selling.
The goal was easy to state. Every Shopify order should reach Zoho Inventory as a correct sales order without anyone touching it, and nobody should have to wonder whether an order made it across.
Why this is harder than it looks
Pointing a webhook at an API call takes an afternoon. Making it trustworthy is the real job, because of how these systems behave in production:
- Webhooks arrive more than once. Shopify retries a delivery when it doesn't get a quick success response, so the same order can show up twice. A naive flow creates two sales orders.
- APIs time out. When a Zoho call is slow or rejected, a flow that gives up on the first error silently loses the order.
- Data has to be mapped. Storefront line items need to match the right Zoho items before anything is written.
- Nobody watches a workflow. If something fails at night, the team should hear about it from the system, not from a customer.
How it works
- Shopify sends the order. n8n receives a webhook the moment a new order is created.
- Validate and map. The payload is checked and line items are mapped to Zoho Inventory items, so only clean data moves on.
- Check the idempotency key. Every write carries a key derived from the Shopify order. If the same order arrives again, the flow finds the existing record instead of creating a second one.
- Create the sales order. Zoho Inventory receives the sales order and stock levels move with it.
- Raise the invoice. Zoho Books gets the invoice from the same validated data.
- If Zoho doesn't answer, retry, then escalate. A timeout triggers up to three retries with backoff. If it still fails, the flow opens a Zoho Desk ticket with the order details, so a person picks it up instead of the order disappearing.
The result
- No orders are typed in by hand.
- A replayed webhook no longer creates a duplicate sales order.
- When the Zoho API fails, the order becomes a Desk ticket with an owner rather than a silent gap.
What carries over to other stores
Check for the record at the destination before writing, rather than trusting each webhook to be unique. Decide the failure path before the happy path: retry, then hand the problem to a person in a tool they already watch. Those two choices are most of the difference between a demo and something a business can rely on.