GithubHelp home page GithubHelp logo

hendt / ebay-api Goto Github PK

View Code? Open in Web Editor NEW
138.0 7.0 35.0 5.73 MB

eBay Node API in TypeScript for Node and Browser with RESTful and Traditional APIs. This library aims to implement all available eBay apis.

Home Page: https://hendt.gitbook.io/ebay-api

License: MIT License

TypeScript 99.50% HTML 0.26% JavaScript 0.23%
ebay-api ebay-sdk ebay-sell-api ebay-browse-api ebay-search ebay-trading-api typescript-library

ebay-api's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ebay-api's Issues

Not able to create proxy server

Please Can anyone help me to create the proxy server for the request? I installed @hendt/ebay-api server and put the worker file in the proxy folder.
image

How to you call getFulfillmentPolicy?

I need to use the getFulfillmentPolicy call and tried to use hendt / ebay-api to do it.

Here is the code I am trying to use but it is failing:

exports.getFulfillmentPolicy = async ( req, res ) => {
  console.log( `Made it to getFulfillmentPolicy!  Here's req.body...`, req.body )
  let user = req.body.user
  let fulfillmentPolicyId = req.body.fulfillmentPolicyId
  try {
    let _user = await User.findById({_id: user})
    console.log(`_user.token...`, _user.token)
    eBay.auth.oAuth2.setCredentials(_user.token[0])
    let result = await eBay.sell.getFulfillmentPolicy({ fulfillmentPolicyId })
    console.log( `result...`, result )
    res.json( result )
  } catch ( e ) { console.log( `Got an error in getFulfillmentPolicy...`, e ); res.json( { error: e } ) }
}

Error Response...

TypeError: eBay.sell.getFulfillmentPolicy is not a function

Can you please share how to properly make this call?

Set grant type

Can you set grant type. I would like to set it to client_credentials

Getting strange XML Errors When Listing

Hi, I'm getting XML Parse errors but cannot find where it's coming from.

Error

{
  meta: {
    ShortMessage: 'XML Parse error.',
    LongMessage: 'XML Error Text: "; nested exception is: \n' +
      '\torg.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the 
entity reference.".',
    ErrorCode: 5,
    SeverityCode: 'Error',
    ErrorParameters: {
      Value: '; nested exception is: \n' +
        '\torg.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference.'
    },
    ErrorClassification: 'RequestError'
  }
}

My description is as follows:

    Description: {
      __cdata: '<div>Now you can enjoy the authentic taste of wood-fired pizza made from scratch in your own 
home. This clay oven is sure to be a hit with friends and family and will add hours of enjoyment to parties. 
Showcase your skills cooking the perfect pie as you teach others the art of baking in a wood-fired oven. Ideal for large family style pies, individual pizzas and breads. You will need to purchase white sand (sold separately) for an insulating layer underneath the pizza stones inside the oven. Includes: clay oven, pizza stone, ember rake and stand Wide mouth for easy placement and retrieval of pizzas We recommend using hardwoods like oak, beech or birch that have been kiln dried, fruit woods can be used for flavor, but avoid sappy soft woods Cover, pizza peels and sand for insulation sold separately For outdoor use only with wood, not for use with charcoal, do not use chemical fire starters Be sure to allow for oven to cool completely before covering.</div>'
    }

I can't see where the issue is.

Can you help?

Having Trouble Listing Images

Hi, I successfully listed some items using your library but can't seem to get the pictures to list.

My images are being sent this way:

    PictureDetails: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ],

Each of the "Object" items looks like this:
'https://imageurl.....'

So that the array appears like this:

pictureURLs: [
   'https://imageurl.....jpeg',
   'https://imageurl.....jpeg',
   'https://imageurl.....jpeg',
   'https://imageurl.....jpeg'
 ]

What is the correct way to send pictures to ebay when I list items though your library?

Help with authorization

Hi, I'm having problems with permissions and suspect I'm doing something stupid. I don't fully understand the eBay auth tokens.

This is what I'm using:

const eBay = new eBayApi({
    appId: "######################",
    certId: "######################",
    sandbox: true,

    scope: ["https://api.ebay.com/oauth/api_scope"],

    // optional parameters, should be omitted if not used
    siteId: eBayApi.SiteId.EBAY_UK, // required for traditional APIs, see https://developer.ebay.com/DevZone/merchandising/docs/Concepts/SiteIDToGlobalID.html
    devId: "######################", // required for traditional trading API
    //ruName: "######################", // required for authorization code grant
    //authToken: "", // can be set to use traditional API without code grant
  });

  eBay.sell.fulfillment
    .getOrders()
    .then((orders) => {
      console.log(JSON.stringify(orders, null, 2));
    })
    .catch((e) => {
      console.log(e);
    });

I'm currently getting the 'Insufficient permissions to fulfill the request.' error.

I can successfully get an Auth Token from using ebay-oauth-nodejs-client

const EbayAuthToken = require("ebay-oauth-nodejs-client");
  const ebayAuthToken = new EbayAuthToken({
    filePath: path.join(configDirectory, "eBayJson.json"),
    // input file path.
  });

  (async () => {
    const token = await ebayAuthToken.getApplicationToken("SANDBOX");
    console.log(token);
  })();

Can I use this token in your API call?

Thanks in advance for the help!

Obtaining eBay OAuth access code after user clicks

So, I am trying to obtain the eBay OAuth access_token (created when a user authorizes my app) back into my React app from the result of it being sent from ebay to an endpoint I created /api/ebayaccepted and have gotten stuck because I don't know how to get that back to my app once the access_token comes through.

I have created a page in React with a button meant to display an eBay OAuth link after user clicks.

