Marketplaces / VeePee Technical Scope / VeePee Product Management / VeePee Create Product

VeePee Create Product

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)

Date Version Name Applied changes
13.02.23 v1.0 Bogomil Pavlov First Publish
27.02.2023 v1.1 Danail Deltchev Update Images to reflect terminology as per abstraction
04.04.2023 v1.2 Bogomil Pavlov Add more details about dimensions handle
06.04.2023 v1.3 Bogomil Pavlov VeePee Status details added
12.04.2023 v1.4 Bogomil Pavlov RRP logic updated with tag v1.4

The purpose of this document is to describe in detail the flow of creating product. Please note all fields in the payload are included in the taxonomy even the SKU. Thus we need to make sure the Hemi required fields are validated against our standards.How to handle variations The way we treat a product as a Variation is when we have Product Account > Variation Group populated. Each Product Account in Hemi can have Item Specifics and Variation Specifics which we validate the same way against the VeePee taxonomy but we use them only in certain cases.

If we DO NOT HAVE Product Account > Variation Group:

We use only the Item Specifics from the product. If any Variation Specifics are also populated we ignore them

If we HAVE Product Account > Variation Group:

We use all of the Variation Specifics and all of the Item Specifics. If there are no Variation Specifics we should return an error. If we have the same attribute added as a Variation Specific and as a Item Specific we pick it only from the Variation Specifics.

For VeePee we want to group all variants when we are creating products and if we have one product set on pending to include all other products with the same variation group (please note if some of the products is closed we do not include them in the payload), because we are not able to add or amend variations on the marketplace!If at some point someone add additional variants to the variation group and try to list them we should return an error because the variation group is already created and we are not able to add more variants.

Complete product flow:

In order to push products for creation we should have:

Product status = Awaiting Creation ; Listing Status **= Inactive; List/Update the whole item= Pending**

If we successfully pick a product for creation, we will have following statuses:

Product status -Awaiting Creation ; Listing Status - Inactive; List/Update the whole Item = Sent

If the internal product validation is not successful or we receive an error from VeePee, we will set following statuses and store the relevant error message in Item Account > Update Item Error:

Product status = Awaiting Creation ; Listing Status=Inactive; List/Update the whole item= Error

API Call: {{BaseURL}}/catalog/{shopChannelId}

API Docs: https://veepeebrandsplace.gitbook.io/brandsplace/pc-integration-methods/templatesWe use the Shop Channel Id from the Account > VeePee as header parameter (shopChannelId).We use the Incremental Quantity set always as true as query parameter (incrementalCatalog). (Default: true. When set to false, after processing the uploaded file, if 5 or more products have been updated, remaining products (not updated) will be disabled, that means Pink Connect will send stock 0 to the marketplace for them.)

Example File:

SHOP_CATALOG_EXAMPLE.json

[
 {
   "category": "COMPLEMENTOS > CALZADO > ZAPATOS > ZAPATOS NÁUTICOS [11529]",
   "gtin": 111111,
   "model": "11111-001",
   "name": "Náuticas Hombre Nautico Marrón ",
   "sku": "11111-001-39",
   "size": 39,
   "color": "Marrón",
   "brand": "Brand",
   "manufacturer_recommended_price": 170,
   "tax_rate_percentage": 21,
   "variation_type": "",
   "description": "Náutico marrón para hombre. Piel flor. \n\nUn estilo clásico que se ha actualizado con la máxima atención a los detalles más esenciales, estos zapatos son esencialmente atemporales.",
   "is_variation": "",
   "image_url_1": "https://www.brand.com/is/image/ZXNob3AwMQ==/15233-001_L.jpg",
   "image_url_2": "https://www.brand.com/is/image/ZXNob3AwMQ==/15233-001_F.jpg",
   "image_url_3": "https://www.brand.com/is/image/ZXNob3AwMQ==/15233-001_C.jpg",
   "image_url_4": "https://www.brand.com/is/image/ZXNob3AwMQ==/15233-001_T.jpg",
   "image_url_5": "https://www.brand.com/is/image/ZXNob3AwMQ==/15233-001_P.jpg",
   "image_url_6": "",
   "image_url_7": "",
   "image_url_8": "",
   "boot_type": "",
   "derby_oxford_type": "",
   "calf_size": "",
   "ankle_boot_type": "",
   "shoe_size_es": 39,
   "closure_type": "",
   "composition": "Empeine:\nPiel (Piel vacuna)\nColor: Marrón\nSuela/Características:\nGoma con un agarre extraordinario\nCostura a lo largo de todo el borde para mayor durabilidad\nForro: \n100% Piel vacuna\n",
   "size_country_origin": "España",
   "dimension": "",
   "washing_properties": "",
   "color_normalized": "Marron",
   "size_guide": "",
   "morphogender": "Hombre",
   "manufacturer_reference": "",
   "product_warranty_information": "",
   "heel_height": "",
   "collection": "",
   "sales_justification": "",
   "shoe_tip_type": "",
   "rod_height": "",
   "manufacturing_country": "",
   "capacity": "",
   "sandal_type": "",
   "selling_price": "",
   "stock": ""
 }
]

