Product Master Data
The product flow is the most complex as it involves most of the data and requires attention to data types, especially on metafields configured on the Shopify side.
The single product insertion call contains internally a simplification of Shopify APIs resulting from 6 years of experience on the application. This adapter especially integrates internally about 23 calls for each product, which increase depending on cases (new images, new files, market changes etc...).
Product master data JSON
Information on the structure related to product insertion
- Information will be in Shopify's primary language
- Essential data for creating a product (in draft as per Puro/SBS procedure) are title and sku
- For updating the product, SKU is required
- Attributes not present in the json will not be updated on Shopify (meaning with attributes the base fields, metafields and files)
- Attributes with NULL or empty value will be cleared on Shopify as well
- The variants attribute when present must include all variants (those not present are removed)
- Variant ordering can be implicit, through array order or explicit through the "sortingNumber" metadata
- The optionValues attribute of variants contains the attributes that define product configurability (color, size etc...). There can be a maximum of 3 levels of configuration
- Images can be associated with the main product or variants.
- In update the images list must be complete, missing images will be removed.
- If no image is sent, neither on the main product nor on variants, the image gallery is not updated. (This especially to avoid erroneous image removals)
- Metafields are typed already in the example structure, the type must be maintained to preserve integration success.
To identify a metafield, you can specify a simple key, which must match the key defined in the metafield,
or a compound key in the format
namespace.key, where namespace and key are separated by a dot. In the case of a simple key, if multiple definitions with the same key are present (but with different namespaces), the first definition found will always be considered. - The metaobjects section contains the association with entities created on Shopify. You can use the metaobject handle (e.g: "app-test-con-link" or "type.app-test-con-link" if you also want to specify the metaobject type) or via resourceId
- The markets section indicates the list of markets where a product is visible. If the field is absent or defined as an empty array, during creation the product will be visible on all markets. Instead, during update: if the field is empty no modification is made, if defined as an empty array the product will be visible on all markets.
- As for the inventory item part, we support the following properties: weight, weightUnit, harmonizedSystemCode, countryCodeOfOrigin, provinceCodeOfOrigin, costPerItem and isDigitalItem. They can be specified both at product level (for example if the weight is the same for all variants it is possible to specify it only there) and at variant level. In the case of harmonizedSystemCode, countryCodeOfOrigin, provinceCodeOfOrigin, costPerItem and isDigitalItem if variants exist in the request, it is necessary to specify such data at variant level. (Note the values that can be associated with weightUnit are: 'g' and 'kg'. If omitted, the default value is kg. Instead, the default value of isDigitalItem is 'false', i.e. the product is considered physical and not digital)
- Information regarding SEO can be inserted using the metaTitle and metaDescription fields.
- The barcode, if specified at product level, is inserted only in the absence of variants or in the case of a single variant. If the product has multiple variants, it is necessary to assign the barcode to each specific variant.
- It is possible to configure the redirect URL via the not-found-handle field to handle cases of archiving or excluding the product from a catalog (market), only in the case of an active product. In addition, it automatically updates the product redirect to the URL (handle) when it is modified. (Note When the product is archived and subsequently reactivated on Shopify, the redirect URL is deleted by Shopify)
- Tags can be managed in two ways:
- Complete Insert/Update: tags present on Shopify will be completely replaced by those specified in the tags field of the structure.
- Partial Insert/Update: tags indicated in the tagsDomain field are added or modified without altering existing ones, inserted manually or from other applications.
- The product price (price) can be specified in two ways: globally for the product or specifically for each variant. If the price is not defined for a variant, the one indicated globally for the product will be used, if present. However, if both pieces of information are available or if they are specified only in the variant, the latter will have priority. The same principle applies to the compareAtPrice field, following the same priority logic between variant and product. (Note The price is mandatory information when the product is synchronized as 'active')
- It is possible to add videos to the product media section. For more details on supported file formats, maximum sizes,
duration, recommended resolution and other technical criteria, refer to the official Shopify documentation.
Videos can be included in product media in the following ways:
- Via Youtube or Vimeo URL
- Via direct public URLs (e.g. link to MP4 file)
Structure
Structure for product insertion with example of typed metafields.
{
"sku": "BGSM001C210",
"title": "Product Test 1 Con Varianti",
"barcode": "14785985742",
"handle": "product-product-1",
"not-found-handle": "/collections/all",
"description": "Description of product",
"type": "product-type",
"price": 15.99,
"compareAtPrice": 19.99,
"vendor": "SBS",
"tags": [
"tagprimo",
"tag2"
],
"markets": [
"81543987507",
"81544020275",
"81544053043",
"81544085811",
"82294604083"
],
"media": [
{
"alternativeText": "image test",
"url": "https://demo.sintra-soh.com/csv-import-images/BGSM001C005/BGSM001C005.jpg"
},
{
"alternativeText": "image test 1",
"url": "https://demo.sintra-soh.com/csv-import-images/BGSM001C005/BGSM001C005_1.jpg"
}
],
"metaobjects": {
"namespace.app": [
"type.app-test-senza-link",
"type.app-test-con-link"
],
"tech": "test-da-cancellare"
},
"files": {
"namespace.certification_file": "http://demo.sintra-soh.com/LdV/samplepdf.pdf",
"documents_file": "http://demo.sintra-soh.com/LdV/samplepdf_1.pdf",
"gallery_images_file": "http://demo.sintra-soh.com/ShippingLabels/1002-816-0.pdf",
"manual": "http://demo.sintra-soh.com/ShippingLabels/1006-867-0.pdf"
},
"metafields": {
"namespace.accessories_included": "value",
"addition_features": "value",
"attachment": "value",
"attachment_system": "value",
"audio_output": "value",
"audio_power": "value",
"audio_power_unit": "value",
"logistic_depth": 1,
"type_product": "[\"tipo1\",\"tipo2\"]",
"video": "https://www.youtube.com/watch?v=WqDiH5bnZ4s",
"volume_control_position": "value",
"warrentyupgrade": false
},
"variants": [
{
"sortingNumber": 1,
"sku": "BGSM001C210-1",
"barcode": "1478598574258",
"price": 12.99,
"compareAtPrice": 15.99,
"optionValues": {
"color": "Blue"
},
"media": [
{
"alternativeText": "image test 1 facoltativo",
"url": "http://demo.sintra-soh.com/csv-import-images/BGSM003C014/BGSM003C014.jpg"
},
{
"alternativeText": "image test 2 facoltativo",
"url": "http://demo.sintra-soh.com/csv-import-images/BGSM003C014/BGSM003C014_1.jpg"
}
],
"metafields": {
"subtitle": "value"
},
"files": {
"gallery_images_file": "http://demo.sintra-soh.com/ShippingLabels/1006-867-0.pdf"
},
"harmonizedSystemCode": "147856923",
"countryCodeOfOrigin": "IT",
"provinceCodeOfOrigin": "IT-52",
"costPerItem": 14.95,
"isDigitalItem": true
},
{
"sortingNumber": 2,
"sku": "BGSM001C210-2",
"barcode": "1478598574259",
"optionValues": {
"color": "Lilac"
},
"media": [
{
"alternativeText": "lilla davanti",
"url": "http://demo.sintra-soh.com/csv-import-images/BGSM003C015/BGSM003C015.jpg"
},
{
"alternativeText": "lilla sopra",
"url": "http://demo.sintra-soh.com/csv-import-images/BGSM003C015/BGSM003C015_1.jpg"
}
],
"metafields": {
"subtitle": "value"
},
"files": {
"gallery_images_file": "http://demo.sintra-soh.com/ShippingLabels/1006-867-0.pdf"
},
"weight": "1.09",
"weightUnit": "kg",
"harmonizedSystemCode": "123456789",
"countryCodeOfOrigin": "IT",
"provinceCodeOfOrigin": "IT-52",
"costPerItem": 14.95,
"isDigitalItem": true
}
],
"weight": "1090",
"weightUnit": "g",
"metaTitle": "SEO Product metaTile",
"metaDescription": "SEO Product metaDescription",
"harmonizedSystemCode": "987456321",
"countryCodeOfOrigin": "IT",
"provinceCodeOfOrigin": "IT-52",
"costPerItem": 14.95,
"isDigitalItem": true
}
Product flow configurations
In addition to the base data flow configurations
add the following settings in Settings Override:
| Field | Value | Note |
|---|---|---|
Base Url | https://adapt.flowlyze.com | adapter URL |
Resource Path | /api/adp/shopify/egress/sync-product-to-shopify | adapter path for products |
Headers :: x-api-key | ********** | API key for endpoint interaction verification |
Headers :: x-shopify-graphql-url | https://SHOPIFYURL.myshopify.com/ | Shopify shop URL to connect to |
Headers :: x-shopify-access-token | shpat_CODICEALFANUMERICO | secret of the custom app created for integration |
Headers :: x-active-product | true/false | determines if products are created as active (true) or draft (false) |
Headers :: x-publish-product | true/false | determines if products are published on online store (true) or not (false) |
Headers :: x-avoid-title-update | true/false | determines if the product title must be updated (false) or not (true) |