If you’ve tried to build Shopify integration with Salesforce, you know that products, prices, customers, and orders can flow between platforms effectively. For stores with a simple product lineup – basic SKUs and flat pricing – a standard Shopify to Salesforce integration might be sufficient.
But what if your store isn’t basic? What if you’re managing hundreds of SKUs, each with variants, custom fields, region-based pricing, and special inventory rules? In these cases, advanced data mapping is a must-have. This article explores how to handle complex Shopify catalogs in Salesforce and how to set up a mapping system that fits your business requirements.
Why Sometimes Basic Sync Isn’t Enough
Basic Salesforce Shopify integration covers the essentials: syncing products, customers, orders, and sometimes inventory. For many businesses, this basic data exchange is enough, especially if their product catalog is simple and consistent across regions.
However, things start to fall apart when your store becomes more complex or grows.
Just imagine that you sell t-shirts. One style might come in 5 sizes (XS to XL) and 6 colors. That’s 30 product variants, each with its own SKU, barcode, price, and inventory level. Now imagine offering different prices for EU and US customers, plus some variants that are only available in specific regions due to shipping rules or tax restrictions.
With a basic integration, here’s what might go wrong:
- Only the parent product syncs, not the individual variants.
- Region-specific pricing gets lost, leading to incorrect listings or invoicing issues.
- Custom fields like “Material Type” or “Care Instructions” don’t make it into Salesforce.
- Inventory may be treated globally, with no visibility into warehouse-specific stock levels.
And that’s just one t-shirt.
Get exclusive access to all things tech-savvy, and be the first to receive
the latest updates directly in your inbox.
Now imagine this happening with hundreds of products. Without advanced data mapping, keeping everything organized gets messy, leading to mistakes and making life harder for your operations and sales teams.
Understanding Shopify’s Product Data Model
Before we can map Salesforce and Shopify data, it’s important to understand how Shopify organizes product information. For businesses using multi-platform setups, comparing Shopify’s eCommerce structure with other CMS platforms can clarify integration needs.
More information about the product model can be found in documentation.
Shopify’s Core Product Structure
Product
This is the top-level item. Think of it as the concept of the item being sold like “Classic Cotton T-Shirt.”
Variants
Each product can have multiple variants. A variant is a specific combination of options like size and color. For example:
- Product: Classic Cotton T-Shirt
- Variant 1: Size: S, Color: Blue
- Variant 2: Size: M, Color: Blue
- Variant 3: Size: S, Color: Black
Each variant has its own:
- SKU
- Price
- Barcode
- Inventory quantity
Metafields
Shopify also supports Metafields – custom fields that store extra data not included by default. Find more info about Metafields in official documentation. This is where things like:
- Ingredient details
- Washing instructions
- Wholesale prices
- B2B labels
- Internal tags
are stored. These are critical for many Salesforce use cases but are often overlooked in basic integrations.

