3

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?

ricks
  • 3,154
  • 31
  • 51

1 Answers1

2

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.

ricks
  • 3,154
  • 31
  • 51
  • This is the exact issue I'm running into. Currently using an auto generated library based off of their schema. Will give this a try after the break and see if it resolves my issue. – Melvin Gaye Dec 31 '21 at 15:37