Amazon MWS XML how to specify shipping template - amazon-mws

Would appreciate some sample XML. I simply want to specify which shipping template should apply to any given product.
Amazon support pointed me to https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_4_1/Override.xsd but I fail to see how to specify the shipping template.
I was hoping there was something simple that could be included as part of _POST_PRODUCT_PRICING_DATA_ such as
<shipping_template>template1</shipping_template>
but I don't see that.
Thanks!

You should use the _POST_PRODUCT_DATA_
Here is the xml example that works for amazon.com:
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion><MerchantIdentifier>XYZ</MerchantIdentifier></Header>
<MessageType>Product</MessageType>
<Message>
<MessageID>1</MessageID>
<OperationType>PartialUpdate</OperationType>
<Product><SKU>YOURSKUNAME</SKU>
<DescriptionData>
<Title>Sometitle</Title><MerchantShippingGroupName>SHIPPINGTEMPLATENAME</MerchantShippingGroupName></DescriptionData>
</Product>
</Message>
</AmazonEnvelope>
Unfortunately it looks like the <Title> is mandatory even if you just want to change shipping template. If you want to change multiple skus at once just add more <Message> to the feed.

I Use this XML Feed for shipping orders and it works:
<?xml version="1.0"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>MERCHANT_IDENTIFIER</MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<Message>
<MessageID>MESSAGE_ID2</MessageID>
<OrderFulfillment>
<AmazonOrderID>123-1234567-1234567</AmazonOrderID>
<FulfillmentDate>SHIP_DATE</FulfillmentDate> //$ship_date = date("c");
<FulfillmentData>
<CarrierCode>Royal Mail</CarrierCode>
</FulfillmentData>
</OrderFulfillment>
</Message>
<Message>
<MessageID>MESSAGE_ID2</MessageID>
<OrderFulfillment>
<AmazonOrderID>321-7654321-7654321</AmazonOrderID>
<FulfillmentDate>SHIP_DATE</FulfillmentDate> //$ship_date = date("c");
<FulfillmentData>
<CarrierCode>Royal Mail</CarrierCode>
</FulfillmentData>
</OrderFulfillment>
</Message>
.
.
.
</AmazonEnvelope>
$parameters = array(
'Merchant' => $MERCHANT_ID,
'MarketplaceIdList' => $marketplaceIdArray,
'FeedType' => '_POST_ORDER_FULFILLMENT_DATA_',
'FeedContent' => $feedHandle,
'PurgeAndReplace' => false, //Leave this PurgeAndReplace to false so that it want replace whole product in amazon inventory
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true))
);
rewind($feedHandle);
$request = new MarketplaceWebService_Model_SubmitFeedRequest($parameters);
$return_feed = invokeSubmitFeed($service, $request);
fclose($feedHandle);

Related

MWS submit feed returns InputDataError

I have implemented submit feed API for _POST_ORDER_FULFILLMENT_DATA_ and get feedsubmission result. it returns InputDataError.
request:
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>A1OLX7E3BCNOP2</MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<Message>
<MessageID>1</MessageID>
<OrderFulfillment>
<MerchantOrderID>114-7129872-3010653</MerchantOrderID>
<MerchantFulfillmentID>5e79aa3205f4f</MerchantFulfillmentID>
<FulfillmentDate>2020-03-06T09:00:00Z</FulfillmentDate>
<FulfillmentData>
<CarrierCode>USPS</CarrierCode>
<ShippingMethod>First Class</ShippingMethod>
<ShipperTrackingNumber>9405511298370995607859</ShipperTrackingNumber>
</FulfillmentData>
<Item>
<MerchantOrderItemID>60227359610258</MerchantOrderItemID>
<MerchantFulfillmentItemID>item_5e79aa3205f4f</MerchantFulfillmentItemID>
<Quantity>1</Quantity>
<Transparencycode>AZ:SHGNCW8HKBBB8O4WZKYSHN7GYI</Transparencycode>
</Item>
</OrderFulfillment>
</Message>
</AmazonEnvelope>
Response:
<?xml version="1.0"?>
<ErrorResponse xmlns="http://mws.amazonaws.com/doc/2009-01-01/">
<Error>
<Type>Sender</Type>
<Code>InputDataError</Code>
<Message>InputDataError</Message>
<Detail />
</Error>
<RequestID>7d4ebf9a-6cb1-4b45-9191-0a00c268982a</RequestID>
</ErrorResponse>
Can anyone help me for this issue?
In my past experience, MWS is very picky about capitalization (and spelling). Check TransparencyCode. You don't have the "c" capitalized. According to the XSD, it is. Make sure everything matches.
https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_4_1/OrderFulfillment.xsd

