2

I'm trying to access GetDealItems API and i have a nightmare to get this working. Even though I use the valid client_id','client_secret','ruName' i keep getting

{'error': 'invalid_client', 'error_description': 'client authentication failed'}

below is the ebay doc

https://developer.ebay.com/api-docs/buy/deal/resources/deal_item/methods/getDealItems

I guess i need to use this scope and url in my request

scopes:'https://api.ebay.com/oauth/api_scope/buy.deal' and the 
url='https://api.ebay.com/buy/deal/v1/deal_item?limit=1000'

Please see below my Python code.

import requests, urllib, base64

def getAuthToken():
    AppSettings = {
          'client_id':'xxxx7c8ec878c-c80c4c69',
          'client_secret':'xxxx56db-4b4a-97b4-fad2',
          'ruName':'xxxxx-gscrcsrtj'}

    authHeaderData = AppSettings['client_id'] + ':' + AppSettings['client_secret']
    encodedAuthHeader = base64.b64encode(str.encode(authHeaderData))

    headers = {
          "Content-Type" : "application/x-www-form-urlencoded", 
          "Authorization" : "Bearer " + str(encodedAuthHeader)
          }

    body= {
          "grant_type" : "client_credentials",
          "redirect_uri" : AppSettings['ruName'],
          "scope" : "https://api.ebay.com/oauth/api_scope/buy.deal"
      }

    data = urllib.parse.urlencode(body)

    tokenURL = "https://api.ebay.com/identity/v1/oauth2/token"

    response = requests.post(tokenURL, headers=headers, data=data) 
    return response.json()


response = getAuthToken()
print(response)
response['access_token'] #access keys as required
response['error_description'] #if errors
sunny babau
  • 195
  • 1
  • 3
  • 17

2 Answers2

4

The most obvious problem I see is that you are using Bearer when you should be using Basic in your Authorization header.

Also, You are urlencoding your redirect_url when you pass the entire dictionary into urlencode. The docs say you are supposed to urlencode the scope parameter, but honestly, I never encode the scope and it still works for me.

Here is your modified code, with a few formatting changes:

import requests, urllib, base64

client_id='xxxx7c8ec878c-c80c4c69'
client_secret='xxxx56db-4b4a-97b4-fad2'
ruName='xxxxx-gscrcsrtj'

scope = urllib.parse.quote('https://api.ebay.com/oauth/api_scope/buy.deal')

def basic_token(key, secret):
    return 'Basic ' + base64.b64encode((key + ':' + secret).encode()).decode()

def getAuthToken():

    headers = {
        "Content-Type" : "application/x-www-form-urlencoded",
        "Authorization" : basic_token(client_id, client_secret)
    }

    data = (
        'grant_type=client_credentials&'
        f'redirect_uri={ruName}&'
        f'scope={scope}'
    )

    tokenURL = "https://api.ebay.com/identity/v1/oauth2/token"

    response = requests.post(tokenURL, headers=headers, data=data)
    return response.json()

Update:

I think you need to use the authorization_code grant instead of client_credentials.

To use the authorization_code grant, modify your body to look like this:

data = (
    'grant_type=authorization_code&'
    f'code={authorization_code}&'
    f'redirect_uri={ruName}&'
    f'scope={scope}'
)

Also, you will need to follow your "redirect url" to get the actual authorization code. Execute the following:

redirect_url = (
    'https://auth.ebay.com/oauth2/authorize?'
    f'client_id={client_id}&'
    f'response_type=code&'
    f'redirect_uri={ruName}&'
    f'scope={scope}'
)
print(redirect_url)

Copy/paste the url from stdout, follow the link, and click "accept", then you will be redirected to a url that looks like this:

https://signin.ebay.com/ws/eBayISAPI.dll?ThirdPartyAuthSucessFailure&isAuthSuccessful=true&code=<authorization code here>&expires_in=299

Copy/paste the authorization code into your code, then see if it works.

Realistically, eBay expects you to automate this within your application using a server, but it doesn't make sense for you to go through the trouble if you are building an app for personal use.

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • so i just added r = response.json() and then print(r) and i get "{'error': 'invalid_request', 'error_description': 'request is missing a required parameter or malformed.'}" Is it because of buy.deal scope on my account? if yes, how do i get that scope?? – sunny babau Jul 23 '20 at 23:03
  • @sunnybabau I think the problem is with the `client_credentials` grant, because the `buy.deal` scope isn't specified under the [allowed scopes](https://developer.ebay.com/api-docs/static/oauth-scopes.html) for client credentials. I'll update to walk you through using the `authorization_code` grant flow. – Lord Elrond Jul 23 '20 at 23:13
  • sadly i get this after clicking on the redirect_url "{"error_id":"unauthorized_client","error_description":"The OAuth client was not found.","http_status_code":401}" – sunny babau Jul 23 '20 at 23:34
  • @sunnybabau Try using the redirect url they give you at the [application keys](https://developer.ebay.com/my/keys) dashboard. – Lord Elrond Jul 23 '20 at 23:37
  • I appreciate all the help.. so i took the successful "code=" from UI and copy and replaced code={authorization_code} and yet i get "{'error': 'invalid_request', 'error_description': 'request is missing a required parameter or malformed.'}" – sunny babau Jul 23 '20 at 23:56
  • Do you think I should activate eBay premium support and get this solved please? – sunny babau Jul 24 '20 at 13:43
  • @sunnybabau Are you using production keys? According to the [Buy API](https://developer.ebay.com/api-docs/buy/deal/static/overview.html): *"The use of eBay’s Buy APIs in production is intended for eBay partners only."* This might be why you are getting errors, also, I doubt premium support would help if this were the case. – Lord Elrond Jul 24 '20 at 16:56
  • Sorry I couldn't tell you this earlier. I don't have experience with the Buy API specifically. – Lord Elrond Jul 24 '20 at 16:56
  • No problem thank you for all the support. Also, was curious if you can provide ur expert guidance on this please https://stackoverflow.com/questions/63079625/python-xml-parse-and-getelementsbytagname – sunny babau Jul 24 '20 at 18:50
0

GetDealItems API uses client_credentials grant as evident from the docs

enter image description here

The authorization should be using client_id and secret as described in getting access tokens

curl -X POST 'https://api.ebay.com/identity/v1/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic UkVTVFRlc3...wZi1hOGZhLTI4MmY=' \
-d 'grant_type=client_credentials&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fbuy.deal'

Note: if the error is client_authorization_failed, ensure that the correct Keyset for production is used for production. Also ensure that the keyset is also enabled for Oauth

Finally, you can use/refer to the official python SDK as well here

A simple way to check if the particular scope, in this case https://api.ebay.com/oauth/api_scope/buy.deal is even allowed for this app, is to navigate to the keyset page under Keys link and click on "Oauth scopes" under the keyset which details the scopes allowed and their purpose. If the application is once authorized for buy.deal, then the scope will appear there.

enter image description here

UPDATE

GetDeals API is restricted in Production for authorized applications only. Please reach out to the eBay developer program as provided in the link on the page below.

https://developer.ebay.com/api-docs/buy/deal/overview.html#API

enter image description here

  • Thanks you. So i have tried with both Basic Base64 encode the following: : and as well as Basic keyset for production and nothing seem to work?? – sunny babau Jul 27 '20 at 04:49
  • @sunnybabau I believe your app is not authorized for buy.deal scope as it needs explicit agreements. I have edited my answer above with more details. – Senthilkumar Gopal Jul 28 '20 at 15:52