Marketplaces / Fruugo Technical Scope / Fruugo Product Management / Fruugo Create Products

Fruugo Create Products

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
v1.0 15/01/2024 Hristiyan First publish

We are able to create products in Fruugo using the create products call. The request will be made via a JSON payload which will contain all the information for the products. Since the API calls are asynchronous, we should provide a webhook endpoint to Fruugo in order for them to provide us with a response whenever it is ready.

We want all triggers, validations and standardizations to be as per the abstraction Product Listing general requirements

When submitting the request, we can provide a X-Correlation-ID which is an identifier used for tracking the request. The X-Correlation-ID is used to tie the response back to the original request. If we provide a correlation id when making a request, Fruugo will use that and include it in the webhook response. If we don’t provide one, Fruugo will auto-generate one for us, which should be included in the initial response to our request, then it will also be included in the web-hook response. We are fine with both cases so it is up to the developers to decide whether to provide a X-Correlation-ID or not.

The webhook endpoint is : TBA

API Docs : https://developer.fruugo.com/#tag/products-v1

API Call : POST https://product-api.fruugo.com/v1/products

Example request :

{
  "products": [
    {
      "product": {
        "productId": "prod-ab-1234",
        "brand": "string",
        "manufacturer": "string",
        "category": "string"
      },
      "skus": [
        {
          "skuId": "string",
          "gtins": [
            {
              "codeType": "EAN",
              "code": "string"
            }
          ],
          "details": {
            "skuDescriptions": [
              {
                "language": "ar",
                "title": "string",
                "text": "string",
                "attributes": [
                  {
                        "name": null,
                        "value": null
                  }
                ]
              }
            ],
            "media": [
              {
                "description": "string",
                "url": "string",
                "type": "IMAGE"
              }
            ]
          },
          "supplyInfo": {
            "stockStatus": "INSTOCK",
            "stockQuantity": 99999,
            "leadTime": 1,
            "restockDate": "2019-08-24"
          },
          "pricingInfo": [
            {
              "vatRate": 20.55,
              "currency": "AED",
              "country": [
                "AE"
              ],
              "normalPrice": {
                "price": 0,
                "vatInclusive": false
              },
              "discountPrice": {
                "price": 0,
                "vatInclusive": false,
                "startDate": "2019-08-24",
                "endDate": "2019-08-24"
              }
            }
          ],
          "packageWeight": 99999,
          "volume": 0
        }
      ]
    }
  ]
}

Request mapping :

Fruugo Field Fruugo Notes Required? Hemi Field Hemi Notes
products
product
productId Product identifier code that you recognise when it is provided on order information. The same ProductId should be used to group together SKUs where they are available with multiple options (Colours, Sizes etc.). Yes Product Account > Variation Group

OR Product > SKU | We need to have a logic when the products we are sending are part of a variation, we need to send the Variation Group, if it is a single item then send the SKU. | | | | brand | | | The brand name of the Product. | No | Product Account > Item Specifics OR Product > Brand | Product Account > Item Specifics is with priority. | | | | manufacturer | | | The name of the manufacturer of the Product. | No | Product Account > Item Specifics | | | | | category | | | The accurate category of the Product to be classified in on Fruugo using the Fruugo category path. The category value must be accurate to the nature of the Product for taxation and use the full Fruugo category path. | Yes | Product Account > Primary Category ID | | | | skus | | | | | | | | | | | skuId | | | If the Product has multiple options, the SkuId uniquely identifies and separates each option. If a Product doesn’t have multiple options the SkuId can be the same as the ProductId. Each ProductId & SkuId combination must be unique and not repeated for any other Product(s) | Yes | Product > SKU | | | | | gtins | | | | | | | | | | | codeType | | | Yes | EAN OR MPN OR UPC OR ISBN | We need to send the type of the product code. We want to be able to control which codeType to be sent via radio buttons in the Account Fruugo table. | | | | | code | | The Product code. Do not include spaces or hyphens. | Yes | Product > EAN OR MPN OR UPC OR ISBN | string <= 14 characters.

Depending on what is selected in the Account Fruugo , we send the value of the selected field. | | | | details | | | Describes the details of the Product SKU | Yes | | | | | | | skuDescriptions | | | | | | | | | | language | | Two digit ISO code (lower case) of the language of the text fields of the feed, such as Title, Description, AttributeColor etc. The language must be one of those supported on Fruugo | Yes | Account Fruugo > Language Default | We want to have a dropdown list with predefined languages : ar cs da de el en "es" et fi fr he hi hu it jp ko lt lv nl no pl pt ro ru sk sv tr zh Default value should be en . If the Account Fruugo > Language Default is filled, we send the value in it, otherwise we send the default value. | | | | | title | | Product in title case (not block capitals) which identifies the nature of the Product. | Yes | Product Account > Title | | | | | | text | | | Yes | Product Account > Description | | | | | | attributes | | | No | | | | | | | | name | The name if this attribute, custom mappings to Fruugo attribute types are currently defined by Fruugo operations. Use of the name "Colour" and "Size" are universally mapped to Fruugo Colour and Size types respectively | Yes | Product Account > Variation Specifics OR Product Account > Item Specifics | We need to send the Variation Specifis name If the item is not a variation, we sent the Item Specifics name | | | | | | value | The value of this attribute | Yes | Product Account > Variation Specifics OR Product Account > Item Specifics | We need to send the Variation Specifics value If the item is not a variation, we sent the Item Specifics value | | | | media | | | | No | | | | | | | description | | | No | N/A | | | | | | url | | | Yes | This should be handled as per the Images Abstraction https://hemi.atlassian.net/wiki/spaces/HEMI/pages/1969540 | We need to send all images that we have for the product as separate nodes under the media node. | | | | | type | | | Yes | Hardcoded as IMAGE | | | | | supplyInfo | | | Provides the availability of this Product option | Yes | | | | | | | stockStatus | | The stock status of a Product which indicates whether it’s available for purchase. | Yes | Check Notes | The permitted values are: • INSTOCK – We have the Product currently in stock. • BACKORDERED – The Product is currently out of stock but is on backorder. • OUTOFSTOCK – The Product is currently out of stock but may return. • NOTAVAILABLE – The Product is permanently out of stock and needs to be removed. We want to use the INSTOCK and OUTOFSTOCK for now. We want to have a logic : If we have Product Account > Quantity >= 1 , we send INSTOCK If we have Product Account > Quantity <= 0 we send OUTOFSTOCK. | | | | | stockQuantity | | | | Product Account > Quantity | | | | | | leadTime | | The number of days from order to dispatch for any INSTOCK Product. | No | Shipping Template > Dispatch Time Max OR Product Account > Dispatch Time Max | Product Account > Dispatch Time Max is with priority. If we dont have it in the product account, we use the shipping template. If we dont have a shipping template we just exclude the node from the payload as it is not required. | | | | | restockDate | | The date when a Product which is currently marked as OUTOFSTOCK in 'StockStatus' will be back in stock and available for order. | No | N/A | | | | | pricingInfo | | | | Yes | | | | | | | vatRate | | | No | Account > VAT OR Product Account > VAT | Product Account > VAT is with priority. | | | | | currency | | Three letter ISO code (Upper Case) of the currency of the price properties | Yes | Account > Exchange Rate Calculator Currency | | | | | | country | | | No | Account > Country | We need to send the ISO 3166-1 alpha-2 code. For example Great Britain will be GB, USA is US etc. | | | | | normalPrice | | The normal price for this Product option. | Yes | | | | | | | | price | | Yes | Product Account > RRP | If RRP is empty we should send the Product Account > Price as normalPrice and not include discountPrice in the payload. | | | | | | vatInclusive | Is the price inclusive of VAT? | Yes | Account Fruugo > Price includes VAT | boolean Options are true or false | | | | | discountPrice | | | No | | | | | | | | price | | Yes | Product Account > Price | | | | | | | vatInclusive | | Yes | Account Fruugo > Price includes VAT | boolean Options are true or false | | | | | | startDate | The start date for the discount price to begin being displayed, if it is a time limited promotion. | No | Product Account Fruugo > Sale Start Date | New field in Product Account Fruugo If only the Sale End Date is filled we push NOW() as Sale Start Date If none of the fields are filled we exclude them from the payload. Date format is 2019-08-24 | | | | | | endDate | The end date for the discount price to stop being displayed, if it is a time limited promotion. | No | Product Account Fruugo > Sale End Date | New field in Product Account Fruugo If only the Sale Start Date is filled we exclude both fields from the payload. If the field is empty we just exclude it from the payload. Date format is 2019-08-24 | | | | packageWeight | | | The shipping weight of the Product provided in grams with no decimal places or unit of measurement. For example, 190. | No | Product > Weight | | | | | volume | | | | No | N/A | |

As mentioned above, the connection is asynchronous, so we would not immediately receive a response. A successful request would return a 204 ****Request has been accepted for processing, and update will be performed asynchronously response.

Callback POST: The MessageEnvelope payload will be a SaveProductResponse in a JSON format.

Callback payload sample :

{
  "value": {
    "type": "SaveProductResponse",
    "merchantId": 7418,
    "correlationId": "c3145570-0731-45db-9c9a-33f97d588400",
    "payload": "{'productCreated': true, 'productUpdated': false, 'merchantProductId': 'papi599VAT','createdSkus': [{'merchantSkuId': 'papi599_1VAT','merchantSkuQualityStatus': 'OK','validationErrors': []}],'updatedSkus': []}"
  }
}

Mapping :

Fruugo Field Hemi Field Hemi Notes
value
type N/A
merchantId N/A
correlationId N/A
payload N/A From the payload node we only want to check for two things : 'productCreated' and 'validationErrors' .

If productCreated is false and there are any validation errors we want to store the errors in the Product Account > Update Item Error (as per the abstraction) and not mark the product as created. If productCreated is true then there shouldn’t be any validationErrors so we consider the product as created successfully. |

Example unsuccessful responses :

400 Bad Request

Response sample :

[
  {
    "type": "field",
    "field": "productId",
    "message": "must not be null"
  },
  {
    "type": "field",
    "field": "skuIds",
    "message": "size must be between 1 and 200"
  }
]

Mapping :

Fruugo Field Hemi Field Notes
type N/A
field N/A
message Product Account > Update Item Error

429 Request has been rejected due to exceeding rate limit. Retry after delay specified in “Retry-After” response header.

Sample response :

{
  "status": 429,
  "reason": "Too Many Requests",
  "method": "GET",
  "path": "/v1/Products"
}

If we receive a 429 response we don’t want to store any error or map anything. Instead we want to check in the response header for the ‘retry-after’ where Fruugo will provide the time (in seconds) we need to wait before retrying the request and then re-send the request after the givne time has passed.

Is this article helpful?
0 0 0