Hemi Connectors / Shopify Connector Technical Scope / Shopify as ERP Product Management Technical Scope

Shopify as ERP Product Management Technical Scope

In order to be able to get stock levels and create orders we will need to get all product IDs from Shopify and store them on Item level because they will be the same for all marketplaces.

Summary of Changes: (The purpose of this table is to keep traceability and Product team to highlight the things that were changed into the scope, based on comments or discussions)

Version Date Created / Updated Notes
1.0 23.03.2022 Bogomil Pavlov First publish
1.1 04.07.2022 Bogomil Pavlov Get Product Prices Taxable node
1.2 24.09.2024 Bogomil Pavov Get Product Details Validations

Get Products

API Call: GET /admin/api/2022-01/products.json

API Docs: https://shopify.dev/api/admin-rest/2022-01/resources/product#get-products

<v1.2>

When we are obtaining the Shopify ids we want to have couple of validations which should work with priority as follows:

1 We check if we have duplicate SKUs on Shopify because the SKU is not a unique identifier in Shopify and we want to set an error on the SKU in Hemi so if we have the same SKU assigned on different products in Shopify we want to set Item Shopify > Get Product Details Error - “The SKU is assigned on more than one product in shopify!” and Item Shopify >Product Details Received = No.

2 Second check is to see if the SKU in Hemi is actually existing on the client Shopify and if no we want to set Item Shopify > Get Product Details Error - “SKU does not exist in Shopify“ and Item Shopify >Product Details Received= No.

3 If we match the SKU we store all the details and set **Shopify > Get Product Details = Yes

4 **If we already have a match of the SKU with already stored Shopify IDs in Hemi we want to check if the ids are different and if yes to update them and set Shopify > Get Product Details = Yes

5 **If we dont have a match of the SKU with already stored Shopify IDs in Hemi we want to remove the ids and set Shopify > Get Product Details = Yes and Item Shopify > Get Product Details Error -** “SKU does not exist in Shopify“

</v1.2>

Example Call:

-X GET "https://your-development-store.myshopify.com/admin/api/2022-01/products.json"
-H "X-Shopify-Access-Token: {access_token}"
-P "limit:250"
-P "fields":"id,variants"

Example Response:

{
    "product": {
        "id": 7022212612273,
        "variants": [
            {
                "id": 41014312566961,
                "product_id": 7022212612273,
                "title": "50мл",
                "price": "121.00",
                "sku": "GP-12487",
                "position": 1,
                "inventory_policy": "deny",
                "compare_at_price": "125.00",
                "fulfillment_service": "manual",
                "inventory_management": "shopify",
                "option1": "50мл",
                "option2": null,
                "option3": null,
                "created_at": "2021-10-22T22:38:45+03:00",
                "updated_at": "2022-03-09T18:36:31+02:00",
                "taxable": true,
                "barcode": "GP-12487",
                "grams": 1000,
                "image_id": null,
                "weight": 1.0,
                "weight_unit": "kg",
                "inventory_item_id": 43105192149169,
                "inventory_quantity": 1000,
                "old_inventory_quantity": 1000,
                "requires_shipping": true,
                "admin_graphql_api_id": "gid://shopify/ProductVariant/41014312566961"
            },
            {
                "id": 41014312599729,
                "product_id": 7022212612273,
                "title": "100мл",
                "price": "165.00",
                "sku": "GP-53705",
                "position": 2,
                "inventory_policy": "deny",
                "compare_at_price": null,
                "fulfillment_service": "manual",
                "inventory_management": "shopify",
                "option1": "100мл",
                "option2": null,
                "option3": null,
                "created_at": "2021-10-22T22:38:45+03:00",
                "updated_at": "2022-03-12T16:00:26+02:00",
                "taxable": true,
                "barcode": "GP-53705",
                "grams": 1000,
                "image_id": null,
                "weight": 1.0,
                "weight_unit": "kg",
                "inventory_item_id": 43105192181937,
                "inventory_quantity": 999,
                "old_inventory_quantity": 999,
                "requires_shipping": true,
                "admin_graphql_api_id": "gid://shopify/ProductVariant/41014312599729"
            }
        ]
    }
}

