0

This error has plagued me for about a week now... I'm trying to create a shipment in Ebay but I'm getting a 500 error code in the response. Here is a link to the documentation https://developer.ebay.com/api-docs/sell/fulfillment/resources/order/shipping_fulfillment/methods/createShippingFulfillment

I'm running this code in the production environment:

  @header = {
    'Content-Type': 'application/json',
    'Authorization': "Bearer #{@token}"
  }

  uri = URI.parse("https://api.ebay.com/sell/fulfillment/v1/order/#{order.order_number}/shipping_fulfillment")

  # Create the HTTP objects
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  items = []
  order.items.each do |i|
    items << {"lineItemId": i[:id]}
  end
  params = {
    "lineItems": items,
    "shippedDate": Time.parse(date).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
    "shippingCarrierCode": "USPS",
    "trackingNumber": tracking_number
  }

  request = Net::HTTP::Post.new(uri.request_uri, @header)


  request.body = params.to_json
  response = http.request(request)
  puts response.code #prints 500

My Error:

{"errors": [{
"errorId": 2003,
"domain": "ACCESS",
"category": "APPLICATION",
"message": "Internal error",
"longMessage": "There was a problem with an eBay internal system or process. Contact eBay developer support for assistance",
"parameters": [{
    "name": "reason",
    "value": "Failed to transform underlying error response, see logs."
}]
}]}

I paid for the premium developer support and I've yet to receive a response. Any help would be greatly appreciated. I've tried submitting the same request with an empty body but that doesn't change the response. I have also tried changing the headers. If I add 'Accept': 'application/json', then I get a 500 error with an empty body. It doesn't make any sense.

UPDATE

From the suggestions in the comments, I have tried changing the params hash to:

params = {
    "lineItems": "[{\"lineItemId\":10025031700524,\"quantity\":1}]",
    "shippedDate": "2020-05-01T08:05:00.000Z",
    "shippingCarrierCode": "USPS",
    "trackingNumber": "9400111899562795104724"
  }

I have also tried running subsequent requests. I have also tried submitting the following JSON in the body:

request.body = {
    "lineItems": [
      {
        "lineItemId": "10025031700524",
        "quantity": "1"
      }
    ],
    "shippedDate": "2020-05-01T08:05:00.000Z",
    "shippingCarrierCode": "USPS",
    "trackingNumber": "9400111899562795104724"
  }.to_json

Each of these attempts produces the exact same error as before. I've tried changing the quantity to an integer & string as well.

UPDATE 2

Here are the contents of my request:

