node.jsxmlwalmart-api

How do I POST correctly an XML price file to Walmart Canada Marketplace API using Nodejs


I am trying to POST an XML pricing file to Walmart Canada with Nodejs. I receive a response code 200, but there is an error reading my file on the Walmart side. I believe it has something to do with the way Buffer.from() parses the file, that causes the file to be unreadable when received by the server.

Here is my code:

  import { createSign, randomBytes } from 'crypto'
  import fetch from 'node-fetch';
  import { resolve } from 'url';
  import FormData from 'form-data';



  const method = 'POST';

  const BASE_URL = 'https://marketplace.walmartapis.com'

  const PK_HEADER = '\n-----BEGIN PRIVATE KEY-----\n'
  const PK_FOOTER = '\n-----END PRIVATE KEY-----\n'

  const WALMART_CONSUMER =  "walmart consumer";
  const WALMART_CHANNEL = 'walmart channel';
  const WALMART_SECRET = 'walmart secret';


  function generateCorrelationId () {
    return randomBytes(16).toString('hex')
   }

 function generateSignature (url, method, timestamp) {

 const privateKey = `${PK_HEADER}${WALMART_SECRET}${PK_FOOTER}`



const stringToSign = WALMART_CONSUMER + '\n' +
                 url + '\n' +
                 method.toUpperCase() + '\n' +
                 timestamp + '\n'

const sign = createSign('RSA-SHA256')

sign.update(stringToSign)
return sign.sign(privateKey, 'base64')
}
const url = BASE_URL + "/v3/ca/feeds?feedType=price";

const timestamp = Date.now()
const signature = generateSignature(url, method, timestamp)

const headers = {
  'WM_SVC.NAME': 'Walmart Marketplace',
  'WM_CONSUMER.ID': WALMART_CONSUMER,
  'WM_SEC.TIMESTAMP': timestamp,
  'WM_SEC.AUTH_SIGNATURE': signature,
  'WM_QOS.CORRELATION_ID': generateCorrelationId(),
  'WM_CONSUMER.CHANNEL.TYPE': WALMART_CHANNEL,
  'WM_TENANT_ID' : 'WALMART.CA',
  'WM_LOCALE_ID' : 'en_CA',
  "Content-Type": "multipart/form-data",
  'accept':'application/xml'

}

var form = new FormData();
const fileBuffer = Buffer.from("./prices.xml","utf8");
form.append('file',fileBuffer,"./prices.xml");

fetch(url, {
  method: method,
  headers: headers,
  body: form
 })
.then(response => console.log(response))
.catch(function (error) {
console.log(error)
});

xml file-

<?xml version="1.0" encoding="UTF-8"?>
<PriceFeed xmlns="http://walmart.com/">
  <PriceHeader>
     <version>1.5.1</version>
  </PriceHeader>
   <Price>
      <itemIdentifier>
          <sku>SKU</sku>
      </itemIdentifier>
      <pricingList>
          <pricing>
              <currentPrice>
                  <value currency="CAD" amount="340.00"/>
              </currentPrice>
          </pricing>
      </pricingList>
   </Price>
</PriceFeed> 

Solution

  • Buffer.from takes a string, not file path. That's probably why it doesn't work. Can you try to read the file and pass the string over to Buffer.from

    https://nodejs.org/api/buffer.html#buffer_static_method_buffer_from_string_encoding