Please note the marked in red rows are for the skipped attributes which we map based on our internal fields or are always hardcoded.

VeePee Field VeePee Notes Integration Required Hemi Field Comment
category Product Category Code Yes Product Account > Primary Category ID The category path is expected for mapping
gtin Yes Product Account > Marketplace EAN

OR Product > EAN | Product Account > Marketplace EAN is with priority | | model | Variation reference or model. Please fill this value for every product that you want to group per size (in this case, also the attribute \"Size\" has to be filled) or Color (in this case, also the attribute \"Color\" has to be filled). The attribute is mandatory for some products, if you don't have the Model and you don't want to group these products, please use the SKU. | Depends on Taxonomy | Product Account > Variation GroupORProduct > SKU | If we have Product Account > Variation Group we use it as model otherwise we use the Product > SKU | | name | | Yes | Product Account > Title | | | sku | | Yes | Product > SKU | | | size | Free text to specify the size of the product (MAXIMUM: 255 characters). It won't be used for filtering. This information usually appears on the label of your product. This is a variation attribute; as it is mandatory for some products, do not forget to set the attribute is_variation to false if you don't want to group your products. | Depends on Taxonomy | Product Account >Item Specific OR Product Account >Variation Specific | If we have Product Account > Variation Group we use Product Account >Variation Specific else Product Account >Item Specific | | color | Free text to specify the color of the product (MAXIMUM: 255 characters). It won't be used for filtering; for this purpose use the attribute \"color_normalized\". This information will be shown on a special place after the name of the product. This is a variation attribute; as it is mandatory for some products, do not forget to set the attribute is_variation to false if you don't want to group your products. In case you have different shades of the same colour, please specify the right shade in order to avoid duplicated references in the same variations. | Depends on Taxonomy | Product Account >Item Specific OR Product Account >Variation Specific | If we have Product Account > Variation Group we use Product Account >Variation Specific else Product Account >Item Specific | | brand | Fill in the brand name of the product. MAXIMUM: 255 characters | Depends on Taxonomy | Product Account> Item specifics OR Product > Brand | Product Account > Item Specifics is with priority | | manufacturer_recommended_price | MSRP Price. Price without discount including taxes. Only 2 decimals are permitted | Depends on Taxonomy | Product Account > RRP | (v1.4)If we have mandatory RRP but it is not populated in Hemi we would like to push it as “0.00“ in order to push the product for creation | | retail_price_justification | | Depends on Taxonomy | “MSRP“ | Hardcoded as “MSRP” | | tax_rate_percentage | | Depends on Taxonomy | Product Account > VAT OR Account > VAT | Product Account > VAT is with priority | | variation_type | Indicate here the type of variation for the offer from the list. If you specify variation_type \"Size\" all sizes from the same model will be grouped together. | Depends on Taxonomy | Product Account > Variation Specific | We want to get only the name of the Variation Specific without the value. Please note the only available variations are size and color thus if we have another type of Variation Specific we should return an error. Also if we have variant using both Size and Color we need to push it as an array in the payload. | | description | | Yes | Product Account > Description | | | is_variation | Indicate here if the product is part of a variation (is_variation <= true) or not (is_variation <= false). In case of inconsistency, the information contained in this attribute prevails over other criteria. In case you specify is_variation <= true you need to fill out attributes \"color\" or \"size\" in order to group the products properly. If you don't specify this attribute, a variation may be created for your product based on the content of other attributes. | Depends on Taxonomy | “true” OR ”false” | If we have a Product Account > Variation Group filled in we mark it as “true” otherwise it is “false” | | image_url_1 | | Yes | Leading Image | We want to use the image logic as per abstraction described herehttps://wearepentagon.atlassian.net/wiki/spaces/HEMI/pages/1494482956/Product+Listing+general+requirements#Images-management The structure of the payload is without a master meaning as per the abstraction we want to identify the one leading image for the product and add everything else to “Additional Images” | | image_url_2 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_3 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_4 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_5 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_6 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_7 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | image_url_8 | | Depends on Taxonomy | “Additional Image” - the next available | See “Leading Image” notes above | | boot_type | | Depends on Taxonomy | Product Account >Item specifics | | | derby_oxford_type | | Depends on Taxonomy | Product Account >Item specifics | | | calf_size | | Depends on Taxonomy | Product Account >Item specifics | | | ankle_boot_type | | Depends on Taxonomy | Product Account >Item specifics | | | shoe_size_es | | Depends on Taxonomy | Product Account >Item specifics | | | closure_type | | Depends on Taxonomy | Product Account >Item specifics | | | composition | | Depends on Taxonomy | Product Account >Item specifics | | | size_country_origin | | Depends on Taxonomy | Product Account >Item specifics | | | dimension | Write the measurements in cm Length x width x height. Example: 30x20x30cm | Depends on Taxonomy | Product >Length Product > Width Product > Height | We need to make sure if the dimensions are populated in our Product fields we need to concatenate the with “x“ in order to represent one string and in the end to add “cm“ as our default metric in Hemi.We would like to allow the user to decide which one of the dimensions to import so there wont be additional validation if any of the dimensions are missing. For example if we have populated only Height we push it in the payload. If we have Heigh and Length we concatenate both fields and push it in the payload.

The only thing we want to validate is if we have required dimensions for specific category and we do no specify any of them in Product. | | washing_properties | | Depends on Taxonomy | Product Account >Item specifics | | | color_normalized | Normalized value for filter on the website | Depends on Taxonomy | Product Account >Item specifics | | | size_guide | | Depends on Taxonomy | Product Account >Item specifics | | | morphogender | | Depends on Taxonomy | Product Account >Item specifics | | | manufacturer_reference | Unique Reference of the product provided by the manufacturer, can be the same as SKU | Depends on Taxonomy | Product Account >Item specifics | | | product_warranty_information | | Depends on Taxonomy | Product Account >Item specifics | | | heel_height | | Depends on Taxonomy | Product Account >Item specifics | | | collection | | Depends on Taxonomy | Product Account >Item specifics | | | sales_justification | | Depends on Taxonomy | Product Account >Item specifics | | | shoe_tip_type | | Depends on Taxonomy | Product Account >Item specifics | | | rod_height | | Depends on Taxonomy | Product Account >Item specifics | | | manufacturing_country | | Depends on Taxonomy | Product Account >Item specifics | | | capacity | | Depends on Taxonomy | Product Account >Item specifics | | | sandal_type | | Depends on Taxonomy | Product Account >Item specifics | | | selling_price | Final sale price including VAT and, if there is, with the promotion discount already applied. Only 2 decimals are permitted | Yes | Product Account > Price | | | stock | | Yes | Product Account > Quantity | |

Please note VeePee supports only variation based on “Size”, “Color” or “Size + Color” Thus we want to have extra validation for all products which we try to create with other that these attributes added in Product Account > Variation Specific. For example if we have a variation of 5 products and one of them have different VS than Size and Color we want to block the whole variation group and return error on all of the products.

Example Response:

SHOP_CATALOG_1160_20230215091331.json"

After each successfully send feed for creation we need to store the filename which is returned from VeePee in the response and need to store it in Marketplace Feeds table. All products that are included in the feed need to be marked as Product Account > List/Update the whole Item - Sent

VeePee Field Hemi Field Comment
FileName Marketplace Feed > External ID This field is used to get the response of the import.
Marketplace Feed > Account For which account is the feed generated.
Marketplace Feed > Type Hardcoded as “Listing Create“
Marketplace Feed > Submitted Date When the feed is submitted
Marketplace Feed > Sent Objects Count How many products we have pushed in the feed

Please note we will also add the feed objects which after processing need to be removed.

Get the import status for a product import

API Call: {{BaseURL}}/status/{filename}

API Docs: https://pinkstaging.pink-connect.com/swagger#operation/getFileStatus

UPDATED: the change was successfully imported (we treat this as success)

SKIPPED: there was no change compared to the last feed (we treat this as success)

NEW: New product is created (we treat this as success)

ERROR: the data was not imported due to an error (we treat this as error)

WARNING: The update/create is successful but with warnings (we treat this as success)

Example pending response:

{
    "status": "PENDING",
    "result": null,
    "stats": "",
    "errorList": []
}

Example success response:

{
    "status": "FINISHED",
    "result": "ok",
    "stats": "PRODUCT [ UPDATED :0, ERROR :0, NEW :1, SKIPPED :0, WARNING :1]",
    "errorList": []
}

Example error response #1:

{
    "status": "FINISHED",
    "result": "ok",
    "stats": "PRODUCT [ UPDATED :0, ERROR :2, NEW :0, SKIPPED :0, WARNING :0]",
    "errorList": [
        {
            "category": "113991",
            "gtin": 5055286279677,
            "model": "36306124510",
            "sku": "36306124511",
            "status": "ERROR",
            "error_description": [
                "Category not found 113991"
            ]
        },
        {
            "category": "113992",
            "gtin": 5055286279678,
            "model": "36306124512",
            "sku": "36306124512",
            "status": "ERROR",
            "error_description": [
                "Category not found 113992"
            ]
        }
    ]
}

If we have errors during the product creation we will receive each product in separate node and we want to map directly the "sku" and store the "error_description" as error.

Example error response #2:

{
    "status": "FINISHED",
    "result": "ok",
    "stats": "PRODUCT [ UPDATED :0, ERROR :1, NEW :0, SKIPPED :0, WARNING :1]",
    "errorList": [
        {
            "category": "11529",
            "gtin": 1234567891012,
            "model": "1234",
            "sku": "1234",
            "status": "ERROR",
            "error_description": [
                "Mandatory attribute shoe_size_fr was not provided",
                "Mandatory attribute color was not provided",
                "Mandatory attribute retail_price_justification was not provided",
                "Not valid value España for attribute size_country_origin (fr)",
                "Not valid value Hombre for attribute morphogender (fr)"
            ]
        }
    ]
}

If we have multiple errors during the product creation for single product we want to map directly the "sku" and store all the "error_description" as error.

Example error response #3:

{
    "status": "FINISHED",
    "result": "critical",
    "stats": "",
    "errorList": [
        "description: Provided file SHOP_CATALOG_1160_20230404105456.json content is corrupt "
    ]
}

We can receive an error without status as well which we want to treat as full feed error and mark all products (feed objects) as error with the relevant error message from the “errorList“

Example error response #4

{
    "status": "FINISHED",
    "result": "ok",
    "stats": "OFFER [ SKIPPED :0, UPDATED :0, NOT_FOUND :0, ERROR :0]",
    "errorList": []
}

We can receive a response with 0 processed products as well which we want to treat as full feed error and mark all products (feed objects) as error

Based on the response we need to map each product and we will have to update the products either with error or success as well as the Marketplace Feed > Status and Marketplace Feed > External Status. If the product is created successfully and we do not receive and error in the errorList from the response we want to update: Product Account > Channel Item Id = Product > SKU or Product Account > Variation Group (If we have a variantion group we want to use it as a Channel Item ID otherwise we use the SKU) Product Account > Product status - Product Published Product Account > Listing Status - Active Product Account > List/Update the whole Item - Not Needed

If we receive and error and the product is not created: Product Account > Product status - Awaiting Creation Product Account > Listing Status - Inactive Product Account > List/Update the whole Item - Error

Any Triggers or Validations that are not specifically mentioned, changed or removed from the above mentioned scope should follow the standard flow as per the Link Here abstraction.

Additional Information:

For this integration we will need to make sure the protect flags are working as expected:

Closed -will stop all the creation of the products to the MPs.

Is this article helpful?
0 0 0