Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
doverradio opened this issue Jun 16, 2021 · 2 comments

Comments

@doverradio
Copy link

doverradio commented Jun 16, 2021

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": []
}
@dantio
Copy link
Collaborator

dantio commented Jun 17, 2021

We also using Express as Backend. I don't know what exactly is the error. Here is how we do the call, maybe it helps:

const eBay = new eBayApi({
  // ....
  scope: [
          '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.readonly',
          'https://api.ebay.com/oauth/api_scope/sell.account',
          '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'
        ]
});

const token = await getFromDb(); // get the token that was created in the ebay sign in process
eBay.setCredentials(token);

// Listen to refresh token event, and update the token in the DB
eBay.OAuth2.on('refreshAuthToken', (token: any) => {
      storeInDb(token).then(() => console.log('token is stored'))
});

eBay.sell.fulfillment.getOrders({
  limit: 5
}).then(order => {
  console.log('order', JSON.stringify(order, null, 2));
}).catch(e => {
  console.error(JSON.stringify(e, null, 2));
});

Check if you always use the same scope for sign in and API request.
You have to generate the first token with all scopes you need for you app.
If you add a new scopes later and use a token that was not authorized with this scope, it will not work!
I'm sure that refreshing the token will also not help. You have to obtain the token already with all required scopes!

Btw. You don't need to refresh it manually. It's done automatically. You can listen to the event and store the token (as shown in the example above)

@doverradio
Copy link
Author

Thank you, it completely works now for me. In the end, it was passing in the original complete token object that solved it...

  let user = await User.findById({_id})
  
  // set OAuth2 eBay credentials
  eBay.auth.oAuth2.setCredentials(user.token[0])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants