Create Offer
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 | Applied changes | |
---|---|---|---|
28/09/2022 | 1.0 | Bogomil Pavlov | Initial Version |
01/02/2023 | 1.1 | Bogomil Pavlov | Additional Details updated and Discount Price Logic |
The purpose of this page is to describe in details the process of creating offer to already existing product on MIRAKL.
To create offer we should use following API calls - POST OF01 (Import a file to add offers), GET OF02 (Get information and statistics about an offer import), GET OF03 (Get the error report file for an offer import)
Complete flow:
Аfter successful product creation should have Channel Item ID, which for MIRAKL integration is the SKU!
Create offer cron should pick products only with statuses:
Product status = Product created and Listing Status = Inactive and List/Update the whole item =Pending
When the offer is successfully picked for creation we will set:
Product status = Product created and Listing Status = Inactive and List/Update the whole item =Sent
When the offer is created, we set statuses:
Product status - Product Published and Listing Status - Active and List/Update the whole item =Not Needed
If there is an error during offer creation, we will set following statuses:
Product status = Product created and Listing Status = Inactive and List/Update the whole item =Error
and we need to store the relevant error in Update Item Error field
- POST OF01 - Import a file to add offers
API Call: /api/offers/imports
API Docs: https://decathlonbelgium-preprod.mirakl.net/help/api-doc/seller/mmp.html#OF01
Returns the import identifier to track the status of the import.
This call allow us to submit XML file with all our offer. The xml structure is as follows:
Mapping - Offers
Documents:
offers-en_GB-20220405122024.xlsx
<?xml version='1.0' encoding='UTF-8'?>
<import><offers>
<offer>
<sku>OFFER_SKU_1</sku>
<product-id>PRODUCT_SKU_1</product-id>
<product-id-type>SHOP_SKU</product-id-type>
<description>This is the description of my amazing offer!</description>
<internal-description>This is the internal description of my offer.</internal-description>
<price>1000</price>
<price-additional-info>Price including taxes</price-additional-info>
<quantity>1</quantity>
<min-quantity-alert>20</min-quantity-alert>
<state>11</state>
<available-start-date>2012-12-25</available-start-date>
<available-end-date>2013-05-17</available-end-date>
<logistic-class></logistic-class>
<discount-price>1</discount-price>
<discount-start-date>2012-12-25</discount-start-date>
<discount-end-date>2013-12-25</discount-end-date>
<leadtime-to-ship>15</leadtime-to-ship>
<update-delete>UPDATE</update-delete>
<eco-contributions>
<eco-contribution>
<producer-id>ProducerID1</producer-id>
<eco-contribution-amount>0.99</eco-contribution-amount>
</eco-contribution>
<eco-contribution>
<producer-id>ProducerID2</producer-id>
<eco-contribution-amount>3.49</eco-contribution-amount>
</eco-contribution>
</eco-contributions>
<all-prices>
<pricing>
<channel-code>GB</channel-code>
<price>1000</price>
<discount-price>1</discount-price>
<discount-start-date>2012-12-25</discount-start-date>
<discount-end-date>2013-12-25</discount-end-date>
</pricing>
</all-prices>
<offer-additional-fields>
<offer-additional-field>
<code>active-channels</code>
<value>
<item>BE</item>
<item>CH</item>
</value>
</offer-additional-field>
<offer-additional-field>
<code>free-return</code>
<value>true</value>
</offer-additional-field>
</offer-additional-fields>
</offer>
</offers>
</import>
Mapping:
Mirakl Field | Mirakl Notes | Integration Required | Hemi Field | Comment | ||
---|---|---|---|---|---|---|
sku |
The offer’s unique identifier in the shop - Required - Maximum 40 characters, no "/" character | Required | item>SKU | |||
product-id |
Unique product identifier for a given product-id-type - Required at offer creation - Maximum 40 characters | Required | item>EAN | Decathlon supports only EAN and the EAN is Mandatory | ||
product-id-type |
Type of product-id identifier - Required at offer creation - Element from the list | Required | Hardcoded as “EAN” | |||
description |
Offer description - Recommended - Maximum 2000 characters | Recommended | Product Account > Description | |||
internal-description |
The description of the offer as shown in the back office view - Optional - Maximum 2000 characters | Optional | N/A | |||
price |
The price of the offer in the currency of the Marketplace - Required when creating an offer - Positive number | Required | Product Account > Price or Product Account > RRP | we send Product Account > RRP If RRP is populated and is bigger than Price | ||
price-additional-info |
Information about the offer's price - Optional - Maximum 100 characters | Optional | Product Account Decathlon > Price Additional Info | |||
quantity |
Quantity available in stock - Recommended - Positive integer | Recommended | Product Account > Quantity | |||
min-quantity-alert |
The minimum quantity which triggers a stock alert - Optional - Positive integer | Optional | N/A | |||
state |
The state of the offer - Required at offer creation - Element from the list | Required | “NEW“ | Mapping to our conditions: |
11- New > 1000;
1-Excellent > 1500;
2-Very Good >4000;
3-Good >5000;
4-Sufficient >6000;
5-Refurbished_like_new > 2750
6-Refurnished_very_good >2500
7-Refurbished_good > 2000
8-Refurbished_acceptable > New state(condition) to be created in Hemi (8000) |
| available-start-date
| | | The first day the offer becomes available (if blank, the offer is immediately available) - Optional - Valid date | Optional | N/A | |
| available-end-date
| | | The last day the offer is available (if blank, the offer has no end date) - Optional - Valid date | Optional | N/A | |
| logistic-class
| | | The logistic class of the offer (this logistic class will overwrite the default logistic class defined for the product category assigned to the offer) - Optional - Element from the list | Optional | account_decathlon > Logistic class
Product Account Decathlon > Logistic class | Our default Logistic Class is selected on account level and if we have selected on Item Account we pick it with priority |
| discount-price
| | | The discount price of the offer - Optional - Positive number | Optional | If RRP and is bigger than Price we push our Product Account > Price | If RRP > Price
- If there are discount dates imported in Hemi we use them
- If there are no dates imported in Hemi we use the default dates (Now) and (Now + 2y)
If RRP <= Price
3.We include the discount fields with empty values |
|
discount-start-date
| | | The first day the discount becomes available (if blank, the discount has no start date and is immediately active) - Optional - Valid date | Optional | Item Account Decathlon > Discount Start Date | If RRP > Price and If we do not specify any dates in the relevant fields we hardcoded current date (“NOW“) Date format -2017-02-20T10:45:53+01
If RRP <= Price We include the discount fields with empty values | |discount-end-date
| | | The last day the discount is available (if blank, the discount has no end date) - Optional - Valid date | Optional | Item Account Decathlon > Discount End Date | If RRP > Price and If we do not specify any dates in the relevant fields we hardcode current date + 2 year (“NOW“ +2y) Date format -2017-02-20T10:45:53+01
If RRP <= Price
We include the discount fields with empty values |
| leadtime-to-ship
| | | The lead time to ship for the offer - Optional - Positive integer lesser than 45 | Optional | Shipping template > Dispatch time max (defalut) or
Product Account > Dispatch time max | |
| update-delete
| | | Only use with the Normal import mode (if blank, the Update mode is used) - Optional - Element from the list | Optional | N/A | |
| offer-additional-fields
| | | | | | |
| | offer-additional-fields
| | | | | |
| | | active-channels
| select the channel where you want your offer published | Optional | Account Decathlon > Channel | Need to confirm if we have to check and get all active channels for SKU.
e.g.
active-channels
Decathlon specifics:
Field | Note | Integration Required | Hemi Field | Comment | ||||||
---|---|---|---|---|---|---|---|---|---|---|
eco-contributions |
Optional - Use the format "ProducerIdentifier1 | Eco-contributionAmount1,ProducerIdentifier2 | Eco-contributionAmount2". E.g. "ProducerID1 | 3.00,ProducerID2 | 0.49" | Optional | ||||
eco-contribution |
||||||||||
producer-id |
Item Account Decathlon > Eco Contributions | |||||||||
eco-contribution-amount |
Item Account Decathlon > Eco Contributions | |||||||||
all-prices |
||||||||||
pricing |
||||||||||
channel-code |
Account Decathlon > Channel | |||||||||
price |
price[channel=GB] - Offer Price for channel GB | Required | Product Account > Price or Product Account > RRP | we send Product Account > RRP If RRP is populated and is bigger than Price | ||||||
discount-price |
Optional | If RRP and is bigger than Price we push our Product Account > Price | ||||||||
discount-start-date |
Optional | “NOW“ | Hardcoded current date | |||||||
discount-end-date |
Optional | “NOW“+2 year | Hardcoded current date + 2 year | |||||||
offer-additional-fields |
||||||||||
free-return |
Free return | Optional | Product Account Decathlon > Free Return | check box (yes/no) |
- GET OF02 - Get information and statistics about an offer import
API Call: /api/offers/imports/{import}
API Docs: https://decathlonbelgium-preprod.mirakl.net/help/api-doc/seller/mmp.html#OF02
Parameter | Integration Notes / Value | Required |
---|---|---|
import |
Import identifier | Yes |
Using this call, we are able to check the import status:
Example Response:
{
"date_created": "2019-04-01T15:16:31Z",
"has_error_report": false,
"import_id": 2035,
"lines_in_error": 0,
"lines_in_pending": 0,
"lines_in_success": 1,
"lines_read": 1,
"mode": "NORMAL",
"offer_deleted": 0,
"offer_inserted": 1,
"offer_updated": 0,
"status": "COMPLETE"
}
OF02 call is returning the response for the actual offer import (all offers).
For example, { "message": "Not Found", "status": 404 }, this means there is no feed, no matter of the status of the feed - complete or error.
Based on the response, we will need to check if we have to continue with the error report (if "has_error_report": true or "has_transformation_error_report": true
) we continue with OF03 & OF04, otherwise we treat it as success.
Success case (once the offer is created successfully)
Product status = Product Published and Listing Status = Active and List/Update the whole item =Not Needed
Error case:
Product status = Product created and Listing Status = Inactive and List/Update the whole item =Error
and we need to store the relevant error in Update Item Error field
- GET OF03 - Get the error report file for an offer import In order to check if there are any errors related to the products, into imported file we should use the GET OF03 API Call.
API Call: /api/offers/imports/{import}/error_report
API Docs: https://decathlonbelgium-preprod.mirakl.net/help/api-doc/seller/mmp.html#OF03
"sku";"product-id";"product-id-type";"description";"internal-description";"price-additional-info";"quantity";"min-quantity-alert";"state";"available-start-date";"available-end-date";"logistic-class";"update-delete";"discount-start-date";"discount-end-date";"price";"discount-price";"discount-ranges";"price-ranges";"discount-start-date[channel=FR]";"discount-end-date[channel=FR]";"price[channel=FR]";"discount-price[channel=FR]";"discount-ranges[channel=FR]";"prices-ranges[channel=FR]";"discount-start-date[channel=CA]";"discount-end-date[channel=CA]";"price[channel=CA]";"discount-price[channel=CA]";"discount-ranges[channel=CA]";"prices-ranges[channel=CA]";"leadtime-to-ship";"error-line";"error-message"
"OFFER_SKU_004";"MKP100000000195360";"SKU";"My Offer Description n°1";"My Internal description 1";"My price Additional innformations";"1000000";"20";"11";"2017-02-20T10:45:53+01";"2017-04-30T10:45:53+01";"S";"update";"2017-02-22T10:45:53+01";"2017-04-30T10:45:53+01";"110.52";"108,56";"";"5|109.20,10|108.736";"2017-02-22T10:45:53+01";"2017-03-31T10:45:53+01";"105.56";"102,36";"";"5|104.56,10|103.27";"2017-02-22T10:45:53+01";"2017-03-31T10:45:53+01";"190.23";"175,36";"";"5|182.58,10|181.27";"15";"2";"The product does not exist"
As described above, this response give us detailed report of the SKUs and the actual SKUs errors are in the “error-message“
OF02 come directly when we import the file. if OF02 is 404 we set everything on Error and then we use the the actual response reader, which is OF03 API Call.
Get all logistic classes SH31 - List all logistic classes
API Call: /api/shipping/logistic_classes
API Docs: https://decathlonbelgium-preprod.mirakl.net/help/api-doc/seller/mmp.html#SH31
Sample Respons
{
"logistic_classes": [
{
"code": "S",
"description": "Small items less than 1 kg and dimension less than 1 meter (L x W x H)",
"label": "Small"
},
{
"code": "M",
"description": "Medium items between 1 and 3 kg and dimension less than 1 meter (L x W x H)",
"label": "Medium"
},
{
"code": "L",
"description": "Large between 3 and 5 kg and dimension less than 1 meter (L x W x H)",
"label": "Large"
}
]
}
Once we get the logistic classes we need to store them in Hemi and display them as enumerations in Account Decathlon > Logistic class and Product Account Decathlon > Logistic class. Please note we need to push the code to MIRAKL and display the label in Hemi.
Additional Information:
For this integration we will need to make sure the protect flags are working as expected:
Protect Quantity (Stop all quantity updates) - Applicable for already created offers. If the offer is not created this flag is ignored. If Protect Quantity = Yes and Update Quantity = Pending - We skip the product If Protect Quantity = Yes and Update Price= Pending - We pick the product only for price update and do NOT include the quantity in the payload If Protect Quantity = Yes and List/Update the Whole Item = Pending - We pick the product for full update but do NOT include the quantity in the payload
Protect Price (Stop all price updates) -Applicable for already created offers. If the offer is not created this flag is ignored. If Protect Price = Yes and Update Quantity = Pending -We pick the product only for stock update and do NOT include the prices in the payload If Protect Price = Yes and Update Price= Pending - We skip the product If Protect Price = Yes and List/Update the Whole Item = Pending - We pick the product for full update but do NOT include the prices in the payload
Protect the whole item - (Stop all product updates apart from Quantity) -Applicable for already created offers. If the offer is not created this flag is ignored. If Protect the whole item = Yes and Update Quantity = Pending -We send the quantity only If Protect the whole item = Yes and Update Price= Pending - We skip the product If Protect the whole item = Yes and List/Update the Whole Item = Pending - We skip the product
Closed -will stop all the updates to the MPs apart from the end item (send 0 stock update). This flag applies for all products the ones which are created and all new products.