Error during application initialization : ClusterSearcher should have a top level dispatch

Application with multiple content and each content with multiple documents is throwing "ClusterSearcher should have a top level dispatch." when deployed on multi node cluster with multiple content nodes. The same is working on a single node cluster with a single content node.
Using [Vespa version: ] 7.51.13
com.yahoo.container.di.componentgraph.core.ComponentNode$ComponentConstructorException: Error constructing 'com.yahoo.prelude.cluster.ClusterSearcher in acme'
Caused by: java.lang.IllegalStateException: ClusterSearcher should have a top level dispatch.
================= services.xml ==============
<?xml version="1.0" encoding="utf-8" ?>
<admin version="2.0">
<adminserver hostalias="admin0"/>
<configservers>
<configserver hostalias="admin0"/>
</configservers>
</admin>
<container id="container" version="1.0">
<config name="search.config.qr-start">
<jvm>
<heapSizeAsPercentageOfPhysicalMemory>50</heapSizeAsPercentageOfPhysicalMemory>
</jvm>
</config>
<document-api />
<http>
<server id="stateless1" port="8080">
</server>
</http>
<search>
<chain id="default" inherits="vespa">
<searcher id="com.acme.search.CatalogSearcher" bundle="sth-search">
<config name="com.acme.search.Searcher">
<redirectsFile>redirects.txt</redirectsFile>
<autoCorrectAPI>https://apps02.acme.com:9815/search/</autoCorrectAPI>
<connectionTimeout>250</connectionTimeout>
<connectionRequestTimeout>250</connectionRequestTimeout>
<socketTimeout>250</socketTimeout>
</config>
</searcher>
</chain>
</search>
<nodes jvmargs="-verbose:gc">
<node hostalias="stateless0"/>
<node hostalias="stateless1"/>
</nodes>
</container>
<content id="sth" version="1.0">
<redundancy>2</redundancy>
<documents>
<document type="sth" mode="index" />
</documents>
<nodes>
<node hostalias="content0" distribution-key="0"/>
<node hostalias="content1" distribution-key="1"/>
</nodes>
</content>
<content id="thesaurus" version="1.0">
<redundancy>2</redundancy>
<documents>
<document type="thesaurus" mode="index"/>
</documents>
<nodes>
<node hostalias="content0" distribution-key="0"/>
<node hostalias="content1" distribution-key="1"/>
</nodes>
</content>
<content id="acme" version="1.0">
<redundancy>2</redundancy>
<documents>
<document type="vc_products" mode="index" />
<document type="vc_thesaurus" mode="index"/>
</documents>
<nodes>
<node hostalias="content0" distribution-key="0"/>
<node hostalias="content1" distribution-key="1"/>
</nodes>
</content>
From comments, you get this not when you actually deploy on multiple nodes but when you try to instantiate a mock Application instance in a unit test, as in Application.fromApplicationPackage(...).
The reason for this is that Application is not able to fully mock a full application, only the stateless container parts. The ClusterSearcher which is instantiated in this setup complains that it can't see any real content clusters downstream (which is correct), it does not know it has been created in a mocked setup.
For this reason you need to create special services.xmls for unit tests as in general the one you use in production will give problems like this. Using Application works well for testing specific functionality of a set of components but not for unit testing your true production application.
We would like to improve this by mocking component clusters inside application but nobody's working on it at the moment. if you want to have a go at it the code is in
https://github.com/vespa-engine/vespa/tree/master/application

