-1

There's a lot to unpack here. First of all, I've edited the title because I realize while eventually my REST request will be implemented into PHP code, right now I've stripped this down to Postman to test JUST the REST, so I've stripped it as low and basic as possible. I can officially say the problem is with my request.

Basically, I'm making a POST request and also testing with a PUT request to Walmart's API using the "new" OAuth authentication. Sounds grand. GET works BEAUTIFULLY in Postman and in my actual PHP code. POST and PUT immediately return the exact same error, no matter what and how I do: 400 Bad Request, Invalid URL. In the case of my PUT test, which I was doing because it's a simpler and faster text with far less XML to try to comb through, here's the exact response in HTML headers:

<HTML>
    <HEAD>
        <TITLE>Invalid URL</TITLE>
    </HEAD>
    <BODY>
        <H1>Invalid URL</H1>
The requested URL "http&#58;&#47;&#47;&#37;5bNo&#37;20Host&#37;5d&#47;v3&#47;inventory&#63;", is invalid.
        <p>
Reference&#32;&#35;9&#46;c9384317&#46;1556319123&#46;8c89b8dc

        </BODY>
    </HTML>

I have left testing in PHP through my server and moved into Postman to try to locate the exact issue I'm having, and GET requests work beautifully. I am generating a new Token every 15 minutes or so. I have done... SO many minor changes, but the way the Feed examples and requests work, for all that I can tell I'm doing everything right. I honestly think I'm losing my marbles at this point.

What is most frustrating to me is that GET works. My TOKEN is working. My OAuth is working just fine. A lot of the headers that GET uses for the Walmart API are the exact same between PUT/POST/GET. The difference here is ONLY that the link has query parameters AND XML being shoved into the body. Edit: What I mean is that my headers do not change between the GET and the POST; the only thing that changes in what I am supplying is that XML is being sent in the body, and that query params are required. This is the only thing that changes between a successful GET and an unsuccessful 400 bad request PUT/POST. This leads me to believe something is wrong with how I'm processing the query params or my XML, but considering in the below example I've copy/pasted the XML... I'm not sure. It is an existing item in our catalog, I know for a fact.

Something I have noticed that I'm not quite knowledgeable enough to know if it's an issue or not with Postman is that Walmart's API requests that content-type be multipart/form-data. I've noticed it uses the term "example" when stating this, however, it usually says "this or this" if it'll accept something else. If I switch content-type in Postman to multipart/form-data, however, the Body automatically becomes raw: text instead of raw: XML(application/xml) or text/xml. If I try to swap the raw to those types, it flips my content-type automatically to application/xml, so that's a little... hinky.

