facebook

Blog

Stay updated

Discover together how to integrate products data sheets from our e-commerce with information from Amazon
When Amazon helps you
Tuesday, March 19, 2019

During a consulting meeting with a client, that commissioned us the development of an e-commerce for technological products, we should face the lack of technical and commercial information about products provided by suppliers: we would have a bare website, with almost naked products data sheets.

One of the best solution we found, to add and complete products information, was the use of Amazon Product Advertising API (ex Amazon Web Service AWS):they are different services Amazon makes available to sell your products on other stores too.

You are required to register for free as Amazon Associate, then you can subscribe the Amazon Product Advertising API program and obtain credentials to use different services.

In the documentation,you can find those services available:

  • ItemSearch: products research on Amazon;
  • BrowseNodeLookup: it returns the categories’ pecking order, starting from a product/category;
  • ItemLookup: it returns the attributes list for the specified object;
  • SimilarityLookup: it returns objects similar to the specified one.

As you invoke these services, you can either add more parameters to obtain personalized results. Among the available parameters to add, we can find for example: Accessories (items bought together); EditoralReview (product descrption); Images (a set of images in different sizes); ItemAttributes (items particular characteristics); OfferListing (a list of offers of other sellers); RelatedItems (items related to the selected one); Reviews.

Among these services, the most useful to satisfy our demands is ItemSearch. It is also the one that allow us to make the less invocations, since it receives as input the EAN code and returns information we need, as the response below:

<Item>
    <ASIN>B00TZL96BY</ASIN>
    <ParentASIN>B012E5CKMY</ParentASIN>
    <DetailPageURL>https://www.amazon.com/Lacoste-Womens-Sleeve-Stretch-Varsity/dp/B00TZL96BY%3Fpsc%3D1%26SubscriptionId%3D[AWS Access Key ID]%26tag%3D[Associate ID]%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00TZL96BY</DetailPageURL>
    <ItemLinks>
        <ItemLink>
            <Description>Technical Details</Description>
            <URL>https://www.amazon.com/Lacoste-Womens-Sleeve-Stretch-Varsity/dp/tech-data/B00TZL96BY%3FSubscriptionId%3D[AWS Access Key ID]%26tag%3D[Associate ID]%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB00TZL96BY</URL>
        </ItemLink>
        <ItemLink>
            <Description>Add To Baby Registry</Description>
            <URL>https://www.amazon.com/gp/registry/baby/add-item.html%3Fasin.0%3DB00TZL96BY%26SubscriptionId%3D[AWS Access Key ID]%26tag%3D[Associate ID]%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB00TZL96BY</URL>
        </ItemLink>
        <ItemLink>
            <Description>Add To Wedding Registry</Description>
            <URL>https://www.amazon.com/gp/registry/wedding/add-item.html%3Fasin.0%3DB00TZL96BY%26SubscriptionId%3D[AWS Access Key ID]%26tag%3D[Associate ID]%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB00TZL96BY</URL>
        </ItemLink>
        ...
    </ItemLinks>
    <ItemAttributes>
        <Manufacturer>Lacoste Womens Apparel</Manufacturer>
        <ProductGroup>Apparel</ProductGroup>
        <Title>Lacoste Women's Long Sleeve Stretch Pique Slim Fit Polo Shirt, Varsity Blue, 40</Title>
    </ItemAttributes>
</Item>

The limit of the free version is for 25.000 items until now, then it is particularly useful even for big e-commerce.

To use the services, we need to validate our client id and secret we received as we complete the registration.

To implement in .NET environment, we used a Java class we found in some examples provided by Amazon, SignedRequestsHelper, and we write it again in C#. This class provides us the access and the use of Amazon services.

We decided to proceed in two different steps, both to deal with usage limit of the service and to best manage mistakes:

  1. save product information on a Swap DB;
  2. Equalize the product on Amazon with those on the e-commerce.

With this method, in the second step we could decide what to import, define products similarity and restore information modified by error, if needed.

Let’s implement the import service AmazonSwapImportManager, where we instance the object SignedRequestHelper in the constructor and we pass to its the parameter received when we register to the service:

SignedRequestHelper helper;
 
public AmazonSwapImportManager() {
    try {
        helper = new SignedRequestHelper(ACCESS_KEY_ID, SECRET_KEY, ENDPOINT);
    } catch (Exception e) {
        //logga l’eccezione;
    }
}

to obtain information related to product, we create the method GetInfoFromAmazonServices:

private String GetInfoFromAmazonServices(String ean) {
    try {
        //ottieni la url del prodotto richiesto tramite il suo EAN
        String requestUrl = GetProductUrlRequestByEan(ean);
        //ottieni l'oggetto XML dalla url del prodotto
        String xmlObject = GetXmlObjectFromUrl(requestUrl).Result;
        //trasforma in JSON l'oggetto XML ricevuto precedentemente.
        return GetJsonFromXml(xmlObject);
    } catch (Exception e) {
        //logga l’eccezione;
    }
}