If successful, eBay grants the access_token and sends it to my express endpoint /api/ebayaccepted.

However, I am doing all this testing from my local machine, namely localhost:3000 (frontend) and localhost:8000 (express backend). So, to bypass the https requirement by ebay (I am using http://localhost:8000 which is a no-no for the eBay redirect url), I am using ngrok to produce links that look like https://8e37hhnc176c.ngrok.io/ which go in the ebay RuName settings.

All is well and good until I have to obtain the access_token because by clicking the link created by clicking that initial button, it opens a new page that I cannot access the localstorage or cookie for. I am at a loss as to how to get this back to my redux React frontend app. I thought about having it write this token to a temp file on the server but I don't like that potential security risk.

How can I return the access_code returned from eBay to my app?

Attempts:

Tried res.cookie by returning a view page which ultimately showed me that wouldn't work because it's a new tab that opens and even tho you could put a cookie in, it just cannot be seen by my app :(
Tried res.send() with res.cookie but that STILL produces another unrelated tab

Access denied: Insufficient permissions to fulfill the request

Hello,

I've written this simple script:

const _fulfillment = eBay.factory.createSellApi().fulfillment;
_fulfillment.getOrders().then(item => {
  console.log(JSON.stringify(item, null, 2));
}).catch(e => {
  console.error(JSON.stringify(e));
});

And am getting this error:

EBayAccessDenied: Access denied: Insufficient permissions to fulfill the request.
    at EBayAccessDenied.EBayError [as constructor] 

Can you help me diagnose what's wrong with the permissions? Is that on the @hendt/ebay-api library side or my eBay sandbox configuration?

Unable to perform getOrders / Error - Insufficient permissions to fulfill the request

Hi I am having no success with the getOrders call.

Here's the auth scopes I'm using when setting the ORIGINAL User access token...:

      eBay.auth.oAuth2.setScope([
        'https://api.ebay.com/oauth/api_scope',
        'https://api.ebay.com/oauth/api_scope/sell.marketing.readonly',
        'https://api.ebay.com/oauth/api_scope/sell.marketing',
        'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
        'https://api.ebay.com/oauth/api_scope/sell.inventory',
        'https://api.ebay.com/oauth/api_scope/sell.account',
        'https://api.ebay.com/oauth/api_scope/sell.account.readonly',
        'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
        'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
        'https://api.ebay.com/oauth/api_scope/sell.analytics.readonly',
        'https://api.ebay.com/oauth/api_scope/sell.finances',
        'https://api.ebay.com/oauth/api_scope/sell.payment.dispute',
        'https://api.ebay.com/oauth/api_scope/commerce.identity.readonly',
    ]);

Here's my code (ExpressJS backend controller method...):

exports.getOrders = async (req, res) => { 
  let  _id = req.params.userId; // user's _id
  let token = await refreshEbayToken(_id, eBay)
  console.log(`token...`, token) // not an array!  It's an object!

  // set OAuth2 eBay credentials
  eBay.auth.oAuth2.setCredentials(token.access_token);

  try {
    let result = await eBay.sell.fulfillment.getOrders({
      filter: 'orderfulfillmentstatus:{NOT_STARTED|IN_PROGRESS}',
        limit: 5
    })
    console.log(`Got a result...`, result)
    res.json(result)
  } catch (e) {
    console.log(`Got an error in getOrders...`, e)
    res.status(400).json( { error: e } )
  }
  
}

Here's the error I get:

{
        "meta": {
            "errors": [
                {
                    "errorId": 1100,
                    "domain": "ACCESS",
                    "category": "REQUEST",
                    "message": "Access denied",
                    "longMessage": "Insufficient permissions to fulfill the request."
                }
            ]
        },
        "name": "EBayAccessDenied"
    }

Even freshly minted User access tokens through those scopes get this error.

According to the ebay docs on getOrders, these are the required auth scopes for this call:

https://api.ebay.com/oauth/api_scope/sell.fulfillment
https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly

Upon further investigation, I found I am certainly using those scopes in the response (below is a snippet of the scopes grabbed from the larger ebay error)...

...%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.analytics.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.finances%20...

As shown above, I am clearly using the sell.fulfillment and sell.fulfillment.readonly scopes so I do not understand what is the issue.

How are you making your getOrders calls successfully?

UPDATE: I successfully made a getOrders call but did it using fetch (tho I rather use hendt/ebay-api) but here's the code which actually works for me now (until we could solve this)...

exports.getOrders2 = async (req, res) => { 
  let  _id = req.params.userId; // user's _id
  let token = await refreshEbayToken(_id, eBay)
  if(Array.isArray(token) === true) {
    console.log(`Converting token from array to object...`)
    token = token[0]
  }
  console.log(`token...`, token) // not an array!  It's an object!

  try {
    let result = await fetch(`https://api.ebay.com/sell/fulfillment/v1/order`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Bearer ${token.access_token}`
      },
    })
    result = await result.json()
    console.log(`Got a result...`, result)
    // res.json(result)
  } catch (e) {
    console.log(`Got an error in getOrders...`, e)
    res.status(400).json( { error: e } )
  }
  
}

Getting this output from that...

{
    "href": "https://api.ebay.com/sell/fulfillment/v1/order?limit=50&offset=0",
    "total": 0,
    "limit": 50,
    "offset": 0,
    "orders": []
}

Finding Api attributes

how to pass attributes ? I was trying to pass something like this

    ```
    await eBay.finding.findItemsByProduct(
                {
                  productId: {
                    "_text": 53039031,
                    "_type": 'ReferenceID',
                  },
                },
                {
                  parseOptions: {
                    attributeNamePrefix: '_',
                    textNodeName: '_text',
                    ignoreAttributes: false,
                    parseNodeValue: true,
                    parseAttributeValue: false,
                  },
                })

but it fails with the error ProductID not found.

How do you properly call getPrivileges? Got error: TypeError: eBay.sell.getPrivileges is not a function

Hi,

I want to know the seller limits for an account so I tried to call getPrivileges but got this error:
Got error: TypeError: eBay.sell.getPrivileges is not a function

My code:

exports.getSellerLimits = async (req, res) => {  
  let {        
    ebayAuthToken,
    } = req.body


    eBay.auth.oAuth2.setScope([
      'https://api.ebay.com/oauth/api_scope',
      'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
      'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
      'https://api.ebay.com/oauth/api_scope/sell.account',
      'https://api.ebay.com/oauth/api_scope/sell.account.readonly'
  ]);
    
    eBay.auth.oAuth2.setCredentials(ebayAuthToken);
  
    try {
    let result = await eBay.sell.getPrivileges()

    console.log('result...')
    console.log(result)
    res.json(result)

    }
    catch(e) {
      console.log(`Got error: `, e)
      res.json({error: e})
    }
    

}

How do you make this call?

specifying url params in fulfilment.getorders

How do I specify multiple url params?

Like this example, using filter and limit in getOrders()

function getOrders(orderId) {
    if (orderId) {
      return eBay.sell.fulfillment.getOrder(orderId);
    } else {
      return eBay.sell.fulfillment.getOrders(
        "?filter=orderfulfillmentstatus:{NOT_STARTED|IN_PROGRESS}?limit=5"
      );
    }
  }

thanks!!!

Request header field authorization is not allowed by Access-Control-Allow-Headers AND Accept-Encoding error

Hi,

im triyng to connect to the AOI but I get alwasy this issue:

Access to XMLHttpRequest at 'https://api.sandbox.ebay.com/identity/v1/oauth2/token' from origin 'http://localhost:8100' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

Here is my code:

const eBayApi = require('@hendt/ebay-api')

const eBay = new eBayApi({
  appId: 'xxxxxxxxx',
  certId: 'xxxxxxxxx',
  devId: 'xxxxxxxx',
  sandbox: true,
  siteId: eBayApi.SiteId.EBAY_DE,
  marketplaceId:  eBayApi.MarketplaceId.EBAY_DE,
  acceptLanguage: eBayApi.Locale.en_DE, 
  contentLanguage: eBayApi.ContentLanguage.en_DE, 
});

const item = await eBay.buy.browse.getItem('v1|254188828753|0');
console.log(JSON.stringify(item, null, 2));

image

How I can solve this problem?

ebay post-order api all operations return 401, any ideas?

I'm getting 401 for all postOrder.case.search(), postOrder.inquier.search() and postOrder.return.search()

Any ideas? Thanks

const api = new EbayApi({
  appId: channel.credential.appId,
  devId: channel.credential.devId,
  certId: channel.credential.certId,
  sandbox: false,
  siteId: EbayApi.SiteId.EBAY_US,
});

const returns = await channel.api.postOrder.return.search({});
console.dir(returns, { depth: Infinity });

How do you properly call refreshToken() to obtain a new token?

Hi, I am receiving undefined for the result of the token after calling refreshToken. How do you make the refresh call correctly?

Please see my code below. This is a controller method of Express and I am using mongoose and there is a User model in there.

exports.getItem = async (req, res) => {

  let { ebayItemId, user } = req.body // user is _id
  let result, token
  
  let { access_token } = await User.findById({_id: user}) // retrieve user and refresh tokens
  console.log(`access_token: `, access_token)

  eBay.auth.oAuth2.setCredentials(access_token);   // Get access token and pass it to this method

  try{ // make the call (which is expected to fail in order to activate the refresh token...)
    result = await eBay.browse.getItem(`v1|${ebayItemId}|0`)
  } catch (e) {
    console.log(`What's the problem #1...`, e)
  }
  
  try { // trying to get the refresh token
    token = await eBay.auth.oAuth2.refreshToken()
    token = await token.json()
    console.log(`New refreshed token? Check this: `, token)
  } catch (e) { // left out the error because it's enormous and contains the full request...
    console.log(`Token got a problem...`)
  }
  
  try {
    eBay.auth.oAuth2.setCredentials(token);
    result = await eBay.browse.getItem(`v1|${ebayItemId}|0`)
    result = await result.json()

  } catch (e) {
    console.log(`What's the problem #3...`, e)
  }

  console.log(`Final result: `, result)
  res.json(result)
}

The output I get is this...

What's the problem #1... TypeError: Cannot read property 'getItem' of undefined
    at exports.getItem (C:\Users\User\project_root\controllers\ebay.js:470:34)
    at process._tickCallback (internal/process/next_tick.js:68:7)
What's the problem #2
What's the problem #3... TypeError: Cannot read property 'getItem' of undefined
    at exports.getItem (C:\Users\User\project_root\controllers\ebay.js:490:34)
    at process._tickCallback (internal/process/next_tick.js:68:7)
Final result:  undefined

What is the correct way to obtain a new token from calling refreshToken?

I had saved both the access_token and refresh_token in the database from the initial authorization.

Days later, I wanted to test if this code worked as I knew it would be a hard expired access_token.

Add enums

Many types are enums, defined by eBay. These enums should be added so that types can be restricted to these enums, instead of strings.

For example, the type CategoryType, which is currently:

export type CategoryType = {
    default?: boolean
    name: string
}

Would become:

export type CategoryType = {
    default?: boolean
    name: CategoryTypeEnum
}

The enum CategoryTypeEnum could be defined as:

export enum CategoryTypeEnum {
    MOTORS_VEHICLES = 'MOTORS_VEHICLES',
    ALL_EXCLUDING_MOTORS_VEHICLES = 'ALL_EXCLUDING_MOTORS_VEHICLES'

Or, to use TypeScript case conventions:

export enum CategoryTypeEnum {
    MotorsVehicles = 'MOTORS_VEHICLES',
    AllExcludingMotorsVehicles = 'ALL_EXCLUDING_MOTORS_VEHICLES'
}

This will improve type safety in the library.

Listing success responds with error

Got a weird one which I suspect is more on Ebay's side, but as of today, when I use trading.ReviseFixedPriceItem on a managed payment account, the listing is correctly listed, but instead of returning the listing, it returns the standard ebay error response, with a warning "This selling account is enabled for payments managed by eBay. PayPal is not currently accepted as a payment method and has been removed from the listing."

Is there a way to control DetailLevel in the getItem call?

I need a reliable way to get the quantity sold for any valid ebay item. I used your library and specifically the getItem call. It worked except I noticed it was missing Item.SellingStatus.QuantitySold in the responses. How can I use hendt / ebay-api to get this value?

I was thinking maybe the call is not passing in DetailLevel and that's the reason it's not in the response. Could this be the case and if so, is there a way to pass in the DetailLevel parameter as "ReturnAll"

findCompletedItems returns undefined

Hello, I observed findCompletedItems work once and then after I constantly get undefined.

Here is my code:

// set OAuth2 eBay credentials
eBay.auth.oAuth2.setCredentials(ebayAuthToken);

let post = {
  RequesterCredentials: {
    eBayAuthToken: ebayAuthToken
  },
  categoryId: categoryId,
  itemFilter: {
    name: `SoldItemsOnly`,
    value: true
  }
}

try {
let result = await eBay.finding.findCompletedItems(post)

console.log('result...')
console.log(result)
res.json(result)
} 

catch(e) {
  console.log(`Got error: `, e)
  res.json({error: e})
}

Is there any issue you can see with the code or is there an issue with this call?

Restrict/Update Typescript Types

Saw that in several instances, any is used when I believe the type should be known.

For example:
/src/api/resetful/index.ts

    private async doRequest(
        method: keyof ILimitedRequest,
        url: string,
        config: any,
        data?: any
    ): Promise<any> {
        ...
    }

Could be restricted to:

    private async doRequest(
        method: keyof ILimitedRequest,
        url: string,
        config: AxiosRequestConfig,
        data?: {[key: string]: any}
    ): Promise<any> {
        ...
    }

Which would limit the parameters being passed in and make the program that much safer.

If this makes sense and you agree, I could take a whack at it this weekend.

The warning reply from UploadSiteHostedPictures is treated as an outright error.

According to the image guidelines on eBay:

If your image is less than 1,000 pixels (width + height in pixels), a warning is provided but the picture is not rejected.

However, in your handleEBayJsonResponse function, you're not checking the Ack property of the response, only checking that the Errors property is not null. Since the warning message from eBay comes in the Errors property, your code detects that and then throws your own EbayApiError, so the original response never gets through and I do not get a chance to see the still valid SiteHostedPictureDetails response:

Screen Shot 2021-10-11 at 3 18 48 PM

Is there any way to get those warnings handled as warnings and allowing those responses through, instead of handling them as outright errors and throwing EbayApiErrors?

Error [EbayApiError]: IAF token supplied is invalid. / 'invalid_grant' / 'the provided authorization refresh token is invalid or was issued to another client'

Hi, I have been successfully listing items to ebay on behalf of members of my site.

A problem has been happening for the past several days when it comes time to reprice/end their listings (on their behalf) and I attempt to relist items. I am receiving this error:

Got error:  Error [EbayApiError]: IAF token supplied is invalid.
    at EbayApiError.EBayError [as constructor] (/root/myserver/node_modules/@hendt/ebay-api/lib/errors/index.js:26:47)
    at new EbayApiError (/root/myserver/node_modules/@hendt/ebay-api/lib/errors/index.js:101:24)
    at XMLRequest.handleEBayJsonError (/root/myserver/node_modules/@hendt/ebay-api/lib/api/traditional/XMLRequest.js:270:19)
    at XMLRequest.<anonymous> (/root/myserver/node_modules/@hendt/ebay-api/lib/api/traditional/XMLRequest.js:247:30)
    at step (/root/myserver/node_modules/@hendt/ebay-api/lib/api/traditional/XMLRequest.js:63:23)
    at Object.next (/root/myserver/node_modules/@hendt/ebay-api/lib/api/traditional/XMLRequest.js:44:53)
    at fulfilled (/root/myserver/node_modules/@hendt/ebay-api/lib/api/traditional/XMLRequest.js:35:58)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  meta: {
    ShortMessage: 'Invalid IAF token.',
    LongMessage: 'IAF token supplied is invalid.',
    ErrorCode: 21916984,
    SeverityCode: 'Error',
    ErrorClassification: 'RequestError'
  }
}

What could be the cause of this error?

I believe I am correctly generating User access tokens because they do succeed in listing the items initially.

However, the next day comes and my system tries to revise their listings (change price or end listing) and it throws the error that the IAF token supplied is invalid.

Here is my code that attempts to refresh the token below. Is it that I am generating the WRONG token every time??

exports.refreshEbayToken = async (user, eBay) => {  
    console.log(`Made it to refreshEbayToken with user...${user}`)
    let token
    let minutes
    // first check the age of the prior token

    try {
        let userData = await User.findById( {_id: user} ) // gets the user doc
        let { token_last_refresh } = userData // gets the last time the token was refreshed
        token = userData.token // assigns token from user doc to token variable
        let startDate = Date.parse(token_last_refresh) // gets last refreshed date/time
        let endDate = new Date() // creates new time as a reference point
        endDate = Date.parse(endDate) // makes it readable for next step
        let seconds = (endDate - startDate) / 1000; // get seconds
        minutes = seconds / 60; // get minutes
        console.log(`minutes since ebay token last refresh: `, minutes)
    } catch(e) { console.log(e) }
  
    if(minutes > 115) { // if 2 hours has not yet passed from minting a new one...
        try{
            token = await eBay.oAuth2.refreshClientToken() // gets the brand new application access token
            console.log(`Got the refresh token...`)
            try { // try to update the user doc with new token
                let userData = await User.findByIdAndUpdate(
                    {_id: user},
                    {$set: {
                        token: [token],
                        access_token: token.access_token,
                        token_last_refresh: Date.now()
                    }}
                    )
                token = userData.token // double confirm it's the right token by returning the overwritten doc token
                return token // send back token
            } catch(e) { console.log(e) }
        
          } catch(e) { console.log(e); return e }

    } else { // less than 2 hours since minting access token, return current token
        console.log(`Less than 2 hours since minting access token, sending current token instead...`)
        return token // send back token
    }
  }

Also, after noticing this page in your code, I switched my code from refreshClientToken to refreshToken but still I got that IAF error...

token = await eBay.oAuth2.refreshToken()

Please help me. I need to be able to reliably call ReviseFixedPriceItem as I am getting more members but everything is stopped due to this error.

Update: After refactoring my code again (thinking surely this time it will work) I got the following error (sorry it's the full error):

Error: Request failed with status code 400
    at createError (/root/project_directory/backend/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/root/project_directory/backend/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/root/project_directory/backend/node_modules/axios/lib/adapters/http.js:260:11)
    at IncomingMessage.emit (events.js:326:22)
    at IncomingMessage.EventEmitter.emit (domain.js:483:12)
    at endReadableNT (_stream_readable.js:1241:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  config: {
    url: 'https://api.ebay.com/identity/v1/oauth2/token',
    method: 'post',
    data: 'grant_type=refresh_token&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory',
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/x-www-form-urlencoded',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': 'X-Requested-With, Origin, Content-Type, X-Auth-Token',
      'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE',
      'User-Agent': 'axios/0.21.1',
      'Content-Length': 500
    },
    auth: {
      username: '<removed>',
      password: '<removed>'
    },
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus]
  },
  request: ClientRequest {
    _events: [Object: null prototype] {
      socket: [Function],
      abort: [Function],
      aborted: [Function],
      connect: [Function],
      error: [Function],
      timeout: [Function],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: null,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.ebay.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.ebay.com',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(asyncId)]: 16460,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    connection: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.ebay.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.ebay.com',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(asyncId)]: 16460,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /identity/v1/oauth2/token HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/x-www-form-urlencoded\r\n' +
      'Access-Control-Allow-Origin: *\r\n' +
      'Access-Control-Allow-Headers: X-Requested-With, Origin, Content-Type, X-Auth-Token\r\n' +
      'Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n' +
      'User-Agent: axios/0.21.1\r\n' +
      'Content-Length: 500\r\n' +
      'Host: api.ebay.com\r\n' +
      'Authorization: Basic <removed>==\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      scheduling: 'fifo',
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    insecureHTTPParser: undefined,
    path: '/identity/v1/oauth2/token',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      readable: false,
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [TLSSocket],
      connection: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 400,
      statusMessage: 'Bad Request',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular],
      responseUrl: 'https://<removed>:<removed>@api.ebay.com/identity/v1/oauth2/token',
      redirects: [],
      [Symbol(kCapture)]: false
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'api.ebay.com',
    protocol: 'https:',
    _redirectable: Writable {
      _writableState: [WritableState],
      writable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 500,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function],
      _currentRequest: [Circular],
      _currentUrl: 'https://<removed>:<removed>@api.ebay.com/identity/v1/oauth2/token',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'access-control-allow-origin': [Array],
      'access-control-allow-headers': [Array],
      'access-control-allow-methods': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      host: [Array],
      authorization: [Array]
    }
  },
  response: {
    status: 400,
    statusText: 'Bad Request',
    headers: {
      rlogid: '<removed>',
      'x-ebay-c-version': '1.0.0',
      'x-ebay-client-tls-version': 'TLSv1.3',
      'x-frame-options': 'SAMEORIGIN',
      'x-content-type-options': 'nosniff',
      'x-xss-protection': '1; mode=block',
      'set-cookie': [Array],
      'content-type': 'application/json',
      'content-length': '131',
      date: 'Mon, 07 Jun 2021 23:45:59 GMT',
      server: 'ebay-proxy-server',
      'x-envoy-upstream-service-time': '38',
      'x-ebay-pop-id': 'UFES2-RNOAZ03-api',
      connection: 'close'
    },
    config: {
      url: 'https://api.ebay.com/identity/v1/oauth2/token',
      method: 'post',
      data: 'grant_type=refresh_token&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory',
      headers: [Object],
      auth: [Object],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      adapter: [Function: httpAdapter],
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      validateStatus: [Function: validateStatus]
    },
    request: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [TLSSocket],
      connection: [TLSSocket],
      _header: 'POST /identity/v1/oauth2/token HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/x-www-form-urlencoded\r\n' +
        'Access-Control-Allow-Origin: *\r\n' +
        'Access-Control-Allow-Headers: X-Requested-With, Origin, Content-Type, X-Auth-Token\r\n' +
        'Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n' +
        'User-Agent: axios/0.21.1\r\n' +
        'Content-Length: 500\r\n' +
        'Host: api.ebay.com\r\n' +
        'Authorization: Basic <removed>==\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      insecureHTTPParser: undefined,
      path: '/identity/v1/oauth2/token',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'api.ebay.com',
      protocol: 'https:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    data: {
      error: 'invalid_grant',
      error_description: 'the provided authorization refresh token is invalid or was issued to another client'
    }
  },
  isAxiosError: true,
  toJSON: [Function: toJSON]
}


API translates my listings into German

new eBayApi({
	appId: config.eBay.clientID,
	certId: config.eBay.clientSecret,
	sandbox: false,
	siteId: eBayApi.SiteId.EBAY_GB,
	scope: [
		"https://api.ebay.com/oauth/api_scope",
	],
	acceptLanguage: "en-GB",
	contentLanguage: ContentLanguage.en_GB,
});

this.ebay.oAuth2.getClientAccessToken()`

This is how I initialize the API wrapper. Later I call

let item = await this.ebay.buy.browse.getItemByLegacyId({
	legacy_item_id: itemID,
});

This query works, but the title of the listing is translated into German from English.
For example. the title Samsung SMT-C7100/C7101 500GB Boxed with Remote Control NEW becomes Samsung smt-c7100/c7101 500gb boxed mit Fernbedienung NEU but the description remains in English. Also, some details such as condition are also translated into German, such as condition, neu. The price is also converted into Euros.

Help with this would be appreciated.

No documentation for refreshing tokens

From looking at the code, it appears to automatically refresh the token if a request is made with an expired token. However, I want to sometimes refresh the token myself (and store the token in a database), to avoid extra (wasted) API calls with an expired token.

I see there are refreshToken, refreshClientToken, and refreshAuthToken methods exposed in oAuth2, but no documentation on how to use them. I want to know how to retrieve the refreshed token that refreshAuthToken is presumably getting from eBay.

Re-authorizing

Thanks so much for this work - it is excellent. When I am developing with your ebay-api (using it in a docker container) I find myself having to re-authorise at eBay (eBay.OAuth2.generateAuthUrl()) every time I take the container down. I could persist the tokens so I can reuse them without going back to eBay. I get an access token (eBay.OAuth2.getToken) when I get this token I could persist it and re-use it I think.
My question is can I persist a token (I am usually rerunning the docker container within 30 minutes)? What token would I persist and what method in your api would I call with this token to maintain/re-establish the connection? Thanks again its the flow that is confusing me.
Gary

Complex aspect filters with spaces don't work

example:

will return correctly filtered items

 this.api.buy.browse.search({
        q: searchTerm,
        category_ids: "15709",
        sort: "price",
        aspect_filter: "categoryId:15709,Color:{Red}",
        limit: limit,
        offset: offset || 0,
      });

will return items but will totally ignore aspect_filter

 this.api.buy.browse.search({
        q: searchTerm,
        category_ids: "15709",
        sort: "price",
        aspect_filter: "categoryId:15709,US Shoe Size(Men's):{7}",
        limit: limit,
        offset: offset || 0,
      });

also tried encoding the aspect filter string before calling search, but the same issue

Getting error details

When using the bulk create offer endpoint, e.g.:

try {
	return await this.ebay.sell.inventory.bulkCreateOffer({ requests });
} catch (e) {
	console.log(e);
}

I get this from the console:

EBayError: Request failed with status code 400
    at new EBayError ([REPO]\node_modules\@hendt\ebay-api\src\errors\index.ts:17:5)
    at Object.exports.handleEBayError ([REPO]\node_modules\@hendt\ebay-api\src\errors\index.ts:179:2)
    at Inventory.<anonymous> ([REPO]\node_modules\@hendt\ebay-api\src\api\restful\index.ts:204:7)
    at step ([REPO]\node_modules\@hendt\ebay-api\lib\api\restful\index.js:57:23)
    at Object.throw ([REPO]\node_modules\@hendt\ebay-api\lib\api\restful\index.js:38:53)
    at rejected ([REPO]\node_modules\@hendt\ebay-api\lib\api\restful\index.js:30:65)
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  meta: {
    res: { status: 400, statusText: 'Bad Request', headers: [Object] },
    req: {
      url: 'https://api.ebay.com/sell/inventory/v1/bulk_create_offer',
      method: 'post',
      headers: [Object],
      params: undefined
    },
    [Symbol(raw-error)]: Error: Request failed with status code 400
        at createError ([REPO]\node_modules\axios\lib\core\createError.js:16:15)
        at settle ([REPO]\node_modules\axios\lib\core\settle.js:17:12)
        at Unzip.handleStreamEnd ([REPO]\node_modules\axios\lib\adapters\http.js:260:11)
        at Unzip.emit (events.js:376:20)
        at endReadableNT (internal/streams/readable.js:1336:12)
        at processTicksAndRejections (internal/process/task_queues.js:82:21) {
      config: [Object],
      request: [ClientRequest],
      response: [Object],
      isAxiosError: true,
      toJSON: [Function: toJSON]
    }
  }
}

This is the response I get when sending the request to eBay via their web tool, which includes the duplicated offer ID that I need. I can't find any way to get this from the e that is thrown by the bulkCreateOffer request.

{
  "responses": [
    {
      "statusCode": 400,
      "sku": "REDACTED",
      "marketplaceId": "EBAY_AU",
      "format": "FIXED_PRICE",
      "warnings": [],
      "errors": [
        {
          "errorId": 25002,
          "domain": "API_INVENTORY",
          "subdomain": "Selling",
          "category": "REQUEST",
          "message": "A user error has occurred. Offer entity already exists.",
          "parameters": [
            {
              "name": "offerId",
              "value": "78...[REDACTED]...18"
            }
          ]
        }
      ]
    }
  ]
}

Example buying an item from ebay?

Hello, thanks a lot for sharing this library, I really appreciate your work!

I'm trying to figure out a way to:

  1. Find and item I'm looking for ( for instance Madonna - Like a Virgin )
  2. Select the itemId from the search query
  3. Buy the item using my ebay and paypal account

This way I could "Automatically buy" an item that meets my requirements.

I tried to understand how this works from the eBay Documentation but I didn't manage to find a way yet, hopefully it's going to be much easier using your library.

Again, thank you very much.

How to authroize the client?

There are examples on how to refresh the client and oauth tokens and and example to get an oauth token. I'm trying to simply use the API from a client and am struggling to understand how to authenticate calls without having to constantly open a new tab and copy in the code.

How do you call createPaymentPolicy properly through hendt / ebay-api?

I can successfully create payment policies directly but I want to use your library to do so.

My code (which returns 404 error):

exports.createPaymentPolicy = async ( req, res ) => {
  try {
    let user = req.body.user 
    let _user = await User.findById({_id: user})
    eBay.auth.oAuth2.setCredentials(_user.token[0])
    let PaymentPolicyRequest = `{
      "categoryTypes": [     
       {     
        "default": false,     
        "name": "ALL_EXCLUDING_MOTORS_VEHICLES"     
       }     
      ],  
       "paymentMethods": [ ]
      },     
      "description": "Created from API call.",
      "immediatePay": true,     
      "marketplaceId": "EBAY_US",     
      "name": "testPayments_${_user.firstName}",
     }     
     `
    let result = await eBay.sell.account.createPaymentPolicy( PaymentPolicyRequest )
    console.log( `result...`, result ) 
    res.json( result )
  } catch ( e ) { console.log( `Got an error in createPaymentPolicy...`, e ); res.json( { error: e } ) }
}

I constantly get a 404 error when running this. What is the correct way to make this call?

Token giving access to ebay store question

Hey...I'm sorry to come back with another question.

With my GetNotificationPreferences, and SetNotificationPreferences and getOrders working in sandbox. I've added some production keys.
I've then got the owner of the ebay store account to log in and authorize a token and stored the token locally. And I can use that token to get notification preferences and orders, getting success API responses.

However, it's not bringing back ANY orders, and I'm not getting any notifications even though they have been set by the API. I can even use the API Explorer in eBay to check with the token: -

image

image

What am I missing? Why can't I get orders from the ebay store.
I'm using the sandbox = false; and the production cert, app ids etc...

It's saying Return policy is not specified when clearly it's specified

I'm having a strange issue all of a sudden when trying to add a fixed price items to ebay. Here's the errors first...

  meta: [
    {
      ShortMessage: 'Return policy is not specified.',
      LongMessage: 'A return option is missing or not valid. Update your return options.',
      ErrorCode: 21916250,
      SeverityCode: 'Error',
      ErrorParameters: [Object],
      ErrorClassification: 'RequestError'
    },
    {
      ShortMessage: 'Return policy is not specified.',
      LongMessage: 'A return option is missing or not valid. Update your return options.',
      ErrorCode: 21916250,
      SeverityCode: 'Error',
      ErrorParameters: [Object],
      ErrorClassification: 'RequestError'
    },
    {
      ShortMessage: 'Return policy is not specified.',
      LongMessage: 'A return option is missing or not valid. Update your return options.',
      ErrorCode: 21916250,
      SeverityCode: 'Error',
      ErrorParameters: [Object],
      ErrorClassification: 'RequestError'
    },
    {
      ShortMessage: 'A shipping service is not specified.',
      LongMessage: 'At least one valid shipping service must be specified.',
      ErrorCode: 21915469,
      SeverityCode: 'Error',
      ErrorClassification: 'RequestError'
    }
  ]

Yet, here is what I am sending (I removed actual values but certainly the Returns/Shipping/Payment profiles and their corresponding id numbers are going into the request to ebay to list this)...

{
	"RequesterCredentials": {
		"eBayAuthToken": "<super long access_token>"
	},
	"Item": {
		"Title": "ACME Rosia Recliner in Gray",
		"Description": {
			"__cdata": "<p>For ultimate comfort, the Rosia linen recliner is covered with smooth fabric in various color options to match with any home decor. Additional back comfort is created by the vertical stitch line and tuft while the horizontal section makes room for your shoulders. Sweeping arched overstuffed armrests are added to the comfort level by elevating your arms at an angle while reclined.</p><br /><b>Features : </b><ul><li>Motion: Reclining Function</li><li>Tight Back and Seat Cushion</li><li>Seat: Pocket Coil</li><li>Pillow Top Arm</li><li>Arm With Cup Holder</li><li>External Latch Handle (No Power)</li></ul><br /><b>Specifications : </b><ul><li>Product Dimensions : 39\" H x 32\" W x 37\" D</li><li>Product Weight : 78 lbs</li></ul>"
		},
		"PrimaryCategory": {
			"CategoryID": "54235"
		},
		"StartPrice": 485.49,
		"CategoryMappingAllowed": true,
		"Country": "US",
		"Currency": "USD",
		"ConditionID": 1000,
		"ItemSpecifics": {
			"NameValueList": [{
				"name": "Material",
				"value": "Fabric"
			}, {
				"name": "Item Height",
				"value": "39\""
			}, {
				"name": "Collection",
				"value": "Rosia"
			}, {
				"name": "Item Width",
				"value": "32\""
			}, {
				"name": "Brand",
				"value": "ACME Furniture"
			}, {
				"name": "Item Length",
				"value": "37\""
			}, {
				"name": "Model",
				"value": "59549"
			}, {
				"name": "Category",
				"value": "Recliners"
			}, {
				"name": "Color",
				"value": "Gray"
			}, {
				"name": "California Prop. 65 Warning",
				"value": "Yes"
			}, {
				"name": "Type",
				"value": "Chair"
			}, {
				"name": "UPC",
				"value": "840412111617"
			}]
		},
		"DispatchTimeMax": 3,
		"ListingDuration": "GTC",
		"ListingType": "FixedPriceItem",
		"PictureDetails": {
			"PictureURL": ["<picture url>"]
		},
		"PostalCode": "90001",
		"Quantity": "1",
		"SellerProfiles": {
			"SellerShippingProfile": {
				"ShippingProfileID": "xxxxxxxxxxx",
				"ShippingProfileName": "myShippingPolicy"
			},
			"SellerReturnProfile": {
				"ReturnProfileID": "xxxxxxxxxxx",
				"ReturnProfileName": "myReturnsPolicy"
			},
			"SellerPaymentProfile": {
				"PaymentProfileID": "xxxxxxxxxxx",
				"PaymentProfileName": "myPaymentsPolicy"
			}
		}
	}
}

I am constantly getting the error that it's missing the Shipping, Returns, and Payment Profiles are not specified, preventing me from listing further. Please help!

Having Tough Time Getting AddFixedPriceItem to list an item

Hi, I am trying to use your library with ExpressJS.

Not sure if I'm even doing this right but I have set up 4 endpoints to handle the 4 parts mentioned in your README.md:

// Step 1: Generate OAuth URL
router.post("/ebay/getoauthurl", generateEbayOauthUrl)
// Step 2: Get eBay Code
router.post("/ebayaccepted", getEbayCode)
// Step 3: get eBay Token and save to localhost
router.post("/ebay/gettoken", getToken)
// Step 4: Add Fixed Price Item
router.post("/ebay/addfixedpriceitem", addFixedPriceItem)

So, in Step 1, the controller method looks like this:

exports.generateEbayOauthUrl = ( req, res ) => {
    eBay.auth.oAuth2.setScope([
      'https://api.ebay.com/oauth/api_scope',
      'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
      'https://api.ebay.com/oauth/api_scope/sell.fulfillment'
  ]);

  const url = eBay.auth.oAuth2.generateAuthUrl();
  // 2. Open Url and Grant Access
  console.log('Open URL', url);
  res.json(url)
  
}

This endpoint successfully works and I get the response containing the url.
I am testing this in Postman, so when I see the url, I click it and then see in the browser the code in the url params.

After, I take that code and send it to Step 2, like so:

exports.getEbayCode = ( req, res ) => {
  let code = req.params.code
  const expires_in = req.params.expires_in
  res.json({code, expires_in})

}

But when I try to get the token, it fails. Here is my code to handle getting the token:

exports.getToken = async (req, res) => {
  let code = req.body.code  // oauth granted code
  
  const token = await eBay.auth.oAuth2.getToken(code);

  let result = eBay.auth.oAuth2.setCredentials(token);
  res.json(result)

}

Here is what the error shows:

(node:20020) UnhandledPromiseRejectionWarning: Error: Request failed with status code 400
    at createError (C:\Users\Eric\Desktop\wiki\e\ebay\ebay-selling-platform\backend\node_modules\axios\lib\core\createError.js:16:15)
    at settle (C:\Users\Eric\Desktop\wiki\e\ebay\ebay-selling-platform\backend\node_modules\axios\lib\core\settle.js:17:12)
    at IncomingMessage.handleStreamEnd (C:\Users\Eric\Desktop\wiki\e\ebay\ebay-selling-platform\backend\node_modules\axios\lib\adapters\http.js:260:11)
    at IncomingMessage.emit (events.js:327:22)
    at IncomingMessage.EventEmitter.emit (domain.js:486:12)
    at endReadableNT (_stream_readable.js:1327:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)
(node:20020) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with 
.catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:20020) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

As a result, I never make it to list the AddFixedPriceItem call to try to list.

I am pretty sure I got the above steps wrong but I did not find any examples of what a successful call from beginning to end is.

Please help and give guidance so I can finally use this library to list items to ebay! Thank you!

Using HTML in Description of AddFixedPriceItem results in Schema XML request error

I've got the API creating new eBay listings and everything works fine when I just include text as the description. For example, this works great:

Screen Shot 2020-11-10 at 12 53 18 PM

But when I add any html tags, such as the following:

Screen Shot 2020-11-10 at 12 52 49 PM

...I get this error:

"Schema XML request error: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize"

Screen Shot 2020-11-10 at 12 53 59 PM

Site Id is staying on German even if I put the enum or manual number

Have my setup like this

   this.ebay = new eBayApi({
      appId: process.env.EBAY_APP_ID,
      certId: process.env.EBAY_CERT_ID,
      sandbox: false,
      scope: ['https://api.ebay.com/oauth/api_scope'],
      siteId: eBayApi.SiteId.EBAY_US,
      devId: process.env.EBAY_DEV_ID,
    });

Yet in the headers I keep seeing it set to German

headers: {
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache',
    'Accept-Encoding': 'application/gzip',
    'X-EBAY-C-MARKETPLACE-ID': 'EBAY_DE',
    Authorization: ...

I've tried with just 0 as well but the same issue. Any ideas?

Hi how to address that cannot use import

I want to use this module in aws Lambda/cloud9, but I can't import it in my js file, only can use 'require'. I found many ways to transforms the two forms, but they all can't be used in Lambda this cloud server platform.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.