POST /sell/fulfillment/v1/order/24-04954-08727/shipping_fulfillment
content-type: application/json
authorization: Bearer v#i^1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
accept: */*
user-agent: Ruby
connection: close
host: api.ebay.com
content-length: 159
content-type: application/x-www-form-urlencoded
{"lineItems":[{"lineItemId":"10025031700524"}],"shippedDate":"2020-05- 01T08:05:00.000Z","shippingCarrierCode":"USPS","trackingNumber":"9400111899562795104724"}
Cannon Moyer
  • 3,014
  • 3
  • 31
  • 75
  • @Canon they have this strange note in their documentation for this end point: `Note: In some cases, this call may succeed if you issue it once more after receiving this error.` did you pay attention to it ? try their advice as a debugging step – Abdullah Fadhel May 09 '20 at 09:46
  • try adding `"quantity" : 1` to your line item object and see what will be the response, since as I can see they did not make it clear if it is optional or not. – Abdullah Fadhel May 09 '20 at 09:48
  • I took this from their docs: `[{ "lineItemId": 6254458011, "quantity": 1 }]` and then converted it `to_json`, then got: `"[{\"lineItemId\":6254458011,\"quantity\":1}]"` which sends `lineItemId` as an integer not string. – Abdullah Fadhel May 09 '20 at 09:56
  • try doing: `items << {"lineItemId": i[:id].to_s}` and see if will work – Abdullah Fadhel May 09 '20 at 09:58
  • if you have a test version end point of it try making a request with hard coding their example in the docs: `{ "lineItems": [ { "lineItemId": "6254458011", "quantity": 1 } ], "shippedDate": "2016-07-20T00:00:00.000Z", "shippingCarrierCode": "USPS", "trackingNumber": "1Z50992656936"}` as it is. and see what will you get. – Abdullah Fadhel May 09 '20 at 10:00
  • @AbdullahFadhel I have updated the question. Thanks – Cannon Moyer May 11 '20 at 20:59
  • `request.body = { "lineItems": [ { "lineItemId": 10025031700524,# try this by removing the quotes "quantity": "1" } ], "shippedDate": "2020-05-01T08:05:00.000Z", "shippingCarrierCode": "USPS", "trackingNumber": "9400111899562795104724" }.to_json` – Abdullah Fadhel May 12 '20 at 05:27
  • try submitting the body above without double quotes on `lineItemId` – Abdullah Fadhel May 12 '20 at 05:28
  • @AbdullahFadhel I tried it but still getting the same error. – Cannon Moyer May 12 '20 at 05:31
  • Could you share the output of the following: `puts("#{request.method} #{request.path}");request.to_hash.each{|header,values|puts("#{header}: #{values.join(', ')}")};puts;puts(request.body)`? Of course **mocking your token**. This might give us a better view on what you're actually sending to the Ebay server. – 3limin4t0r May 12 '20 at 16:43
  • 1
    Using Net::HTTP directly is always a huge pain in the ass because it's easy to shoot yourself in the foot. I recommend retrying with a higher level library like https://github.com/jnunemaker/httparty. Here's an example of making this type of request with HTTParty: https://stackoverflow.com/q/7455744/3784008 – anothermh May 14 '20 at 20:19
  • Do you have the correct OAuth scope(s) for your application? – TygerTy May 18 '20 at 11:42
  • @3limin4t0r Please see my updated question. Thanks – Cannon Moyer May 18 '20 at 21:22
  • @TygerTy I do. When I first started developing with the Ebay API I incorrectly set the scope and I got an auth error due to that and I haven't gotten that since I updated the scope which includes the shipping fulfillment. – Cannon Moyer May 18 '20 at 21:24
  • 1
    @anothermh httparty worked. I passed all the same headers and body parameters as I did with net/http. Just seems strange. – Cannon Moyer May 18 '20 at 21:46
  • Glad to hear it. Net::HTTP is finicky. Always better to use the higher level tools to ensure your options are properly passed to Net::HTTP or other underlying library. – anothermh May 18 '20 at 22:48
  • You have `content-type` in the request twice, probably once as symbol and once as string. Headers should be supplied as string, not as symbols. Could you try update your `@header` to `{ 'Content-Type' => 'application/json', 'Authorization' => "Bearer #{@token}" }` (Notice the change of `:` into `=>`). Could you check the resulting headers with `request.to_hash`? Is `content-type` still present twice after making the change? – 3limin4t0r May 19 '20 at 09:07
  • @3limin4t0r That worked! You're amazing! I thought there was no difference between the `:` syntax and the `=>`. I thought it was an update of the same syntax back in like Ruby 2.3. – Cannon Moyer May 19 '20 at 13:25
  • @CannonMoyer I've added it as an answer with explanation. – 3limin4t0r May 19 '20 at 14:21

1 Answers1

1

In the request content:

POST /sell/fulfillment/v1/order/24-04954-08727/shipping_fulfillment
content-type: application/json
authorization: Bearer v#i^1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
accept: */*
user-agent: Ruby
connection: close
host: api.ebay.com
content-length: 159
content-type: application/x-www-form-urlencoded
{"lineItems":[{"lineItemId":"10025031700524"}],"shippedDate":"2020-05- 01T08:05:00.000Z","shippingCarrierCode":"USPS","trackingNumber":"9400111899562795104724"}

It occurred to me that content-type is present twice.

After running some samples in irb it seems that the net/http library works with strings, not with symbols. By having a : in your @header definition the keys are interpreted as symbols.

To quote the Ruby documentation:

Hashes

A hash is created using key-value pairs between { and }:

{ "a" => 1, "b" => 2 }

Both the key and value may be any object.

You can create a hash using symbol keys with the following syntax:

{ a: 1, b: 2 }

This same syntax is used for keyword arguments for a method.

Like Symbol literals, you can quote symbol keys.

{ "a 1": 1, "b #{1 + 1}": 2 }

is equal to

{ :"a 1" => 1, :"b 2" => 2 }

See Hash for the methods you may use with a hash.

To use string keys use => instead of :.

For you that means changing:

@header = {
  'Content-Type': 'application/json',
  'Authorization': "Bearer #{@token}"
}

Into:

@header = {
  'Content-Type' => 'application/json',
  'Authorization' => "Bearer #{@token}"
}
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52