which is based on other utility methods:

private static String GetJsonFromXml(string xmlObject) {
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xmlObject);
    var node = doc.DocumentElement.GetElementsByTagName("Item");
    if (node.Item(0) == null) return "none";
    string json = JsonConvert.SerializeXmlNode(node.Item(0));
    return json;
}
 
private String GetProductUrlRequestByEan(String ean) {
    IDictionary <string, string> requestParams = new Dictionary <string, String> ();
 
    requestParams.Add("Service", "AWSECommerceService");
    requestParams.Add("Operation", "ItemSearch");
    requestParams.Add("AWSAccessKeyId", ACCESS_KEY);
    requestParams.Add("AssociateTag", TAG);
    requestParams.Add("Keywords", EAN);
    requestParams.Add("IdType", "EAN");
    requestParams.Add("ResponseGroup", "Accessories,AlternateVersions,BrowseNodes,EditorialReview,Images,ItemAttributes,ItemIds,OfferFull,OfferListings,Offers,OfferSummary,PromotionSummary,RelatedItems,Reviews,SalesRank,Similarities");
    requestParams.Add("SearchIndex", "All");
    requestParams.Add("RelationshipType", "AuthorityTitle");
 
    return helper.Sign(requestParams);
}
 
private async Task <String> GetXmlObjectFromUrl(String requestUrl) {
    return await requestUrl.GetStringAsync();
}

The method GetInfoFromAmazonServices is used inside a method ImportProductInfo, that cycles on all store products and try to obtain needed information:

private void ImportProductsInfo(IList <Product> products) {
 /* altre operazioni di utilità */
 
    //cicla sui prodotti
    foreach(var product in products) {
        String productInfo = GetInfoFromAmazonServices(product.Ean);
        //salva su un DB di swap le informazioni trovate sul prodotto
        StoreItemToAmazonSwapDB(product.Ean, productInfo);
    }
    /* altre operazioni di riepilogo */
}

the object saved on Swap DB is a SwapItem type, defined as:

public class SwapItem
{
    public int Id { get; set; }
    public string Ean { get; set; }
    public string Content { get; set; }
}

as soon as we saved product data on a Swap DB, we can proceed with the accordance with our production DB. Create a class AmazonSwapSyncer, that contains the Sync method, defined as:

public void Sync()
{
    SynchronizeProductsInfo(GetItemsFromAmazonSwapDB());
}

which, in turn, is based on SynchronizeProductsInfo:

private void SynchronizeProductsInfo(IList <SwapItem> swapItems) {
 /* altre operazioni di utilità */
 
    foreach(var swapItem in swapItems) {
    //ricerca sul nostro DB se ci sono occorrenze del prodotto con l'EAN specificato
        var currentProduct = dbContext.Products.FirstOrDefault(p => p.Ean == swapItem.Ean);
        if (currentProduct != null) {
            try {
            //deserializza la stringa in un oggetto AmazonItem
                var amazonItem = JsonConvert.DeserializeObject <AmazonItem> (swapItem.Content);
                //ottiene la descrizione
                currentProduct.Description = amazonItem.Item.EditorialReviews.EditorialReview.Content;
                //ottiene le caratteristiche techiche del prodotto
                currentProduct.Features = String.Join(" * ", amazonItem.Item.ItemAttributes.Feature);
                //ottiene la url dell'immagine di grandi dimensioni
                currentProduct.ImageUrl = amazonItem.Item.LargeImage.Url;
                /* ottieni altre informazioni */
            } catch (Exception e) {
                //logga l’eccezione;
            }
        }
    }
    //salva le informazioni ottenute
    dbContext.SubmitChanges();
}

the class AmazonItem, with all aggregated classes, is then defined as per our requirements:

public class AmazonItem
{
    public Item Item { get; set; }      
}
 
public class Item
{
    public String ASIN { get; set; }
    public long SalesRank { get; set; }
    public ItemAttributes ItemAttributes { get; set; }
    public EditorialReviews EditorialReviews { get; set; }
    public AmazonImage LargeImage { get; set; }
}
 
public class ItemAttributes
{
    public String Binding { get; set; }
    public String Color { get; set; }
    public String[] Feature { get; set; }
}
 
public class EditorialReviews
{
    public EditorialReview EditorialReview { get; set; }
}
 
public class EditorialReview
{
    public String Content { get; set; }
}
 
public class AmazonImage
{
    public String Url { get; set; }
    public int Height { get; set; }
    public int Width { get; set; }
}

Thanks to that, as the synchronization process finishes, we get updated products information thanks to subjects available on Amazon.

You can find the code of this article on GitHub, at following link.