Running an eCommerce business is exciting, but let’s be honest — it can also be a logistical nightmare if your systems don’t talk to each other. Imagine a scenario where a customer places an order in your Shopify store, but your ERP (Enterprise Resource Planning) system doesn’t get updated.
What happens next?
1. Your warehouse team has no clue about the new order.
2. Inventory records become outdated and risk overselling.
3. Customers get frustrated due to delays and cancellations.
Sounds like a disaster, right? But don’t worry, we have a solution! Custom API integration between Shopify and your ERP system can automate all of this. In this blog, I’ll walk you through every step — no fluff, just practical solutions. And don’t worry, even if you’re not a coding expert, I’ll break it down in a way that makes sense.
Why Integrate Shopify with Your ERP System?

If you’re handling high volumes of orders, manual data entry is NOT an option. Mistakes happen, time is wasted, and your team ends up frustrated. A proper integration can:
1. Sync orders from Shopify to your ERP in real time.
2. Update inventory instantly when stock changes.
3. Keep customer data consistent between both platforms.
By using Shopify’s GraphQL API and your ERP system’s API, we’ll build a real-time, automated data flow — so your business runs smoothly without you breaking a sweat.
How the Integration Works

To make this work, we need to:
1. Capture data from Shopify whenever an event happens (like an order being placed).
2. Process the data and format it properly.
3. Send the data to the ERP system via API.
This integration will be built using Node.js — a fast, scalable, and widely used backend language. If you’re comfortable with JavaScript, you’ll love it!
Step 1: Setting Up Shopify Webhooks
First, we need to tell Shopify, “Hey, let me know when something important happens!” Shopify provides Webhooks, which notify your server whenever an event (like a new order) occurs.
Here’s how you create a Webhook in Shopify:
- Go to your Shopify Admin Panel.
- Navigate to Settings > Notifications.
- Scroll down to Webhooks and click Create Webhook.
- Select Order Creation as the event and enter your server’s URL (where Shopify will send data).
- Set the format to JSON and save.
Once done, Shopify will send data to your URL whenever a new order is placed. Now, let’s write the Node.js code to receive and process this webhook.
Step 2: Setting Up a Node.js Server to Handle Webhooks
To handle Shopify’s webhook, we’ll create a simple Express.js server that listens for incoming data.
Install Dependencies First:
Run this in your terminal:
npm init -y
npm install express crypto node-fetch dotenv
- Express.js: To create a web server.
- Crypto: To verify webhook authenticity.
- Node-fetch: To send API requests to the ERP system.
- Dotenv: To store API keys securely.
Now, create a file named server.js and add the following code:
const express = require('express');
const crypto = require('crypto');
const fetch = require('node-fetch');
require('dotenv').config();
const app = express(); app.use(express.json());
const SHOPIFY_SECRET = process.env.SHOPIFY_SECRET; const ERP_API_URL = process.env.ERP_API_URL; const ERP_API_KEY = process.env.ERP_API_KEY;
// Verify Webhook Signature const verifyWebhook = (req) => { const hmac = req.headers['x-shopify-hmac-sha256']; const body = JSON.stringify(req.body); const calculatedHmac = crypto.createHmac('sha256', SHOPIFY_SECRET) .update(body) .digest('base64'); return hmac === calculatedHmac; };
// Webhook Endpoint for Order Creation app.post('/shopify-webhook', async (req, res) => { if (!verifyWebhook(req)) { return res.status(403).send('Invalid Signature'); }
const order = req.body; console.log('New Shopify Order Received:', order);
const response = await syncOrderToERP(order); if (response.success) { res.status(200).send('Order Synced to ERP'); } else { res.status(500).send('Failed to Sync Order'); } });
// Function to Sync Order Data to ERP const syncOrderToERP = async (order) => { const erpOrderData = { order_id: order.id, customer_name: `${order.customer.first_name} ${order.customer.last_name}`, total_amount: order.total_price, items: order.line_items.map(item => ({ product_id: item.product_id, quantity: item.quantity, price: item.price })), };
const response = await fetch(ERP_API_URL, { method: 'POST', headers: { 'Authorization': `Bearer ${ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(erpOrderData), });
return await response.json(); };
// Start the Server app.listen(3000, () => console.log('Server running on port 3000'));
Shopify Dropshipping: A Complete Step-by-Step Guide
Step 3: Handling Inventory Sync to ERP
When inventory changes in Shopify (e.g., after an order is placed), we need to update our ERP system to ensure stock levels match.
Here’s how we do it:
const syncInventoryToERP = async (productId, newInventory) => {
const inventoryData = {
product_id: productId,
inventory_level: newInventory,
};
const response = await fetch(`${ERP_API_URL}/inventory`, { method: 'PUT', headers: { 'Authorization': `Bearer ${ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(inventoryData), });
return await response.json(); };
Step 4: Sync Customer Data to ERP
Whenever a new customer is created or updated in Shopify, we should push that data to the ERP system for proper record-keeping.
const syncCustomerToERP = async (customer) => {
const customerData = {
customer_id: customer.id,
first_name: customer.first_name,
last_name: customer.last_name,
email: customer.email,
phone: customer.phone,
};
const response = await fetch(`${ERP_API_URL}/customers`, { method: 'POST', headers: { 'Authorization': `Bearer ${ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(customerData), });
return await response.json(); };
If you want to elevate your Shopify store’s appeal and drive more engagement, linking your Instagram posts directly to your homepage is a game-changer. In today’s digital world, showcasing your products and brand through social media is essential, and Instagram is one of the best platforms to create a strong visual connection with your audience. By linking Instagram posts to your homepage, you can enhance your store’s aesthetic, keep customers engaged, and encourage them to explore your products. Ready to take your store to the next level? Dive into this guide and learn how to seamlessly integrate Instagram into your Shopify homepage!
This Is File Structure Code For Shopify-ERP Integration to Better Understand
Remember: This is an example for explaining how we can do Shopify-ERP integration. You need to adjust it according to your requirements and API credentials.
/shopify-erp-integration
│── .env # Store API credentials securely
│── server.js # Main server file with webhook handling
│── config.js # Configuration settings
│── logger.js # Logger setup for error handling
│── services/
│ ├── shopifyService.js # Handles Shopify API interactions
│ ├── erpService.js # Handles ERP API interactions
│── package.json # Dependencies and scripts
│── README.md # Documentation
Main Code Files
1. Install Required Dependencies
Run the following command to install necessary packages:
npm init -y
npm install express dotenv winston node-fetch crypto
2. Environment Variables (.env)
SHOPIFY_SECRET=your_shopify_secret_key
ERP_API_URL=https://your-erp-api.com
ERP_API_KEY=your_erp_api_key
3. Main Server File (server.js
)
This file initializes the Express server and defines webhook endpoints.
const express = require('express');
const { verifyWebhook } = require('./shopifyService');
const { syncOrderToERP, syncPaymentToERP, syncInventoryToERP } = require('./erpService');
const logger = require('./logger');
require('dotenv').config();
const app = express(); app.use(express.json());
// Shopify Order Webhook app.post('/shopify-webhook', async (req, res) => { if (!verifyWebhook(req)) { logger.error('Invalid webhook signature'); return res.status(403).send('Invalid Signature'); }
try { const response = await syncOrderToERP(req.body); res.status(200).send(response.success ? 'Order Synced' : 'Failed to Sync Order'); } catch (error) { logger.error(error.message); res.status(500).send('Failed to Sync Order'); } });
// Shopify Payment Webhook app.post('/shopify-payment-webhook', async (req, res) => { if (!verifyWebhook(req)) { logger.error('Invalid webhook signature'); return res.status(403).send('Invalid Signature'); }
try { await syncPaymentToERP(req.body); res.status(200).send('Payment Synced'); } catch (error) { logger.error(error.message); res.status(500).send('Failed to Sync Payment'); } });
// Shopify Inventory Webhook app.post('/shopify-inventory-webhook', async (req, res) => { if (!verifyWebhook(req)) { logger.error('Invalid webhook signature'); return res.status(403).send('Invalid Signature'); }
try { await syncInventoryToERP(req.body); res.status(200).send('Inventory Synced'); } catch (error) { logger.error(error.message); res.status(500).send('Failed to Sync Inventory'); } });
// Start the server app.listen(3000, () => console.log('Server running on port 3000'));
4. Shopify Webhook Verification (shopifyService.js
)
const crypto = require('crypto');
require('dotenv').config();
const verifyWebhook = (req) => { const hmac = req.headers['x-shopify-hmac-sha256']; const body = JSON.stringify(req.body); const calculatedHmac = crypto.createHmac('sha256', process.env.SHOPIFY_SECRET) .update(body) .digest('base64'); return hmac === calculatedHmac; };
module.exports = { verifyWebhook };
5. ERP Sync Logic (erpService.js
)
const fetch = require('node-fetch');
require('dotenv').config();
// Sync Order Data to ERP const syncOrderToERP = async (order) => { const erpOrderData = { order_id: order.id, customer_name: `${order.customer.first_name} ${order.customer.last_name}`, total_amount: order.total_price, items: order.line_items.map(item => ({ product_id: item.product_id, quantity: item.quantity, price: item.price })), payment_status: order.financial_status };
const response = await fetch(`${process.env.ERP_API_URL}/orders`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(erpOrderData), }); return await response.json(); };
// Sync Payment Data to ERP const syncPaymentToERP = async (paymentData) => { const erpPaymentData = { order_id: paymentData.order_id, payment_status: paymentData.financial_status, transaction_id: paymentData.id };
const response = await fetch(`${process.env.ERP_API_URL}/payments`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(erpPaymentData), }); return await response.json(); };
// Sync Inventory to ERP const syncInventoryToERP = async (inventoryData) => { const erpInventoryData = { product_id: inventoryData.inventory_item_id, inventory_level: inventoryData.available };
const response = await fetch(`${process.env.ERP_API_URL}/inventory`, { method: 'PUT', headers: { 'Authorization': `Bearer ${process.env.ERP_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(erpInventoryData), }); return await response.json(); };
module.exports = { syncOrderToERP, syncPaymentToERP, syncInventoryToERP };
6. Logger for Error Handling (logger.js
)
const winston = require('winston');
const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: 'error.log', level: 'error' }) ] });
module.exports = logger;
Bottom Line
At this point, you’ve successfully built an integration that automates the Shopify-to-ERP workflow. No more manual data entry, no more errors — just smooth, real-time updates!
- New orders? Instantly sent to your ERP.
- Inventory updates? Synced in real time.
- Customer details? Always up to date.
With this setup, your eCommerce store runs like a well-oiled machine, letting you focus on growing your business instead of wrestling with spreadsheets.
If you found this guide helpful, share it with fellow eCommerce owners! Let’s automate the boring stuff and focus on what truly matters — building an amazing business.
If you enjoy this article or find it helpful. Please like, comment, and share this post.