Connect Shopify to a CRM via API (Orders and Customers Sync)
To synchronize Shopify customer and order data with a CRM (such as HubSpot, Salesforce, or Zoho) in real-time, the standard architecture uses Shopify Webhooks for event-driven updates, combined with the Shopify Admin API for historical data backfills.
Step 1: Generate Shopify API Credentials
You must create a Custom App in your Shopify Admin to authorize API requests and secure webhook signatures:
- Navigate to Settings > Apps and sales channels > Develop apps.
- Click Create an app and assign a name.
- Under Configuration, select Admin API integration.
- Enable the following OAuth scopes:
read_customers(for customer sync)read_orders(for order sync)
- Install the app and save the Admin API access token and the API client secret (used for webhook verification).
Step 2: Configure Webhooks for Real-Time Sync
Webhooks push JSON payloads to your server immediately when events occur. Register for these specific topics via the Shopify Admin (Settings > Notifications) or programmatically via the API:
customers/createandcustomers/update: Syncs profile details, contact info, and marketing preferences.orders/create: Triggers when a new order is placed.orders/updated: Triggers on fulfillment status updates, refunds, or cancellations.
Step 3: Build the Webhook Receiver and CRM Mapper
Your middleware server must listen for Shopify POST requests, verify they originate from Shopify using HMAC validation, map the Shopify payload to your CRM's schema, and send it to the CRM's API.
const express = require('express');
const crypto = require('crypto');
const axios = require('axios');
const app = express();
app.use(express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}));
const SHOPIFY_SHARED_SECRET = process.env.SHOPIFY_SHARED_SECRET;
const CRM_API_KEY = process.env.CRM_API_KEY;
// Middleware to verify Shopify Webhook Authenticity
function verifyShopifyWebhook(req, res, next) {
const hmac = req.headers['x-shopify-hmac-sha256'];
const hash = crypto
.createHmac('sha256', SHOPIFY_SHARED_SECRET)
.update(req.rawBody, 'utf8')
.digest('base64');
if (hash === hmac) {
return next();
}
return res.status(401).send('Unauthorized webhook signature');
}
// Endpoint for Order Creation Sync
app.post('/webhooks/orders/create', verifyShopifyWebhook, async (req, res) => {
const shopifyOrder = req.body;
// Map Shopify Order to CRM Deal/Sales Pipeline Schema
const crmPayload = {
deal_name: `Shopify Order #${shopifyOrder.order_number}`,
amount: parseFloat(shopifyOrder.total_price),
customer_email: shopifyOrder.customer?.email,
shopify_order_id: shopifyOrder.id.toString(),
pipeline_stage: "Closed Won"
};
try {
// Post to CRM API (Example endpoint)
await axios.post('https://api.yourcrm.com/v1/deals', crmPayload, {
headers: { 'Authorization': `Bearer ${CRM_API_KEY}` }
});
res.status(200).send('Webhook Processed');
} catch (error) {
console.error('CRM Sync Error:', error.response?.data || error.message);
res.status(500).send('Failed to sync to CRM');
}
});
app.listen(3000, () => console.log('Webhook receiver listening on port 3000'));
Step 4: Handle Edge Cases and Rate Limits
Production integrations must account for API limitations to prevent data loss:
- HMAC Validation: Always validate the
X-Shopify-Hmac-Sha256header to prevent spoofing. - Shopify API Rate Limits: The REST Admin API is limited to 40 requests per second per app (leaky bucket algorithm). If you hit a
429 Too Many Requestserror, parse theRetry-Afterheader. - CRM Rate Limits: CRMs enforce strict daily or per-second API call limits. Implement a message queue (such as Redis/BullMQ or AWS SQS) to ingest webhooks immediately, return a
200 OKto Shopify within 5 seconds, and process the CRM API calls asynchronously.
Need this done fast? order an integration on Kwork.
I take on freelance fixes and builds in this area.