Summary
All Shopify integration customers must update their iPaaS.com integration to version 1.9 before February 2025 to continue integrating products and collections. iPaaS.com recommends testing this upgrade to the Shopify Integration V1.9 in your (or your MiSP’s) sandbox, if possible.
This will allow you to confirm all operations are successful before applying the same changes to production.
More information about the Shopify changes can be found here.
The sections below outline changes necessary to switch to the latest version, as well as describe optional new features. A summary checklist is also provided to assist with upgrades.
NOTE: All below settings apply to Product and Product Variant fields and mappings.
Subscription Settings
In your iPaaS.com subscription for Shopify, the Shopify API version must be set to 2024-10 (or higher) and the integration version must be 1.9 (or higher) to begin using the updated Shopify APIs.
Fully Deprecated Fields
Any mappings to the following product or variant fields must be removed as the latest Shopify APIs offer no replacement:
Grams
PublishedScope
Option 1
Option 2
Option 3
Modified Fields
Any mapping formulas that reference the following fields may need to be reviewed and adjusted for data type compatibility:
Product Id: long? -> string
Variant Id: long? -> string
Product Tags: string -> List<string>
Option Values: List<string> -> List<dynamic>
Option Value Value: string -> dynamic
Mapping Changes - Shopify Product Add From iPaaS
New Filter
An updated mapping collection filter now checks the first variant for a duplicate SKU; previously only simple product SKUs were checked for duplicates which omitted variant products. The new filter is below:
if (Sku == "SHOPIFY-GC") {return false;}
if (TrackingMethod == "Product") {
var value = await ValidateProductSkuCountAsync(Sku);
if (value == false )
{
//Sku was found on another Shopify product and will need to be manually repaired
return false;
}
else {
//Sku is unique and can be added to Shopify
return true;
}
} else if (TrackingMethod == "Variant") {
if (Variants != null && Variants.count > 0) {
var value = await ValidateProductSkuCountAsync(Variants[0].Sku);
if (value == false)
{
//"Sku was found on another Shopify product and will need to be manually repaired
return false
}
else
{
//Sku is unique and can be added to Shopify
return true;
}
}
}
The filter checks whether a product SKU already exists in Shopify before adding it by using the ValidateProductSkuCountAsync function. If this is a variant product, only the first variant SKU is checked for duplicates.
If the SKU exists already or matches a giftcard placeholder SKU "SHOPIFY-GC", this mapping collection filter does not allow the product to transfer.
Important: This filter should only be used in a product Add mapping collection. If used in a product update or add/update mapping collection, unique products will not update without modifying the filter.
Channel Assignments are now required
Previous Shopify APIs would automatically assign new products to all sales channels however channel assignments must now be specified. This will require two additional mappings in product mapping collections from iPaaS:
Channel Assignment Required API Permission Changes
If using a manually configured application access token to connect to Shopify, the application must be edited (in Shopify, Settings>Apps and sales channels>App>Configuration>Edit) to include read_publication and write_publication which are now required for channel assignments:
Channel Assignment Mapping: DisableChannelAssignment
A mapping to DisableChannelAssignment must be used to enable and disable this feature. Map a static value of “false” to allow iPaaS to assign products to channels. During each product update, the product will be removed from any channels and will be reassigned to the channels provided via separate mapping.
Map a static value of “true” to disable this channel assignment remove and create the feature of the product transfer. This field exists only for the Product collection type.
Channel Assignment Mapping: ChannelIds
When using the Channel Assignment feature, a mapping to ChannelIds must include a list of Shopify channel ids. A helper function has also been added that will accept the friendly names of the channels and will convert them to Shopify ids automatically. For example:
return await GetChannelIdsByNames("Point Of Sale,Online Store");
The new template mappings demonstrate checking an iPaaS custom field “Shopify Product Channels” for this list, and then passes the result into the helper function.
var customFieldvalue = GetCustomFieldValue(CustomFields, "Shopify Product Channels");
var channels = "";
if (!string.IsNullOrEmpty(customFieldvalue)){
channels = customFieldvalue;
}
if(!string.IsNullOrEmpty(channels)) {
return await GetChannelIdsByNames(channels);
}
return null;
This method retrieves a list of unique channel IDs for each channel name provided, based on matching channel names case-insensitively with a set of existing channels. Example:
var names => "Point Of Sale,Online Store" GetChannelIdsByNames(names)
This example takes a list of names (separated by commas if there is more than one) and returns a list of strings containing the corresponding channel IDs.
This field exists only for the Product collection type. A hardcoded example is below:
return await GetChannelIdsByNames("Point Of Sale,Online Store");
InventoryPolicy is now required
Previous versions of the integration allowed mappings to override a default value for InventoryPolicy in either the product or variant mapping collections already, however version 1.9 of the integration will no longer set a default value and will now require the field to be mapped.
Template mappings now include a mapping translation collection to provide this value for both products and variants with the following logic:
Check an iPaaS custom field “Inventory Policy” for a match of a source value listed below and return the appropriate destination value.
If no match is found a default value of “DENY” will be applied in Shopify.
The final translation is a formula with the result of true, and a sort order of 99. This is used to apply the default of DENY if none of the custom field values included match the current product. Adjust the defaults as needed for your installation.
A hardcoded mapping example can be seen below.
Important: Lowercase values provided for this mapping such as “continue” or “deny” must now be uppercase: “CONTINUE” or “DENY”
RequiresShipping is now InventoryLevel_RequiresShipping
Any previous mappings to the RequiresShipping field must be moved to the new InventoryLevel_RequiresShipping field and may use the same values.
Important: Any active mappings to RequiresShipping will need to be deactivated (or deleted) before product transfers can proceed.
Template mappings include an updated version of the mapping which now checks the value of a custom field first before applying the original mapping logic based on the iPaaS product type.
Mapping:
var value = GetCustomFieldValue(CustomFields, "Requires Shipping");
if (!string.IsNullOrEmpty(value)){
return value.ToLower() == "true";
}
return true;
This code checks the "Requires Shipping" custom field: If the field has a value, it returns true if that value is "true" (case-insensitive); otherwise, it returns false. If the field is empty or null, it defaults to true.
Please note that the requires_shipping field is now deprecated. The equivalent functionality is now achieved by mapping true or false to the InventoryLevel_RequiresShipping field.
InventoryManagement is now InventoryLevel_Tracked
Previous versions of the integration allowed mappings to override a default value for InventoryManagement in either the product or variant mapping collections, however version 1.9 of the integration will now require these mappings to use a new boolean field InventoryLevel_Tracked and any previous mappings to InventoryManagement must be removed.
In addition, the new field will now only accept true or false values as allowed.
The template mapping example provided will check an iPaaS custom field “Inventory Tracked” and will default to “true” if no value is found.
Mapping:
var value = GetCustomFieldValue(CustomFields, "Inventory Tracked");
if (!string.IsNullOrEmpty(value)){
return value.ToLower() == "true";
}
return true;
This code checks the "Inventory Tracked" custom field: If the field has a value, it returns true if that value is "true" (case-insensitive); otherwise, it returns false. If the field is empty or null, it defaults to true. Please note that the inventory_management field is now deprecated. The equivalent functionality is now achieved by mapping true or false to the InventoryLevel_Tracked field.
Important: Any active mappings to InventoryManagement will need to be deactivated before product transfers can proceed.
Mapping Changes - Shopify Product Variant From iPaaS
InventoryPolicy is now required
Previous versions of the integration allowed mappings to override a default value for InventoryPolicy in either the product or variant mapping collections already, however version 1.9 of the integration will no longer set a default value and will now require the field to be mapped.
Template mappings now include a mapping translation collection to provide this value for both products and variants with the following logic:
Check an iPaaS.com custom field “Inventory Policy” for a match of a source value listed below and return the appropriate destination value.
If no match is found a default value of “DENY” will be applied in Shopify.
RequiresShipping is now InventoryLevel_RequiresShipping
Any previous mappings to the RequiresShipping field must be moved to the new InventoryLevel_RequiresShipping field and may use the same values.
Any mappings to RequiresShipping will then need to be removed.
Template mappings include an updated version of the mapping which now checks the value of a custom field first before applying the original mapping logic based on the iPaaS product type.
Mapping:
var value = GetCustomFieldValue(CustomFields, "Requires Shipping");
if (!string.IsNullOrEmpty(value)){
return value.ToLower() == "true";
}
return true;
This code checks the "Requires Shipping" custom field: If the field has a value, it returns true if that value is "true" (case-insensitive); otherwise, it returns false. If the field is empty or null, it defaults to true for physical products and false for all others.
Please note that the requires_shipping field is now deprecated. The equivalent functionality is now achieved by mapping true or false to the InventoryLevel_RequiresShipping field.
InventoryManagement is now InventoryLevel_Tracked
Previous versions of the integration allowed mappings to override a default value for InventoryManagement in either the product or variant mapping collections, however version 1.9 of the integration will now require these mappings to use a new boolean field InventoryLevel_Tracked and any previous mappings to InventoryManagement must be removed.
In addition, the new field will now only accept true or false as allowed values.
The template mapping example provided will check an iPaaS custom field “Inventory Tracked” and will default to true if no value is found.
Mapping:
var value = GetCustomFieldValue(CustomFields, "Inventory Tracked");
if (!string.IsNullOrEmpty(value)){
return value.ToLower() == "true";
}
return true;
This code checks the "Inventory Tracked" custom field: If the field has a value, it returns true if that value is "true" (case-insensitive); otherwise, it returns false. If the field is empty or null, it defaults to true. Please note that the inventory_management field is now deprecated. The equivalent functionality is now achieved by mapping true or false to the InventoryLevel_Tracked field.
VariantOptions is now VariantOption
The previous versions of the integration required a mapping from Options to VariantOptions however this mapping is now deprecated and must be removed.
The new mapping to the new VariantOption field uses a new function:
return SetVariantOptionAndValues(Options);
This field exists only for the Product Variant collection type.
Note: If mappings are detected to deprecated fields, iPaaS will return an error describing the field cannot be found in the data model:
Variant Id is now required for update
In variant mapping collections from iPaaS that will perform updates, a mapping to the “Id” field is now required:
return await GetExternalIdAsync(Id, "Product Variant", SpaceportSystemId);
Important: Variant updates missing the Id mapping will return errors such as:
Field 'variants -> 0': The variant 'SANDSTONE / SMALL' already exists
Sample Upgrade Checklist
Task | Location | Notes |
Add permissions to API token in Shopify | Settings / Apps / Develop / Configuration | read_publication and write_publication |
Change integration version to 1.9 | Subscription Settings |
|
Apply new filter | Product Add Mapping Collection |
|
Add mapping: DisableChannelAssignment | Product Add Mapping Collection |
|
Add mapping: ChannelIds | Product Add Mapping Collection |
|
Add mapping: InventoryPolicy | Product Add Mapping Collection | Uppercase DENY or CONTINUE |
Delete mapping: RequiresShipping | Product Add Mapping Collection |
|
Add mapping: InventoryLevel_RequiresShipping | Product Add Mapping Collection | true or false |
Add mapping: InventoryLevel_Tracked | Product Add Mapping Collection | true or false |
Add mapping: InventoryPolicy | Variant Add Mapping Collection | Uppercase DENY or CONTINUE |
Delete mapping: RequiresShipping | Variant Add Mapping Collection |
|
Add mapping: InventoryLevel_RequiresShipping | Variant Add Mapping Collection | true or false |
Delete mapping: InventoryManagement | Variant Add Mapping Collection |
|
Add mapping: InventoryLevel_Tracked | Variant Add Mapping Collection | true or false |
Delete mapping: VariantOptions | Variant Add Mapping Collection |
|
Add mapping: VariantOption | Variant Add Mapping Collection |
|
Add mapping: DisableChannelAssignment | Product Update Mapping Collection | Map a static value of “true” to disable this channel assignment remove and create |
Add mapping: ChannelIds | Product Update Mapping Collection | Optional - can be omitted if channels won't be updated |
Add mapping: InventoryPolicy | Product Update Mapping Collection | Uppercase DENY or CONTINUE |
Delete mapping: RequiresShipping | Product Update Mapping Collection |
|
Add mapping: InventoryLevel_RequiresShipping | Product Update Mapping Collection |
|
Add mapping: InventoryLevel_Tracked | Product Update Mapping Collection |
|
Add mapping: Id | Variant Update Mapping Collection |
|
Add mapping: InventoryPolicy | Variant Update Mapping Collection | Uppercase DENY or CONTINUE |
Delete mapping: RequiresShipping | Variant Update Mapping Collection |
|
Add mapping: InventoryLevel_RequiresShipping | Variant Update Mapping Collection | true or false |
Delete mapping: InventoryManagement | Variant Update Mapping Collection |
|
Add mapping: InventoryLevel_Tracked | Variant Update Mapping Collection | true or false |
Delete mapping: VariantOptions | Variant Update Mapping Collection |
|
Add mapping: VariantOption | Variant Update Mapping Collection |
|
New Features
Increased variant limits
When using the latest version of the integration, during product transfer your Shopify account will be checked for the current variant limit. This value will be saved to the Shopify subscription in iPaaS.com and can be found in the persistent data section under the “Store Maximum Variants”:
This is only checked once; however the value may be deleted so that it will be reset during the next product transfer.
If a variant product is transferred which exceeds this value, the Shopify integration will return an error that the limit has been exceeded.
Future versions of the Shopify API expected in 2025 are anticipated to unlock the new
limits. Consult with your MiSP or Shopify partner for more information about increasing your store limits.
Batch variant creation
When using the latest version of the integration, during product transfer it is possible to create variants in large batches to reduce transfer times. In the Shopify subscription in iPaaS.com modify the value for “Concurrent Batch Executions” to increase or decrease this batch size limit. For basic Shopify stores, low limits are suggested to prevent exceeding API throttle limits for the Shopify plan.
Media URLs
Image URLs may now be provided in a mapping to MediaUrls for both products and variants, however the mapping must provide these values in the following format:
"{alt}|{Media Type}|{Public URL}"
Multiple images may be provided in the following example format, with each image entry separated by a comma:
"{alt1}|{Media Type1}|{Public URL1},{alt2}|{Media Type2}|{Public URL2}"
Example:
"Comparison video, showing the different models of watches|IMAGE|https://i.ibb.co/fYZpW80/1080-1721284657-1111-1721278087-brochure-1456.png,Another comparison video showing the different models of watches|IMAGE|https://i.ibb.co/fYZpW80/1080-1721284657-1111-1721278087-brochure-1456.png"
Shopify will download valid images from the URLs provided in this mapping where they may be found in Content / Files and attached to the products and variants.
During an update from iPaaS, any existing images will be deleted and re-uploaded. For products with many variant images, it is recommended to consult with your MISP to adjust your iPaaS.com mapping collections to only update images when necessary, to preserve Shopify API resources.
Returning a null value to this field mapping will preserve existing images in Shopify.
The iPaaS.com integration supports the following Shopify media types:
EXTERNAL_VIDEO
IMAGE
MODEL_3D
VIDEO
IMPORTANT: Deleting and re-uploading all media during each product update will have a performance impact that will require additional considerations for larger products. Consult with your MISP for planning an appropriate method to initiate bulk updates.
IMPORTANT: Template mappings include examples of sample image URLs for both products and variants – change or remove these mappings before attempting bulk transfers!
Collections To iPaaS.com Product Categories
Shopify Collections may now be initialized from the Shopify subscription page in iPaaS.com. Initialization will attempt to transfer all Shopify collections to iPaaS.com.
Products To iPaaS.com
Many enhancements have been added for Shop ify Products To iPaaS.com workflows including brand new template mappings! In-depth mappings are provided in separate documents.
Accessing metafield values
The GetValueFromMetaFields mapping function retrieves the value of a metadata field from a list based on a matching Key and Namespace or Just Key, returning null if not found or invalid. It is important that the “Name” of the metafield is not provided to the function and Key and Namespace or only Key is provided such as in the examples below:
GetValueFromMetaFields(MetaFields, "meta_color"); GetValueFromMetaFields(MetaFields, "custom.meta_color"); GetValueFromMetaFields(MetaFields, "global.meta_color");
If no namespace is provided, the first matching key will be returned.
Category Assignments
Shopify Collection assignments may now be included in transfers of Shopify products to iPaaS using a new mapping formula:
return await ConvertShopifyProductCategoriesToiPaaS(Categories);
Channel Assignments
Shopify Channel assignments may now be included in transfers of Shopify products to iPaaS using a new mapping formula:
return await GetChannelNamesByIds(ChannelIds);
Template mappings will save this value to an iPaaS custom field, in a format necessary to support any transfers of the same product from iPaaS back to Shopify.
Accessing media information
Shopify media urls may now be included in transfers of Shopify products to iPaaS using a new mapping formula:
return GetImageDataFromMedia(Media);
Template mappings will save this value to an iPaaS custom field, in a format necessary to support any transfers of the same images from iPaaS back to Shopify.
Control Settings
Additional information is saved to iPaaS.com custom fields to support the same product configuration in transfers of the same product back to Shopify.
Inventory Policy
Inventory Tracked
Requires Shopping
Updated template mappings for transfer of products from iPaaS.com to Shopify include considerations to check the same custom fields for existing values before applying any additional defaults or mapping logic.