Amazon Order Fulfillment with Multiple Packages for one Order _POST_ORDER_FULFILLMENT_DATA_

I have been dealing with a problem that pops up once a day. An order with multiple packages (fulfillmentdata,item). This is an order where the person may have ordered two different items and they were sent by the merchant in two different packages with different tracking numbers. Tends to be uncommon on amazon but very common in other systems.
I have tried multiple versions of the XML to try and make this work but to no success.
My first attempt:
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>XXXXXXXX</MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<Message>
<MessageID>1</MessageID>
<OrderFulfillment>
<MerchantOrderID>55XXXX</MerchantOrderID>
<FulfillmentDate>2018-10-01T17:XX:XX-00:00</FulfillmentDate>
<FulfillmentData>
<CarrierCode>USPS</CarrierCode>
<ShippingMethod>First Class Parcel</ShippingMethod>
<ShipperTrackingNumber>940011590109XXXXXX</ShipperTrackingNumber>
</FulfillmentData>
<FulfillmentData>
<CarrierCode>USPS</CarrierCode>
<ShippingMethod>First Class Parcel</ShippingMethod>
<ShipperTrackingNumber>940011590109XXXXX</ShipperTrackingNumber>
</FulfillmentData>
<Item>
<AmazonOrderItemCode>354178450XXXX</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
<Item>
<AmazonOrderItemCode>014909917XXXX</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
</OrderFulfillment>
</Message>
</AmazonEnvelope>
Next I tried to split it up into two different messages
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>XXXXXXXX</MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<Message>
<MessageID>1</MessageID>
<OrderFulfillment>
<MerchantOrderID>554XXX</MerchantOrderID>
<FulfillmentDate>2018-10-01T17:XX:XX-00:00</FulfillmentDate>
<FulfillmentData>
<CarrierCode>USPS</CarrierCode>
<ShippingMethod>First Class Parcel</ShippingMethod>
<ShipperTrackingNumber>94001159010920XX</ShipperTrackingNumber>
</FulfillmentData>
<Item>
<AmazonOrderItemCode>0149099174XXXX</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
</OrderFulfillment>
</Message>
<Message>
<MessageID>2</MessageID>
<OrderFulfillment>
<MerchantOrderID>554XXX</MerchantOrderID>
<FulfillmentDate>2018-10-01T17:XX:XX-00:00</FulfillmentDate>
<FulfillmentData>
<CarrierCode>USPS</CarrierCode>
<ShippingMethod>First Class Parcel</ShippingMethod>
<ShipperTrackingNumber>9400115901092029XXX</ShipperTrackingNumber>
</FulfillmentData>
<Item>
<AmazonOrderItemCode>3541784506XXXX</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
</OrderFulfillment>
</Message>
</AmazonEnvelope>
With the second message I received the following error (for both message 1 and 2):
<MessageID>2</MessageID>
<ResultCode>Error</ResultCode>
<ResultMessageCode>18028</ResultMessageCode>
<ResultDescription>The data you submitted is incomplete or invalid. For help fixing this, see http://sellercentral.amazon.com/gp/help/30721</ResultDescription>

Can you simplify XML Arrays?