I am not going through a Proxy. I've turned off Global Proxy Configuration and Use System Proxy. Request timeout is set to 0. There's nothing Client Certificates. I mean, GET works, and my Token is successfully generated via outside PHP code (not in Postman, couldn't get that to work, said heck it).

HEADERS

PUT URL: https://marketplace.walmartapis.com/v3/inventory?sku=0xyz0

AUTHORIZATION

Bearer Token: Bearer Basic --insert token here--

WM_SVC.NAME: Walmart Marketplace
WM_QOS.CORRELATION_ID: randomString123
WM_SEC.ACCESS_TOKEN: --insert token here--
Accept: application/xml
Host: https://marketplace.walmartapis.com
Content-type: multipart/form-data

BODY raw: XML(application/xml)

<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns="http://walmart.com/">
    <sku>0xyz0</sku>
    <quantity>
        <unit>EACH</unit>
        <amount>7</amount>
    </quantity>
    <fulfillmentLagTime>1</fulfillmentLagTime>
</inventory>

Exact response

400 Bad Request

<HTML>
    <HEAD>
        <TITLE>Invalid URL</TITLE>
    </HEAD>
    <BODY>
        <H1>Invalid URL</H1>
The requested URL "http&#58;&#47;&#47;&#37;5bNo&#37;20Host&#37;5d&#47;v3&#47;inventory&#63;", is invalid.
        <p>
Reference&#32;&#35;9&#46;c9384317&#46;1556320429&#46;8ca752c4

        </BODY>
    </HTML>

Please send help, I think I've been staring at this so long I'm going to leave this physical world behind. Walmart relatively recently updated their authentication to OAuth and they've made vague passes at saying their old authentication will be deprecated and phased out, so I obviously want to try to get this to work.I tried to copy paste everything as best as possible. That XML is copy-pasted almost letter for letter from their example, with my own product switched in.

Also, the reference number down there always changes every time I run this, so it's not something I can actually look up. I've only supplied the Postman side of things because frankly if I can get that to work, my PHP will be fine, I've already knocked out some minor issues with the successful GET request.

If it's a semi-colon issue, I'll scream.

API Documentation: https://developer.walmart.com/#/apicenter/marketPlace/latest#updateInventoryForAnItem

Kitfoxpup
  • 265
  • 1
  • 2
  • 11
  • if "The difference here is ONLY that the link has query parameters", why do you use those parameters in your request? shouldn't your PUT url be without them? `https://marketplace.walmartapis.com/v3/inventory` – Flash Thunder Apr 26 '19 at 23:41
  • Oh shoot I may have worded that wrong- I meant that the only difference in my code is that, meaning I haven't changed anything else in the headers or authentication. The params are required; in this situation, the PUT requires a SKU be defined in the URL/Query Parameter. In Postman, it automatically puts that into the query, so I have no choice in that matter. Edit: For example, if I go into Postman's Params and edit the SKU value, it adds into the URL automatically so it becomes https://marketplace.walmartapis.com/v3/inventory?sku=0xyz0 – Kitfoxpup Apr 26 '19 at 23:45
  • really hard to help without a documentation of that api, the error basically says that you can't do that action on that url – Flash Thunder Apr 26 '19 at 23:51
  • Sure thing. https://developer.walmart.com/#/apicenter/marketPlace/latest#updateInventoryForAnItem – Kitfoxpup Apr 26 '19 at 23:54
  • seems that your url for `POST` should be `https://marketplace.walmartapis.com/v3/feeds` – Flash Thunder Apr 26 '19 at 23:55
  • yes, but as I mentioned Postman automatically turns the URL into `marketplace.walmartapis.com/v3/inventory?sku=0xyz0` as soon as I enter the required SKU parameter. It is required, otherwise the API won't know which item to update the quantity for, in this particular example. The ultimate hope is to hit POST, but in this situation, I'm trying to work up to it, since it's a little more complicated than this PUT. – Kitfoxpup Apr 26 '19 at 23:57
  • 1
    in fact it would know from XML file that contains `0xyz0`, do you have "CURLOPT_FOLLOWLOCATION" set in curl? – Flash Thunder Apr 27 '19 at 00:00
  • I gave it a whirl, but it still returned with a 400 error and the same HTML response. – Kitfoxpup Apr 27 '19 at 00:02
  • 1
    I guess I can't help you, but maybe will be easier when you would give some PHP code with curl request. The interesting fact is that it says that "http://No Host/v3/inventory/;" is invalid -> `no host` ... so maybe proxy server is doing something wrong with the request, like removing `host` header? or maybe You should add a `host:` header yourself, as it's not being added with `PUT` request by default by curl. It surely has nothing to do with your XML, as it would throw other error. Would suggest using curl in verbose mode and see what it's sending. – Flash Thunder Apr 27 '19 at 00:25
  • Postman actually is not using any PHP code. It's allowing me to have an environment to test my CURL- or actually, REST- without actually worrying about any programming. So right now, what you're seeing is exactly what I'm doing- just REST, no code. It'll wind up in PHP once this is all finished, but right now, all I'm doing is straight CURL into Postman. I'm also supplying a Host, as Walmart API requires one- specifically, `Host: https://marketplace.walmartapis.com`. I'm also not using a proxy, I disabled it. So that was my bad when I posted this originally, I've been a bit frustrated. – Kitfoxpup Apr 28 '19 at 01:46
  • 1
    there was one post on walmart developers forum about the same issue, but no solution... – Flash Thunder Apr 28 '19 at 08:13
  • Your comment on Host was initially what got me thinking, and another post about someone having the same error due to multiple "//" in their URL request kind of made me consider for a minute. I forgot to thank you, so thank you very much for working with me. I had the curse of working way too closely on it for too long. – Kitfoxpup Apr 29 '19 at 15:24

1 Answers1

0

Well, I've figured it out.

You'll notice I'm required to supply a "Host" with my headers. That host is replacing my URl that I'm trying to connect to via POST/PUT/GET, so if my Host is https://marketplace.walmartapis.com, then my request URL is https://https://marketplace.walmartapis.com.

Once I took the https:// out of the host, the entire thing granted me a 200 response. The times I got a correct GET response, I had actually copy-pasted the correct HOST without the HTTPS by pure chance, so I completely missed this between my two separate test cases.

Kitfoxpup
  • 265
  • 1
  • 2
  • 11