ruby-on-railshttprequestwalmart-api

Bulk Item Setup endpoint on Walmart no working with JSON


I am trying to submit a feed to Walmarts API following this guide and this api documentation

In their guide it says

Send an item feed to Walmart with payload in either XML or JSON format

I am sending this JSON

{
   "MPItemFeedHeader":{
      "version":"1.0",
      "sellingChannel":"mpsetupbymatch",
      "locale":"en"
   },
   "MPItem":[
      {
         "Item":{
            "productIdentifiers":{
               "productId":"042666047173",
               "productIdType":"UPC"
            },
            "ShippingWeight":2,
            "price":420.69,
            "sku":"RICKS-12345"
         }
      }
   ]
}

Via a POST request like so:

# Submits a feed to Walmart
# @param feed_data [Hash] data that will be submited with the feed
# @param type [String] Enum: "item" "RETIRE_ITEM" "MP_ITEM" "MP_WFS_ITEM" "MP_ITEM_MATCH" "MP_MAINTENANCE" "SKU_TEMPLATE_MAP" "SHIPPING_OVERRIDES" 
def submit_feed(feed_data, type)
  # To add a param to a multipart POST request you need to append the params to the URL
  endpoint = "https://marketplace.walmartapis.com/v3/feeds?feedType=" + type
  
  headers = self.api_client.headers.with_indifferent_access 

  uri = URI(endpoint)
  request = Net::HTTP::Post.new(uri)

  # Add Required Headers
  request['Authorization'] = headers["Authorization"]
  request['WM_SEC.ACCESS_TOKEN'] = headers["WM_SEC.ACCESS_TOKEN"]
  request['WM_QOS.CORRELATION_ID'] = headers["WM_QOS.CORRELATION_ID"]
  request['WM_SVC.NAME'] = headers["WM_SVC.NAME"]
  request['Accept'] = headers["Accept"]

  # Set form wants an array of arrays, basically the first item is the key and the second the value
  request.set_form([["file", feed_data]], 'multipart/form-data')
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(request)
  end
end

The feed successfully submits, but when i check the status this is the response:

 {
   "feedId":"6DCFAA97311140358D6D842488B24333@AQMBCgA",
   "feedStatus":"ERROR",
   "shipNode":null,
   "submittedBy":null,
   "feedSubmissionDate":1627595359155,
   "ingestionErrors":{
      "ingestionError":[
         {
            "type":"DATA_ERROR",
            "code":"ERR_EXT_DATA_0801001",
            "field":"IB",
            "description":"Unexpected character '{' (code 123) in prolog; expected '\u003c'\n at [row,col {unknown-source}]: [1,1]"
         }
      ]
   },
   "itemsReceived":0,
   "itemsSucceeded":0,
   "itemsFailed":0,
   "itemsProcessing":0,
   "offset":0,
   "limit":50,
   "itemDetails":{
      "itemIngestionStatus":[
         
      ]
   },
   "additionalAttributes":null
}

Judging by the error message

Unexpected character '{' (code 123) in prolog; expected '\u003c'\n at [row,col {unknown-source}]: [1,1]

It seems like they are expecting me to be sending an XML file, i can't figure out what it is i am doing wrong.

They require that the data is sent as multipart so i can't set the Content-Type to application/json

enter image description here

Is there anything i am missing to tell them in the request that the payload is JSON?


Solution

  • I figured it out with the help of this answer on another question.

    You are better off referencing this than Walmarts official documentation

    You need to submit a post request to the "https://marketplace.walmartapis.com/v3/feeds endpoint appending your type on the url ?feedType=[something]

    You need to make sure that your "Content-Type" is "application/json" if you are sending them JSON.

    You do not need to send it multipart like the documentation suggests, just send your entire JSON file as the body and it should work correctly.

    Here is my new ruby code to get this done:

    # Submits a feed to Walmart
    # @param feed_data [Hash] data that will be submited with the feed
    # @param type [String] Enum: "item" "RETIRE_ITEM" "MP_ITEM" "MP_WFS_ITEM" "MP_ITEM_MATCH" "MP_MAINTENANCE" "SKU_TEMPLATE_MAP" "SHIPPING_OVERRIDES" 
    def submit_feed(feed_data, type)
      # To add a param to a multipart POST request you need to append the params to the URL
      endpoint = "https://marketplace.walmartapis.com/v3/feeds?feedType=" + type
    
      uri = URI.parse(endpoint)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.post(uri.path, feed_data, self.api_client.headers)
    end
    

    If someone from Walmart is looking at this question, please improve your documentation.