I want to create an XML "database" that currently looks like this:
<?xml version="1.0"?>
<ArrayOfSport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<sport name="football">
<countries>
<country name="england">
<leagues>
<league name="premierleague">
<teams>
<team key="man" value="Manchester United" />
<team key="arse" value="Arsenal" />
<team key="bour" value="Bournemouth" />
</teams>
</league>
</leagues>
</country>
</countries>
</sport>
</ArrayOfSport>
As you can see, this XML can be very messy. So, my question is, can you simplify XML Arrays (<countries>, <leagues>, <teams>) like in the example above into something like this?:
<?xml version="1.0"?>
<ArrayOfSport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<sport name="football">
<country name="england">
<league name="premierleague">
<team key="man" value="Manchester United" />
<team key="arse" value="Arsenal" />
<team key="bour" value="Bournemouth" />
</league>
</country>
</sport>
</ArrayOfSport>
Or am I missing something?
Fixed it by using XDocument.
Here's the C# code that generated the valid XML:
var sports =
new XElement("sports",
new XElement("sport", new XAttribute("name", "football"),
new XElement("country", new XAttribute("name", "england"),
new XElement("league", new XAttribute("name", "premierleague"),
new XElement("team", new XAttribute("key", "man"), new XAttribute("value", "Manchester United")),
new XElement("team", new XAttribute("key", "arse"), new XAttribute("value", "Arsenal")),
new XElement("team", new XAttribute("key", "bour"), new XAttribute("value", "Bournemouth"))
)
)
)
);
using (var fileStream = new FileStream(#"C:\XElementTest.xml", FileMode.Create))
using (var writer = new StreamWriter(fileStream))
{
writer.Write(sports);
}
It generated this XML:
<sports>
<sport name="football">
<country name="england">
<league name="premierleague">
<team key="man" value="Manchester United" />
<team key="arse" value="Arsenal" />
<team key="bour" value="Bournemouth" />
</league>
</country>
</sport>
</sports>

Empty results when filtering based on position in XQuery

I tried to print the details of 3rd and 4th products in the catalog, but I am getting empty results.
XML input:
<catalog>
<product dept="WMN">
<number>557</number>
<name language="en">Fleece Pullover</name>
<colorChoices>navy black</colorChoices>
</product>
<product dept="ACC">
<number>563</number>
<name language="en">Floppy Sun Hat</name>
</product>
<product dept="ACC">
<number>443</number>
<name language="en">Deluxe Travel Bag</name>
</product>
<product dept="MEN">
<number>784</number>
<name language="en">Cotton Dress Shirt</name>
<colorChoices>white gray</colorChoices>
<desc>Our <i>favorite</i> shirt!</desc>
</product>
</catalog>
what I tried:
SELECT xDoc.query(' for $prod in //product
let $x:=$prod
return (<Item>{data($x[3])}{data($x[4])}</Item>)')
FROM AdminDocs
where id=6
Output displayed:
<Item />
<Item />
<Item />
<Item />
This defines a loop over all products:
for $prod in //product
For each of those products, you return the third and fourth node out of a sequence of a single product, which obviously will yield empty nodes:
let $x:=$prod
return (<Item>{data($x[3])}{data($x[4])}</Item>)
For a better understanding, return the whole product node each time:
for $prod in //product
return <item>{ $prod }</item>
Which will result in something like this:
<item>
<product dept="WMN">
<number>557</number>
<name language="en">Fleece Pullover</name>
<colorChoices>navy black</colorChoices>
</product>
</item>
<item>
<product dept="ACC">
<number>563</number>
<name language="en">Floppy Sun Hat</name>
</product>
</item>
<item>
<product dept="ACC">
<number>443</number>
<name language="en">Deluxe Travel Bag</name>
</product>
</item>
<item>
<product dept="MEN">
<number>784</number>
<name language="en">Cotton Dress Shirt</name>
<colorChoices>white gray</colorChoices>
<desc>Our <i>favorite</i> shirt!</desc>
</product>
</item>
And each of those <product/> elements being a $prod[1]. Try:
for $prod in //product
return <item>{ $prod[1] }</item>
which will return the exactly same result, compared to
for $prod in //product
return <item>{ $prod[2] }</item>
(or any other positional predicate) resulting in empty <item/> nodes.
Finally, to return only the third and fourth products, shift the positional predicate into the for loop argument:
for $prod in //product[position() = 3 or position() = 4]
return <item>{ $prod }</item>
(and apply data(...) as needed, but I'd guess it won't yield the results you expect here).

Resources