Response Mapping:

Integration Field Integration Notes Integration required Hemi Mapping Hemi Notes
product
id Yes N/A
variants
id Yes Item Shopify > Variant ID
product_id Yes Item Shopify > Product ID
sku Yes Used for the mapping
inventory_item_id Yes Item Shopify > Inventory Item ID

Get Stock

API Call: GET /admin/api/2022-01/inventory_levels.json

API Docs: https://shopify.dev/api/admin-rest/2022-01/resources/inventorylevel#top

Basically depends how many location ids we have mapped in Shopify Connector Locations table we can either get for all of the location ids if we specify them in the location_ids parameter separated by comma or we can call each ID with a separate call. Please note if we have inventory item ID in Item Shopify which is missing from the payload which we receive from Shopify we will have to set the Item Location Quantity > Quantity = 0. Please have in mind the right location should be selected.

Example Call:

-X GET "https://your-development-store.myshopify.com/admin/api/2022-01/inventory_levels.json"
-H "X-Shopify-Access-Token: {access_token}"
-P "location_ids: {A comma-separated list of location IDs. To find the ID of a location, use the}"
-P "limit:250"

Example Response:

"inventory_levels":[
{
"inventory_item_id": 43105057669297,
"location_id": 64966426801,
"available": 1000,
"updated_at": "2021-11-11T10:20:35+02:00",
"admin_graphql_api_id": "gid://shopify/InventoryLevel/99293921457?inventory_item_id=43105057669297"
}

Response Mapping:

Integration Field Integration Notes Integration required Hemi Mapping Hemi Notes
inventory_levels
inventory_item_id Yes We use this ID in order to Map Item Shopify > Inventory Item ID and get the SKU on Item level
location_id Yes Based on the Mapping we have and the Locations added in the Account we will:
Map this location_id with Shopify Connector Locations > External ID and get the Location >Name which must be added in the Account as Account Location and them store the Quantity in the correct Item Location Quantity > Location
available Yes Location Quantity > Quantity
updated_at No N/A
admin_graphql_api_id No N/A

If the there are inventory_item_id which do not match any of our Item Shopify > Inventory Item ID we skip them.

History need to be incorporated and keep track of all stock changes in Item Location Quantity.

Get Prices

API Call: GET /admin/api/2022-01/products.json

API Docs: https://shopify.dev/api/admin-rest/2022-01/resources/product#get-products

Here we will have two options on how we will be getting the prices. Case1 we get the “price” and “compare at price” and store it as Item Account > Original Price and Item Account > Original RRP Case2 we get the “price” and “compare at price” and store them as Item Account > Price and Item Account > RRP These will be controlled by parameter added in the Account Shopify Connector > Get Prices Update Original Price.

Only in Case2 if there is price difference we will need to set the Item Account > Update Price = pending

The way we are getting prices is we call all products which have the Item Shopify > Product ID and depends on the parameter we update all Item Accounts for that Item.

Example Call:

 -X GET "https://your-development-store.myshopify.com/admin/api/2022-01/products.json"
-H "X-Shopify-Access-Token: {access_token}"
-P "fields:variants"
-P "ids: {add all Item Shopify > Product IDs separated by comma}"
-P "limit:250"

Example Response:

{
    "products": [
        {
            "variants": [
                {
                    "id": 42538050027735,
                    "product_id": 7586215395543,
                    "title": "Default Title",
                    "price": "125.00",
                    "sku": "TE-1205181201",
                    "position": 1,
                    "inventory_policy": "deny",
                    "compare_at_price": null,
                    "fulfillment_service": "manual",
                    "inventory_management": "shopify",
                    "option1": "Default Title",
                    "option2": null,
                    "option3": null,
                    "created_at": "2022-03-21T21:15:12+02:00",
                    "updated_at": "2022-03-21T21:15:12+02:00",
                    "taxable": true,
                    "barcode": "TT-1205181201",
                    "grams": 1000,
                    "image_id": null,
                    "weight": 1.0,
                    "weight_unit": "kg",
                    "inventory_item_id": 44629971763415,
                    "inventory_quantity": 10,
                    "old_inventory_quantity": 10,
                    "requires_shipping": true,
                    "admin_graphql_api_id": "gid://shopify/ProductVariant/42538050027735"
                }
            ]
        },
        {
            "variants": [
                {
                    "id": 42538050683095,
                    "product_id": 7586215755991,
                    "title": "Default Title",
                    "price": "107.60",
                    "sku": "TE-04788",
                    "position": 1,
                    "inventory_policy": "deny",
                    "compare_at_price": null,
                    "fulfillment_service": "manual",
                    "inventory_management": "shopify",
                    "option1": "Default Title",
                    "option2": null,
                    "option3": null,
                    "created_at": "2022-03-21T21:15:50+02:00",
                    "updated_at": "2022-03-21T21:15:50+02:00",
                    "taxable": true,
                    "barcode": "TT-04788",
                    "grams": 1000,
                    "image_id": null,
                    "weight": 1.0,
                    "weight_unit": "kg",
                    "inventory_item_id": 44629972418775,
                    "inventory_quantity": 10,
                    "old_inventory_quantity": 10,
                    "requires_shipping": true,
                    "admin_graphql_api_id": "gid://shopify/ProductVariant/42538050683095"
                }
            ]
        },
        {
            "variants": [
                {
                    "id": 42538050257111,
                    "product_id": 7586215559383,
                    "title": "Default Title",
                    "price": "24.20",
                    "sku": "TE-12051609",
                    "position": 1,
                    "inventory_policy": "deny",
                    "compare_at_price": null,
                    "fulfillment_service": "manual",
                    "inventory_management": "shopify",
                    "option1": "Default Title",
                    "option2": null,
                    "option3": null,
                    "created_at": "2022-03-21T21:15:23+02:00",
                    "updated_at": "2022-03-21T21:15:23+02:00",
                    "taxable": true,
                    "barcode": "TT-12051609",
                    "grams": 1000,
                    "image_id": null,
                    "weight": 1.0,
                    "weight_unit": "kg",
                    "inventory_item_id": 44629971992791,
                    "inventory_quantity": 10,
                    "old_inventory_quantity": 10,
                    "requires_shipping": true,
                    "admin_graphql_api_id": "gid://shopify/ProductVariant/42538050257111"
                }
            ]
        }
    ]
}

*Response Mapping:*Account Shopify Connector > Get Prices Update Original Price = NO

Integration Field Integration Notes Integration required Hemi Mapping Hemi Notes
variants
price Product Account > Price
compare_at_price Product Account > RRP
taxable Product Account > Prices Includes VAT If we receive:

"taxable": true – Item Account > Prices Includes VAT = 1 "taxable": false – Item Account > Prices Includes VAT = 0 |

If there are changes in the prices after successful update we will also have to set Item Account > Update Price = pending

Account Shopify Connector > Get Prices Update Original Price = YES

Integration Field Integration Notes Integration required Hemi Mapping Hemi Notes
variants
price Product Account > Original Price
compare_at_price Product Account > Original RRP
taxable Product Account > Prices Includes VAT If we receive:

"taxable": true – Item Account > Prices Includes VAT = 1 "taxable": false – Item Account > Prices Includes VAT = 0 |

If there are changes in the original price we just update it and do nothing.

History need to be incorporated and keep track of all price changes.

Get Full Product Details File

API Call: GET /admin/api/2022-01/products.json

API Docs: https://shopify.dev/api/admin-rest/2022-01/resources/product#get-products

The purpose of this call is to be able to get all the product details information from Shopify in a csv file from where we can pick the data optimize it and manually import it in Hemi. The CSV delimiter will be comma (,) and we need to place all the enclosing (“) and escaping end line characters (\r\n)

Get Products Response

{
   "product":{
      "id":5076458340485,
      "title":"Боди С Къс Ръкав Папагали Summer Nice Day",
      "body_html":"Боди с къс ръкав Папагали SUMMER NICE DAY",
      "vendor":"Pinokio",
      "product_type":"Боди Къс Ръкав",
      "created_at":"2020-05-27T23:00:07+03:00",
      "handle":"боди-с-къс-ръкав-папагали-summer-nice-day",
      "updated_at":"2022-05-03T02:45:07+03:00",
      "published_at":"2020-05-27T23:00:07+03:00",
      "template_suffix":null,
      "status":"active",
      "published_scope":"web",
      "tags":"color_colorful, katieghorii_bodi-ks-rkav, marka_pinokio, price_0-50lv, razmier_62sm-1-3m, Пол_Универсални",
      "admin_graphql_api_id":"gid:\/\/shopify\/Product\/5076458340485",
      "variants":[
         {
            "id":34279122075781,
            "product_id":5076458340485,
            "title":"62",
            "price":"15.90",
            "sku":"PNK00004",
            "position":1,
            "inventory_policy":"deny",
            "compare_at_price":"22.59",
            "fulfillment_service":"manual",
            "inventory_management":"shopify",
            "option1":"62",
            "option2":null,
            "option3":null,
            "created_at":"2020-05-27T23:00:07+03:00",
            "updated_at":"2022-04-03T17:52:19+03:00",
            "taxable":true,
            "barcode":"PNK00004",
            "grams":1000,
            "image_id":17459333890215,
            "weight":1.0,
            "weight_unit":"kg",
            "inventory_item_id":36161640038533,
            "inventory_quantity":1,
            "old_inventory_quantity":1,
            "requires_shipping":true,
            "admin_graphql_api_id":"gid:\/\/shopify\/ProductVariant\/34279122075781"
         },
         {
            "id":34279122108549,
            "product_id":5076458340485,
            "title":"68",
            "price":"15.90",
            "sku":"PNK00005",
            "position":2,
            "inventory_policy":"deny",
            "compare_at_price":"22.59",
            "fulfillment_service":"manual",
            "inventory_management":"shopify",
            "option1":"68",
            "option2":null,
            "option3":null,
            "created_at":"2020-05-27T23:00:07+03:00",
            "updated_at":"2022-04-03T17:52:19+03:00",
            "taxable":true,
            "barcode":"PNK00005",
            "grams":1000,
            "image_id":null,
            "weight":1.0,
            "weight_unit":"kg",
            "inventory_item_id":36161640104069,
            "inventory_quantity":1,
            "old_inventory_quantity":1,
            "requires_shipping":true,
            "admin_graphql_api_id":"gid:\/\/shopify\/ProductVariant\/34279122108549"
         },
         {
            "id":34279122141317,
            "product_id":5076458340485,
            "title":"74",
            "price":"15.90",
            "sku":"PNK00006",
            "position":3,
            "inventory_policy":"deny",
            "compare_at_price":"22.59",
            "fulfillment_service":"manual",
            "inventory_management":"shopify",
            "option1":"74",
            "option2":null,
            "option3":null,
            "created_at":"2020-05-27T23:00:07+03:00",
            "updated_at":"2022-04-03T17:52:19+03:00",
            "taxable":true,
            "barcode":"PNK00006",
            "grams":1000,
            "image_id":null,
            "weight":1.0,
            "weight_unit":"kg",
            "inventory_item_id":36161640169605,
            "inventory_quantity":1,
            "old_inventory_quantity":1,
            "requires_shipping":true,
            "admin_graphql_api_id":"gid:\/\/shopify\/ProductVariant\/34279122141317"
         },
         {
            "id":34279122174085,
            "product_id":5076458340485,
            "title":"80",
            "price":"15.90",
            "sku":"PNK00007",
            "position":4,
            "inventory_policy":"deny",
            "compare_at_price":"22.59",
            "fulfillment_service":"manual",
            "inventory_management":"shopify",
            "option1":"80",
            "option2":null,
            "option3":null,
            "created_at":"2020-05-27T23:00:07+03:00",
            "updated_at":"2022-04-03T17:52:20+03:00",
            "taxable":true,
            "barcode":"PNK00007",
            "grams":1000,
            "image_id":null,
            "weight":1.0,
            "weight_unit":"kg",
            "inventory_item_id":36161640202373,
            "inventory_quantity":0,
            "old_inventory_quantity":0,
            "requires_shipping":true,
            "admin_graphql_api_id":"gid:\/\/shopify\/ProductVariant\/34279122174085"
         }
      ],
      "options":[
         {
            "id":6609445912709,
            "product_id":5076458340485,
            "name":"variations",
            "position":1,
            "values":[
               "62",
               "68",
               "74",
               "80"
            ]
         }
      ],
      "images":[
         {
            "id":17459333890215,
            "product_id":5076458340485,
            "position":1,
            "created_at":"2020-06-17T20:35:22+03:00",
            "updated_at":"2022-05-03T02:45:07+03:00",
            "alt":"Боди С Къс Ръкав Папагали Summer Nice Day Боди Къс Ръкав BebeMama Pinokio",
            "width":1400,
            "height":1400,
            "src":"https:\/\/cdn.shopify.com\/s\/files\/1\/0257\/1868\/5778\/products\/pinokio--62-summer-nice-day-pnk00004-summer-nice-day-pnk00004-16554482008197.jpg?v=1651535107",
            "variant_ids":[
               34279122075781
            ],
            "admin_graphql_api_id":"gid:\/\/shopify\/ProductImage\/17459333890215"
         }
      ],
      "image":{
         "id":17459333890215,
         "product_id":5076458340485,
         "position":1,
         "created_at":"2020-06-17T20:35:22+03:00",
         "updated_at":"2022-05-03T02:45:07+03:00",
         "alt":"Боди С Къс Ръкав Папагали Summer Nice Day Боди Къс Ръкав BebeMama Pinokio",
         "width":1400,
         "height":1400,
         "src":"https:\/\/cdn.shopify.com\/s\/files\/1\/0257\/1868\/5778\/products\/pinokio--62-summer-nice-day-pnk00004-summer-nice-day-pnk00004-16554482008197.jpg?v=1651535107",
         "variant_ids":[
            34279122075781
         ],
         "admin_graphql_api_id":"gid:\/\/shopify\/ProductImage\/17459333890215"
      }
   }
}

Get Products Response Mapping

Field CSV Header Name CSV Position
product
id Shopify Product ID 14 Will be the same for all variants
title Title 2 Will be the same for all variants
body_html Description 4 Will be the same for all variants
vendor Brand 5 Will be the same for all variants
product_type Category 6 Will be the same for all variants
created_at
handle
updated_at Updated Date 18 Will be the same for all variants
published_at
template_suffix
status Shopify Status 19 Will be the same for all variants
published_scope
tags Tags 12 Will be the same for all variants
admin_graphql_api_id
variants
id Shopify Variant ID 15
product_id
title Variant 3
price Price 7
sku SKU 1
position
inventory_policy
compare_at_price RRP 8
fulfillment_service
inventory_management
option1
option2
option3
updated_at
created_at
taxable
barcode Barcode 10
grams Weight (g) 11
image_id
weight
weight_unit
inventory_item_id Inventory Item ID 13
inventory_quantity Quantity 9
old_inventory_quantity
requires_shipping
admin_graphql_api_id
options
id
product_id
name
position
values
images
id
product_id
position
created_at
updated_at
alt
width
height
src More Images 17 Need to combine all Image > src and concatenate them separated by ;
variant_ids
image
id
product_id
position
created_at
updated_at
alt
width
height
src Main Image 16
variant_ids
admin_graphql_api_id

We will need to be able to decide where to drop the file and on which FTP so we will need to use FTP Credentials (130) table and setup the FTP details there . File name - GetProducts{{YYYYMMDD_HHMMSS}}.csv

FTP Path Label: ExportProductDetails

Is this article helpful?
0 0 0