Reputation: 10797
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
Content-Type: multipart/form-data;
. So I did, results in the failure response.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
Reputation: 31
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
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
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
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
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:
Content-Type: multipart/form-data; boundary=qwerty
, where qwerty is any arbitrary string you choose.--qwerty
, and end with --qwerty--
Upvotes: 3