Shopify Flow Inventory Fix: Solving Inventory Adjustments for POS Orders
Hey everyone! As a Shopify expert who spends a lot of time poking around the community forums, I often see recurring themes. One common headache that pops up, especially for stores blending online sales with physical retail or using external POS systems, is keeping inventory perfectly in sync. It’s a classic integration challenge, right?
Recently, a thread caught my eye that perfectly illustrates this. Our friend mstaplet87 was grappling with orders coming into Shopify from a third-party POS (Clover, in this case). The twist? These orders represented sales where the customer had already walked out of the store with their goods, meaning fulfillment wasn't strictly necessary in Shopify's eyes. They had a Shopify Flow set up to mark these orders as fulfilled, which is a great start, but here’s the kicker: simply marking an order as fulfilled via Flow doesn't always reduce your inventory levels, and that's a big problem for accurate stock counts!
The Inventory Sync Conundrum with Shopify Flow
So, mstaplet87 needed to go a step further. They wanted to ensure that when these POS orders hit Shopify and were marked fulfilled, the inventory for the purchased products was also accurately reduced. This is where the powerful but sometimes finicky Admin API Request action in Shopify Flow comes into play, specifically using the inventoryAdjustQuantities mutation. It’s the right tool for the job when you need granular control over inventory outside of standard fulfillment actions.
They put together a GraphQL Admin API call, but ran into a familiar foe: a JSON parsing error. The exact message was: "Exception: Mutation input evaluated to invalid JSON. Please ensure the input forms valid JSON after Liquid code is run." This kind of error can be super frustrating because sometimes the problem is just a tiny, invisible character or a misplaced comma.
Unpacking the "Invalid JSON" Error: What Went Wrong?
Let's look at the code mstaplet87 initially tried, which caused the error:
{
“input”: {
“reason”: “flow_correction”,
“name”: “available”,
“changes”: [
{
“delta”: “-{{lineItemsForeachitem.totalQuantity}}”,
“inventoryItemId”: “{{lineItemsForeachitem.inventoryItemId}}”,
“locationId”: “gid://shopify/Location/77014401211”,
}
]
}
}
If you've ever wrestled with JSON, you might spot the culprits! There were actually two subtle but critical issues here:
- The
deltaValue Type: Thedeltafield, which tells Shopify how much to adjust the quantity by, was wrapped in double-quotes:“delta”: “-{{lineItemsForeachitem.totalQuantity}}”. This makes it a string. However, for quantity adjustments, the API expects a number (an integer, to be precise). So, even though{{lineItemsForeachitem.totalQuantity}}would evaluate to a number, wrapping it in quotes tells JSON to treat it as text. - The Trailing Comma: Take a close look at the end of the
locationIdline:“locationId”: “gid://shopify/Location/77014401211”, }. That extra comma right before the closing curly brace of the object within thechangesarray is a classic JSON no-no. While some parsers are forgiving, the Shopify API is strict, and this will definitely throw an "invalid JSON" error.
The Fix: Precision in Your API Call
Thankfully, mstaplet87, with a little perseverance (and perhaps the nudge of finally posting the question!), figured it out and shared the corrected code. This is what makes the community so great – learning from each other's breakthroughs! The successful API call looks like this:
{
“input”: {
“reason”: “correction”,
“name”: “available”,
“changes”: [
{
“delta”: -{{lineItemsForeachitem.totalQuantity}},
“inventoryItemId”: “{{lineItemsForeachitem.inventoryItemId}}”,
“locationId”: “gid://shopify/Location/77014401211”
}
]
}
}
See the difference? The delta is now just -{{lineItemsForeachitem.totalQuantity}}, without the surrounding quotes, making it a proper number. And that pesky trailing comma after locationId? Gone! Simple changes, but absolutely crucial for the API to accept the request.
Implementing This in Your Shopify Flow: A Step-by-Step Guide
If you're facing a similar inventory sync challenge, here’s how you can set up this Admin API Request action in your Shopify Flow:
- Choose Your Trigger: Start with the appropriate trigger for your POS orders. This could be Order created, or perhaps Order risk analyzed if you have specific conditions for these types of orders. Add any necessary conditions to filter for only your POS orders.
- Mark as Fulfilled (Optional but Recommended): If your goal is also to mark these orders as fulfilled without needing actual fulfillment processing, add the action "Mark fulfillment order as fulfilled." Remember, this step alone won't adjust inventory.
- Iterate Through Line Items: Since an order can have multiple products, you’ll need to process each one. Add a For each action, selecting
Order > Line items. This will ensure your inventory adjustment runs for every product in the order. - Add the Admin API Request Action: Inside the "For each" loop, add an action called Admin API Request.
- Configure the GraphQL Mutation:
- API Action: Select
Run GraphQL mutation. - GraphQL Body: Paste the corrected JSON code into the body.
- API Action: Select
Here’s that corrected code again for easy copy-pasting, but remember to replace the locationId with your store's specific location ID:
{
"input": {
"reason": "correction",
"name": "available",
"changes": [
{
"delta": -{{lineItemsForeachitem.totalQuantity}},
"inventoryItemId": "{{lineItemsForeachitem.inventoryItemId}}",
"locationId": "gid://shopify/Location/YOUR_LOCATION_ID_HERE"
}
]
}
}
A Critical Note on locationId: The locationId (e.g., gid://shopify/Location/77014401211) is unique to your store and the specific location where the inventory is stored. You'll need to replace YOUR_LOCATION_ID_HERE with the correct ID for your primary retail location or whichever location corresponds to your POS sales. You can find your location IDs via the Shopify Admin API (e.g., using a tool like Postman or a simple API call to /admin/api/2023-10/locations.json) or sometimes within the URL when viewing a location in your Shopify admin.
Once you’ve got this Flow set up, don't forget to thoroughly test it with a few dummy orders to make sure your inventory levels are adjusting exactly as expected. This kind of automation is incredibly powerful for maintaining accurate stock, reducing manual work, and keeping your numbers reliable across all your sales channels. It just goes to show that sometimes, the smallest syntax detail can make all the difference in building a robust integration!