ahnbizcad
ahnbizcad

Reputation: 10797

Walmart API - payload mime type issue - bulk create/update items not working

I am able to make API calls to other Walmart API endpoints successfully (specifically the GET request endpoints), but the bulk items endpoint (a POST request) results in an errors, even though I seem to have everything correct.

Here is the reference to that endpoint https://developer.walmartapis.com/#bulk-createupdate-items


HTTP RESPONSE META INFO

500 Internal Server Error

xml

HTTP RESPONSE

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:errors xmlns:ns2="http://walmart.com/">
    <ns2:error>
        <ns2:code>SYSTEM_ERROR.GMP_GATEWAY_API</ns2:code>
        <ns2:description>Couldn't determine the boundary from the message!</ns2:description>
        <ns2:info>System encountered some internal error.</ns2:info>
        <ns2:severity>ERROR</ns2:severity>
        <ns2:category>DATA</ns2:category>
        <ns2:causes/>
        <ns2:errorIdentifiers/>
    </ns2:error>
</ns2:errors>

HTTP REQUEST:

url https://marketplace.walmartapis.com/v2/feeds?feedType=item

method POST

request headers

WM_SVC.NAME: Walmart Marketplace
WM_CONSUMER.ID: {my consumer id key}
WM_QOS.CORRELATION_ID: {my arbitrary text key}
Content-Type: multipart/form-data
Accept: application/xml
WM_SEC.AUTH_SIGNATURE:{my jar-file-generated key}
WM_SEC.TIMESTAMP:{my jar-file-generated timestamp}

POST payload (just text, no key for the parameter)

<?xml version="1.0" encoding="UTF-8"?>
<MPItemFeed xmlns="http://walmart.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://walmart.com/ MPItem.xsd ">
  <MPItemFeedHeader>
    <version>2.1</version>
    <requestId>qqq</requestId>
    <requestBatchId>qqq1</requestBatchId>
  </MPItemFeedHeader>
  <MPItem>
    <sku>qqq</sku>
    <Product>
      <productName>QQQ 1-Foot S-Video Male to 2 S-Video Female Y Cable (CSV2F)</productName>
      <longDescription><![CDATA[<div class="productDescriptionWrapper"> QVS Premium S-Video Mini4 Male to Two Female Splitter Cable CSV2F A/V Device Cables <div class="emptyClear">
      </div>
      </div>]]></longDescription>
      <shelfDescription><![CDATA[QVS 1-Foot S-Video Male to 2 S-Video Female Y Cable (CSV2F)]]></shelfDescription>
      <shortDescription>QQQ 1-Foot S-Video Male to 2 S-Video Female Y Cable (CSV2F)</shortDescription>
      <mainImage>
        <mainImageUrl>http://images.antonline.com/img-main/500/037229400328.jpg</mainImageUrl>
      </mainImage>
      <productIdentifiers>
        <productIdentifier>
          <productIdType>Item ID</productIdType>
          <productId>46817049</productId>
        </productIdentifier>
      </productIdentifiers>
      <productTaxCode>2038710</productTaxCode>
      <Electronics>
        <brand>QQQ</brand>
        <ElectronicsCables>
        </ElectronicsCables>
      </Electronics>
    </Product>
    <price>
      <currency>USD</currency>
      <amount>12.34</amount>
    </price>
    <shippingWeight>
      <value>1.234</value>
      <unit>LB</unit>
    </shippingWeight>
  </MPItem>
</MPItemFeed>

NOTES:

I tried using Google' Advanced REST Client Application as well as POSTMAN when making http requests, in order to rule out issues stemming from my code.

I've tried tweaking everything that came to mind.

I got other endpoints having GET requests to work, so I know it's not an issue with authentication, IP, firewall, or anything like that.

