user1254053
user1254053

Reputation: 765

Connect to Amazon MWS

I am trying to connect to Amazon MWS API. I have these information with me: String accessKeyId = ""; String secretAccessKey = ""; String merchantId = ""; String marketplaceId = ""; I have created a web form in vs2012 C# and on button click have added the above variable but how do I add a reference to marketplacewebservice? I want to get the sales information of my products listed there. Do i need to add some files, are there any files/dll provided by them that needs to be added. Please advice.

Edit: I have downloaded this MWSOrdersCSharpClientLibrary-2013-09-01.V293335039 and from dist folder added both dll in references. Here is the other code to get order details:

private void GetOrders()
    {
        MarketplaceWebServiceOrdersConfig config = new MarketplaceWebServiceOrdersConfig();
        config.ServiceURL = "https://mws.amazonservices.com/Orders/2011-01-01";

        MarketplaceWebServiceOrdersClient service = new MarketplaceWebServiceOrdersClient(accessKeyId, secretAccessKey, applicationName, applicationVersion, config);

        ListOrdersRequest request = new ListOrdersRequest();
        request.SellerId = sellerID;

        List<string> mpiList = new List<string>();
        mpiList.Add(marketplaceId);

        request.MarketplaceId = mpiList;

        request.LastUpdatedAfter = DateTime.UtcNow.AddDays(-1);
        bool retryRequest = true;
        do
        {
            try
            {
                ListOrdersResponse response = new ListOrdersResponse();
                response = service.ListOrders(request);

                if (response.IsSetListOrdersResult())
                {
                    if (response.ListOrdersResult.IsSetOrders())
                    {
                        foreach (Order order in response.ListOrdersResult.Orders)
                        {
                            Response.Write(order.AmazonOrderId);
                        }
                    }
                }

                retryRequest = false;
            }
            catch (MarketplaceWebServiceOrdersException ex)
            {
                if (ex.ErrorCode.Contains("RequestThrottled"))
                {
                    retryRequest = true;
                    System.Threading.Thread.Sleep(60000);
                }                  
            }
        } while (retryRequest == false);

    }

This does not return any order details, infact goes into throttle error.

Upvotes: 2

Views: 1349

Answers (1)

Nate M.
Nate M.

Reputation: 842

Use the Amazon .NET SDK. The download has some tutorials and sample files that will walk you through how to connect and do all of this 'inital setup'. Check the link below for a download of the SDK. Once you work through the tutorials, we can help with more specific questions.

You will want to use the Orders or Reports API for accessing sales information. Long term, you will want to use reports API because its very difficult to get large amounts of data with Orders API, but the Orders API is easier to learn when you are starting out. So.. I would start playing with the Orders API, and then move up to the Reports API once you have a feel for how the system works.

Orders API Libraries

Download the C# client libraries and check out src/MarketplaceWebServiceOrders/MarketplaceWebServiceOrdersSample.cs

In the aforementioned file, you may want to try out InvokeGetOrder() Simply add in your relevant keys into accessKey, secretKey, add your SellerID into the InvokeGetOrder() function and an mwsAuthToken if you have one. (If you don't have an auth token, you may have been grandfathered in, just remove the mwsAuthToken lines from the code).

Once all of that is done, you just have to supply an amazonOrderID, and the function will retrieve the details associated with that order. InvokeListOrders() is another good function to start learning with.

Edit

Once you get the hang of the sample programs, you can add the supplied DLL into your custom project, and any of the sample source you may want to add to help construct the various objects used in the function calls.

Edit

Ok.. First thing I see is your serviceURL is incorrect. For the live site, use https://mws.amazonservices.com

It appears that the rest of your code is pretty well formed. I would put a breakpoint on the catch, and see exactly what is going on. If the service exception is not throttled, your routine will free-wheel until you hit the throttling cap which is what you are seeing happen, but there should be multiple catches before you throttle. The Exception.Message will be informative regarding what the problem is.

Additionally, I would put a Thread.Sleep in the do-while loop outside of any conditions. Without some sort of sleep to slow the routine down, you will very quickly exceed your allowable throttling limits. Just fyi, handling throttling is probably the hardest part of communicating to Amazon effectively. I typically actually allow the throttle to occur and do something like the following:

try
{
    response = _service.GetReportListByNextToken(request);
}
catch (MarketplaceWebServiceException ex)
{
    bool success = false;
    for (int i = 0; i < 5 && !success; i++)
    {
        System.Threading.Thread.Sleep(3000);
        try
        {
            response = _service.GetReportListByNextToken(request);
            success = true;
        }
        catch (MarketplaceWebServiceException newEx)
        {
            success = false;
        }
    }
    if (response == null)
    {
        Console.WriteLine("GetReportListByNextToken failed.  Exceeded Throttling limits.");
        //Don't throw an error, since there may be reports that we still want to process.
    }

}

Keep in mind, each sleep is dependent on the call that you are performing. Additionally, on occasion, I will have two separate sleeps depending on if the error is throttling related or not.

Edit

It would look something like the following (integrated into your original code example)

private void GetOrders()
    {
        MarketplaceWebServiceOrdersConfig config = new MarketplaceWebServiceOrdersConfig();
        config.ServiceURL = "https://mws.amazonservices.com/";

        MarketplaceWebServiceOrdersClient service = new MarketplaceWebServiceOrdersClient(accessKeyId, secretAccessKey, applicationName, applicationVersion, config);

        ListOrdersRequest request = new ListOrdersRequest();
        request.SellerId = sellerID;

        List<string> mpiList = new List<string>();
        mpiList.Add(marketplaceId);

        request.MarketplaceId = mpiList;

        request.LastUpdatedAfter = DateTime.UtcNow.AddDays(-1);
        bool retryRequest = true;
        ListOrdersResponse response = new ListOrdersResponse();
        try
            {
                response = service.ListOrders(request);
            }
            catch (MarketplaceWebServiceException ex)
            {
                bool success = false;
                for (int i = 0; i < 5 && !success; i++)
                {
                    System.Threading.Thread.Sleep(30000);
                    try
                    {
                        response = service.ListOrders(request);
                        success = true;
                    }
                    catch (MarketplaceWebServiceException newEx)
                    {
                        success = false;
                    }
                }
                if (response == null)
                {
                    Console.WriteLine("ListOrders failed.  Exceeded Throttling limits.");
                    //Don't throw an error, since there may be reports that we still want to process.
                }
            }
        if (response.IsSetListOrdersResult())
        {
            if (response.ListOrdersResult.IsSetOrders())
            {
                foreach (Order order in response.ListOrdersResult.Orders)
                {
                    Response.Write(order.AmazonOrderId);
                }
            }
        }
}

This is a rough outline of what you would need to implement. Basically you put the try-catch around any function call that would make a request to amazon, and tune the sleep function to the throttling requirements of the function call. I put a 30 second sleep into the catch because there is a 60 second refresh on this call, and we have essentially 6 cycles to allow the call to not be throttled, so it should hit throttling on a maximum of 2 function calls and then go through successfully. Depending on your application, this may need to be tuned up closer to 60 seconds, or down, depending on how responsive you need the program to be (think if you hit throttling 1 second before your refresh, then you could have a maximum wait time of a 1.5 minutes with a 30 second sleep, whereas if you were using 15 seconds, your maximum wait time would be about 1.25 minutes. You have to balance that with the fact that you don't want to slam Amazon with requests (and some calls have hourly limits so you really don't want to hit that limit).

Upvotes: 2

Related Questions