Markets / Region-Based Pricing
With Shopify Markets, you can set different pricing per region. For example:
- US: $25.00
- EU: €22.00
- UK: £19.00
This pricing is tied to the variant level and must be mapped carefully when connecting the Shopify Store with Salesforce.
Custom Integration: Shopify to Salesforce
A truly useful Shopify to Salesforce integration must handle product variants, include Shopify metafields for custom attributes, sync region-based pricing accurately, and respect stock locations and fulfillment logic to ensure reliable inventory management.
Let’s walk through a simplified example of pulling Shopify products (with variants and metafields) into Salesforce custom objects.
Step 1: Get Shopify API Access
To authenticate Salesforce and access your Shopify store data, you’ll need to create a private app in Shopify to obtain an access token.
Here’s how to set it up:
- Go to your Shopify Admin
Navigate to Settings – Apps and Sales Channels – Click “Develop apps”.
Source: Shopify: Apps and sales channels
- Create a New App
- Click “Create an app”
- Name it (e.g., Salesforce Integration)
- Assign an app developer (your email or team account)
Source: Shopify: Create an app
- Configure Admin API scopes
In the API access section, click Configure Admin API scopes, and grant access to:- read_products
- read_inventory
- read_customers
- read_orders
- read_prices (for regional pricing via Shopify Markets)
- read_metafields (for custom field mapping) (You can add more depending on your business case)
- Install the app in your store
Click Install app – Shopify will generate your Admin API access token (save it securely).
Note your API endpoint structure
Use the following pattern for your API endpoint:
https://your-store-name.myshopify.com/admin/api/2025-01/
- Use the Token in Salesforce Named Credential
In Salesforce, create a Named Credential to securely authenticate with Shopify:
Source: Salesforce Named Credential
Label: ShopifyAPI
URL: https://your-store.myshopify.com/admin/api/2025-01/
Identity Type: Named Principal
Authentication Protocol: Custom
Header: X-Shopify-Access-Token
Token Value: [Paste your Admin API Access Token from Shopify]
Step 2: Custom Objects in Salesforce
You’ll need custom objects like:
- Shopify_Product__c (fields: Name, Shopify_ID__c, Description__c)
- Shopify_Variant__c (fields: Title__c, SKU__c, Price__c, Barcode__c, Inventory__c, Shopify_Product__c lookup)
- Shopify_Metafield__c (fields: Namespace__c, Key__c, Value__c, Variant or Product lookup)
Step 3: Apex Class to Pull Products and Variants
Here’s an example of how to pull product data from Shopify into Salesforce. This code is designed to be customizable. You can modify it to fit your catalog’s specific needs, including metafields or region-based pricing.
public with sharing class ShopifyProductSyncService {
public static void syncProducts() {
HttpRequest req = new HttpRequest();
req.setEndpoint(‘callout:ShopifyAPI/products.json?limit=50’);
req.setMethod(‘GET’);
req.setHeader(‘Content-Type’, ‘application/json’);
Http http = new Http();
HttpResponse res = http.send(req);
if (res.getStatusCode() == 200) {
Map<String, Object> jsonResponse = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
List<Object> products = (List<Object>) jsonResponse.get(‘products’);
List<Shopify_Product__c> productList = new List<Shopify_Product__c>();
Map<String, List<Shopify_Variant__c>> variantsByProductId = new Map<String, List<Shopify_Variant__c>>();
for (Object pObj : products) {
Map<String, Object> product = (Map<String, Object>) pObj;
Shopify_Product__c prod = new Shopify_Product__c();
prod.Shopify_ID__c = String.valueOf(product.get(‘id’));
prod.Name = String.valueOf(product.get(‘title’));
prod.Description__c = String.valueOf(product.get(‘body_html’));
productList.add(prod);
List<Object> variants = (List<Object>) product.get(‘variants’);
List<Shopify_Variant__c> variantList = new List<Shopify_Variant__c>();
for (Object vObj : variants) {
Map<String, Object> variant = (Map<String, Object>) vObj;
Shopify_Variant__c var = new Shopify_Variant__c();
var.Title__c = String.valueOf(variant.get(‘title’));
var.SKU__c = String.valueOf(variant.get(‘sku’));
var.Price__c = Decimal.valueOf(variant.get(‘price’));
var.Barcode__c = String.valueOf(variant.get(‘barcode’));
var.Inventory__c = Integer.valueOf(variant.get(‘inventory_quantity’));
variantList.add(var);
}
variantsByProductId.put(prod.Shopify_ID__c, variantList);
}
insert productList;
// Now link and insert variants
List<Shopify_Variant__c> finalVariantList = new List<Shopify_Variant__c>();
for (Shopify_Product__c insertedProd : productList) {
List<Shopify_Variant__c> variants = variantsByProductId.get(insertedProd.Shopify_ID__c);
if (variants != null) {
for (Shopify_Variant__c var : variants) {
var.Shopify_Product__c = insertedProd.Id;
finalVariantList.add(var);
}
}
}
insert finalVariantList;
} else {
System.debug(‘Shopify API Error: ‘ + res.getStatusCode() + ‘ – ‘ + res.getBody());
}
}
}
Step 4: Extend with Region-Based Prices and Metafields
Once your core product and variant data are syncing, it’s time to level up. To pull metafields (e.g., ingredient lists, B2B tags, internal data), use this endpoint:
req.setEndpoint(‘callout:ShopifyAPI/products/’ + productId + ‘/metafields.json’);
For region-based pricing, Shopify’s Markets API allows you to retrieve prices set per country or region. Each market can have different pricing per variant, so be sure to structure your logic around variant-level pricing. This step ensures your Salesforce data isn’t just accurate — it’s global-ready.
Handling Complex Product Catalogs
When dealing with a large or complex product catalog in Shopify, several challenges can arise that require careful planning and execution in your integration.
1. API Pagination and Limits
Shopify’s API has a limit on the number of products returned in a single request, typically capped at 50. If your catalog has thousands of products, you’ll need to implement pagination to fetch all records. This means using the rel=next attribute in response headers to request subsequent pages of data.
2. Managing Updates vs. Inserts
As products are added, updated, or removed from Shopify, your integration should effectively distinguish between inserts and updates (upserts) in Salesforce. Implementing logic that checks for existing records (based on unique identifiers like SKU or Shopify ID) can help avoid duplicates and maintain accurate inventory records.
3. Sync Strategies for Large Data Sets
Consider whether to run scheduled syncs at night or real-time updates during business hours. Nightly batches are effective for large catalogs, while webhooks can trigger immediate updates for critical changes like stock levels or new product launches.
4. Handling Product Variants and Bundles
For products with multiple variants, each variant needs to be represented in Salesforce with its unique attributes. If you offer bundles or kits, you’ll need to decide how to structure these in Salesforce. One option is to create a separate object that associates bundles with their components.
5. Mapping Nested Collections
If your products fall into multiple collections or categories, ensure that your data model in Salesforce can accommodate this hierarchy. You may need additional custom objects or junction objects to represent these relationships accurately.
6. Indexing and Batching in Apex
If you’re dealing with significant data volumes, consider batching your Apex jobs to process records in chunks. This can prevent hitting governor limits in Salesforce and improve performance. Indexing key fields in custom objects can also enhance query performance.
Tips & Best Practices
When mapping Shopify data into Salesforce, certain tools and naming habits consistently help keep things organized, testable, and easier to maintain:
Tools like Postman are useful when testing Shopify endpoints before putting anything into Apex. It helps to see the raw responses first and figure out which fields matter. Once the structure is clear, it’s easier to set up the callout and handle the response in code.
Data Loader can be used to bulk check or update the synced product and variant records. For testing in Salesforce, using debug logs and System.debug() can help catch problems like null values, unexpected formats, or issues with list handling.
Naming fields and objects consistently is important. Prefixing custom fields with Shopify_ (like Shopify_ID__c or Shopify_Variant__c) makes them easier to find and group. Separating the main product from its variants also helps – it keeps the data more organized and allows for better reporting or referencing later.
If there are multiple regions or pricing strategies, it helps to build around that early rather than adding it as an afterthought.
Final Thoughts
Mapping product data correctly is not just a technical detail. For sales teams, it means being able to see the right product, variant, price, and stock, without jumping between systems or checking with someone else. That kind of access speeds things up and reduces mistakes during quoting or selling.
For operations teams, clear data structures make it easier to build reports, automate tasks, and connect with other systems in the future.
If you’re new to integrations, start by syncing the basic product data first. Once that’s working, add variants, metafields, or pricing per region step by step. Trying to cover everything at once can make troubleshooting harder.
Clean structure early on helps later, especially when new teams or systems need to work with the same data.