I know the credentials generated by the jar file provided by walmart (see the authentication section of the documention https://developer.walmartapis.com/#jar-executable-recommended ) has to be fed the url you're sending to. So I know it's not an issue of generating the wrong key with the jar file.


HYPOTHESES:

Couldn't determine the boundary from the message!

sounds like the xml is doesn't have balanced tags, but I've validated this xml

But using this header doesn't seem to make sense to me, since the payload body is an xml string. Shouldn't it be Content-Type: application/xml? I tried this too, but it failed with the failed response above (500, SYSTEM_ERROR.GMP_GATEWAY_API, Couldn't determine the boundary from the message!)

So it seems Content-Type: application/xml can be ruled out.

I'm out of ideas, has anyone else gotten bulk create/update items to work? Anyone have example code that actually works?

Upvotes: 7

Views: 3513

Answers (5)

i fixed this issue by formatting my payload this way:

 $eol = "\r\n";
$data = '';

$mime_boundary="12345";

$data .= '--' . $mime_boundary . $eol;
$data .= '<?xml version="1.0"?>' . $eol . $eol;
$data .= '<MPItemFeed xmlns="http://walmart.com/">' . $eol;
$data .= '<MPItemFeedHeader>' . $eol;
$data .= '<version>2.1</version>' . $eol;
$data .= '<mart>WALMART_US</mart>' . $eol;
// $data .= '<locale>en_US</locale>' . $eol;
$data .= '</MPItemFeedHeader>' . $eol;



$data .= '<MPItem>' . $eol;
$data .= '<sku>UHP-8224-JH</sku>' . $eol;
$data .= '<productIdentifiers>' . $eol;
$data .= '<productIdentifier>' . $eol;
$data .= '<productIdType>UPC</productIdType>' . $eol;
$data .= '<productId>849849004721</productId>' . $eol;
$data .= '</productIdentifier>' . $eol;
$data .= '</productIdentifiers>' . $eol;
$data .= '<MPProduct>' . $eol;
$data .= '<productName>295 / 30 R 22 103Y  ANTARES MAJORIS M5  30 K MILES </productName>' . $eol;
$data .= '<ProductIdUpdate>No</ProductIdUpdate>' . $eol;
// $data .= '<SkuUpdate>No</SkuUpdate>' . $eol;
$data .= '<category>' . $eol;
$data .= '<Vehicle>' . $eol;
//$data .= '<Vehicle>' . $eol;
$data .= '<shortDescription>295 / 30 R 22 103Y  ANTARES MAJORIS M5  30 K MILES</shortDescription>' . $eol;
$data .= '<brand>ANTARES</brand>' . $eol;
$data .= '<mainImageUrl>https://www.stuff4crafts.com/media/catalog/product/4/3/437764.jpg</mainImageUrl>' . $eol;
$data .= '<tireSize>2255516</tireSize>' . $eol;
$data .= '</Vehicle>' . $eol;
//$data .= '</Vehicle>' . $eol;
$data .= '</category>' . $eol;
$data .= '</MPProduct>' . $eol;
$data .= '<MPOffer>' . $eol;
$data .= '<price>203.99</price>' . $eol;
$data .= '<MinimumAdvertisedPrice>203.99</MinimumAdvertisedPrice>' . $eol;
$data .= '<ShippingWeight>' . $eol;
$data .= '<measure>0.8000</measure>' . $eol;
$data .= '<unit>lb</unit>' . $eol;
$data .= '</ShippingWeight>' . $eol;
$data .= '</MPOffer>' . $eol;
$data .= '</MPItem>' . $eol;



$data .= '</MPItemFeed>' . $eol;

$data .= "--" . $mime_boundary . "--" . $eol . $eol; // finish with two eol's!!

Upvotes: 1

Siddhesh Ture
Siddhesh Ture

Reputation: 1

Choose your Arbitrary String let's say arbString e.g. abcdefghijklmnop(any String that should not repeat in your XML body)

Create your XML payload(File Input Stream) of bulk price/inventory. Convert your Payload to String with FileString = Ioutils.toString("FIS",standardCharacterset.UTF_8) .

Now append "--arbString/n/n"+FileString+"/n--arbString--"

Upvotes: 0

Alexey Kosov
Alexey Kosov

Reputation: 3128

Here's an example of working request:

POST /v2/feeds?feedType=inventory
Content-Length: 750
Content-Type: multipart/form-data; boundary=72c4c966adda8bba2e0b3ebc3176cc0c395dd8c8
Host: marketplace.walmartapis.com
Accept: application/xml
Accept-Encoding: gzip, deflate, br
User-Agent: <...>
Accept-Language: en-US
WM_CONSUMER.CHANNEL.TYPE: <...>
WM_CONSUMER.ID: <...>
WM_SEC.TIMESTAMP: <...>
WM_SEC.AUTH_SIGNATURE: <...>
WM_SVC.NAME: Walmart Marketplace
WM_QOS.CORRELATION_ID: <...>

--72c4c966adda8bba2e0b3ebc3176cc0c395dd8c8
Content-Disposition: form-data; name="xml"
Content-Length: 591

<?xml version="1.0" encoding="UTF-8"?>
<InventoryFeed xmlns="http://walmart.com/">
  <InventoryHeader>
    <version>1.4</version>
  </InventoryHeader>
  <inventory>
    <sku>sku</sku>
    <quantity>
      <unit>EACH</unit>
      <amount>1</amount>
    </quantity>
    <fulfillmentLagTime>5</fulfillmentLagTime>
  </inventory>
</InventoryFeed>

--72c4c966adda8bba2e0b3ebc3176cc0c395dd8c8--

Upvotes: 1

ShaneOH
ShaneOH

Reputation: 1557

In case anyone is stumbling across this using PHP and still having trouble even after trying OP's solution (e.g. 500 response with message "Couldn't determine the boundary from the message!" or "System encountered some internal error", you can use cURL to automatically handle the boundary for you by passing CURLOPT_POSTFIELDS as an array, like so:

curl_setopt($c, CURLOPT_POSTFIELDS, ['file' => $xml]);

Upvotes: 3

ahnbizcad
ahnbizcad

Reputation: 10797

The issue was that it needed an HTTP request boundary.

since the mime type is multipart/form-data, it needs a few things:

  1. The header line should be Content-Type: multipart/form-data; boundary=qwerty, where qwerty is any arbitrary string you choose.
  2. The payload body needs to start with --qwerty, and end with --qwerty--

Upvotes: 3

Related Questions